web-dev-qa-db-ja.com

CreateProcessでエラー193が発生する理由(%1は有効なWin32アプリではありません)

以下のコードはドキュメントを開始できません。エラー193を受け取ります(%1は有効なWin32アプリではありません)。実行可能ファイルの起動は正常に機能します。ファイルは適切に関連付けられており、ダブルクリックすると対応するアプリが起動します。 SOおよびその他の場所でエラーメッセージ、createprocessスタッフなどを検索しました。たとえば、 Windows Server 2003 64ビットでCreateProcessが失敗するのはなぜですか? コマンドライン。

  • これは、Win7 64ビットVMWare VMのDelphi XE2(Update 4)Win32アプリです。

  • また、コードはホストマシン(Win7 64ビット)およびVirtual PC VM 32ビットXPで)でも失敗します。

  • 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://stackoverflow.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;
18
Jan Doggen

そのエラーの最も可能性の高い説明は次のとおりです。

  1. ロードしようとしているファイルは実行可能ファイルではありません。 CreateProcessでは、実行可能ファイルを提供する必要があります。関連するアプリケーションで任意のファイルを開くことができるようにするには、ShellExecuteではなくCreateProcessが必要です。
  2. 実行可能ファイルの依存関係の1つ、つまり実行可能ファイルにリンクされているDLLの読み込みに問題があります。その最も一般的な理由は、32ビット実行可能ファイルと64ビットDLLの不一致、またはその逆です。調査するには、 Dependency Walker's プロファイルモードを使用して、何が問題なのかを正確に確認します。

コードの最後まで読むと、問題が1番であることがわかります。

24
David Heffernan

きみの Button2ClickおよびButton3Click関数が渡すklad.xlsおよびsmimime.txt。ほとんどの場合、これらのファイルは実際の実行可能ファイルではありません。

それらに関連付けられたアプリケーションを使用して任意のファイルを開くには、 ShellExecute を使用します

6
Frerich Raabe