为什么:: CreateProcess(path,cmd,...)失败并显示错误“找不到文件”?

时间:2011-06-22 22:58:24

标签: c++ winapi

我正在尝试让C ++程序调用已经制作的C#程序在后台运行。

STARTUPINFO info = {sizeof(info)};
PROCESS_INFORMATION processinfo;
DWORD error1 = GetLastError();
bool x = ::CreateProcess((LPCWSTR)"C:\Convert_Shrink.exe", GetCommandLine(), NULL, NULL, false, 0,NULL,NULL, &info, &processinfo);
DWORD error = GetLastError();

在CreateProcess之前,error1为0 CreateProcess

后错误为2

错误2:

ERROR_FILE_NOT_FOUND 2 (0x2) The system cannot find the file specified.

我已将其更改为C:\ \如果他们正在检查转义序列,但我仍然收到错误2,我不确定原因。

4 个答案:

答案 0 :(得分:4)

你可以:

  • 使用CreateProcessA匹配您的ANSI文件路径:

    bool x = ::CreateProcessA("C:\\Convert_Shrink.exe", GetCommandLineA(), NULL, NULL, false, 0,NULL,NULL, &info, &processinfo);
    

<击> *提供与Unicode设置所需的字符串格式匹配的文件路径:

    bool x = ::CreateProcess(_T("C:\\Convert_Shrink.exe"), GetCommandLine(), NULL, NULL, false, 0,NULL,NULL, &info, &processinfo);

    <击>
  • 使用CreateProcessW以便传递Unicode文件路径(支持扩展字符):

    bool x = ::CreateProcessW(L"C\\\Convert_Shrink.exe", GetCommandLineW(), NULL, NULL, false, 0,NULL,NULL, &info, &processinfo);
    

    <击>

(正如@dolphy所说,参数必须是可写的字符串)

  • 提供与Unicode设置所需的字符串格式匹配的文件路径:

    #if UNICODE
    std::wstring exename =
    #else
    const char* exename =
    #endif
        _T("C:\\Convert_Shrink.exe");
    bool x = ::CreateProcess(&exename[0], GetCommandLine(), NULL, NULL, false, 0,NULL,NULL, &info, &processinfo);
    

  • 使用CreateProcessW以便您可以传递Unicode文件路径(支持扩展字符):

    wchar_t exename[] = L"C:\\Convert_Shrink.exe";
    bool x = ::CreateProcessW(exename, GetCommandLineW(), NULL, NULL, false, 0,NULL,NULL, &info, &processinfo);
    

答案 1 :(得分:2)

仅供记录。 CreateProcessAsUser在内部调用SearchPath。 SearchPath使用文件系统重定向器https://msdn.microsoft.com/en-us/library/windows/desktop/aa384187%28v=vs.85%29.aspx

因此,如果您在WOW64下运行32位应用程序并且要求使用system32目录中的exe进程,例如“c:\ windows \ system32 \ myapp.exe”,CreateProcessAsUser将在syswow64中查找,例如“c:\ windows \ syswow64 \ myapp.exe”。如果您的exe不存在,您将收到“找不到文件错误”。

答案 2 :(得分:0)

我只是查找了GetCommandLine(),MSDN声明它获取了当前进程的命令行。 CreateProcess()的MSDN条目声明第二个参数是您要执行的命令行命令,如果我正确读取它。所以你基本上告诉CreateProcess()运行C ++程序的另一个实例,而不是C#程序。

(编辑) 实际上,经过仔细检查,CreateProcess()文档似乎没有清楚地解释如果同时提供第一个和第二个参数会发生什么。它表示第一个指定模块,第二个指定命令行。什么是差异?

对于不确定的答案,我很抱歉,如果可以的话,我会将这个答案转换成对你的问题的一些评论。

答案 3 :(得分:-2)

您是否尝试过将字符串转换为LPCTSTR

bool x = ::CreateProcess((LPCTSTR)"C:\Convert_Shrink.exe", GetCommandLine(), NULL, NULL, false, 0,NULL,NULL, &info, &processinfo); 

From Microsoft

The Unicode version of this function, CreateProcessW, can modify the contents 
of this string. Therefore, this parameter cannot be a pointer to read-only 
memory (such as a const variable or a literal string). If this parameter is a 
constant string, the function may cause an access violation.