为什么我不能在Windows Server 2008中使用System()从服务启动批处理文件

Why can't I start a batch file from a service using system() in Windows Server 2008?

本文关键字:System 服务 批处理文件 启动 不能 Windows Server 2008 为什么      更新时间:2023-10-16

我有一个C 程序,该程序在64位Windows Server 2008计算机上运行。该程序试图使用以下命令启动批处理文件:

system(C:pathtofilefile.bat)

在32位Windows Server 2003中,此功能良好(执行了批处理文件),但是在Windows Server 2008上,批处理文件未执行,我获得了0xc000000142文件作为测试以查看是否执行)。即使我尝试执行不存在的东西,我实际上也会得到相同的回报值。

我在Windows Server 2008中阅读了有关Session 0隔离的信息,因此我使用PSEXEC在会话0中启动命令提示符为同一域用户,该域用户被列为" log as on a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a as"用户:

psexec -i 0 -u DOMAINserviceuser -p passwd cmd.exe

然后,我能够从命令提示符成功执行批处理文件。

被列为"服务用户"的登录的域用户在管理员组中。另外,如果我手动启动C 应用程序(不是作为服务),它将启动批处理文件。

那么,关于会话0隔离是否有一些使System()调用作为服务运行时不起作用的东西?还是关于行为变化的其他一些解释?我知道System()不一定是这样做的最佳方法,但是我正在寻找这种不再起作用的实际原因。

从我现在对问题的了解中,您无法使用system()在Windows Server 2008中从服务运行批处理文件的原因是因为Windows考虑了任何尝试调用CMD的尝试.exe(就像运行批处理文件一样)作为启动交互式服务的尝试。由于会议0隔离,这是不允许的,即使您可能不会将批处理文件视为互动或有GUI(这使我失望),也只会失败。

我弄清楚了如何获得使用CreateProcess的效果。这里的关键是您必须将dwCreationFlags参数设置为create_no_window。因此,我(简化的)呼叫最终看起来像这样:

CreateProcess(NULL,   // No module name (use command line)
    L"C:\Windows\System32\cmd.exe /C myfile.bat", // Call cmd.exe with /C flag
    NULL,           // Process handle not inheritable
    NULL,           // Thread handle not inheritable
    FALSE,          // Set handle inheritance to FALSE
    CREATE_NO_WINDOW,              // Use CREATE_NO_WINDOW!!!
    NULL,           // Use parent's environment block
    NULL,           // Use parent's starting directory 
    &si,            // Pointer to STARTUPINFO structure
    &pi )           // Pointer to PROCESS_INFORMATION structure