Partager via


Inscription à l’exécution d’un programme

Vous pouvez vous inscrire pour que BITS exécute un programme basé sur le transfert de travail et les événements d’erreur, mais pas sur les événements de modification du travail. BITS exécute le programme dans le contexte de l’utilisateur.

Pour s’inscrire pour exécuter un programme

  1. Appelez la méthode IBackgroundCopyJob::QueryInterface pour récupérer un pointeur d’interface IBackgroundCopyJob2 . Spécifiez __uuidof(IBackgroundCopyJob2) comme identificateur d’interface.

  2. Appelez la méthode IBackgroundCopyJob2::SetNotifyCmdLine pour spécifier le programme à exécuter et tous les arguments requis par le programme, tels que l’identificateur du travail.

  3. Appelez la méthode IBackgroundCopyJob::SetNotifyFlags pour spécifier quand la ligne de commande s’exécute.

    Vous pouvez uniquement spécifier les indicateurs d’événement BG_NOTIFY_JOB_TRANSFERRED et BG_NOTIFY_JOB_ERROR. L’indicateur BG_NOTIFY_JOB_MODIFICATION est ignoré.

Notez que BITS n’exécutera pas le programme si vous vous êtes également inscrit pour recevoir des rappels COM et que le pointeur d’interface de rappel est valide ou si la méthode de notification que BITS appelle retourne un code de réussite. Toutefois, si la méthode de notification retourne un code d’échec, tel que E_FAIL, BITS exécute la ligne de commande.

BITS appelle la fonction CreateProcessAsUser pour lancer le programme. Si vous spécifiez une chaîne de paramètre, le premier paramètre doit être le nom du programme.

L’exemple suivant montre comment s’inscrire pour exécuter un programme lorsque l’événement transféré par le travail se produit. L’exemple suppose que le pointeur d’interface IBackgroundCopyJob est valide.

#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.
    }
  }
}

Lorsque l’état du travail devient BG_JOB_STATE_TRANSFERRED, BITS exécute le programme spécifié dans pProgram. L’exemple suivant est une implémentation simple d’un programme qui prend un identificateur de travail comme argument. Le programme suppose que le nombre correct d’arguments lui sont passés.

#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);
}