2009-10-28 279 views
0

我試圖在遠程計算機上啓動一個進程。我正在使用OpenSCManager(),CreateService(),QueryServiceStatusEx()和StartService()API-s。我能夠成功地將我的進程安裝爲serice,但是當我嘗試啓動它時,StartService會返回錯誤代碼1053(「服務沒有及時響應啓動或控制請求」)。任何人都可以幫我解決這個問題嗎?StartService失敗,錯誤代碼爲1053

在此先感謝!

kampi

更新:這是我到目前爲止的代碼(幾乎從MSDN,但我已經編輯了一下)

#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

您是否顯示實際的代碼? – 2009-10-29 00:10:54

+0

當然!這裏是 :) – kampi 2009-10-29 01:30:13

回答

1

我覺得你在這裏缺少的重要組成部分:啓動服務控制調度。正如documentation說你必須爲了使Windows的服務控制管理器(SCM)將命令發送到您的服務啓動,服務控制調度程序如下(如SERVICE_CONTROL_STOP例如)

啓動調度完成:

  1. 創建SERVICE_TABLE_ENTRYlook at MSDN library)包含您服務的名字以及其服務主要功能(至極是從普通的主要方法不同!)
  2. 開始服務控制調度與此服務表項

背景是,每一個服務都正在通過供應鏈管理開始,即等待服務,以獲得它的命令開始其Service Control Dispatcher ...

我在代碼中看到另一個問題:您正試圖在每次啓動時安裝您的服務!您最好檢查適當的命令行參數以確定服務是要安裝還是開始!

1

這是一個很好的機會,你的服務是可以立即關閉或崩潰。我會建議添加一些日誌信息到您的服務,以發現它爲什麼退出。

0

其實你試圖做的是冒充遠程電腦。如果電腦使用的是Windows XP,則需要管理員以外的特權才能創建服務。要調整權限,請參閱遠程PC中的本地系統策略。順便說一下,你是否可以在你的遠程PC上打開ADMIN $共享?如果不是,那麼這就是問題所在。

供進一步參考檢查sysinternals中的psexec。

NO BSOD,沒有Rootkit的,沒有樂趣 - 比斯沃尼特·喬德赫裏(Win32的內核開發)

相關問題