Windows API - 带空格的CreateProcess()路径

dav*_*led 12 winapi

如何将带空格的路径传递给CreateProcess()函数?

以下作品

STARTUPINFO si;
            PROCESS_INFORMATION pi;

            ZeroMemory( &si, sizeof(si) );
            si.cb = sizeof(si);
            ZeroMemory( &pi, sizeof(pi) );

            if( !CreateProcess(_T("c:\\installer\\ew3d.exe"),    // No module name (use command line)
                _T("c:\\installer\\ew3d.exe /qr"),//argv[1],        // Command line
                NULL,           // Process handle not inheritable
                NULL,           // Thread handle not inheritable
                FALSE,          // Set handle inheritance to FALSE
                0,              // No creation flags
                NULL,           // Use parent's environment block
                NULL,           // Use parent's starting directory 
                &si,            // Pointer to STARTUPINFO structure
                &pi )           // Pointer to PROCESS_INFORMATION structure
                ) 
            {
                printf( "CreateProcess failed (%d).\n", GetLastError() );
                return false;
            }

            //Wait until child process exits.
            WaitForSingleObject( pi.hProcess, INFINITE );

            // Close process and thread handles. 
            CloseHandle( pi.hProcess );
            CloseHandle( pi.hThread );
Run Code Online (Sandbox Code Playgroud)

但是,如果我使用带有空格的路径,如下面的代码,它就不起作用了.

CreateProcess(_T("c:\\master installer\\ew3d.exe"),    // No module name (use command line)
                    _T("c:\\master installer\\ew3d.exe /qr"),//argv[1],        // Command line
                    NULL,           // Process handle not inheritable
                    NULL,           // Thread handle not inheritable
                    FALSE,          // Set handle inheritance to FALSE
                    0,              // No creation flags
                    NULL,           // Use parent's environment block
                    NULL,           // Use parent's starting directory 
                    &si,            // Pointer to STARTUPINFO structure
                    &pi )           // Pointer to PROCESS_INFORMATION structure
                    ) 
Run Code Online (Sandbox Code Playgroud)

引用下面的命令也没有用

CreateProcess(_T("\"c:\\master installer\\ew3d.exe\""),    // No module name (use command line)
                    _T("\"c:\\master installer\\ew3d.exe\" /qr"),//argv[1],        // Command line
                    NULL,           // Process handle not inheritable
                    NULL,           // Thread handle not inheritable
                    FALSE,          // Set handle inheritance to FALSE
                    0,              // No creation flags
                    NULL,           // Use parent's environment block
                    NULL,           // Use parent's starting directory 
                    &si,            // Pointer to STARTUPINFO structure
                    &pi )           // Pointer to PROCESS_INFORMATION structure
                    ) 
Run Code Online (Sandbox Code Playgroud)

通过空间路径的正确方法是什么?

dya*_*sta 20

作为对另一个答案的回答,示例#3 不是正确的答案.

问题是,该报价应封装为CreateProcess的第一个参数传递的模块路径.但是,引号应该封装为命令行传递的arg0(再次模块路径)(CreateProcess的第二个参数).

所以,正确的再现将是:

CreateProcess(_T("c:\\master installer\\ew3d.exe"),    
                    _T("\"c:\\master installer\\ew3d.exe\" /qr"),
                    NULL,           // Process handle not inheritable
                    NULL,           // Thread handle not inheritable
                    FALSE,          // Set handle inheritance to FALSE
                    0,              // No creation flags
                    NULL,           // Use parent's environment block
                    NULL,           // Use parent's starting directory 
                    &si,            // Pointer to STARTUPINFO structure
                    &pi )           // Pointer to PROCESS_INFORMATION structure
                    ) 
Run Code Online (Sandbox Code Playgroud)

  • 这是正确的答案。谢谢 :) (2认同)

Han*_*ant 3

您的第三个片段是正确的,不确定为什么您遇到麻烦。拥有 GetLastError() 返回值在这里很有价值。但请注意,CreateProcess 的第二个参数是 LPTSTR,而不是LPCTSTR。换句话说,Windows 可以写回该字符串。非常令人毛骨悚然,不是吗?也许有足够的理由使用 ShellExecuteEx() 来代替。

  • 问题是引号不应封装模块路径名(CreateProcess 的第一个参数)。这就是为什么错误是路径不存在。但是,您*应该*继续引用为命令行传递的封装arg0(再次是模块路径)(CreateProcess 的第二个参数)。我在下面发布了新答案。 (3认同)