C++ 在windows上创建服务

C++ 在windows上创建服务,c++,windows-services,C++,Windows Services,我在电脑上启动服务时遇到问题。我的代码基于本文 当我从int main(int argc,char*argv[])调用installService时,它已成功注册(我可以在msconfig和services.msc中看到它)。然而,它还没有开始。我通过services.msv手动启动服务,并收到错误“错误2:系统找不到指定的文件”。为什么会这样?我在一分钟前注册了这些服务,我的外部HD仍处于打开状态(当前存储的位置。准备好后,我会将一个非DEV版本移动到c:),我做错了什么,还有没有其他教程可以

我在电脑上启动服务时遇到问题。我的代码基于本文

当我从int main(int argc,char*argv[])调用installService时,它已成功注册(我可以在msconfig和services.msc中看到它)。然而,它还没有开始。我通过services.msv手动启动服务,并收到错误“错误2:系统找不到指定的文件”。为什么会这样?我在一分钟前注册了这些服务,我的外部HD仍处于打开状态(当前存储的位置。准备好后,我会将一个非DEV版本移动到c:),我做错了什么,还有没有其他教程可以看(我只找到了通过google链接的教程)

也许你可以用它来找出问题所在

启动它,并查找与服务启动相关的
NAME NOT FOUND
结果。

也许您可以使用查找错误


启动它,并查找与服务启动相关的
NAME NOT FOUND
结果。

是否调用StartServiceCtrlDispatcher、RegisterServiceCtrlHandler和SetServiceStatus,从服务启动时开始?路径是否是exe的完整路径,因为它不能是相对的。是的,我有完整路径我不确定您的意思您问题中的代码仅使用名为
MyTestService\u 01312009b
的指定服务注册可执行文件。当此可执行文件启动时,它必须调用上述函数以符合Win32服务规则。那么,您是从服务调用上述函数吗?您是在调用StartServiceCtrlDispatcher、RegisterServiceCtrlHandler和SetServiceStatus,从服务启动时开始?路径是否是exe的完整路径,因为它不能是相对的。是的,我有完整路径我不确定您的意思您问题中的代码仅使用名为
MyTestService\u 01312009b
的指定服务注册可执行文件。当此可执行文件启动时,它必须调用上述函数以符合Win32服务规则。那么,您是从服务调用上述函数吗?
#define srvName "MyTestService_01312009"

void installService(char*path)
{
    SC_HANDLE handle = ::OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS );
    SC_HANDLE service = ::CreateService(
        handle,
        srvName,
        "MyTestService_01312009b",
        GENERIC_READ | GENERIC_EXECUTE,
        SERVICE_WIN32_OWN_PROCESS,
        SERVICE_AUTO_START,
        SERVICE_ERROR_IGNORE,
        path,
        NULL,
        NULL,
        NULL,
        NULL,
        NULL
    );
}
void uninstallService()
{
    SC_HANDLE handle = ::OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS );//?
    SC_HANDLE service = ::OpenService( handle, srvName, DELETE );
    if( service != NULL )
    {
        // remove the service!
        ::DeleteService( service );
    }
}

SERVICE_STATUS_HANDLE hStatus;
SERVICE_STATUS status;

/*
if( ::StartServiceCtrlDispatcher( dispatchTable ) == 0 )
{
    // if this fails, it's probably because someone started us from
    // the command line.  Print a message telling them the "usage"
}
*/
void WINAPI ServiceCtrlHandler( DWORD control )
{
    switch( control )
    {
    case SERVICE_CONTROL_SHUTDOWN:
    case SERVICE_CONTROL_STOP:
        // do shutdown stuff here

        status.dwCurrentState = SERVICE_STOPPED;
        status.dwWin32ExitCode = 0;
        status.dwCheckPoint = 0;
        status.dwWaitHint = 0;
        break;
    case SERVICE_CONTROL_INTERROGATE:
        // just set the current state to whatever it is...
        break;
    }

    ::SetServiceStatus( hStatus, &status );
}
void WINAPI ServiceDispatch( DWORD numArgs, char **args )
{
    // we have to initialize the service-specific stuff
    memset( &status, 0, sizeof(SERVICE_STATUS) );
    status.dwServiceType = SERVICE_WIN32;
    status.dwCurrentState = SERVICE_START_PENDING;
    status.dwControlsAccepted = SERVICE_ACCEPT_STOP;

    hStatus = ::RegisterServiceCtrlHandler( srvName, &ServiceCtrlHandler );

    // more initialization stuff here
    FILE *f = fopen("c:/testSrv.bin", "wb");
    ::SetServiceStatus( hStatus, &status );
}
SERVICE_TABLE_ENTRY dispatchTable[] =
{
    { srvName, &ServiceDispatch },
    { NULL, NULL }
};