CreateProcess() C++ 文件未找到

Posted

技术标签:

【中文标题】CreateProcess() C++ 文件未找到【英文标题】:CreateProcess() c++ file not found 【发布时间】:2013-11-01 19:21:55 【问题描述】:

我正在尝试使用 CreateProcess 启动子进程,但是我不断收到 error 2,根据文档,找不到文件。

我的代码如下所示:

if (!(CreateProcess(LPCTSTR("test.exe") ,NULL ,NULL,NULL,FALSE ,0  ,NULL ,NULL ,&producer_si
              ,&producer)))

    printf("Create process failed!(%d)\n", GetLastError());

test.exe 是我之前创建的可执行程序。子进程很简单,代码如下:

void _tmain (int argc, TCHAR* argv[])

printf("%s\n", "hello!"); 
 

test.exe 也位于与父进程相同的文件夹中。我不明白为什么我总是收到错误代码 2。

【问题讨论】:

我会强烈建议使用CreateProcess的UTF-16版本@ANSI版本有奇怪的行为 是的,您应该使用 Unicode 版本,但要注意如果您使用 lpCommandLine 参数,它必须指向可写内存,因为 CreateProcessW() 可以修改指向的数据。 CreateProcessA() 没有这个限制。 正如 Remy 所说,您会被 ANSI 版本所吸引。并不是说那会让你离开 Unicode 版本。你只需要做对。而且 ANSI 版本也需要一个常量字符串,这只是一个实现的怪癖,可以改变,让你摆脱它。 【参考方案1】:

错误 2 是 ERROR_FILE_NOT_FOUND。正如其他人告诉您的那样,当您需要使用绝对路径时,您依赖的是相对路径。

另外,LPCTSTR("test.exe") 不是有效代码。如果定义了UNICODE,则CreateFile() 映射到CreateFileW(),而LPCTSTR 映射到LPCWSTR,即const wchar_t*。您不能将 char* 类型转换为 wchar_t* 并最终得到有意义的数据。如果要使用TCHAR 敏感字面量,请改用TEXT() 宏,例如:

if (!CreateProcess(TEXT("full path to\\test.exe"), ...))

否则,请忘记使用TCHAR,而是根据您的需要编写特定于 Ansi 或 Unicode 的代码:

if (!CreateProcessA("full path to\\test.exe", ...))

if (!CreateProcessW(L"full path to\\test.exe", ...))

【讨论】:

感谢您的信息;我将是第一个承认我对 Win32 编程很陌生,所以我不知道 Win32 实现的所有不同字符串【参考方案2】:

test.exe 永远不会在调用 exe 所在的目录中被查找。它会在 当前目录 中查找,该目录是每个进程的路径变量。也许当前目录没有指向test.exe 所在的位置。你也不应该依赖它,因为它可以任意更改(例如通过使用文件对话框,或者当父进程更改它时)。

【讨论】:

【参考方案3】:

CreateProcess 函数在涉及文件名时非常敏感,至少在我看来是这样。 当您像这样指定您的exe时,您实际上是根据当前目录指定它,这可能与您的主exe所在的目录不同,这解释了找不到文件。 一种解决方法是简单地使用 GetModulePath 获取当前 exe 的目录,并从中删除 exe 名称,然后您就拥有相同的目录,或者只是使用绝对路径。

根据CreateProcess 文档,第一个参数可以为NULL:

lpApplicationName 参数可以为 NULL。在这种情况下,模块名称必须是 lpCommandLine 字符串中第一个以空格分隔的标记。

至少对我来说,如果你只指定命令行,它似乎比使用应用程序名称要好得多,而且在应用程序名称中你无法处理命令行。

【讨论】:

【参考方案4】:

使用 QT 的 MSDN 函数 TEXT() 它不起作用:QTCreator 的编译器返回:

'Lvar' 未声明(在此函数中首次使用)

其中 var 是 Text() 的输入,因为 QT 启用了 UNICODE,因此:

    #ifdef UNICODE
/*
 * NOTE: This tests UNICODE, which is different from the _UNICODE define
 *       used to differentiate standard C runtime calls.
 */
typedef WCHAR TCHAR;
typedef WCHAR _TCHAR;
/*
 * __TEXT is a private macro whose specific use is to force the expansion of a
 * macro passed as an argument to the macro TEXT.  DO NOT use this
 * macro within your programs.  It's name and function could change without
 * notice.
 */
#define __TEXT(q) L##q
#else
typedef CHAR TCHAR;
typedef CHAR _TCHAR;
#define __TEXT(q) q
#endif

#endif

尤其是这段话:

#define __TEXT(q) L##q

windows.h 包含的 winnt.h 中 所以,为了解决这个问题,我们必须添加这个:

DEFINES -= UNICODE

在 QTCreator 项目的 .pro 文件中,它会起作用。

【讨论】:

以上是关于CreateProcess() C++ 文件未找到的主要内容,如果未能解决你的问题,请参考以下文章

使用 CreateProcess() 的唯一配置文件的多个浏览器实例未提供预期输出

无法识别 C++ CreateProcess 'telnet'

使用 CreateProcess 运行游戏可执行文件

exe文件无效时CreateProcess等待

C++ 如何使用 CreateProcess 来处理进程?

SetWinEventHook 与 CreateProcess, C++