CreateProcess 适用于某些计算机,而不适用于其他计算机。为啥?
Posted
技术标签:
【中文标题】CreateProcess 适用于某些计算机,而不适用于其他计算机。为啥?【英文标题】:CreateProcess works on some computers, not on others. Why?CreateProcess 适用于某些计算机,而不适用于其他计算机。为什么? 【发布时间】:2011-09-08 16:58:21 【问题描述】:我正在开发一个通过 CreateProcess 调用另一个应用程序的应用程序。我在Win7 64位。被调用的应用程序是一个通过管道接收数据的控制台。调用代码如下:
STARTUPINFOA si;
PROCESS_INFORMATION pi;
GetStartupInfoA(&si);
memset( &si, 0, sizeof(STARTUPINFOA) );
memset( &pi, 0, sizeof(pi) );
si.cb = sizeof(STARTUPINFOA);
char cmdline[MAX_PATH];
sprintf(cmdline,"\"%s\" %s",AppToCallName,PipeName);
BOOL bRet = CreateProcessA(NULL,cmdline,NULL,NULL,FALSE,CREATE_NEW_CONSOLE|CREATE_BREAKAWAY_FROM_JOB,NULL,NULL,&si,&pi);
在我的电脑上(我试过两台),它可以工作。在其他情况下,它返回 (bRet=)FALSE 然后 GetLastError() 返回 5,这意味着 ACCESS_DENIED。
我不知道问题出在哪里。不好的是它对我有用,所以我无法调试它!
我的设置是:
Win7 Pro 64 位 SP1
VStudio 2005 SP1
(使用的编译器:Intel C++ 9.1
如果您需要,我很乐意提供更多设置信息!
有什么想法吗?
【问题讨论】:
什么类型的应用程序触发了 ACCESS_DENIED?在这些情况下,命令行上有什么?另外,您是否以提升的用户身份运行代码?我建议不要这样做,因为如果你这样做,你自己不会发现这个错误...... 触发 ACCESS_DENIED 的应用程序是一个简单的控制台应用程序,它将(将)通过命名管道从调用应用程序接收数据。管道创建是正确的。命令行如下所示: "\"MyConsoleApp.exe\" ThePipeName" 调用者和被调用的应用程序都位于同一目录中。 另外,我们在这里都有管理员权限。即使是那些无法在计算机上运行我的应用程序的人。 【参考方案1】:CreateProcess
使用与调用进程相同的权限,如果它没有正确初始化,它也会终止该进程,因此即使CreateProcess
返回成功,您也应该等待并验证启动的进程。但是,您的访问被拒绝问题可能与您的调用进程对您尝试在目标计算机上启动的任何应用程序没有执行或写入权限有关。
除了GetLastError
,当函数成功时检查GetExitCodeProcess
,因为这可能是你的下一个问题。
也供参考:http://msdn.microsoft.com/en-us/library/ms682425(v=vs.85).aspx
【讨论】:
谢谢。更多信息:在我的计算机上,当我从 HD 运行它时它会成功,但当我从 USB 密钥运行它时它会失败。时间???? CreateProcess 在内部是如何工作的?它是否异步启动该过程然后返回?如果是这样,它如何知道它是成功还是失败?另一方面,如果进程是同步创建的,怎么可能是时间问题?第二个应用程序将以与从 HD 或 USB 密钥加载时相同的速度运行......我很困惑! “如果在函数返回时它还没有初始化,它也会终止进程”这并不是一个准确的引用。 MSDN 说 CreateProcess 在初始化完成之前返回,所以即使 CreateProcess 成功,进程仍然可能因为初始化失败而终止。 @dom 当您从 USB 运行应用程序时,系统可能会先将其复制到本地;这可能是失败的原因。试试 filemon - 这很可能会显示失败的原因。 @dom_beau,使用带有进程句柄的 WaitForSingleObject 等待进程终止。然后使用 GetExitCodeProcess 来检查退出代码。以上是关于CreateProcess 适用于某些计算机,而不适用于其他计算机。为啥?的主要内容,如果未能解决你的问题,请参考以下文章
使用迭代器成员函数“empty()”是不是仅适用于某些向量类型?