Windows 服务未在冷启动时启动

Windows Service not starting on cold boot

Windows 并不总是在冷启动时启动我的服务,大部分时间都是这样,但有时它无法启动,系统日志中出现 'Timeout was reached' 错误.

我在服务开始时添加了一行来转储时间以查看发生了什么。

经过大约 15 次关机和重启,我的服务终于没有启动。

查看应用程序事件日志,我在 8:18:29 看到 Windows 许可证验证事件,WMI 在 8:19:04 开始 但是当我查看我的日志文件时,我看到 '08:15:21: _tmain'

这意味着我的服务在这次重启时甚至没有加载,或者至少 'main' 没有被调用。

查看系统事件日志: 我在 8:18:57 看到事件 7009:等待 XXXX 服务连接时超时(30000 毫秒)。

在 'HKLM\System\CurrentControlSet\Control' 的注册表中,我将值 'ServicesPipeTimeout' 设置为 90000

我的服务可执行文件是 C++,支持基于 .Net 2.0 的 /clr 可执行文件也没有签名,我添加了

<generatePublisherEvidence enabled="false"/>

到 .config 文件,只是为了确定。

该服务依赖于事件日志,这显然是有效的。

这是 Windows 7 x64 VM,具有 4GB 内存和其他一些东西,但似乎在启动时会出现抖动,并且在获得网络连接时遇到问题。

如果我手动启动服务,它会在 5 秒内启动。

我不想将服务设置为“自动(延迟启动)”,因为这会在 Windows 启动后 2 分钟发生。

我不知道接下来要尝试什么,甚至不知道去哪里看。

任何指导将不胜感激。

谢谢。

[编辑] 这是我的代码的入口。请注意,在对服务执行任何操作之前,我正在写入日志,这些服务都在 MyService class.

int _tmain(int /*argc*/, TCHAR* /*argv*/[], TCHAR* /*envp*/[])
{
 SaveStringToFile(L"C:\start.txt",  CTime::GetCurrentTime().Format("%H:%M:%S") + L": _tmain\n");
 SetUnhandledExceptionFilter( MyCustomFilter ); 
 OutputDebugString(_T(__FUNCTION__));
 CMyService Service;

启动期间可能存在竞争条件。如果事件日志在系统尝试启动您的服务之前尚未开始工作,并且存在对该日志的依赖性,这可能会导致您的服务失败。

也许你可以Change the order in which your service application is started with respect to the Log.

编辑 从评论中添加信息

根据我的经验,如果在初始化过程中执行过多操作,则确实存在无法启动服务可执行文件的危险。我只放入了必需品。在这种情况下,写入日志:(还包括 main 和 ServiceMain() 的片段以说明我之前提到的异常日志记录...)

////////////////////////////////////////////////////////    
//  
//  InitService(void)  - Service initialization
//
//  Caution - limit what is done from this function.
//  The service start function: SVC_ServiceStart()
//  is limited in how much time can be allocated  
//  to start this executable before it times out.   
//  
////////////////////////////////////////////////////////    
int InitService(void)
{
    char buf[200];

    sprintf(buf, "Monitoring started");
    if(LOG_STRTSTOP==1)WriteToLog(buf);

    return SVC_SUCCESS;
}

其中 我的 main() 和 ServiceMain() 看起来像这样:

void main()
{
    SERVICE_TABLE_ENTRY ServiceTable[2];
    ServiceTable[0].lpServiceName = "xyzMon";
    ServiceTable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)ServiceMain;

    ServiceTable[1].lpServiceName = NULL;
    ServiceTable[1].lpServiceProc = NULL;
    // Start the control dispatcher thread for our service
    StartServiceCtrlDispatcher(ServiceTable);
    LogProgramFlow("Leaving main()");
}

void ServiceMain(int argc, char** argv)
{
    int error, result;

    pS = &s;

    ServiceStatus.dwServiceType             = SERVICE_WIN32;
    ServiceStatus.dwCurrentState            = SERVICE_START_PENDING;
    ServiceStatus.dwControlsAccepted        = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
    ServiceStatus.dwWin32ExitCode           = 0;
    ServiceStatus.dwServiceSpecificExitCode = 0;
    ServiceStatus.dwCheckPoint              = 0;
    ServiceStatus.dwWaitHint                = 3000;


    hStatus = RegisterServiceCtrlHandler( "xyzMon", (LPHANDLER_FUNCTION)ControlHandler);
    if (hStatus == (SERVICE_STATUS_HANDLE)0)
    {
        // Registering Control Handler failed
        if(LOG_ERR==1) WriteToLog("Registering Control Handler failed");

        return;
    }
    // Initialize Service
    error = InitService();
    ....