Registrieren zum Ausführen eines Programms
Sie können sich registrieren, damit BITS ein Programm basierend auf übertragenen Aufträgen und Fehlerereignissen, aber nicht auf Ereignissen mit Auftragsänderung ausführt. BITS führt das Programm im Kontext des Benutzers aus.
So registrieren Sie sich zum Ausführen eines Programms
Rufen Sie die IBackgroundCopyJob::QueryInterface-Methode auf, um einen IBackgroundCopyJob2-Schnittstellenzeiger abzurufen. Geben Sie _ _ uuidof(IBackgroundCopyJob2) als Schnittstellenbezeichner an.
Rufen Sie die IBackgroundCopyJob2::SetNotifyCmdLine-Methode auf, um das auszuführende Programm und alle vom Programm benötigten Argumente anzugeben, z. B. den Auftragsbezeichner.
Rufen Sie die IBackgroundCopyJob::SetNotifyFlags-Methode auf, um anzugeben, wann die Befehlszeile ausgeführt wird.
Sie können nur die Ereignisflags BG _ NOTIFY _ JOB _ TRANSFERD und BG NOTIFY JOB _ _ ERROR _ angeben. Das FLAG BG _ NOTIFY JOB MODIFICATION wird _ _ ignoriert.
Beachten Sie, dass BITS das Programm nicht ausführt, wenn Sie sich auch für den Empfang von COM-Rückrufen registriert haben und der Rückrufschnittstellenzeiger gültig ist oder die von BITS aufgerufene Benachrichtigungsmethode einen Erfolgscode zurückgibt. Wenn die Benachrichtigungsmethode jedoch einen Fehlercode zurückgibt, _ z. B. E FAIL, führt BITS die Befehlszeile aus.
BITS ruft die CreateProcessAsUser-Funktion auf, um das Programm zu starten. Wenn Sie eine Parameterzeichenfolge angeben, muss der erste Parameter der Programmname sein.
Im folgenden Beispiel wird gezeigt, wie sie registriert werden, um ein Programm auszuführen, wenn das vom Auftrag übertragene Ereignis auftritt. Im Beispiel wird davon ausgegangen, dass der IBackgroundCopyJob-Schnittstellenzeiger gültig ist.
#define MAX_PARAMETER_LEN 4000
HRESULT hr;
IBackgroundCopyJob* pJob;
IBackgroundCopyJob2* pJob2 = NULL;
WCHAR szJobId[48];
const WCHAR *pProgram = L"c:\\PATHHERE\\PROGRAMNAMEHERE.exe";
WCHAR szParameters[MAX_PARAMETER_LEN+1];
GUID JobId;
int rc;
hr = pJob->GetId(&JobId);
if (SUCCEEDED(hr))
{
rc = StringFromGUID2(JobId, szJobId, ARRAYSIZE(szJobId));
if (rc)
{
StringCchPrintf(szParameters, MAX_PARAMETER_LEN+1, L"%s %s", pProgram, szJobId);
pJob->QueryInterface(__uuidof(IBackgroundCopyJob2), (void**)&pJob2);
hr = pJob2->SetNotifyCmdLine(pProgram, szParameters);
if (SUCCEEDED(hr))
{
hr = pJob->SetNotifyFlags(BG_NOTIFY_JOB_TRANSFERRED);
}
pJob2->Release();
if (FAILED(hr))
{
//Handle error - unable to register for command line notification.
}
}
}
Wenn der Status des Auftrags BG _ JOB _ STATE _ TRANSFERD wird, führt BITS das in pProgram angegebene Programm aus. Das folgende Beispiel ist eine einfache Implementierung eines Programms, das einen Auftragsbezeichner als Argument verwendet. Das Programm geht davon aus, dass die richtige Anzahl von Argumenten an sie übergeben wird.
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
#include <windows.h>
#include <bits.h>
#include <strsafe.h>
int wmain(int argc, wchar_t *argv[])
{
HRESULT hr;
IBackgroundCopyManager *pManager = NULL;
IBackgroundCopyJob *pJob = NULL;
GUID JobId;
LPWSTR pDisplayName = NULL;
LPCWSTR pSuccessString = L" completed successfully.";
LPWSTR pMessage;
hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
hr = CoCreateInstance(__uuidof(BackgroundCopyManager),
NULL, CLSCTX_LOCAL_SERVER,
__uuidof(IBackgroundCopyManager), (void**)&pManager);
if (pManager)
{
hr = CLSIDFromString(argv[1], &JobId);
if (SUCCEEDED(hr))
{
hr = pManager->GetJob(JobId, &pJob);
if (SUCCEEDED(hr))
{
hr = pJob->GetDisplayName(&pDisplayName);
if (SUCCEEDED(hr))
{
int messageLen = wcslen(pDisplayName) + wcslen(pSuccessString) + 1;
pMessage = (WCHAR*)malloc(messageLen * sizeof(WCHAR));
if (pMessage)
{
StringCchPrintf(pMessage, messageLen,
L"%s%s", pDisplayName, pSuccessString);
MessageBox(HWND_DESKTOP, pMessage, L"MyProgram - Transferred", MB_OK);
free(pMessage);
}
else
{
hr = E_OUTOFMEMORY;
}
CoTaskMemFree(pDisplayName);
}
pJob->Release();
}
}
pManager->Release();
}
CoUninitialize();
return(hr);
}