Freigeben über


Registrieren zum Ausführen eines Programms

Sie können sich registrieren, damit BITS ein Programm basierend auf Auftragsübermittlungen und Fehlerereignissen, aber nicht auf Auftragsänderungsereignissen ausführt. BITS führt das Programm im Kontext des Benutzers aus.

So registrieren Sie sich zum Ausführen eines Programms

  1. Rufen Sie die IBackgroundCopyJob::QueryInterface-Methode auf, um einen IBackgroundCopyJob2-Schnittstellenzeiger abzurufen. Geben Sie __uuidof(IBackgroundCopyJob2) als Schnittstellenbezeichner an.

  2. Rufen Sie die IBackgroundCopyJob2::SetNotifyCmdLine-Methode auf, um das auszuführende Programm und alle vom Programm erforderlichen Argumente wie den Auftragsbezeichner anzugeben.

  3. Rufen Sie die IBackgroundCopyJob::SetNotifyFlags-Methode auf, um anzugeben, wann die Befehlszeile ausgeführt wird.

    Sie können nur die BG_NOTIFY_JOB_TRANSFERRED und BG_NOTIFY_JOB_ERROR Ereignisflags angeben. Das BG_NOTIFY_JOB_MODIFICATION-Flag 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 wenn die Benachrichtigungsmethode, die BITS-Aufrufe enthält, einen Erfolgscode zurückgibt. Wenn die Benachrichtigungsmethode jedoch einen Fehlercode wie E_FAIL zurückgibt, führt BITS die Befehlszeile aus.

BITS ruft die Funktion CreateProcessAsUser auf, um das Programm zu starten. Wenn Sie eine Parameterzeichenfolge angeben, muss der erste Parameter der Programmname sein.

Das folgende Beispiel zeigt, wie Sie sich registrieren, um ein Programm auszuführen, wenn das Auftragsübermittlungsereignis 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_TRANSFERRED 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 das Programm ü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);
}