Domanda

Sto cercando di avviare un processo su un computer remoto. Sto usando OpenSCManager (), CreateService (), QueryServiceStatusEx () e StartService () API-s. Sono in grado di installare correttamente il mio processo come un servizio, ma quando sto cercando di avviarlo, StartService restituisce con il codice di errore 1053 (" Il servizio non ha risposto alla richiesta di avvio o controllo in modo tempestivo. & Quot; ). Qualcuno può aiutarmi a risolvere questo problema?

Grazie in anticipo!

kampi

Aggiornamento: ecco il mio codice finora (quasi da msdn, ma ho modificato un po ')

#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);
}
È stato utile?

Soluzione

Penso che qui manchi un componente chiave: avviare Service Control Dispatcher . Come indicato nella documentazione devi avviare il dispatcher di controllo del servizio per consentire a Service Control Manager (SCM) di Windows di inviare comandi al tuo servizio (come SERVICE_CONTROL_STOP per esempio)

L'avvio del dispatcher avviene come segue:

  1. crea un SERVICE_TABLE_ENTRY ( guarda la libreria MSDN ) contenente il nome dei tuoi servizi e la funzione principale del servizio (che è diversa dal tuo normale metodo principale!)
  2. avvia il Dispatcher controllo servizi con questa voce della tabella di servizio

Lo sfondo è che ogni servizio viene avviato tramite SCM, in attesa che il servizio inizi Service Control Dispatcher per ricevere i suoi comandi ...

Vedo un altro problema nel tuo codice: stai provando a installare il tuo servizio ogni volta che viene avviato! Faresti meglio a cercare gli opportuni argomenti della riga di comando per determinare se il servizio verrà installato o avviato!

Altri suggerimenti

È possibile che il servizio venga chiuso immediatamente o si blocchi. Consiglierei di aggiungere alcune informazioni di registrazione al tuo servizio per scoprire perché sta uscendo.

In realtà quello che stai provando a fare è Impersonare il pc remoto. Se il PC utilizza Windows XP, per creare servizi sono necessari privilegi diversi dall'amministratore. Per regolare i privilegi, vedere la politica di sistema locale nel PC remoto. A proposito, puoi semplicemente aprire la quota ADMIN $ nel PC remoto dal tuo? in caso contrario, questo è il problema.

per ulteriori riferimenti consultare psexec in sysinternals.

NO BSOD, No Rootkit, No Fun - Biswanath Chowdhury (sviluppatore del kernel Win32)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top