2009-12-09 15 views
6

Javaのランタイムexecを使用してブラウザを起動し、Webページをロードします。正確な呼び出しは次のようになります。私の場合はWindowsでのJava Runtime Execが引数のUnicodeで失敗する

String[] explorer = {"C:\\Program Files\\Internet Explorer\\IEXPLORE.EXE", 
    "-noframemerging", 
    "C:\\ ... path containing unicode chars ... \\Main.html"}; 
Runtime.getRuntime().exec(explorer); 

、パスは、文字&#のx65e5を"\u65E5\u672C\u8A9E"が含まれています;&#のx672c;&#のx8a9e ;.

どうやらこれは、Javaのバグです: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4947220

私の質問は:単にJavaを使用して行うことができる実行可能な回避策はありますか?このためにJNIライブラリを書くことは可能ですが、可能ならばそれを避けたいと思います。私はasciiとしてパスをURIエンコーディングし、バッチファイルにコマンドを書き込むことを試みましたが、成功しませんでした。

答えて

0

これらは、多かれ少なかれ回避策をそれぞれの私はと考える2つのソリューション、以下のとおりです。

  1. 適切なページにブラウザをリダイレクトします一時HTMLリダイレクトファイルを作成します。 IEは、ローカルファイル用にエンコードされていないユニコードを期待していますが、他のブラウザは、URLエンコードされたファイルパスのみを受け入れることができます。

  2. Windowsファイルの短いファイル名を使用してください。ユニコード文字は含まれません。

-1

私はあなたが試してみるためにApache Commons ExecライブラリやProcessBuilderを使用することができると思う;)

+0

ProcessBuilderはコマンド引数文字列でユニコードと同じ問題を抱えているようです。私は残念ながら私の特別なケースでは外の図書館を持ち込むことができません。 – Bear

+0

getPath()メソッドを使用して変数への引数を初期化し、ソースコード内でユニコード以外のものに触れることなくProcessBuilderでそれらを使用する方法はありますか? – israkir

+0

Apache Commons Execは内部的にRuntime.exec()APIを使用しますが、以前と同じ問題が残ります。 – Renan

2

あなたがProcessBuilderをを使用して、環境変数のパラメータを包む動作すると報告されている回避策を見つけるでしょうJava bug page述べました。 Parag Thakurのソースコードは次のとおりです。

String[] cmd = new String[]{"yourcmd.exe", "Japanese CLI argument: \ufeff\u30cb\u30e5\u30fc\u30b9"};   
Map<String, String> newEnv = new HashMap<String, String>(); 
newEnv.putAll(System.getenv()); 
String[] i18n = new String[cmd.length + 2]; 
i18n[0] = "cmd"; 
i18n[1] = "/C"; 
i18n[2] = cmd[0]; 
for (int counter = 1; counter < cmd.length; counter++) 
{ 
    String envName = "JENV_" + counter; 
    i18n[counter + 2] = "%" + envName + "%"; 
    newEnv.put(envName, cmd[counter]); 
} 
cmd = i18n; 

ProcessBuilder pb = new ProcessBuilder(cmd); 
Map<String, String> env = pb.environment(); 
env.putAll(newEnv); 
final Process p = pb.start(); 
0

私たちはJNIを使​​用して、Javaから数年間プロセスを開始しています。 Runtime.execもProcessBuilderも動作しません。すでにどれくらいの時間が経過しているかを考えれば、これを修正することはまずありません。

ただし、入力ストリーム、ソケット、環境変数を使用してパラメータを渡すことで、この問題を回避することができます。実行可能ファイルを直接制御できない場合は、ラッパーを作成する必要があります。

0

JNAを使用できます。バージョン3.3.0以降でCreateProcess呼び出す:子プロセスからの出力をリダイレクトする

WinBase.PROCESS_INFORMATION.ByReference processInfo = 
    new WinBase.PROCESS_INFORMATION.ByReference(); 
WinBase.STARTUPINFO startupInfo = new WinBase.STARTUPINFO(); 

String command = "C:\\Program Files\\Internet Explorer\\IEXPLORE.EXE " + 
    "-noframemerging \"C:\\\u65E5\u672C\u8A9E\\Main.html\""; 

if (!Kernel32.INSTANCE.CreateProcess(
    null,   // Application name, not needed if supplied in command line 
    command,  // Command line 
    null,   // Process security attributes 
    null,   // Thread security attributes 
    true,   // Inherit handles 
    0,    // Creation flags 
    null,   // Environment 
    null,   // Directory 
    startupInfo, 
    processInfo)) 
{ 
    throw new IllegalStateException("Error creating process. Last error: " + 
     Kernel32.INSTANCE.GetLastError()); 
} 

// The CreateProcess documentation indicates that it is very important to 
// close the returned handles 
Kernel32.INSTANCE.CloseHandle(processInfo.hThread); 
Kernel32.INSTANCE.CloseHandle(processInfo.hProcess); 

long pid = processInfo.dwProcessId.longValue(); 

を少し難しくなく、不可能ではありません。

0

.bat/.shファイルを作成します。そのファイルにコマンドを書き込んで実行します。ウィンドウの場合にコードページをUnicodeに変更したことを確認してください(chcp 65001)。例えば は、ウィンドウに以下のコマンドを実行します

String[] command ={"C:\\aconex\\学校\\mysql\\bin\\mysql", "-esource", "大村箕島a\\data.sql"}; 

と呼ばれるtemp.bat一時ファイルを作成し、Runtime.getRuntime() 温度をexecして実行します。バット

chcp 65001 
C:\aconex\学校\mysql\bin\mysql -esource 大村箕島a\data.sql 
関連する問題