The code below fails to start documents. I get error 193 (%1 is not a valid Win32 app). Starting executables work fine. The files are properly associated, they start the corresponding app when double clicked. I have searched SO and elsewhere for the error message, createprocess stuff etc. (E.g. Why is CreateProcess failing in Windows Server 2003 64-bit? I know about quoting the command line.
This is a Delphi XE2 (Update 4) Win32 app in a Win7 64bit VMWare VM.
The code also fails on the host machine (Win7 64 bit) and in a Virtual PC VM with 32bit XP.
The apps that should start in the Win7 VM (Excel 2003 and Crimson Editor) are 32 bit.
The failure occurs both when starting from the IDE or when running the test app standalone
It used to be Delphi2007 code, the compiled D2007 app where this code comes from works fine everywhere.
What's wrong with the code?
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://mcmap.net/q/450263/-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;
CreateProcess()
can be used to start.exe
s only. If want to run other types of files you need to useShellExecute()
. – Rodrickrodrigezcmd
with a parameter to open the .xls? Post the smallest reproducible sample that works in Delphi 2007 and fails in Delphi XE2. – Buchenwald