【问题标题】:Paths and CreateProcess路径和 CreateProcess
【发布时间】:2010-09-20 21:47:03
【问题描述】:

我有一个关于我滥用 CreateProcess 的症状的问题。我正在使用 lpcommandline 参数来提供我的可执行文件和参数的路径。我的误用是我没有用引号包围 exe 的路径。

我的问题是,为什么 CreateProcess 在大多数计算机上都能正常工作,而在其他计算机上却不行?我知道路径在大多数情况下都会有空间,但在 90% 的 XP 机器上它可以工作。我当然在那些没有发现的那 10% 上发现了我的问题。但我想知道它不起作用的机器上有什么不同?有没有你们任何人都知道的设置或政策。是的,我要解决报价问题。只是好奇为什么这样的事情不会一败涂地。

所以代码如下所示,szCommandLine 参数如下所示。注意 exe 的路径周围没有引号。

"C:\Program Files\My Company\doit.exe parameter1 parameter2"

CreateProcess(
    NULL,           
    szCommandLine,  
    NULL,           
    NULL,           
    FALSE,          
    NULL, 
    NULL,  
    NULL,           
    &si,            
    &pi )       

【问题讨论】:

    标签: c++ winapi


    【解决方案1】:

    正如 Martin York 链接到的文档所暗示的那样,CreateProcess() 具有一些与预长名称程序向后兼容的行为。

    "c:\program files\sub dir\program name arg1 arg2" 将查找:

    "c:\program.exe" files\sub dir\program name arg1 arg2
    "c:\program files\sub.exe" dir\program name arg1 arg2
    "c:\program files\sub dir\program.exe" name arg1 arg2
    "c:\program files\sub dir\program name.exe" arg1 arg2
    

    因此,如果这些文件中的任何一个存在,Windows 将调用它们,而不是您的程序。另外,我假设如果您没有对这些可能匹配项所在的任何文件夹的读取权限,则 CreateProcess() 可能会立即失败,而不是检查您是否已阅读以后可能的匹配项。 (Windows 默认只检查最终文件夹的读取权限。)

    【讨论】:

      【解决方案2】:

      您应该阅读此页面:
      http://msdn.microsoft.com/en-us/library/ms682425.aspx

      • 如果应用程序名称为 NULL(第一个参数)。
      • 它使用命令行中第一个空格分隔的单词(第二个参数)作为应用程序名称。
      • 如果应用程序名称包含空格,则必须用引号引起来。

      再一次,代码值一百万字:
      是不是像这样:

      char commandline[] = "C:\Program Files\My Company\doit.exe parameter1 parameter2";
      CreateProcess(NULL,commandline, .... );
      

      或者您是在 somwhere 生成路径名吗?
      请记住,通用问题只会为您提供通用答案。
      在获得关于为什么会有太多猜测的具体答案之前,您必须具体。

      【讨论】:

      • 是的,我读到了。这就是我知道我搞砸了引号的方式。这个问题与为什么即使没有在许多机器上而不是其他机器上的引号也能工作有关。我已经解决了这个问题,我只是想知道是什么导致了奇怪的行为。
      • 您是如何生成 exe 名称的。您确定它是“完整路径”还是依赖于相对路径。
      【解决方案3】:

      我只是在同一个问题上苦苦挣扎了一段时间。所以即使这个问题是很久以前提出的,只是为了记录,这就是我的问题所在:

      如果命令行没有被引用并且包含空格,CreateProcess 将尝试解决 Simon 的回答中描述的歧义。 如果空格字符之前的任何测试部分也解析为没有扩展名或 .exe 扩展名的现有文件,则将使用此文件而不是预期的完整路径。

      例子:

      char cmdline[] = "C:\Program Files\App One\bin\app.exe param1 param2";
      CreateProcess(NULL, cmdline, ...);
      

      不幸的是,在我的例子中,实际上存在一个名为“C:\Program Files\App”(无扩展名)的文件。 CreateProcess 找到了这个文件,假设它是一个没有 .exe 扩展名的可执行文件并试图执行它。结果:错误 193“%1 不是有效的 Win32 应用程序”。

      底线:使用引号甚至更好,使用 CreateProcess 的第一个参数,或者去寻找任何其他可能匹配部分违规路径的文件。

      【讨论】:

        【解决方案4】:

        诊断此类问题的一个好方法是内置到您的应用程序错误和报告机制中。这对很多目的都有帮助——主要是针对您自己可能永远看不到的错误,以及一些用户可能只是忽略而不向您报告的错误。通过这种方式,您可以在调用命令并发生故障时诊断这些参数是什么。

        此外,您可以尝试进一步探索 MSDN 站点以及与此方法相关的高级功能。你把它们中的大部分都留了空。通过探索这些扩展功能,您将了解并可能自己找出为什么会出现这种差异。

        另一个通用答案,但我希望这可以帮助您评估您的特定情况。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-08-21
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多