July 26, 2005

[C#]外部exeの標準出力がUnicodeだと化ける

Posted at July 26, 2005 02:44 AM in .

.NET FrameworkではProcessクラスを使って外部exeを実行します。そのとき、標準出力をリダイレクトさせて、Processの側で受け取ることができます。
ところが、Processクラスは受け取った標準出力を勝手にShift-JIS(?)にエンコードしてしまうため、受け取った標準出力がUnicodeその他の文字コードだと、得られる文字列は化け化けになってしまいます。困りますね。
たとえばHyper Estraierのestcmd.exeは出力をUnicodeで返してくるんですが、これを素直にProcessクラスで受け取ると文字化けで使い物になりません。超fuck。

なんとかしてProcessクラスに対して標準出力の文字コードを指定してやりたいところですが、どうも無理なんじゃないかと思われます。少なくとも僕の知識では無理でした。Process.StandardOutput.CurrentEncodingが文字コードの変換をしていると思うのですが、これがReadOnlyになっていてどうにもなりません。

で。対処策としては、間に別のexeを挟む、ということになります。
たとえば、cmd.exe(コマンドプロンプト)を間に挟んで、ファイルとしてリダイレクトし、それをStreamReaderクラス等で読み直すとか。
ファイルを経由するのがだるいので、代理でプログラムを実行して、得られた標準出力をUnicodeに直してから出力し直すプログラムがあれば良いのですが。まあ、とりあえずはファイルを経由する実装でやっておこう。



Trackback

You can ping this entry by using http://windy.ac/MT/mt-tb.cgi/821 .

Comments

こんな感じでいかがでしょう。

using System;
using System.Text;
using System.IO;
using System.Diagnostics;

public class Execute {
public static readonly Encoding encoding = Encoding.GetEncoding("UTF-16");

static void Main(string[] args) {
if(args.Length > 0){
Console.WriteLine("任意のエンコーディングの外部実行ファイルの出力を取り込むテスト:");
ProcessStartInfo psi = new ProcessStartInfo();
psi.FileName = "nkf.exe";
psi.Arguments = "-w16L " + args[0];
psi.UseShellExecute = false;
psi.RedirectStandardOutput = true;
Process p = Process.Start(psi);
StreamReader sr
= new StreamReader(p.StandardOutput.BaseStream, encoding);
string cmdout = sr.ReadToEnd();
sr.Close();
Console.WriteLine(cmdout);
} else {
Console.WriteLine("usage: unipro.cs some.txt");
}
}
}

Posted by naruse at July 26, 2005 04:05 AM

Post a comment










Remember personal info?