エクセルの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 ""; } }
*
コメント
コメントを投稿