2

作成中の .NET コンソール プログラムで、UTF8 でエンコードされたコマンド ライン パラメーターを処理できるようにしたいと考えています。残念ながら、Main() 関数に渡された "args" 配列と Environment クラス メンバー (CommandLine および GetCommandLineArgs()) の両方が既に (誤って) Unicode に変換されており、コマンドラインをシングルバイト拡張として扱っているようです。 -アスキー。

たとえば、UTF8 の U+2019 (シングル アポストロフィで閉じる) は 0xe2 0x80 0x99 です。1252 コードパデでは、0x80 はユーロ記号 (U+20ac) で、0x99 は「TM」記号 (U+2122) です。(0xe2 はサーカムフレックス付きの "a" であり、U+00e2 であるため、変更されません) コマンドラインでこれら 3 バイトを渡すと、文字列の "char" 要素は 0x00e2 0x20ac および 0x2122 になります。 .

コマンドラインをUTF8として解釈するように.NETに指示する方法、または生の未処理のコマンドラインを取得する方法はありますか(喜んでUnicode文字列に変換できます)?

アップデート

以下の dletozeun の回答

特にXPの場合(最初に質問したときに使用していました)、Windowsは奇妙なことをします。.NET コマンド ライン プログラムをバッチ ファイルから呼び出すか、コマンド プロンプトから直接呼び出すかによって、動作が異なるようです。これにはおそらく非常に正当な理由があります™ が、私にはわかりません。とにかく、それが誰かを助けるなら、ここに私が見つけたものがあります:

コマンドライン

標準のコマンド プロンプト ウィンドウを開き、次のコマンドを入力します。

UTF8Cmd.exe abc’def

ここで、UTF8Cmdは dletozeun のソリューションを組み込んだテスト プログラムで、中央の文字は 0xe2、0x80、0x99 (U+2019 の UTF8 バイト -- 単一のアポストロフィを閉じる) であり、次の出力を生成します (dletozeun のコードの前後の引数を両方とも文字列と 16 進数でダンプ):

    Raw : "abcâ?Tdef"    61 62 63 e2 20ac 2122 64 65 66
    UTF8: "abc'def"      61 62 63 2019 64 65 66

元の引数 ( Raw) が 1252 コード ページのバイト値から同等の Unicode 値にマングルされていることを示していますが、投稿されたコードによってそれらが正しい値 (U+2019) に変換されています。

バッチファイル

残念ながら、上記だけをバッチ ファイルに入れても機能しません...まったく異なるマングリングが発生し、以下が生成されます。

    Raw : "abcÔÇÖdef"    61 62 63 d4 c7 d6 64 65 66
    UTF8: "abc???def"    61 62 63 fffd fffd fffd 64 65 66

生のバイトは、おそらく有効な UTF8 ではない何か奇妙なものにマングルされているため、fffd処理後の s です。

ただしchcp 65001、最初に使用する(そして後でリセットする)という@mvpの提案により、dletozeunのコードを必要とずに機能するようになりました。

Active code page: 65001
    Raw : "abc’def"      61 62 63 2019 64 65 66
    UTF8: "abc�def"      61 62 63 fffd 64 65 66
Active code page: 850

以下のコメントに記載されているように、以前にこれを試しことがありますが、それは完全に失敗した XP ボックスでした (コマンドを実行しているようにも見えず、コマンドプロンプトが奇妙な状態のままになります)。Windows 7ボックスで回答に応じて今試してみると、chcp 65001最初に質問したときに期待したとおりにコマンドが機能します!

4

1 に答える 1

3

遅いことはわかっていますが、この問題に遭遇したばかりで、どこにも答えが見つかりませんでした。私はなんとか解決策を見つけたので、引数リストでUTF8でエンコードされた文字を処理するために私がしたことは次のとおりです。

    // Handle UTF8 encoded characters
    byte[] argBytes =  System.Text.Encoding.Default.GetBytes( System.String.Join( " ", System.Environment.GetCommandLineArgs() ) );
    string argString = System.Text.Encoding.UTF8.GetString( argBytes );
    string[] args = argString.Split( ' ' );
于 2014-12-10T10:32:55.853 に答える