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

时间:2010-10-29 15:17:27

标签: 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 );

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

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
                    ) 

引用下面的命令也没有帮助

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
                    ) 

用空格传递路径的正确方法是什么?

5 个答案:

答案 0 :(得分:18)

在回答另一个答案时,示例#3 NOT 是正确答案。

问题是引号应该 NOT 封装作为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
                    ) 

答案 1 :(得分:4)

你的第3段是正确的,不知道你为什么遇到麻烦。拥有GetLastError()返回值在这里很有价值。但请注意,CreateProcess的第二个参数是LPTSTR,不是 LPCTSTR。换句话说,Windows可以回写字符串。相当令人毛骨悚然,不是吗?足够的理由可能会改为使用ShellExecuteEx()。

答案 2 :(得分:2)

您无需在第一个和第二个参数中指定应用程序路径。根据MSDN documentation,如果在第一个参数中列出应用程序名称,则第二个参数应该只是命令行参数。否则,将第一个参数设置为NULL,然后在第二个参数中将应用程序名称括在引号中(如果它包含空格)。不确定为什么你的上一个列表不起作用。

答案 3 :(得分:2)

文档不清楚,但似乎有可能如果你包含一个空格,你必须允许参数2定义完整路径。

  

lpApplicationName参数可以是   空值。在这种情况下,模块名称   必须是第一个白人   空格分隔的标记   lpCommandLine字符串。如果你正在使用   包含a的长文件名   空格,使用引用的字符串来表示   文件名结束的地方和   争论开始;否则,文件   名字含糊不清。

你尝试过这种变化吗?

CreateProcess(NULL,    // 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
             ) 

编辑:以下对我有用(dwError为0)。我的项目是用多字节字符集构建的。

LPTSTR szCmdLine = _tcsdup(TEXT(
    "\"C:\\Program Files\\adobe\\Reader 8.0\\reader\\acrord32.exe\" /qr"));
CreateProcess(NULL,
              szCmdLine,
              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
             );     // This works. Downcasting of pointer to members in general is fine.

DWORD error = GetLastError();

答案 4 :(得分:1)

派对有点晚了。出于某种原因,我无法向普鲁托里安投票,但他是对的。我遇到了同样的问题,并且应用程序名称为NULL。我也在App Name&只是第二个参数中的命令行参数,无济于事。

我在Win7 x64上。

CreateProcess(NULL,“\”路径到exe \“ - x -y -z”,...);

适合我。