为啥 CreateProcess 给出错误 193(%1 不是有效的 Win32 应用程序)
Posted
技术标签:
【中文标题】为啥 CreateProcess 给出错误 193(%1 不是有效的 Win32 应用程序)【英文标题】:Why does CreateProcess give error 193 (%1 is not a valid Win32 app)为什么 CreateProcess 给出错误 193(%1 不是有效的 Win32 应用程序) 【发布时间】:2012-09-20 04:09:03 【问题描述】:以下代码无法启动文档。我收到错误 193(%1 不是有效的 Win32 应用程序)。启动可执行文件工作正常。 文件已正确关联,双击时它们会启动相应的应用程序。 我已经在 SO 和其他地方搜索了错误消息、createprocess 内容等(例如Why is CreateProcess failing in Windows Server 2003 64-bit? 我知道引用命令行。
这是 Win7 64 位 VMWare VM 中的 Delphi XE2(更新 4)Win32 应用程序。
代码在主机(Win7 64 位)和具有 32 位 XP 的 Virtual PC VM 上也会失败。
应在 Win7 VM(Excel 2003 和 Crimson Editor)中启动的应用程序是 32 位的。
从 IDE 启动或独立运行测试应用时都会发生故障
它曾经是 Delphi2007 代码,该代码来自的已编译 D2007 应用程序在任何地方都可以正常工作。
代码有什么问题?就好像我忽略了一些非常明显的东西......
提前致谢,
一月
procedure StartProcess(WorkDir, Filename: string; Arguments : string = '');
var
StartupInfo : TStartupInfo;
ProcessInfo : TProcessInformation;
lCmd : string;
lOK : Boolean;
LastErrorCode: Integer;
begin
FillChar( StartupInfo, SizeOf( TStartupInfo ), 0 );
StartupInfo.cb := SizeOf( TStartupInfo );
StartupInfo.dwFlags := STARTF_USESHOWWINDOW;
StartupInfo.wShowWindow := sw_Normal;
FillChar( ProcessInfo, SizeOf( TProcessInformation ), 0 );
lCmd := '"' + WorkDir + FileName + '"'; // Quotes are needed https://***.com/questions/265650/paths-and-createprocess
if Arguments <> '' then lCmd := lCmd + ' ' + Arguments;
lOk := CreateProcess(nil,
PChar(lCmd),
nil,
nil,
FALSE, // TRUE makes no difference
0, // e.g. CREATE_NEW_CONSOLE or NORMAL_PRIORITY_CLASS makes no difference
nil,
nil, // PChar(WorkDir) makes no difference
StartupInfo,
ProcessInfo);
if lOk then
begin
try
WaitForSingleObject(ProcessInfo.hProcess, INFINITE);
finally
CloseHandle( ProcessInfo.hThread );
CloseHandle( ProcessInfo.hProcess );
end;
end
else
begin
LastErrorCode := GetLastError;
ShowMessage(IntToStr(LastErrorCode) + ': ' + SysErrorMessage(LastErrorCode));
end;
end;
procedure TFrmStartProcess.Button1Click(Sender: TObject);
begin
StartProcess('c:\program files (x86)\axe3\','axe.exe'); // Works
end;
procedure TFrmStartProcess.Button2Click(Sender: TObject);
begin
StartProcess('d:\','klad.xls'); // Fails
end;
procedure TFrmStartProcess.Button3Click(Sender: TObject);
begin
StartProcess('d:\','smimime.txt'); // Fails
end;
【问题讨论】:
如果你专门在文本文件上调用记事本,最后一个会发生什么? 我对Delphi不熟悉,但是WINAPICreateProcess()
只能用来启动.exe
s。如果要运行其他类型的文件,你需要使用ShellExecute()
。
@hjmd 该代码用于在以前的代码版本中工作,调用 .XLS 文件。
之前的代码版本和这个版本有什么区别?您是否使用参数开始 cmd
以打开 .xls?发布在 Delphi 2007 中有效但在 Delphi XE2 中失败的最小可重现样本。
在 David 的分析器下面查看我的评论 - 旧代码实际上并没有启动其他类型的文件。
【参考方案1】:
对该错误最可能的解释是:
-
您尝试加载的文件不是可执行文件。
CreateProcess
要求您提供可执行文件。如果您希望能够使用关联的应用程序打开任何文件,那么您需要ShellExecute
而不是CreateProcess
。
加载可执行文件的依赖项之一时出现问题,即链接到可执行文件的 DLL。最常见的原因是 32 位可执行文件和 64 位 DLL 不匹配,反之亦然。要进行调查,请使用Dependency Walker's 配置文件模式来检查到底出了什么问题。
向下阅读代码的底部,我可以看到问题是数字 1。
【讨论】:
天哪。我们正在将我们的代码从 D2007 重写为 XE2,并在此过程中取消了一些外部库。在那个过程中,我们丢弃了使用 ShellExecute 的第三方“Launcher”组件,并将其替换为我们自己的“Launcher”组件,该组件仅适用于可执行文件,因此使用了 CreateProcess。它会变得多么混乱。对不起,伙计们。 #2 昨天咬了我一口。 Delphi 将 32 位 BPL 和 64 位 BPL 路径添加到同一个全局路径中,因此 DLL 名称必须不同,我昨天了解到,经过一番痛苦。这个问题本身很有用。保留它。 除非您指定完整路径,否则 32 位和 64 位 DLL 使用相同名称的方式只有两种。它们被放置在 system32 中,但只有 MS 可以这样做,或者它们与可执行文件位于同一目录中。【参考方案2】:您的 Button2Click
和 Button3Click
函数通过 klad.xls
和 smimime.txt
。这些文件很可能不是真正的可执行文件。
要使用与其关联的应用程序打开任意文件,请使用ShellExecute
【讨论】:
【参考方案3】:如果您是 Clion/anyOtherJetBrainsIDE 用户,并且 yourFile.exe 导致此问题,只需将其删除,然后让应用程序从头开始创建并将其与库链接。有帮助。
【讨论】:
以上是关于为啥 CreateProcess 给出错误 193(%1 不是有效的 Win32 应用程序)的主要内容,如果未能解决你的问题,请参考以下文章
CreateProcess失败;代码193.%/不是有效的win32应用程序
DBeaver执行sql脚本报错:CreateProcess error=193, %1 不是有效的 Win32 应用程序。
DBeaver执行sql脚本报错:CreateProcess error=193, %1 不是有效的 Win32 应用程序。
Failed to deploy 'Compose: docker' CreateProcess error=193, %1 不是有效的 Win32 应用程序