【NetOffice】【Excel】NetOfficeが利用できるCOMアドインを作成する。

  • 2012.11.15 Thursday
  • 21:31
JUGEMテーマ:コンピュータ

---------------------------------------------------
本投稿は、COMテクノロジー、Excelアプリケーション、VBAなどを全く知らない人間が書いています。
その点をご配慮いただき、読んでいただけると助かります。
---------------------------------------------------

Source and Project

今回は、NetOfficeが利用できるCOMアドインを作成したいと思います。COMアドイン自体は、NetOfficeのサイト(http://netoffice.codeplex.com/releases/view/70943)にある[Tool] Developer Toolbox 1.1.exeを利用すれば、COMアドイン用のViual Studio のプロジェクトが自動生成できるので、特に知識がなくても作成することができます。ただし、知識がないと何をしているのかさっぱりわからないのも問題となることは明白なので、今回は、自動生成したプロジェクトを解析した結果、自分で一から作っていく手順を紹介したいと思います。

1. クラスライブラリーのプロジェクトを作成します。
ターゲットを.NET Framework 4.5にしました。ターゲットによって後々の参照するライブラリーが異なるので注意してください。


2. 参照設定に「Extensibility」を追加する。
COMアドインを作成するのは、「Extensibilty」というライブラリーを参照に追加する必要があります。このライブラリー少し問題がありまして、同名のファイルがいくつか存在します。私の環境ではOffice アドイン用が2つ、Visual Studio アドイン用が1つ存在していました。見分けるには、Visual Studio 2012では、カーソルを当てて、ポップアップを見ることで違いがわかります。Visual Studio 2010では表示される画像がそれっぽいの選ぶと大丈夫だと思います。最悪でもファイルパスを指定する方法があるので、なんとかなると思いますが、本当にわかりずらいんです(笑)




私の環境だと
'C:¥Program Files (x86)¥Microsoft Visual Studio 11.0¥Visual Studio Tools for Office¥PIA¥Common¥Extensibility.dll'
にありました。

3. アセンブリをCOM参照可能にする。
今回、作成するアセンブリはCOM参照可能にしておく必要があります。手順としては二通りあります。一つはVisual Studio のUIを利用する方法で、手順Aです。もう一つはコードに直接編集する方法で、手順Bです。
手順A. プロジェクト>プロパティ>アプリケーションタブ>アセンブリ情報
 「アセンブリをCOM参照可能にする」にチェックを入れる。
Art55.Excel.ComAddIn20121115_001プロジェクトを右クリックし、「プロパティ」を選択、アプリケーションタグの「アセンブル情報」ボタンをクリックすると、下記の画面の「アセンブリ情報」ダイアログが表示されます。一番下にある「アセンブリをCOM参照可能にする」というチェックボックスにチェックをいれると参照可能になります。


手順B. AssemblyInfo.csにComVisible属性をtrueに設定する。
[assembly: ComVisible(true)]
こちらの方が簡単です。

4.クラスをCOMアドイン用に実装する。
COMアドインの情報をレジストリに書き込む必要があります。今回は詳細は書きませんが、大体を説明すると、
クラスに任意のGUIDを指定するためのGuidAttribute属性を指定します。おそらく付けなくてもクラス名からGUIDが生成できるので、問題はないと思いますが、コンパイル前にGUIDを決めておいた方が管理しやすいかと思います。
クラスにProgId属性を指定します。指定しなければクラス名がそのまま適用されるはずですが、39文字という制限があるのであえて意図的に指定しておいた方が良いと思います。
クラスにComVisible属性を指定します。COMサーバーから見えるようにするためにtrueを指定します。既定でtrueとMSDNには書かれているような・・・。

実装すると
[GuidAttribute("15071DAF-177C-4438-9129-4B4DB82BFF84"), ProgId(AddInProcId), ComVisible(true)]
public class SixSheetAddIn
{
  ....
}

GUIDは下記のツールを利用すると適当に作れます。
Microsoft Exchange Server GUID Generator
http://www.microsoft.com/en-us/download/details.aspx?id=17252

5.RegisterFunction・UnregisterFunctionメソッドを実装する。
レジスター登録時に呼び出されるメソッドを実装する必要があります。そのメソッドにComRegisterFunctionAttribute属性をしていする必要があります。逆にレジストリを消す際に呼び出されるメソッドには、ComUnregisterFunction属性を指定する必要があります。メソッド内部の実装は、Developer Toolbox 1.1を参考にしました。Developer Toolbox 1.1の設定と自動生成するコードとの対応を見比べれば、大体何をしているか分かると思います。

using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.InteropServices;
using Microsoft.Win32;
namespace Art55.Excel.ComAddIn20121115_001
{
    [GuidAttribute("15071DAF-177C-4438-9129-4B4DB82BFF84"), ProgId(AddInProcId), ComVisible(true)]
    public class SixSheetAddIn
    {
        private const string AddInProcId = "Art55.Excel.SixSheetAddIn";
        private const string SubKeyPath = @"Software¥Microsoft¥Office¥Excel¥Addins¥" + AddInProcId;
        [ComRegisterFunctionAttribute]
        public static void RegisterFunction(Type type)
        {
            try
            {
                // add codebase value
                Assembly thisAssembly = Assembly.GetAssembly(typeof(SixSheetAddIn));
                RegistryKey key = Registry.ClassesRoot.CreateSubKey("CLSID¥¥{" + type.GUID.ToString().ToUpper() + "}¥¥InprocServer32¥¥1.0.0.0");
                key.SetValue("CodeBase", thisAssembly.CodeBase);
                key.Close();
                key = Registry.ClassesRoot.CreateSubKey("CLSID¥¥{" + type.GUID.ToString().ToUpper() + "}¥¥InprocServer32");
                key.SetValue("CodeBase", thisAssembly.CodeBase);
                key.Close();
                // add bypass key
                // http://support.microsoft.com/kb/948461
                key = Registry.ClassesRoot.CreateSubKey("Interface¥¥{000C0601-0000-0000-C000-000000000046}");
                var defaultValue = key.GetValue("") as string;
                if (null == defaultValue)
                    key.SetValue("", "Office .NET Framework Lockback Bypass Key");
                key.Close();
                Registry.CurrentUser.CreateSubKey(SubKeyPath);
                RegistryKey regKeyExcel = Registry.CurrentUser.OpenSubKey(SubKeyPath, true);
                if (regKeyExcel != null)
                {
                    regKeyExcel.SetValue("LoadBehavior", Convert.ToInt32(3));
                    regKeyExcel.SetValue("FriendlyName", "SixSheetAddIn");
                    regKeyExcel.SetValue("Description", "デフォルトのシートの枚数が6枚になる。");
                    regKeyExcel.Close();
                }
            }
            catch (Exception ex)
            {
                Debugger.Break();
            }
        }

        [ComUnregisterFunction]
        public static void UnregisterFunction(Type type)
        {
            try
            {
                Registry.ClassesRoot.DeleteSubKey(@"CLSID¥{" + type.GUID.ToString().ToUpper() + @"}¥Programmable", false);
                Registry.CurrentUser.DeleteSubKey(SubKeyPath, false);
            }
            catch (Exception throwedException)
            {
                Debugger.Break();
            }
        }
    }
}

6. ビルドのアクションとして、「COM相互運用機能の登録」するようにする。
この手順は必須ではありませんが、登録すると、ビルド時にレジストリーにCOMアドインの情報を書き込むようになります。


注意点として、「COM相互運用機能の登録」にチェックを入れる場合、Visual Studio を管理者権限で実行する必要があります。管理者権限で実行した場合、セキュリティの関係上、エックスプローラーからVisual Studioへファイルをドラッグアンドドロップできなくなったりと少し弊害が生まれる事があります。色々注意です。

手動で、マネージアセンブリーをレジストリーに登録する場合はRegasm.exeを利用する方法があります。
アセンブリ登録ツール (Regasm.exe)
http://msdn.microsoft.com/ja-jp/library/tzat5yw6(v=vs.80).aspx
Regasm.exeを利用する場合も、コマンドプロンプトを管理者権限で実行する必要があります。

7. ビルドをして、レジストリーに登録できるかどうか確かめる。
一度ビルドします。エラーやデバッガのアッタッチが起動しなければ大体成功です。

8. 「regedit.exe」から、レジストリが登録されているかどうか確かめる。
今回は、インストールしたユーザのみ使えるように指定しているため
クラスを指定したアドレスは
HKEY_CLASSES_ROOT¥CLSID¥{15071DAF-177C-4438-9129-4B4DB82BFF84}¥


今回はインストールしたユーザのみ使用可能にしたのでExcelの設定は
HKEY_CURRENT_USER¥Software¥Microsoft¥Office¥Excel¥Addins¥Art55.Excel.SixSheetAddIn


といった感じでレジストリに書き込まれた事が確認できます。

9. Excelにアドインが表示されていることを確認する。
今回作成したアドインは実はまだExcelに読み込むことはできないのですが、COMアドインの一覧に表示されているかどうか見てみることにします。

Excelを立ち上げる。
リボン上部のファイルタブを選択し、オプションを選択



「Excelのオプション」ダイアログの下部にある管理コンボボックスを「COMアドイン」を指定して、「設定」ボタンを押します。


今回、作成した「SixSheetAddIn」が存在する事が分かります。


まだ実装不十分のため、これを読み込む事ができません(続きを読んでください)。

10. IDTExtensibility2インターフェイスを継承させる。
Excelにアドインするには上記のインターフェースを継承する必要があります。

using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.InteropServices;
using Extensibility;
using Microsoft.Win32;
namespace Art55.Excel.ComAddIn20121115_001
{
    [GuidAttribute("15071DAF-177C-4438-9129-4B4DB82BFF84"), ProgId(AddInProcId), ComVisible(true)]
    public class SixSheetAddIn : IDTExtensibility2
    {
        ...
        void IDTExtensibility2.OnConnection(object application, ext_ConnectMode connectMode, object addInInst, ref Array custom)
        {
        }
        void IDTExtensibility2.OnDisconnection(ext_DisconnectMode removeMode, ref Array custom)
        {
        }
        void IDTExtensibility2.OnAddInsUpdate(ref Array custom)
        {
        }
        void IDTExtensibility2.OnStartupComplete(ref Array custom)
        {
        }
        void IDTExtensibility2.OnBeginShutdown(ref Array custom)
        {
        }
    }
}

もう一度、ビルドしてみると、今回はExcelにアドインできる事が分かります。



ここまでの手順は、NetOfficeとは関係なくExcel用のCOMアドインを作成する手順です。これから、NetOfficeを利用する手順を紹介します。

11.NetOffice(Excel)関連のDllを参照設定に追加する。
ExcelApi.dll、NetOffice.dll、OfficeApi.dll、VBIDEApi.dll
相互運用機能型の埋め込みをFalseに設定する。(.NET Framework 4以降)


12.NetOfficeライブラリーを使用したオートメーションロジックを組み込む

        private Application _application;
        void IDTExtensibility2.OnConnection(object application, ext_ConnectMode connectMode, object addInInst, ref Array custom)
        {
            _application = new Application(null, application);
            Workbook workbook = (_application.Workbooks.FirstOrDefault()
                ?? _application.Workbooks.Add());
            int addCount = 6 - workbook.Worksheets.Count;
            if (addCount > 0 && addCount < 6)
            {
                workbook.Worksheets.Add(Type.Missing, workbook.Worksheets.First(), addCount);
            }
        }
        void IDTExtensibility2.OnDisconnection(ext_DisconnectMode removeMode, ref Array custom)
        {
            if (null != _application)
            {
                _application.Dispose();
                _application = null;
            }
        }

13.ビルドをして成功したら完成
Excelを起動するとシートがデフォルト6枚になるアドインの完成です。こんなの作って喜ぶ人はいないと思うのでさっさと、アドインは削除しましょう(笑)


ちなみに今回の手順は「NetOffice Developer Toolbox 1.1」を利用すればボタン操作を数回繰り返すだけで実現できます。

Source and Project

--------------------------------------
本投稿は、CodePlexで公開されているNetOfficeを利用しています。
NetOffice - MS Office in .NET
http://netoffice.codeplex.com/
NetOffice関連の記事は下記にまとめています。
【NetOffice】【Excel】NetOfficeのまとめ
http://pro.art55.jp/?eid=1304102
--------------------------------------
コメント
コメントする








    
この記事のトラックバックURL
トラックバック

calendar

S M T W T F S
     12
3456789
10111213141516
17181920212223
24252627282930
<< June 2018 >>

あわせて読みたい

あわせて読みたいブログパーツ

selected entries

categories

archives

recent comment

  • 【キーボード】6年前のRealForceを復活させることはできる!?その3
    art55 (05/22)
  • 【キーボード】6年前のRealForceを復活させることはできる!?その3
    分解大好き (05/18)
  • 【.NET Framework 4.5】 IListがIReadOnlyListを継承してない理由。
    art55 (02/04)
  • 【.NET Framework 4.5】 IListがIReadOnlyListを継承してない理由。
    Gen (02/04)
  • 【キーボード】RealForce が壊れて帰ってきた。
    art55 (04/29)
  • 【.NET Framework 4.5】 IListがIReadOnlyListを継承してない理由。
    art55 (02/23)
  • 【.NET Framework 4.5】 IListがIReadOnlyListを継承してない理由。
    かるあ (02/22)
  • 【C#】Dictionaryの実装・データ構造・アルゴリズムを観察する。
    art55 (01/16)
  • 【C#】Dictionaryの実装・データ構造・アルゴリズムを観察する。
    karuakun (01/16)
  • 【NetOffice】【Excel】死なないExcelプロセスをKillする。
    art55 (12/05)

recent trackback

recommend

recommend

recommend

C#プログラマのための.NETアプリケーション最適化技法 (Programmer's SELECTION)
C#プログラマのための.NETアプリケーション最適化技法 (Programmer's SELECTION) (JUGEMレビュー »)
Sasha Goldshtein,Dima Zurbalev,Ido Flatow,サシャ・ゴルドシュタイン,ディマ・ズルバレフ,イド・フラトー

recommend

ろんりと集合
ろんりと集合 (JUGEMレビュー »)
中内 伸光
とてもわかりやすいです。

recommend

recommend

シャノン・ノイマン・ディジタル世界
シャノン・ノイマン・ディジタル世界 (JUGEMレビュー »)
市川 忠男
4章がリレーショナルデータベースな内容になってます。ページ数があまりありませんが、ポイントがものすごく的確にまとまっていて、感動します。

recommend

recommend

東プレ Realforce91UBK-S 静音キーボード 静電容量無接点方式 変荷重 ブラック NG01BS
東プレ Realforce91UBK-S 静音キーボード 静電容量無接点方式 変荷重 ブラック NG01BS (JUGEMレビュー »)

テンキーレス、静音のRealForce91UBK-S。スコスコ感がたまらなく気持ちいいです。家と会社で2台持ってます。

recommend

recommend

プログラミング.NET Framework 第4版 (プログラミングシリーズ)
プログラミング.NET Framework 第4版 (プログラミングシリーズ) (JUGEMレビュー »)
Jeffrey Richter
発売予定美 2013年10月10日。.NET Frameworkとお付き合いする人のバイブルですね。

recommend

recommend

キャット・シッターの君に。
キャット・シッターの君に。 (JUGEMレビュー »)
喜多嶋 隆
私のイラストレータデビュー本です。

recommend

Essential .NET ― 共通言語ランタイムの本質
Essential .NET ― 共通言語ランタイムの本質 (JUGEMレビュー »)
ドン・ボックス,クリス・セルズ,Don Box,Chris Sells,吉松 史彰

links

profile

search this site.

others

mobile

qrcode

powered

無料ブログ作成サービス JUGEM