1

これを使用して、cmd (Windows シェル) からワイド文字列を読み取ります。

var
 pBuffer       : array [0..250] of WideChar;
 aBuffer       : array [0..250] of Char;
 RealUnicode   : Integer;
 ExtendedAscii : Integer;
begin
 RealUnicode   := 2;
 ExtendedAscii := 1;
 // ... pipes etc...
 CreateProcessW(nil, pwidechar(ComSpec + ' /U'), nil, nil, TRUE, (CREATE_NEW_CONSOLE or CREATE_BREAKAWAY_FROM_JOB), nil, nil, StartupInfo, ProcessInfo);
 // ...
 while true do begin
  sleep (10); // Reduce CPU Usage
  GetExitCodeProcess(ProcessInfo.hProcess, ExitCode);
  if ExitCode <> STILL_ACTIVE then Break;
  FillChar(pBuffer,SizeOf(PBuffer), #0);
  ReadFile(hoRead, pBuffer[0], 250, BytesRead, nil);    
  if BytesRead > 0 then begin
   if (IsTextUnicode(@pBuffer, BytesRead, @RealUNICODE) or IsTextUnicode(@pBuffer, BytesRead, @ExtendedAscii) then begin
    MessagBoxW(0,dbuffer,'',0);
   end else begin
    FillChar    (aBuffer,SizeOf(aBuffer ), #0);
    CopyMemory  (@aBuffer , @pBuffer, BytesRead * 2);
    MessageBoxA (0, aBuffer, '', 0);
   end;
  end;
 end;
end;

このスニペットは、実際にはかなりうまく機能します。ANSI 文字列/文字がコンソール (ping.exe など) に書き込まれた場合、後で ANSI 出力を取得するようにします。残念ながら、小さな不具合が 1 つあります。ping.exe を使用しており、Unicode 部分に戻るまでは問題なく動作します。説明するのは実際には難しいですが、私の言いたいことを理解していただければ幸いです。ご協力ありがとうございました。

編集: ping.exe が終了すると、スニペットは何らかの理由で空の文字列を返します。readbytes > 0 でも

EDIT2: ここに画像の説明を入力

説明: CreateProcesW で cmd を開始し、パイプなどを設定してから、最初のバッファー バイトを (Unicode で) 読み取りました。次に、ipconfig と入力すると、ANSI に戻りました。次に、バイトを読み取り、それらは空の ANSI 文字列です。その後、「プログラム」(cmd ではない) がクラッシュすることがあります。

EDIT3:ここに例があります(ソースコードとバイナリを使用)。これは、delphi7 と tntcontrols でコンパイルされています。tntcontrols がない場合は、フォームにメモ (name : Memo1) を入力してください。ワイド文字列を文字列に変更するか、messageboxW でデバッグしてみてください。 http://dl.dropbox.com/u/349314/UNICODE%20Shell%20Example.rar この例では、ANSI 入力は気にしません。

4

1 に答える 1

1

コンソールはすべての Unicode 文字を正しく表示できません。これは、コンソール ウィンドウの制限によるものです。コンソール プロセスの出力は、ANSI ではなく OEM エンコーディング (または DOS エンコーディング) です。

出力をファイルにリダイレクトすることで確認できます。通常、ファイルに英語以外の文字が含まれていると、メモ帳で正しく表示されません。

で実行するcmd.exe/u、Unicode 文字がパイプに書き込まれることが期待できます。この場合、常に出力を Unicode として扱う必要があります。


Wide-version を呼び出してプロセスを作成します。ただし、開始されたプロセスが Unicode 関数を使用して出力を行うという意味ではありません。さらに、Windows 2000 以降、Windows API 関数のすべての Ansi バージョンは Wide バージョンのラッパーです。

  1. ANSI 関数は、デフォルトのコード ページを使用して、入力パラメータのすべてのテキストをワイド文字列に変換します。
  2. 次に、Wide バージョンを呼び出します。
  3. 結果があれば、Wide- から Ansi に変換して返します。

ただし、これはコンソール ウィンドウには当てはまりません。プログラムは通常、Unicode 文字列を OEM エンコーディング (DOS エンコーディング) に変換してから、結果を stdout に書き込む必要があります。この場合のみ、コンソール ウィンドウで正しく表示されます。

于 2012-10-21T15:12:11.573 に答える