エクセルのCOMアドインからヘルプを開きたい
エクセルのアドインをC#で作っていて、ヘルプをワードで書いてPDFで保存して用意したのだけど、アドインをセットアップしたときに、PDFファイルがどこに保存されているのかわからないので、PDFファイルを開けない。
なんとも間の抜けた話だが、アドインのセットアップを「発行」つまりClickOnceで実行しているので、いつもと様子が違うのだ。
普通のセットアップだとインストールしたファイルは Programe Files フォルダの下にはいるのだが、ClickOnceだと、どこにはいるのだろう?
アドインの「発行」ではインストールするファイルを選択することができない。PDFファイルをそもそもインストールすることができるのか。
これは、プロジェクトにPDFファイルを追加して、プロパティを「コンテンツ」にすればOKだった。
発行先のフォルダの「Application Files\ExcelAddin_X_X_X_XXX」フォルダの下を見れば、PDFファイルらしきものが含まれているのがわかる。
ということで、あとはPDFファイルのインストール先のパスがわかれば、ファイルを開けるわけだ。
その結果、以下のようなフォルダ名がゲットできた。
C:\Users\XXX\AppData\Local\assembly\dl3\R1NMCHXM.3BO\W1777BQJ.9YD\42693b50\cc850222_7ca7d201
なにこれ?
フォルダを見ると、DLLといっしょに .ini ファイルもある。開いてみると、パスが書いてあった。
全角で書いてあるように見えるが、半角英字で間に空白が挟まっている。これはユニコードだね。中に「file:///」で始まるパスがあるので、そこを開いてみたいが、まずはきちんとしたパスにしないと開きようがない。
ということで、コードを書いてみる。
エンコードをユニコードで指定して読み込んで、「file:///」で始まるパスを、ローカルパスに書き換えている。べたべたですな。
ゲットできたパスが下記の通り。意味不明。
C:\Users\XXX\AppData\Local\Apps\2.0\BRBX20N6.35Q\0JQ5A65E.MG1\mm60..vsto_3aba3d5660836e46_0006.0000_e62396caed0d6103
中を見ると、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 "";
- }
- }
*
コメント
コメントを投稿