開発用メモ
背景 †
何時の頃からか解らないが、FreeTrainでヘルプメニューから
「オンラインヘルプ」を選ぶとエラーが出るようになった。
また、プラグインエラーダイアログで、「バグを報告」ボタンを押すと
同じようなエラーが出るようになった。
これはどちらも、ソースコード上は
System.Diagnostics.ProcessクラスのStartメソッドに
URL文字列を与えて、標準のブラウザで対象URLを開く操作であり、
C#の本やWebなどでも、サンプルとして紹介されている一般的なコードである。
http://dobon.net/vb/dotnet/process/openbrowser.html
概要 †
特定の外部ライブラリなどを組み込むと、Process.Startで実行ファイルをシェルに解決させる
(所謂、ファイル名を指定して実行)機能が働かない場合がある。
この場合の一つの解決方法は、自分でレジストリの関連づけを調べて、
明示的に関連づけられたアプリケーションを起動することである。
詳細 †
本やWebで、指定のURLをブラウザで開くサンプルとして
一般的に紹介されている以下のようなコードですが、
System.Diagnostics.Process.Start("http://www.google.co.jp/");
プロジェクトによっては、以下のようなエラーで正常に機能しない場合があります。
System.ComponentModel.Win32Exception: 指定されたファイルが見つかりません。
at System.Diagnostics.Process.StartWithShellExecuteEx(ProcessStartInfo startInfo)
色々調べたのですが、どこか海外のサイトでは、特定ライブラリを組み込むと
このような現象に陥る、と報告されていました。(当該URL失念)
しかし残念ながら、そのサイトにも解決法は示されていませんでした。
さらに試行錯誤した結果、ProcessStartInfoクラスで実行ファイルと
ワーキングディレクトリを絶対パスで指定すれば、
例えばIExplorer.exeに引数としてURLを与えて起動できることが解りました。
実用上はIExplorer.exeではなく、「通常使うブラウザ」として設定されている
アプリケーションを起動したいところですが、
これは下記のレジストリを読むことで解決できます。
HKEY_CLASSES_ROOT\http\shell\open\command
例えば、元々以下のようなコードが、正常に機能しなかったなら・・・
1
2
3
4
5
| -
-
-
!
!
| public void openUrl(String targetUrl) {
System.Diagnostics.Process.Start(targetUrl);
}
|
次のように修正すれば、問題なくブラウザを起動できます。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
-
-
|
-
!
|
-
|
!
-
|
|
|
!
|
-
|
|
|
!
-
!
-
!
|
!
| using System;
using System.Diagnostics;
using System.IO;
using Microsoft.Win32;
public void openUrl(String targetUrl) {
ProcessStartInfo info = new ProcessStartInfo();
RegistryKey rkey = Registry.ClassesRoot.OpenSubKey(@"http\shell\open\command");
String val = rkey.GetValue("").ToString();
if(val.StartsWith("\""))
{
int n = val.IndexOf("\"",1);
info.FileName = val.Substring(1,n-1);
info.Arguments = val.Substring(n+1);
}
else
{
string[] a = val.Split(new char[]{' '});
info.FileName = a[0];
info.Arguments = val.Substring(a[0].Length+1);
}
info.WorkingDirectory = Path.GetDirectoryName(info.FileName);
info.Arguments += targetUrl;
Process.Start(info);
}
|
MainWindow.cs ソース
UrlLinkLabel.cs ソース
1/3851