none
VSTOで利用するアセンブリ?のバージョンについて RRS feed

  • 質問

  • Visual Studio 2015 Professionalのc#で、Offie(Outlook2010)用の
    VSTOアドインのアプリケーションを開発しています。
    接続先はOffice365です。フレームワークは .NET Framework 4.5.2です。

    c#は始めたばかりの初心者です。Visual Studioやc#の言葉の使い方には
    自信がありません。もし間違えていればご指摘いただくと幸いです。

    [質問1]
    Visual Studio 2015のソリューションエクスプローラーの
    参照を右クリックして「参照の追加」で表示される「参照マネージャー」において、
    [アセンブリ]ー[拡張]と選んでいくと、VSTO関連のアセンブリ?の情報が
    得られると思うのですが、VSTO関連のファイルバージョンは 10.0.50903.0と
    表示されます。

    しかしながら、以下のURLでダウンロードできるOffice2010のVSTOのランタイムの
    バージョンは10.0.60825で、私の開発環境より新しくなっています。

    https://www.microsoft.com/ja-JP/download/details.aspx?id=54251

    Visual Studio 2015のVSTOで利用するアセンブリ?のバージョンを
    10.0.50903.0から10.0.60825に上げることはできますでしょうか?

    [質問2]
    質問1をした理由なのですが、Office365の配布グループの所有者を取得すると、
    所有者が二人以上いるのに、以下のコードでは実際に取得できるのは一人のみだからです。
    結果から、Outlook2010のVSTO関連のアセンブリ?にバグがあり、新しいVSTOの
    アセンブリ?なら解決するかもしれない・・と期待しているためです。
    なので、この問題が現在のVSTO関連のアセンブリ?で解決するのであれば、
    新しいVSTO関連のアセンブリ?にする必要はありません。

    この問題の回避方法をご存じであれば、教えていただけますでしょうか。
    よろしくお願いいたします。

    using System.Windows.Forms; using Outlook = Microsoft.Office.Interop.Outlook; // add namespace OutlookAddIn1C2 { public partial class Form1 : Form { // 配布グループの所有者を取得する部分のみを抜粋
    public void GetOwners() { Outlook.Application Application = Globals.ThisAddIn.Application; Outlook.SelectNamesDialog snd = Application.Session.GetSelectNamesDialog(); Outlook.AddressLists addrLists = Application.Session.AddressLists; snd.NumberOfRecipientSelectors = Outlook.OlRecipientSelectors.olShowTo; snd.ToLabel = "D/L"; snd.ShowOnlyInitialAddressList = true; snd.AllowMultipleSelection = false; snd.Display(); if (snd.Recipients.Count > 0) { Outlook.AddressEntry addrEntry = snd.Recipients[1].AddressEntry; if (addrEntry.AddressEntryUserType == Outlook.OlAddressEntryUserType. olExchangeDistributionListAddressEntry) { Outlook.ExchangeDistributionList exchDL = addrEntry.GetExchangeDistributionList(); Outlook.AddressEntries addrEntries2 = exchDL.GetOwners(); if (addrEntries2 != null) // 常に一人だけしか列挙されない foreach (Outlook.AddressEntry exchDLMember2 in addrEntries2) { //System.Diagnostics.Debug.WriteLine(exchDLMember.Name); listBox1.Items.Add(exchDLMember2.Name); } listBox1.Items.Add(addrEntries2.Count); // 常に1が返される } } }
    }


    2017年3月30日 9:29

回答

  • 参照で追加されるのは開発時用のアセンブリです。

    [回答1]
    ソリューションエクスプローラーでMicrosoft.Office.Tools.Outlookを選択して、プロパティウィンドウでパスを見てみてください。
    C:\Program Files\Reference Assemblies\Microsoft\VSTO40\v4.0.Framework\Microsoft.Office.Tools.Outlook.dll
    あたりにあるとなっているはずです。
    Reference Assembliesとなっていることからも推測できますが、これは参照用のアセンブリです。
    たとえばOfficeをインストールしていない環境でビルドしようとした場合、アセンブリが無いと参照の解決ができずにビルドが失敗します。
    そのため開発時に参照するためだけのアセンブリが用意されており、そのアセンブリのファイルバージョンが古いということです。
    (古いといってもインターフェース等は変更されているわけではないので問題にならないです)

    実行時に参照されるアセンブリのファイルバージョンは

    var path = typeof(Microsoft.Office.Tools.Outlook.Factory).Assembly.Location;
    var version = System.Diagnostics.FileVersionInfo.GetVersionInfo(path);
    System.Windows.Forms.MessageBox.Show(string.Format("{0}\r\n{1}", path, version.FileVersion));

    のようにすれば確認でき、新しいバージョンを参照していることがわかると思います。

    [回答2]
    outlook関係はほとんどわからないので回答ではないですが。
    同等のVBAマクロを実行した場合には想定したとおりの値になるのでしょうか?

    VSTO(Interop)はVBAマクロなどと同様のofficeオートメーションを.Netで扱えるようにラップしたものにすぎません。
    COMオブジェクトというのはインターフェースを公開しており、そのインターフェースに対して操作をするという仕組みになっています。
    .Netではそのインターフェースに一致する定義を用意してやることで操作できるようになりますが、あくまでインターフェースをつなぐだけで、ほぼCOMに直結されます。
    つまり、間違った値が取得されるというのであれば、もとの値から間違っている可能性が高いです。


    個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)

    2017年3月30日 11:17

すべての返信

  • 参照で追加されるのは開発時用のアセンブリです。

    [回答1]
    ソリューションエクスプローラーでMicrosoft.Office.Tools.Outlookを選択して、プロパティウィンドウでパスを見てみてください。
    C:\Program Files\Reference Assemblies\Microsoft\VSTO40\v4.0.Framework\Microsoft.Office.Tools.Outlook.dll
    あたりにあるとなっているはずです。
    Reference Assembliesとなっていることからも推測できますが、これは参照用のアセンブリです。
    たとえばOfficeをインストールしていない環境でビルドしようとした場合、アセンブリが無いと参照の解決ができずにビルドが失敗します。
    そのため開発時に参照するためだけのアセンブリが用意されており、そのアセンブリのファイルバージョンが古いということです。
    (古いといってもインターフェース等は変更されているわけではないので問題にならないです)

    実行時に参照されるアセンブリのファイルバージョンは

    var path = typeof(Microsoft.Office.Tools.Outlook.Factory).Assembly.Location;
    var version = System.Diagnostics.FileVersionInfo.GetVersionInfo(path);
    System.Windows.Forms.MessageBox.Show(string.Format("{0}\r\n{1}", path, version.FileVersion));

    のようにすれば確認でき、新しいバージョンを参照していることがわかると思います。

    [回答2]
    outlook関係はほとんどわからないので回答ではないですが。
    同等のVBAマクロを実行した場合には想定したとおりの値になるのでしょうか?

    VSTO(Interop)はVBAマクロなどと同様のofficeオートメーションを.Netで扱えるようにラップしたものにすぎません。
    COMオブジェクトというのはインターフェースを公開しており、そのインターフェースに対して操作をするという仕組みになっています。
    .Netではそのインターフェースに一致する定義を用意してやることで操作できるようになりますが、あくまでインターフェースをつなぐだけで、ほぼCOMに直結されます。
    つまり、間違った値が取得されるというのであれば、もとの値から間違っている可能性が高いです。


    個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)

    2017年3月30日 11:17
  • gekkaさん、ご回答いただきありがとうございます。

    [回答1]のコードを実行してみると、私での環境では
    実行時に参照されているVSTOのアセンブリのバージョンは、
    10.0.60825(新しいバージョン)でした。
    ※新しいバージョンが参照されていたのは、すでにWEBから
     10.0.60825のOffice2010のVSTOのランタイムをインストールしていたためだと
     予想します。

    [回答2]についてなのですが、VBAのマクロでの検証は行っていません。
    しかしながら、gekkaさんから頂いたご回答の内容から想像すると、
    VBAでも同じ結果しか得られないかもしれませんね。

    すぐにとはいきませんが、VBAでの検証も行ってみたいと考えています。
    検証結果が出たら報告いたします。

    gekkaさんのご回答で、VSTOの理解が深まり感謝いたします。
    今後ともよろしくお願いいたします。

    gekkaさんから頂きました返信を回答とさせていただきました。

    2017年3月31日 3:02