2009-10-28 4 views
0

J'essaie de démarrer un processus sur une machine distante. J'utilise OpenSCManager(), CreateService(), QueryServiceStatusEx() et API StartService(). Je réussis à installer mon processus en tant que serice, mais lorsque j'essaie de le démarrer, StartService revient avec le code d'erreur 1053 ("Le service n'a pas répondu à la demande de démarrage ou de contrôle en temps voulu."). Quelqu'un peut m'aider à résoudre ce problème?StartService échoue avec le code d'erreur 1053

Merci d'avance!

Kampi

Mise à jour: Voici mon code jusqu'à présent (presque de msdn, mais j'ai édité un peu)

#include <windows.h> 
VOID SvcInstall(); 
VOID __stdcall DoStartSvc(); 

#pragma comment(lib, "Advapi32.lib") 
SC_HANDLE schSCManager; 
SC_HANDLE schService; 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
SvcInstall(); 
DoStartSvc(); 

return 0; 
} 

VOID SvcInstall() 
{ 
SC_HANDLE schSCManager; 
SC_HANDLE schService; 
TCHAR szPath[MAX_PATH]; 

if(!GetModuleFileName(NULL, szPath, MAX_PATH)) 
{ 
    printf("Cannot install service (%d)\n", GetLastError()); 
    return; 
} 

// Get a handle to the SCM database. 

schSCManager = OpenSCManager( 
    _T("\\\\kampimachine"), // remote computer 
    NULL,     // ServicesActive database 
    SC_MANAGER_ALL_ACCESS); // full access rights 

if (NULL == schSCManager) 
{ 
    printf("OpenSCManager failed (%d)\n", GetLastError()); 
    return; 
} 

// Create the service 
schService = CreateService( 
    schSCManager,    // SCM database 
    _T("kampi"),     // name of service 
    _T("kampi"),     // service name to display 
    SERVICE_ALL_ACCESS,  // desired access 
    SERVICE_WIN32_OWN_PROCESS, // service type 
    SERVICE_DEMAND_START,  // start type 
    SERVICE_ERROR_NORMAL,  // error control type 
    _T("%SystemRoot%\\system32\\notepad.exe"),// path to service's binary 
    NULL,      // no load ordering group 
    NULL,      // no tag identifier 
    NULL,      // no dependencies 
    _T("domain\\user"), // LocalSystem account 
    _T("password"));   // no password 

if (schService == NULL) 
{ 
    printf("CreateService failed (%d)\n", GetLastError()); 
    CloseServiceHandle(schSCManager); 
    return; 
} 
else printf("Service installed successfully\n"); 

CloseServiceHandle(schService); 
CloseServiceHandle(schSCManager); 
} 

VOID __stdcall DoStartSvc() 
{ 
SERVICE_STATUS_PROCESS ssStatus; 
DWORD dwOldCheckPoint; 
DWORD dwStartTickCount; 
DWORD dwWaitTime; 
DWORD dwBytesNeeded; 

// Get a handle to the SCM database. 

schSCManager = OpenSCManager( 
    _T("\\\\kampimachine"),  // remote computer 
    NULL,     // servicesActive database 
    SC_MANAGER_ALL_ACCESS); // full access rights 

if (NULL == schSCManager) 
{ 
    printf("OpenSCManager failed (%d)\n", GetLastError()); 
    return; 
} 

// Get a handle to the service. 

schService = OpenService( 
    schSCManager,   // SCM database 
    _T("kampi"),   // name of service 
    SERVICE_ALL_ACCESS); // full access 

if (schService == NULL) 
{ 
    printf("OpenService failed (%d)\n", GetLastError()); 
    CloseServiceHandle(schSCManager); 
    return; 
}  

// Check the status in case the service is not stopped. 

if (!QueryServiceStatusEx( 
     schService,      // handle to service 
     SC_STATUS_PROCESS_INFO,   // information level 
     (LPBYTE) &ssStatus,    // address of structure 
     sizeof(SERVICE_STATUS_PROCESS), // size of structure 
     &dwBytesNeeded))    // size needed if buffer is too small 
{ 
    printf("QueryServiceStatusEx failed (%d)\n", GetLastError()); 
    CloseServiceHandle(schService); 
    CloseServiceHandle(schSCManager); 
    return; 
} 

// Check if the service is already running. It would be possible 
// to stop the service here, but for simplicity this example just returns. 

if(ssStatus.dwCurrentState != SERVICE_STOPPED && ssStatus.dwCurrentState != SERVICE_STOP_PENDING) 
{ 
    printf("Cannot start the service because it is already running\n"); 
    CloseServiceHandle(schService); 
    CloseServiceHandle(schSCManager); 
    return; 
} 

// Save the tick count and initial checkpoint. 

dwStartTickCount = GetTickCount(); 
dwOldCheckPoint = ssStatus.dwCheckPoint; 

// Wait for the service to stop before attempting to start it. 

while (ssStatus.dwCurrentState == SERVICE_STOP_PENDING) 
{ 
    // Do not wait longer than the wait hint. A good interval is 
    // one-tenth of the wait hint but not less than 1 second 
    // and not more than 10 seconds. 

    dwWaitTime = ssStatus.dwWaitHint/10; 

    if(dwWaitTime < 1000) 
     dwWaitTime = 1000; 
    else if (dwWaitTime > 10000) 
     dwWaitTime = 10000; 

    Sleep(dwWaitTime); 

    // Check the status until the service is no longer stop pending. 

    if (!QueryServiceStatusEx( 
      schService,      // handle to service 
      SC_STATUS_PROCESS_INFO,   // information level 
      (LPBYTE) &ssStatus,    // address of structure 
      sizeof(SERVICE_STATUS_PROCESS), // size of structure 
      &dwBytesNeeded))    // size needed if buffer is too small 
    { 
     printf("QueryServiceStatusEx failed (%d)\n", GetLastError()); 
     CloseServiceHandle(schService); 
     CloseServiceHandle(schSCManager); 
     return; 
    } 

    if (ssStatus.dwCheckPoint > dwOldCheckPoint) 
    { 
     // Continue to wait and check. 

     dwStartTickCount = GetTickCount(); 
     dwOldCheckPoint = ssStatus.dwCheckPoint; 
    } 
    else 
    { 
     if(GetTickCount()-dwStartTickCount > ssStatus.dwWaitHint) 
     { 
      printf("Timeout waiting for service to stop\n"); 
      CloseServiceHandle(schService); 
      CloseServiceHandle(schSCManager); 
      return; 
     } 
    } 
} 

// Attempt to start the service. 

if (!StartService(
     schService, // handle to service 
     0,   // number of arguments 
     NULL))  // no arguments 
{ 
    printf("StartService failed (%d)\n", GetLastError()); 
    CloseServiceHandle(schService); 
    CloseServiceHandle(schSCManager); 
    return; 
} 
else printf("Service start pending...\n"); 

// Check the status until the service is no longer start pending. 

if (!QueryServiceStatusEx( 
     schService,      // handle to service 
     SC_STATUS_PROCESS_INFO,   // info level 
     (LPBYTE) &ssStatus,    // address of structure 
     sizeof(SERVICE_STATUS_PROCESS), // size of structure 
     &dwBytesNeeded))    // if buffer too small 
{ 
    printf("QueryServiceStatusEx failed (%d)\n", GetLastError()); 
    CloseServiceHandle(schService); 
    CloseServiceHandle(schSCManager); 
    return; 
} 

// Save the tick count and initial checkpoint. 

dwStartTickCount = GetTickCount(); 
dwOldCheckPoint = ssStatus.dwCheckPoint; 

while (ssStatus.dwCurrentState == SERVICE_START_PENDING) 
{ 
    // Do not wait longer than the wait hint. A good interval is 
    // one-tenth the wait hint, but no less than 1 second and no 
    // more than 10 seconds. 

    dwWaitTime = ssStatus.dwWaitHint/10; 

    if(dwWaitTime < 1000) 
     dwWaitTime = 1000; 
    else if (dwWaitTime > 10000) 
     dwWaitTime = 10000; 

    Sleep(dwWaitTime); 

    // Check the status again. 

    if (!QueryServiceStatusEx( 
     schService,    // handle to service 
     SC_STATUS_PROCESS_INFO, // info level 
     (LPBYTE) &ssStatus,    // address of structure 
     sizeof(SERVICE_STATUS_PROCESS), // size of structure 
     &dwBytesNeeded))    // if buffer too small 
    { 
     printf("QueryServiceStatusEx failed (%d)\n", GetLastError()); 
     break; 
    } 

    if (ssStatus.dwCheckPoint > dwOldCheckPoint) 
    { 
     // Continue to wait and check. 

     dwStartTickCount = GetTickCount(); 
     dwOldCheckPoint = ssStatus.dwCheckPoint; 
    } 
    else 
    { 
     if(GetTickCount()-dwStartTickCount > ssStatus.dwWaitHint) 
     { 
      // No progress made within the wait hint. 
      break; 
     } 
    } 
} 

// Determine whether the service is running. 

if (ssStatus.dwCurrentState == SERVICE_RUNNING) 
{ 
    printf("Service started successfully.\n"); 
} 
else 
{ 
    printf("Service not started. \n"); 
    printf(" Current State: %d\n", ssStatus.dwCurrentState); 
    printf(" Exit Code: %d\n", ssStatus.dwWin32ExitCode); 
    printf(" Check Point: %d\n", ssStatus.dwCheckPoint); 
    printf(" Wait Hint: %d\n", ssStatus.dwWaitHint); 
} 

CloseServiceHandle(schService); 
CloseServiceHandle(schSCManager); 
} 
+0

CAn vous montre le code actuel? –

+0

Bien sûr! C'est ici :) – kampi

Répondre

1

Je pense que vous manque un élément clé ici: à partir Service de contrôle Dispatcher. Comme indiqué dans le documentation vous devez démarrer le répartiteur de contrôle de service afin de permettre Service Control Manager Windows (SCM) pour envoyer des commandes à votre service (comme SERVICE_CONTROL_STOP par exemple)

Démarrage du régulateur se fait comme suit :

  1. créer un SERVICE_TABLE_ENTRY (look at MSDN library) contenant vos nom services ainsi que sa fonction principale service (Wich est différent de votre méthode ordinaire principale!)
  2. démarrer le contrôle service Dispatcher avec cette entrée de table de service

L'arrière-plan est que chaque service est démarré par SCM, qui attend que le service démarre son Service Control Dispatcher afin de recevoir ses commandes ...

Je vois un autre problème dans votre code: vous essayez d'installer votre service à chaque démarrage! Vous feriez mieux de vérifier les arguments de ligne de commande appropriés pour déterminer si le service va être installé ou démarré!

1

Il y a une bonne chance que votre service est soit d'arrêter immédiatement ou écraser . Je recommande d'ajouter des informations de connexion à votre service afin de découvrir pourquoi il se termine.

0

En fait, ce que vous essayez de faire, c'est d'usurper l'identité du PC distant. Si le PC utilise Windows XP, vous avez besoin de privilèges autres que l'administrateur pour créer des services. Pour ajuster les privilèges, voir la politique Système local sur le PC distant. En passant, pouvez-vous simplement ouvrir le partage ADMIN $ dans le PC distant du vôtre? sinon, alors c'est le problème.

pour d'autres références, consultez psexec dans sysinternals.

NO BSOD, No Rootkit, No Fun - Biswanath Chowdhury (Win32 noyau développeur)

Questions connexes