Condividi tramite


Registrazione per l'esecuzione di un programma

È possibile registrarsi per fare in modo che BITS eseseguono un programma in base agli eventi di errore e trasferiti processi, ma non agli eventi di modifica del processo. BITS esegue il programma nel contesto dell'utente.

Per registrarsi per eseguire un programma

  1. Chiamare il metodo IBackgroundCopyJob::QueryInterface per recuperare un puntatore all'interfaccia IBackgroundCopyJob2 . Specificare __uuidof(IBackgroundCopyJob2) come identificatore dell'interfaccia.

  2. Chiamare il metodo IBackgroundCopyJob2::SetNotifyCmdLine per specificare il programma da eseguire ed eventuali argomenti richiesti dal programma, ad esempio l'identificatore del processo.

  3. Chiamare il metodo IBackgroundCopyJob::SetNotifyFlags per specificare quando viene eseguita la riga di comando.

    È possibile specificare solo i flag di evento BG_NOTIFY_JOB_TRANSFERRED e BG_NOTIFY_JOB_ERROR. Il flag BG_NOTIFY_JOB_MODIFICATION viene ignorato.

Si noti che BITS non eseguirà il programma se è stato registrato anche per ricevere callback COM e il puntatore all'interfaccia di callback è valido o il metodo di notifica che le chiamate BITS restituisce un codice di esito positivo. Tuttavia, se il metodo di notifica restituisce un codice di errore, ad esempio E_FAIL, BITS eseguirà la riga di comando.

BITS chiama la funzione CreateProcessAsUser per avviare il programma. Se si specifica una stringa di parametro, il primo parametro deve essere il nome del programma.

Nell'esempio seguente viene illustrato come eseguire la registrazione per eseguire un programma quando si verifica l'evento trasferito dal processo. Nell'esempio si presuppone che il puntatore all'interfaccia IBackgroundCopyJob sia valido.

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

Quando lo stato del processo diventa BG_JOB_STATE_TRANSFERRED, BITS esegue il programma specificato in pProgram. L'esempio seguente è una semplice implementazione di un programma che accetta un identificatore di processo come argomento. Il programma presuppone che al programma venga passato il numero corretto di argomenti.

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