title: Why does CreateProcess give error 193 (%1 is not a valid Win32 app)
body: <p>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. <a href="https://stackoverflow.com/questions/331829/why-is-createprocess-failing-in-windows-server-2003-64-bit">Why is CreateProcess failing in Windows Server 2003 64-bit?</a>
  I know about quoting the command line.</p>
  
  <ul>
  <li><p>This is a Delphi XE2 (Update 4) Win32 app in a Win7 64bit VMWare VM. </p></li>
  <li><p>The code also fails on the host machine (Win7 64 bit) and in a Virtual PC VM with 32bit XP.</p></li>
  <li><p>The apps that should start in the Win7 VM (Excel 2003 and Crimson Editor) are 32 bit.</p></li>
  <li><p>The failure occurs both when starting from the IDE or when running the test app standalone</p></li>
  <li><p>It used to be Delphi2007 code, the compiled D2007 app where this code comes from works fine everywhere.</p></li>
  </ul>
  
  <p>What's wrong with the code? It's almost as if I'm overlooking something very obvious....</p>
  
  <p>Thanks in advance,</p>
  
  <p>Jan</p>
  
  <pre><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://stackoverflow.com/questions/265650/paths-and-createprocess
    if Arguments &lt;&gt; '' 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;
  </code></pre>