2012-03-27 10 views
2

次のコードは、CreateProcessを使用して環境変数でコマンドを実行します。ここでは、notepad %APPDATA%\test.txtを実行しようとします。CreateProcessでインスタンス化されたコマンドで環境変数を使用または展開する方法は?

notepad %APPDATA%\test.txtを直接Windows' CMD以内で実行すると、%APPDATA%が展開されます。ただし、環境変数はCreateProcessで実行すると拡張できません。理由と回避策についてコメントしてもらえますか?すべてのコメントをいただければ幸いです!

directly within cmd use CreateProcess

program TestConsole2; 

    {$APPTYPE CONSOLE} 

    uses 
     Windows, SysUtils; 

    var 
     I: Integer; 
     ProgramName: String; 
     StartInfo : TStartupInfo; 
     ProcInfo : TProcessInformation; 
     CreateOK : Boolean; 
    begin 
     try 

     FillChar(StartInfo, SizeOf(StartInfo), #0); 
     FillChar(ProcInfo, SizeOf(ProcInfo), #0); 
     StartInfo.cb := SizeOf(StartInfo); 

     ProgramName := 'NOTEPAD %APPDATA%\test.txt'; 
     CreateOK := CreateProcess(
      nil, PChar(ProgramName), nil, nil, True, 0, nil, nil, StartInfo, ProcInfo); 
     if CreateOK then WaitForSingleObject(ProcInfo.hProcess, INFINITE); 

     Readln(ProgramName); 

     except 
     on E: Exception do 
      Writeln(E.ClassName, ': ', E.Message); 
     end; 
    end. 

答えて

10

コールExpandEnvironmentStringsは、環境変数を展開します。

cmd.exeを使用すると、展開が実行されます。 CreateProcessはCreateProcessを呼び出す前に行う必要はありません。あるいは、環境文字列を展開するShellExecuteを使用することもできます。

現在のコードがCreateProcessの契約を満たしていません。 2番目のパラメータは、変更可能なメモリへのポインタでなければなりません。 ANSI APIを使用していてもUnicodeをターゲットとする場合は、コードが失敗する可能性があります。リテラルへのポインタではなく、変更可能なメモリへのポインタを渡します。環境変数を拡張するための呼び出しを追加した場合は、変更可能な文字列で終了します。

最後に、テキストファイルを開こうとしているようです。なぜユーザーにメモ帳でそれを表示させるのですか?テキストファイル用の私のデフォルトエディタはNotepadではありません。メモ帳を私に強制するプログラムは嫌です。代わりに、シェルがユーザーの優先エディタでファイルを開くようにします。 ShellExecuteを呼び出し、動詞として 'open'を使用し、テキストファイル名をファイル名パラメータとして渡します。一方、おそらくあなたはこれをすべて知っており、これは単なるコード例です。もしそうなら、このアドバイスを無視してください。

+0

あなたの知識豊かなコメントありがとう! :) – SOUser

関連する問題