これを使用して、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 入力は気にしません。