Windows services 如何在服务程序中调用exe程序?

Windows services 如何在服务程序中调用exe程序?,windows-services,createprocess,Windows Services,Createprocess,我正在编写一个Windows服务程序,它将在启动时调用外部exe文件,例如notepad.exe。但它总是失败,并出现“未处理的win32异常” 我的步骤: 将代码编译成exe文件:MemoryStatus.exe 使用以下命令安装服务:sc create MemoryStatus binpath=c:\MyServices\MemoryStatus.exe 从windows控制面板中找到该服务,然后单击Start 错误发生了 谁能帮我指出我做错了什么 void main() { SER

我正在编写一个Windows服务程序,它将在启动时调用外部exe文件,例如
notepad.exe
。但它总是失败,并出现
“未处理的win32异常”

我的步骤:

  • 将代码编译成
    exe
    文件:
    MemoryStatus.exe
  • 使用以下命令安装服务:
    sc create MemoryStatus binpath=c:\MyServices\MemoryStatus.exe
  • 从windows控制面板中找到该服务,然后单击
    Start
  • 错误发生了
  • 谁能帮我指出我做错了什么

    void main()
    {
        SERVICE_TABLE_ENTRY ServiceTable[2];
        ServiceTable[0].lpServiceName = _T("MemoryStatus_new_3");
        ServiceTable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)**ServiceMain**;
    
        ServiceTable[1].lpServiceName = NULL;
        ServiceTable[1].lpServiceProc = NULL;
    
        StartServiceCtrlDispatcher(ServiceTable);
    
    }
    void ServiceMain(int argc, char** argv)
    {
        int error;
        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 = 0;
        hStatus = RegisterServiceCtrlHandler(   _T("MemoryStatus_new_3"),   (LPHANDLER_FUNCTION)ControlHandler);
        if (hStatus == (SERVICE_STATUS_HANDLE)0)
        {
            // Registering Control Handler failed
            WriteToLog("Registering Control Handler failed\n");
            return;
        }
    
        // We report the running status to SCM.
        ServiceStatus.dwCurrentState =  SERVICE_RUNNING;
        SetServiceStatus (hStatus, &ServiceStatus);
    
        // Initialize Service
            startSvc();
    
        return;
    }
    
    void startSvc()
    {
        STARTUPINFO si;
        PROCESS_INFORMATION pi;
        ZeroMemory( &pi, sizeof(pi) );
        ZeroMemory( &si, sizeof(si) );
        si.cb = sizeof(si);
        // Start the child process
        if(CreateProcess(_T("C:\\Program Files\\Source Insight 3\\Insight3.exe"), _T(""), NULL, NULL, FALSE, 0, FALSE, NULL, &si, &pi))
         {
          CloseHandle( pi.hProcess );
          CloseHandle( pi.hThread );
        }
         else 
         {
            hProcess = GetCurrentProcess();//get current process
            TerminateProcess(hProcess,0);         //close process
         }
    }
    
    这里存在一个问题

    将进程名称存储在一个可变数组中

    TCHAR szAppName[MAX_PATH];
    StringCchCat(szAppName, _countof(szAppName), _T("C:\\Program Files\\Source Insight 3\\Insight3.exe"));
    

    如果CreateProcess()失败,为什么进程会自杀?尝试删除该行为并查看异常是否消失。非常感谢您的评论,但删除该行为后仍然失败。当我只在main()函数中调用startSvc()时,它是成功的,但如果通过服务调用它,它就失败了。。。“wins.exe中0x00000000处未处理的异常:0xC0000005:访问冲突读取位置0x00000000。”您的代码是否真的有这一行?它不应使用额外的**:ServiceTable[0]进行编译。lpServiceProc=(LPSERVICE_MAIN_函数)*ServiceMain*;另外,您应该检查并处理StartServiceCtrlDispatcher()中的错误。我认为可以为第一个参数传递一个文本字符串(它是LPCTSTR),但我认为您的想法是正确的。OP将_T(“”)作为第二个参数传递给CreateProcess-MSDN表示“此参数不能是指向只读内存的指针(例如常量变量或文字字符串)。如果此参数是常量字符串,则函数可能会导致访问冲突。”(强调添加)
    TCHAR szAppName[MAX_PATH];
    StringCchCat(szAppName, _countof(szAppName), _T("C:\\Program Files\\Source Insight 3\\Insight3.exe"));