エクセルのCOMアドインからヘルプを開きたい

エクセルのアドインをC#で作っていて、ヘルプをワードで書いてPDFで保存して用意したのだけど、アドインをセットアップしたときに、PDFファイルがどこに保存されているのかわからないので、PDFファイルを開けない。




なんとも間の抜けた話だが、アドインのセットアップを「発行」つまりClickOnceで実行しているので、いつもと様子が違うのだ。

普通のセットアップだとインストールしたファイルは Programe Files フォルダの下にはいるのだが、ClickOnceだと、どこにはいるのだろう?

そもそもPDFファイルはインストールできるのか


アドインの「発行」ではインストールするファイルを選択することができない。PDFファイルをそもそもインストールすることができるのか。

これは、プロジェクトにPDFファイルを追加して、プロパティを「コンテンツ」にすればOKだった。

発行先のフォルダの「Application Files\ExcelAddin_X_X_X_XXX」フォルダの下を見れば、PDFファイルらしきものが含まれているのがわかる。

ということで、あとはPDFファイルのインストール先のパスがわかれば、ファイルを開けるわけだ。

アドインのDLLの実行パスを調べる

アドインはDLLなので実行中のパスを調べれば、どこで動いているのかはわかるはず。コードを書いてみる。

using System.Reflection;

Assembly asm = Assembly.GetExecutingAssembly();
string p1 = asm.Location;

その結果、以下のようなフォルダ名がゲットできた。

C:\Users\XXX\AppData\Local\assembly\dl3\R1NMCHXM.3BO\W1777BQJ.9YD\42693b50\cc850222_7ca7d201

なにこれ?

フォルダを見ると、DLLといっしょに .ini ファイルもある。開いてみると、パスが書いてあった。

全角で書いてあるように見えるが、半角英字で間に空白が挟まっている。これはユニコードだね。中に「file:///」で始まるパスがあるので、そこを開いてみたいが、まずはきちんとしたパスにしないと開きようがない。

ということで、コードを書いてみる。

          string p2 = System.IO.Path.GetDirectoryName(p1) + "\\" + "__AssemblyInfo__.ini";
          if (System.IO.File.Exists(p2))
           {
              System.IO.StreamReader rd = new System.IO.StreamReader(p2, Encoding.Unicode);
               refPath = rd.ReadLine();
              rd.Close();
           }
           int n = refPath.IndexOf("file:///");
          if (n > 0)
          {
               refPath = refPath.Substring(n, refPath.Length - n - 1);
              refPath = refPath.Replace("file:///", "").Replace("/", "\\");
               refPath = System.IO.Path.GetDirectoryName(refPath);
           }

エンコードをユニコードで指定して読み込んで、「file:///」で始まるパスを、ローカルパスに書き換えている。べたべたですな。

ゲットできたパスが下記の通り。意味不明。

C:\Users\XXX\AppData\Local\Apps\2.0\BRBX20N6.35Q\0JQ5A65E.MG1\mm60..vsto_3aba3d5660836e46_0006.0000_e62396caed0d6103

中を見ると、PDFファイルがある。


これで目的は達成できそう。

もっとセンスの良い解決手順

アセンブラ情報にはCodeBaseプロパティがあって、そこにインストール先フォルダのパスがあるらしい。しかも「file:///」はUrlクラスを使えば、簡単にローカルパスの形式に変換してくれる。文字列探して切り出して、、、なんてコードを書いていたのが、本当に悲しい。

        /// アドインの参照ファイルがインストールされるフォルダのパスを得る
        /// </summary>
        /// <returns></returns>
        string getAddinInstallFolderPath()
        {
            try
            {
                Assembly asm = Assembly.GetExecutingAssembly();
                Uri uri = new Uri(asm.CodeBase);
                string p = System.IO.Path.GetDirectoryName(uri.LocalPath);
                return p;
            }
            catch (Exception)
            {
                return "";
            }
        }




コメント

このブログの人気の投稿

varchar をデータ型 numeric に変換中に、算術オーバーフロー エラーが発生しました。