Winapi 如何让CreateProcess/CreateProcessW在路径中执行流程>;最大路径字符数

Winapi 如何让CreateProcess/CreateProcessW在路径中执行流程>;最大路径字符数,winapi,createprocess,max-path,Winapi,Createprocess,Max Path,我试图让CreateProcess或CreateProcessW执行一个名为 memset(&si,0,sizeof(si)); si.cb=sizeof(si); si.dwFlags=STARTF_USESHOWWINDOW; si.wShowWindow=SW_HIDE;> pi为空,如中所示: memset(&pi,0,sizeof(pi)); memset(&pi,0,sizeof(pi)); 我查看了系统事件日志,每次使用事件id 59,source SideBySide:Gener

我试图让CreateProcess或CreateProcessW执行一个名为 我试过了,但没有找到错误路径

我改为CreateProcessW,但仍然得到相同的错误。当我在lpApplicationName前面加\\?\前缀时,如调用CreateProcessW时所述,我得到一个不同的错误,这让我觉得我有点接近:错误\u SXS\u CANT\u GEN\u ACTCTX

我对CreateProcessW的调用是:


CreateProcessW(w_argv0、arg_字符串、NULL、NULL、0、NULL、NULL、si和ipi);

其中w_argv0是
\\?\\foo.exe.

arg\u字符串包含“\foo.exe”foo

si设置如下:

memset(&si,0,sizeof(si)); si.cb = sizeof(si); si.dwFlags = STARTF_USESHOWWINDOW; si.wShowWindow = SW_HIDE;> memset(&si,0,sizeof(si)); si.cb=sizeof(si); si.dwFlags=STARTF_USESHOWWINDOW; si.wShowWindow=SW_HIDE;> pi为空,如中所示:

memset(&pi,0,sizeof(pi)); memset(&pi,0,sizeof(pi)); 我查看了系统事件日志,每次使用事件id 59,source SideBySide:Generate Activation Context failed for.Manifest尝试此操作时都会出现一个新条目。引用错误消息:操作已成功完成

我试图执行的文件在路径 要澄清的是,的任何组件都不超过MAX_路径字符。可执行文件本身的名称当然不是,即使末尾有.manifest。但是,整个路径加起来大于最大路径长度

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

<?xml version='1.0' encoding='UTF-8' standalone='yes'?> <assembly xmlns='urn:schemas-microsoft-com:asm.v1' manifestVersion='1.0'> <dependency> <dependentAssembly> <assemblyIdentity type='win32' name='Microsoft.VC80.DebugCRT' version='8.0.50727.762' processorArchitecture='x86' publicKeyToken='1fc8b3b9a1e18e3b' /> </dependentAssembly> </dependency> </assembly> 有人知道如何让它工作吗?可能:

  • 调用CreateProcess或CreateProcessW以在路径>最大路径字符中执行进程的其他方法

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

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


感谢您的帮助。

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

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


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

嵌入清单并使用GetShortPathNameW为我完成了这项工作。光靠他们自己是不够的

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

wchar_t *w_argv0; wchar_t *w_short_argv0; ... if (wcslen(w_argv0) >= MAX_PATH) { num_chars = GetShortPathNameW(w_argv0,NULL,0); if (num_chars == 0) { syslog(LOG_ERR,"GetShortPathName(%S) to get size failed (%d)",
w_argv0,GetLastError()); /* ** Might as well keep going and try with the long name */ } else { 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) failed (%d)",w_argv0,
GetLastError()); free(w_short_argv0); w_short_argv0 = NULL; } else { syslog(LOG_DEBUG,"using short name %S for %S",w_short_argv0,
w_argv0); } } } wchar_t*w_argv0; wchar_t*w_short_argv0; ... if(wcslen(w_argv0)>=最大路径) { num_chars=GetShortPathNameW(w_argv0,NULL,0); if(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);后来

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