2

WIX を使用してデータベースをインストールするときに、dacpac をデプロイする必要があります。目的のために、必要なスイッチを指定して SQLPackage.exe コマンドを実行することを検討したので、次のようにバイナリ タグを使用して必要な exe と dll を埋め込みました。

<Binary Id="Microsoft.Data.Tools.Schema.Sql.dll" SourceFile="..\DeployDBs\DAC\Microsoft.Data.Tools.Schema.Sql.dll"/>
    <Binary Id="Microsoft.Data.Tools.Schema.Tasks.Sql.11.dll" SourceFile="..\DeployDBs\DAC\Microsoft.Data.Tools.Schema.Tasks.Sql.11.dll"/>
    <Binary Id="Microsoft.Data.Tools.Schema.Utilities.Sql.11.dll" SourceFile="..\DeployDBs\DAC\Microsoft.Data.Tools.Schema.Utilities.Sql.11.dll"/>
    <Binary Id="Microsoft.Data.Tools.Utilities.dll" SourceFile="..\DeployDBs\DAC\Microsoft.Data.Tools.Utilities.dll"/>
    <Binary Id="Microsoft.SqlServer.Dac.dll" SourceFile="..\DeployDBs\DAC\Microsoft.SqlServer.Dac.dll"/>
    <Binary Id="SqlPackage" SourceFile="..\DeployDBs\DAC\SqlPackage.exe"/>
    <Binary Id="SqlPackage.exe.config" SourceFile="..\DeployDBs\DAC\SqlPackage.exe.config"/>

そして、次のようにカスタム アクションを使用して SqlPackage.exe を呼び出します。

 <CustomAction Id="DeployMyDb" BinaryKey="SqlPackage" 
              ExeCommand="/a:publish /sf:&quot;MyDacpac.dacpac&quot; /tsn:localhost /tdn:MyDb" 
              Execute="immediate" />

カスタム アクションは、次のように「InstallFinalize」の後に実行するシーケンスです。

<InstallExecuteSequence>
      <Custom Action="DeployMyDb" After="InstallFinalize"/>
    </InstallExecuteSequence>
    </Product>

dacpac がデプロイされる (つまり、カスタム アクションが実行される) と、組み込みバイナリの 1 つであるアセンブリ 'Microsoft.Data.Tools.Utilities' に対して 'FileNotFoundException' がスローされます。

このexeを実行するために必要な手順や追加事項について教えてください。

4

2 に答える 2

3

これを実装するには、dacpac ファイルをバイナリとして追加し、そのバイナリを CustomAction で読み取り、最後に C# カスタム アクションで 'Microsoft.SqlServer.Dac' (nuget で入手可能) を使用します。

DacPac.Load 関数で使用するバイナリ ファイル ストリームを MemoryStream に書き込む必要がありました。バイナリ ストリームは、Load 関数では使用できない 'RecordStream' の内部型でした。目的に応じて、dacOptions 変数を変更して、目的の結果を得ることができます。

以下の例を参照してください。

Project.wxs:

<Binary Id="Database.dacpac" SourceFile="$(var.ProjectDir)\Database.dacpac" />

<CustomAction Id="DeployDacpac" BinaryKey="CustomAction.dll" DllEntry="DeployDacpac" Execute="immediate" />

<InstallExecuteSequence>
  <Custom Action="DeployDacpac" After="InstallFinalize" />
</InstallExecuteSequence>

CustomAction.cs:

[CustomAction]
    public static ActionResult DeployDacpac(Session session)
    {
        try
        {
            string sql = string.Format("SELECT Data FROM Binary WHERE Name = 'Database.dacpac'");

            View view = session.Database.OpenView(sql);

            view.Execute();
            var dataStream = view.First()["Data"] as Stream;
            byte[] buffer = new byte[dataStream.Length];
            int bytesRead;
            while ((bytesRead = dataStream.Read(buffer, 0, buffer.Length)) > 0) ;
            using (MemoryStream ms = new MemoryStream(buffer))
            {
                var dacOptions = new DacDeployOptions();
                dacOptions.BlockOnPossibleDataLoss = false;
                dacOptions.DropDmlTriggersNotInSource = false;
                dacOptions.DropObjectsNotInSource = false;

                var dacServiceInstance = new DacServices(GenerateConnectionString(session["SQLSERVER"], session["SQLDATABASE"], session["SQLUSER"], session["SQLPASSWORD"]));
                using (DacPackage dacpac = DacPackage.Load(ms))
                {
                    dacServiceInstance.Deploy(dacpac, session["SQLDATABASE"], upgradeExisting: true, options: dacOptions);
                }
            }
        }
        catch (Exception ex)
        {
            session.Log(ex.Message);
            return ActionResult.Failure;
        }
        return ActionResult.Success;
    }
于 2015-08-06T15:41:48.767 に答える
3

解決策を見つけました。

上記のアプローチの代わりに、カスタム アクション用に別のプロジェクトを作成し、必要なバイナリ (つまり、以前に <binary> タグで説明したバイナリ) への参照を追加し、バイナリ タグで形成された対応する dll を追加し、<CustomAction を介して呼び出しました。 >

結果として得られる解決策は次のとおりです。

<Binary Id="InstallerWix_CustomAction.CA.dll" SourceFile="..\InstallerWix_CustomAction\bin\Debug\InstallerWix_CustomAction.CA.dll" />

<CustomAction Id="DeployDb" BinaryKey="InstallerWix_CustomAction.CA.dll" 
                 DllEntry="CustomAction1"                   
                  Execute="immediate" Return="check" />

<InstallExecuteSequence>
  <Custom Action="DeployDb" After="InstallFinalize"/>
</InstallExecuteSequence>
于 2014-09-03T04:23:05.163 に答える