Visual Studio 2010 : VSTO の配置の進化 (CTP 版) (3)


環境:
.NET Framework 4.0 Community Technology Preview (CTP)
Visual Studio 2010 Community Technology Preview (CTP)

  1. 配置後のアクション (Post Deployment Action)

こんにちは。

今回は、配置後のアクションについてです。
この機能も前回同様、かなりの手作業が必要になっていますが、最終的にどのような機能になるかは未定ですのでご注意ください。

機能の背景 

前回の繰り返しになりますが、 VSTO は、エンタープライズシステムを想定した手段です。

現実のアプリケーションでは、配布後の独自な環境設定なども必要になることでしょう。特に開発現場/利用現場では、ドキュメントの配置方法をカスタマイズしたいという声をよく聞きます。VSTO のアーキテクチャはある意味美しくできており、アドインではないドキュメントレベルのアプリケーションでは、ドキュメント (.xslx, .xltx, .docx など) とアセンブリ (.dll) は分離して管理するようになっています。例えば、ClickOnce で配布する際もアセンブリのみの配布や更新をおこない、ドキュメントは利用者が各自(独自)で編集をおこなってローカルに保存できるようになっています。

しかし、"現場" では、これを "美しいアプリケーション構造" と評価してくれることは少ないのが現状です。ドキュメントレベルの開発ではドキュメント上に表示領域のデザインやボタンの配置などをおこなっていることが多く、ClickOnce の配置の際にはドキュメントも一緒に配置してほしい (どうすれば良いの ?) といった質問をよく頂きます。これまでも、厳密にはドキュメントの配布ができるよう ClickOnce をカスタマイズすることはできたのですが、ファイルはすべてユーザーフォルダの深い階層の下にアプリケーションと一緒に配布されてしまい、期待する動きとは異なっていました。

動作確認

では、実際に動作を確認してみましょう。CTP では、まだ機能のベースが存在しているのみですので、今回は、すべて手作業で実施 しています (これが機能の最終形ではありません)。よって今回の設定方法はおぼえておいても意味がありませんが、内部の動きと仕組み (何がどのように拡張されているか) を理解しておくという意味で重要です。

今回は、上記の「機能の背景」に従って、Excel テンプレートのアプリケーションを作成し、このテンプレートファイル (.xltx) を ClickOnce と同時にデスクトップ上に配置するようなアプリケーションのサンプルを作成してみます。

まず、Visual Studio 2010 で、簡単な Excel テンプレートのプロジェクトを作成してみましょう。今回は「ExcelTemplate1」という名称の [Excel 2007 Template] プロジェクトを作成し、簡単に実装をおこいます (例:テンプレートドキュメント上にボタンを配置してメッセージボックスを表示、など)。

つぎに、配置後のカスタムアクションを実装します。上記のソリューションなどに [クラスライブラリ] のプロジェクトを追加し、以下の通り実装します。

  1. Microsoft.VisualStudio.Tools.Applications.Runtime.v10.0 を参照追加します

  2. クラスとして以下のコードを作成します。
    この処理では、ClickOnce 用のユーザーフォルダに配置されたテンプレートファイル (TemplateExcelTemplate1.xltx) をユーザーのデスクトップ上にコピーしています。(ユーザーフォルダへのファイルの配置は、このあと、マニフェストを変更して実施します。)

    ここで使用している IAddInPostDeploymentAction は、VSTO に追加された配置アクション用の新しいインタフェースです。

    using Microsoft.VisualStudio.Tools.Applications.Deployment;
    using System.IO;
    using System.Xml;

    namespace DeploymentActions
    {
        public class CopyTemplate : IAddInPostDeploymentAction
        {
            public void Execute(AddInPostDeploymentActionArgs args)
            {
                string filename = "ExcelTemplate1.xltx";

                string srcDir = Path.Combine(args.AddInPath, "Template");
                string srcFile = Path.Combine(srcDir, filename);
                string dstDir = System.Environment.GetFolderPath(System.Environment.SpecialFolder.DesktopDirectory);
                string dstFile = Path.Combine(dstDir, filename);

                if (args.InstallationStatus == AddInInstallationStatus.InitialInstall || args.InstallationStatus == AddInInstallationStatus.Update)
                {
                    File.Copy(srcFile, dstFile, true);
                }
                else if (args.InstallationStatus == AddInInstallationStatus.Uninstall)
                {
                    if (File.Exists(dstFile))
                        File.Delete(dstFile);
                }
            }
        }
    }

この処理を見て頂くとわかりますが、通常のインストーラプロジェクトのカスタム動作のように、「初回のインストール時のみ設定」、「更新時も独自の処理を実施」、「アンインストール時にロールバック処理を実行」など、開発者により柔軟な処理を記述することが可能です。 

つぎに、最初に作成した ExcelTemplate1 のプロジェクトに、上記のクラスライブラリのプロジェクトを参照追加します。そして、ExcelTemplate1 プロジェクトを共有フォルダなどに発行 (ClickOnce発行) すると、上記のクラスライブラリの dll (以降、このアセンブリの名称を DeploymentActions.dll とします) も一緒に発行先のフォルダに配置されます。 

では、発行されたアプリケーションマニフェスト (ExcelTemplate1.dll.manifest) を以下のように手作業で編集し、テンプレートファイル (ExcelTemplate1.xltx) も同時に (ユーザーフォルダに) 配布をおこない、かつこの配布されたデータファイルをデスクトップ上にコピーする上記のカスタムアクションを実行するように設定しましょう。(変更後のマニフェストを最後に掲載しておきます)

2010/04/04 追記 :

下記の 3 - 6 ですが、すみません、MSDN に記述している通り、以下の手順のほうが簡単です。。。 (下記を実施した場合、この 3 - 6 は不要です)

Visual Studio のプロジェクト (上記の ExcelTemplate1) をいったんビルドする

Visual Studio のプロジェクト (上記の ExcelTemplate1) に、「Template」という名称をフォルダを追加する (ソリューションエクスプローラで、プロジェクトをマウスで右クリックして、[追加] - [新しいフォルダ] を選択)

作成したファイル内に、ビルドで作成された出力フォルダ内の ExcelTemplate.xltx を追加する (ソリューションエクスプローラでフォルダをマウスで右クリックして、[追加] - [既存の項目] を選択)
なお、カスタマイズ機能が含まれたファイルでなければならないので、必ず、上記のビルドで作成された出力ファイルを追加してください。

上記で配置された ExcelTemplate.xltx のプロパティウィンドウで、[ビルドアクション] プロパティとして「コンテンツ」、[出力ディレクトリにコピー] プロパティとして「新しい場合はコピーする」を選択する

発行をおこなう

  1. ここは必要ないかもしれませんが、念のため、最後の <publisherIdentity> 要素以降 (但し、最後の </asmv1:assembly> は削除しないように) を削除しておきましょう。(きっと、mage コマンドが自動的に書き換えてくれるでしょう。)

  2. マニフェストを mageui で編集されたことがある方はご存じと思いますが、mageui のエディターはマニフェスト保存時にすべての記述を再書き換えするため、マニフェストのバージョンによってマニフェストを壊してしまうことが時折あります。
    そこで、保存時に壊してしまわないよう、アプリケーションマニフェストファイル (.dll.manifest ファイル) をコピーしておきましょう。

  3. ここからは、上記のコピーしたマニフェストを編集します。
    まず、発行先のアプリケーションフォルダ (ExcelTemplate1_1_0_0_0) にTemplateなどのサブフォルダを作成し、発行する ExcelTemplate1.xltx ファイルをこのフォルダに移動して分けておきましょう。

  4. Visual Studio コマンドプロンプトなどを起動し、mageui コマンドを実行して、マニフェストエディターの UI を起動し、以下の通り編集します。
    • [File] –[Open] で、先ほどコピーしたアプリケーションマニフェストファイル (.dll.manifest ファイル) を開きます。
    • [Files] タブを表示し、[. . .] ボタンを押して上記の Template サブフォルダを選択して移動し、[Populate]ボタンを押します。すると、このフォルダ内にある上記のテンプレートファイル (.xltx) が追加されますので、パスを元に戻し、追加されたファイル名を [ファイル名].xltx から Template[ファイル名].xltx に変更します。(下記)



    • [File] – [Save] メニューで保存します。(警告が表示されるかもしれませんが無視します。また、保存時に署名を促されたら [Don’t Sign] を選択します。)

  5. 上記の設定によって、以下のような要素がマニフェストに追加されるはずです。
    よって、この追加された要素の部分を元の (コピー元の) マニフェストファイルにコピーしましょう。

      <file name="TemplateExcelTemplate1.xltx" size="13066">
        <hash>
          <dsig:Transforms>
            <dsig:Transform Algorithm="urn:schemas-microsoft-com:HashTransforms.Identity" />
          </dsig:Transforms>
          <dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
          <dsig:DigestValue>XiFFsbicrL0OfpnhZ9TguJ/jkJc=</dsig:DigestValue>
        </hash>
      </file>
  6. Templateフォルダに移動したxltxファイルは、VSTOのデフォルトのマニフェストの設定に従って、拡張子に.deployを付与しておきましょう。(例: ExcelTemplate1.xltx.deploy)

  7. 続いて、配置後のアクションの設定をおこないます。
    アプリケーションマニフェスト (ExcelTemplate1.dll.manifest) の <dependentAssembly> 要素として、上記でビルドした DeploymentActions.dll が既に存在していると思います。よって、配置後のアクションを実行するための dll は正しく配置されます。
    あとは、このアセンブリのクラスが配置後に実行されるように、</vstav3:update> 要素の直後、<vstav3:application> 要素の直前に、以下を追加します (下記で、アセンブリ名、クラス名は、作成したクラスライブラリにあわせて変更します)。

      <vstav3:postActions>
        <vstav3:postAction>
          <vstav3:entryPoint class="DeploymentActions.CopyTemplate">
            <assemblyIdentity name="DeploymentActions" version="1.0.0.0" language="neutral" processorArchitecture="msil" />
          </vstav3:entryPoint>
          <vstav3:postActionData>
            <Filename>ExcelTemplate1.xltx</Filename>
          </vstav3:postActionData>
        </vstav3:postAction>
      </vstav3:postActions>

    今回、上記の postActionData は実は使用していませんが、このようにカスタムアクションに対してカスタムのパラメータを渡すことも可能です。(今回は、サンプルとしてそのまま記載しています。)

変更後のマニフェストは、以下の通りになるでしょう。(太字は追加した箇所です)

<?xml version="1.0" encoding="utf-8"?>
<asmv1:assembly . . .>

  . . . . . 途中省略

  <dependency>
    <dependentAssembly dependencyType="install" allowDelayedBinding="true" codebase="ExcelTemplate1.dll" size="14848">
      <assemblyIdentity name="ExcelTemplate1" version="1.0.0.0" language="neutral" processorArchitecture="msil" />
      <hash>
        <dsig:Transforms>
          <dsig:Transform Algorithm="urn:schemas-microsoft-com:HashTransforms.Identity" />
        </dsig:Transforms>
        <dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
        <dsig:DigestValue>sUq/+HxhLz3c4fQxlKr/551Vr/4=</dsig:DigestValue>
      </hash>
    </dependentAssembly>
  </dependency>
  <file name="TemplateExcelTemplate1.xltx" size="13066">
    <hash>
      <dsig:Transforms>
        <dsig:Transform Algorithm="urn:schemas-microsoft-com:HashTransforms.Identity" />
      </dsig:Transforms>
      <dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
      <dsig:DigestValue>XiFFsbicrL0OfpnhZ9TguJ/jkJc=</dsig:DigestValue>
    </hash>
  </file>
  <vstav3:addIn xmlns:vstav3="urn:schemas-microsoft-com:vsta.v3">
    <vstav3:entryPointsCollection>
      <vstav3:entryPoints>
        <vstav3:entryPoint class="ExcelTemplate1.ThisWorkbook">
          <assemblyIdentity name="ExcelTemplate1" version="1.0.0.0" language="neutral" processorArchitecture="msil" />
        </vstav3:entryPoint>
        <vstav3:entryPoint class="ExcelTemplate1.Sheet1">
          <assemblyIdentity name="ExcelTemplate1" version="1.0.0.0" language="neutral" processorArchitecture="msil" />
        </vstav3:entryPoint>
        <vstav3:entryPoint class="ExcelTemplate1.Sheet2">
          <assemblyIdentity name="ExcelTemplate1" version="1.0.0.0" language="neutral" processorArchitecture="msil" />
        </vstav3:entryPoint>
        <vstav3:entryPoint class="ExcelTemplate1.Sheet3">
          <assemblyIdentity name="ExcelTemplate1" version="1.0.0.0" language="neutral" processorArchitecture="msil" />
        </vstav3:entryPoint>
      </vstav3:entryPoints>
    </vstav3:entryPointsCollection>
    <vstav3:update enabled="true">
      <vstav3:expiration maximumAge="7" unit="days" />
    </vstav3:update>
    <vstav3:postActions>
      <vstav3:postAction>
        <vstav3:entryPoint class="DeploymentActions.CopyTemplate">
          <assemblyIdentity name="DeploymentActions" version="1.0.0.0" language="neutral" processorArchitecture="msil" />
        </vstav3:entryPoint>
        <vstav3:postActionData>
          <Filename>ExcelTemplate1.xltx</Filename>
        </vstav3:postActionData>
      </vstav3:postAction>
    </vstav3:postActions>
    <vstav3:application>
      <vstov4:customizations xmlns:vstov4="urn:schemas-microsoft-com:vsto.v4">
        <vstov4:customization>
          <vstov4:document solutionId="ac6e3fad-df42-413d-9ba8-b1d2fdac0915" />
        </vstov4:customization>
      </vstov4:customizations>
    </vstav3:application>
  </vstav3:addIn>
</asmv1:assembly>

最後に、Visual Studio コマンドプロンプトなどを起動し、.NET Framework SDK の mage コマンドを以下の通り実行し、マニフェストと署名を再設定します。

Mage -sign "Application FilesExcelTemplate1_1_0_0_0ExcelTemplate1.dll.manifest" -Certfile "C:DemoPostDeploymentActionExcelTemplate1ExcelTemplate1_TemporaryKey.pfx"

Mage -update ExcelTemplate1.vsto -AppManifest "Application FilesExcelTemplate1_1_0_0_0ExcelTemplate1.dll.manifest"

Mage -sign ExcelTemplate1.vsto -CertFile "C:DemoPostDeploymentActionExcelTemplate1ExcelTemplate1_TemporaryKey.pfx"
 

発行先のディレクトリの ExcelTemplate1.vsto をクリックすると、ドキュメントレベルの機能が追加されると共に、テンプレートファイル ExcelTemplate.xltx がユーザーのデスクトップ上に配置されます。このファイル (テンプレート) は、インストールされたアセンブリと関連付いていますので (ファイルの _AssemblyLocation プロパティに記載されています)、テンプレートを開いてドキュメント上からインストールされたビジネスロジックを実行することが可能です。

また、上記のカスタムアクション (カスタムの CopyTemplate クラス) のメソッドで記載しているように、アンインストールをおこなうと、デスクトップ上のテンプレートもきれいに削除されます。

ここでは手作業による設定をおこないましたが (この手段はあくまでも暫定的なものです)、CTP には、VSTO アプリケーション配置後のカスタム動作のための基本的な仕組み (.NET Framework 4.0 のマニフェストの新仕様) が備わっていることがおわかり頂けるでしょう。

関連ナンバー

 

Skip to main content