2012-10-15 24 views
1

大家如何調試窗口在C服務啓動代碼,而不是C#

我想知道如何調試C.there Windows服務的啓動代碼有幾個類似這樣的問題,但在C#中,但他們不是我所需要的。 到目前爲止,我只能附加到進程調試。現在我想調試main()函數,該怎麼做?越詳細越好。

非常感謝。

我的代碼如下。

主要功能:

void main() 
{ 
    SERVICE_TABLE_ENTRY ServiceTable[2]; 
    ServiceTable[0].lpServiceName = "MemoryStatus"; 
    ServiceTable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)ServiceMain; //ServiceMain 
    ServiceTable[1].lpServiceName = NULL; 
    ServiceTable[1].lpServiceProc = NULL; 

    StartServiceCtrlDispatcher(ServiceTable); 
} 

ServiceMain函數:

void ServiceMain(int argc, char** argv) 
{   
    //...some codes.... 

    hStatus = RegisterServiceCtrlHandler("MemoryStatus",(LPHANDLER_FUNCTION)ControlHandler); 

    //...some codes.... 

    //the worker loop of a service 
    while(ServiceStatus.dwCurrentState == SERVICE_RUNNING) 
    { 
     char buffer[10];   
     sprintf(buffer,"login..."); 
     int result = WriteToLog(buffer);   
     if (result) 
     { 
      ReportStatus(SERVICE_STOPPED,-1); 
      return; 
     } 
     Sleep(SLEEP_TIME); 
    } 
    return; 
} 

控制手柄功能:

void ControlHandler(DWORD request) 
{ 
    switch(request) 
    { 
    case SERVICE_CONTROL_STOP: 
     WriteToLog("Monitoring stopped."); 
     //...Report Status to SCM code.... 
     return; 
    case SERVICE_CONTROL_SHUTDOWN: 
     WriteToLog("Monitoring stopped."); 
     //...Report Status to SCM code.... 
     return; 
    default: 
     break; 
    } 
//...Report Status to SCM code.... 
    return; 
} 

回答

2

從一開始就有兩種不同的方式來調試Windows服務。兩者都被描述爲here

我的首選之一是使用以服務啓動的遠程調試器會話(您可以使用Windows調試工具中的ntsd)。 Windows中有一種特殊的機制,使您能夠根據映像名稱劫持進程(映像文件執行選項)。下面你可以找到一個.reg文件的內容,將安裝此調試器爲你(路徑更改爲您安裝調試工具,其中一個):

Windows Registry Editor Version 5.00 

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\svchost.exe] 
"Debugger"="\"C:\\tools\\debugging\\Debugging Tools for Windows (x64)\\ntsd.exe\" -server npipe:pipe=svcpipe -noio" 

下一步將會使用附加到這個會議用戶模式調試器:

windbg -remote "npipe:pipe=svcpipe,server=localhost" 

並且您已準備好進行調試。請記住在重新啓動機器之前刪除註冊表設置,否則windows會掛起黑屏:)

+2

使用GFlags.exe工具爲您設置和取消設置Windows註冊表更方便。這很快,並允許您指定所需的一切。只需啓動它,單擊「圖像文件」選項卡,在圖像文本框中鍵入圖像的名稱,點擊TAB,然後進入調試器行。檢查調試器併爲調試器輸入命令行,單擊確定。 未設置很容易。通過調試器取消選中複選框。 – StarPilot

+0

從這個答案鏈接的文章是一個偉大的資產。我想補充說,在更改ServicesPipeTimeout註冊表值以使新值生效後,您必須重新啓動系統。 –

0

好吧,兩種方法: 首先,我們可以在代碼開始時睡眠服務進程。像這樣:

main() 
{ 
    sleep(10); 
    ..... 
} 

,然後附加到服務的過程中,調試器將在斷點的位置停止,因爲我們有10秒的等待。

其次,我們可以在代碼的開頭使用_ASSERT(FALSE)DebugBreak()函數。