【问题标题】:How to get CreateProcess/CreateProcessW to execute a process in a path > MAX_PATH characters如何让 CreateProcess/CreateProcessW 在路径中执行进程 > MAX_PATH 个字符
【发布时间】:2010-09-13 15:40:33
【问题描述】:

我正在尝试让 CreateProcess 或 CreateProcessW 执行名称 http://msdn.microsoft.com/en-us/library/ms682425.aspx 上的文档,我需要确保 lpApplicationName 不为 NULL,然后 lpCommandLine 最多可以包含 32,768 个字符。

我试过了,但我得到了 ERROR_PATH_NOT_FOUND。

我更改为 CreateProcessW,但仍然出现相同的错误。当我按照http://msdn.microsoft.com/en-us/library/aa365247(VS.85).aspx 中的描述在 lpApplicationName 前加上 \\?\ 时,在调用 CreateProcessW 时我得到一个不同的错误,这让我觉得我更接近一点:ERROR_SXS_CANT_GEN_ACTCTX。

我对 CreateProcessW 的调用是:

CreateProcessW(w_argv0,arg_string,NULL,NULL,0,NULL,NULL,&si,&ipi);

其中 w_argv0 是 \\?\<long absolute path>\foo.exe.

arg_string 包含 "\foo.exe" foo

si 设置如下:

memset(&si,0,sizeof(si)); si.cb = sizeof(si); si.dwFlags = STARTF_USESHOWWINDOW; si.wShowWindow = SW_HIDE;>

而 pi 为空,如:

memset(&pi,0,sizeof(pi));

我查看了系统事件日志,每次尝试使用事件 id 59 进行此操作时都会出现一个新条目,源 SideBySide: Generate Activation Context failed for .Manifest。参考错误信息:操作成功完成。

我尝试执行的文件在

为了澄清, 的任何一个组成部分都不大于 MAX_PATH 个字符。可执行文件本身的名称当然不是,即使最后有 .manifest。但是,整个路径加起来的长度超过了 MAX_PATH 个字符。

无论我是否嵌入其清单,我都会收到相同的错误。清单被命名为 foo.exe.manifest,当它没有嵌入时,它与可执行文件位于同一目录中。它包含:

依赖> 汇编>

有人知道如何让它工作吗?可能:

  • 调用 CreateProcess 或 CreateProcessW 以在路径中执行进程的其他方式 > MAX_PATH 个字符

  • 我可以在清单文件中做些什么

我在 XP SP2 上使用 Visual Studio 2005 构建并运行本机。

感谢您的帮助。

【问题讨论】:

    标签: winapi createprocess max-path


    【解决方案1】:

    嵌入清单并使用 GetShortPathNameW 为我做了这件事。一个或另一个是不够的。

    在使用 \\? 前缀的进程的绝对路径名作为第一个参数调用 CreateProcessW 之前,我检查:

    wchar_t *w_argv0; wchar_t *w_short_argv0; ... if (wcslen(w_argv0) >= MAX_PATH) { num_chars = GetShortPathNameW(w_argv0,NULL,0); 如果(num_chars == 0){ syslog(LOG_ERR,"GetShortPathName(%S) 获取大小失败 (%d)",
    w_argv0,GetLastError()); /* ** 不妨继续尝试使用长名称 */ } 别的 { w_short_argv0 = malloc(num_chars * sizeof(wchar_t)); memset(w_short_argv0,0,num_chars * sizeof(wchar_t)); if (GetShortPathNameW(w_argv0,w_short_argv0,num_chars) == 0) { syslog(LOG_ERR,"GetShortPathName(%S) 失败 (%d)",w_argv0,
    GetLastError()); 免费(w_short_argv0); w_short_argv0 = NULL; } 别的 { syslog(LOG_DEBUG,"为 %S 使用短名称 %S",w_short_argv0,
    w_argv0); } } }

    然后调用 CreateProcessW(w_short_argv0 ? w_short_argv0 : w_argv0...);

    记得释放(w_short_argv0);之后。

    这可能无法解决所有情况,但它可以让我产生比以前更多的子进程。

    【讨论】:

      【解决方案2】:

      我在 CreateProcess 文档中没有看到任何说明“\\?\”语法对模块名称有效的参考。 “命名文件或目录”页面也没有说明 CreateProcess 支持它,而 CreateFile 等功能链接到“命名文件”页面。

      确实看到您不能在lpCommandLine 中使用长于MAX_PATH 的模块名称,这表明 CreateProcess 不支持超长文件名。该错误消息还表明在尝试将“.manifest”附加到您的应用程序路径时发生错误(即,长度现在超过了 MAX_PATH)。

      GetShortPathName() 在这里可能会有所帮助,尽管它不保证返回小于 MAX_PATH 的名称(但它确实明确声明 '\\?\' 语法是有效的)。否则,您可以尝试调整PATH 环境变量并将其传递给lpEnvironment 中的CreateProcess()。或者您可以使用 SetCurrentDirectory() 并仅传递可执行文件名称。

      【讨论】:

        猜你喜欢
        • 2023-04-06
        • 1970-01-01
        • 1970-01-01
        • 2019-08-21
        • 2010-09-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-10-14
        相关资源
        最近更新 更多