C# でプログラムからURLを開こうとして既定のブラウザを呼び出すがエラーになってしまう場合

以前はURLを開こうとする時は、Microsoftのページによると、URLをtargetにいれてProcess.Start(target);
のようにすると書いてある。以下そのページ抜粋

string target= "http://www.microsoft.com";
//Use no more than one assignment when you test this code.
//string target = "ftp://ftp.microsoft.com";
//string target = "C:\\Program Files\\Microsoft Visual Studio\\INSTALL.HTM";
try
{
    System.Diagnostics.Process.Start(target);
}
catch (System.ComponentModel.Win32Exception noBrowser)
{
    if (noBrowser.ErrorCode==-2147467259)
    MessageBox.Show(noBrowser.Message);
}
catch (System.Exception other)
{
    MessageBox.Show(other.Message);
}

しかし、いくつかのWindows環境によって、ErrorCode -2147467259にあてはまってしまって、ブラウザ起動に失敗するようです。いや、むしろ失敗することのほうがが多いような気がする。
また、以下のようにFileName = urlとしてProcess.Startする様に書くのも以前は可能だったが・・・

    ProcessStartInfo pri = new ProcessStartInfo()
    {
        FileName = url,
        UseShellExecute = true,
    };

    Process.Start(pri);

今は、このFileNameにURLを代入すると駄目のようだ。
Microsoftさん、デフォルトのブラウザを自分の所のブラウザから変更してほしくないためですか??
とってもブラウザの変更はして欲しくないのでしょうね・・(私見です)
見事にいつの間にか仕様変更してるような気がします。
でも変更したならマニュアルのページも変更してほしいですね~

というわけで、FileName は起動ブラウザのファイルパスを入れ、Arguments にURLを入れればOK
まあ、これのほうがすっきりはしてますねぇ・・・

そんな訳で実際の呼び出しは、urlに実際のURLを入れてレジストリのデフォルトのブラウザを調べて起動です。以下参考に

string url= "http://www.microsoft.com";

//レジストリキー(HKEY_CURRENT_USER\Software\Microsoft\Windows\Shell\Associations\UrlAssociations\http\UserChoice)
//を、新規作成されない様に開く
Microsoft.Win32.RegistryKey regkey = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(
                @"Software\Microsoft\Windows\Shell\Associations\UrlAssociations\http\UserChoice", false);

//レジストリ"ProgId"の値を読み取り
string progId = regkey.GetValue("ProgId").ToString();

//"progID"の書かれているキーを開く
regkey = Microsoft.Win32.Registry.ClassesRoot.OpenSubKey(
                string.Format(@"{0}\shell\open\command", progId), false);

//command作成
string command =regkey.GetValue(null).ToString();
// commandには"C:\Program Files\Google\Chrome\Application\chrome.exe" --single-argument %1 のように
//ファイパス以降に不要な文字が入るので 2つめの'”'を探してそれ以降を削除する
string gomiStr = command.Substring(command.IndexOf("\"", command.IndexOf("\"") + 1) + 1);
command = command.Replace(gomiStr, "");

ProcessStartInfo info = new ProcessStartInfo();
info.UseShellExecute = true;
// デフォルトブラウザ
info.FileName = command;
// URLを加える
info.Arguments = url;
Process p = new Process();
p.StartInfo = info ;

try
{
   p.Start();
}
catch (System.ComponentModel.Win32Exception noBrowser)
{
   if (noBrowser.ErrorCode == -2147467259)
   MessageBox.Show("ブラウザー関連のレジストリに異常がある可能性もあり。"
                        + Environment.NewLine
                        + noBrowser.Message);
}
catch (Exception ex)
{
   MessageBox.Show("エラーが発生しました: " + ex.Message);
}

これでnoBrowser.ErrorCode == -2147467259のエラーは出ずにブラウザが起動してURL表示できているようです。
でもせっかくなんだから、いちいち調べて起動しなくても良いようになれば良いのですがねぇ。

関連記事

前回作成したUDP通信コンポーネントでチャットソフトを作ってみる

C# Windowsショートカットをキーボード入力ではなくボタンのクリックで送る方法

C# UDP通信のためのコンポーネントの作成

QRCodeMaker(QRコード作成、読取りソフト)

LinuxでUSB接続のストレージをsambaで共有する

ホスト名(ドメイン)からIPアドレスを取得する方法 覚書