深入研究 Visual Studio 2012 并尝试按照预期的方式使用它,而不是反对它,我们最终使用了 Web 部署包。它不会创建 MSI 文件,而是创建一个 zip 文件,该文件可以轻松导入目标计算机上的 IIS。
添加了 Windows 服务项目作为对网站项目的引用。这样,服务的二进制文件就包含在网站的 bin 目录中。Entity 框架中的 migrate.exe 文件作为 bin 目录中的链接添加,这意味着它也已部署。
最后,我们在项目中添加了一个 project.wpp.targets 文件,该文件运行所需的命令来安装和启动服务,并将服务的配置文件包含在部署中。这对我们有用,但并不是那么优雅(例如,不同配置的站点安装路径是硬编码的)。
project.wpp.targets 文件:
<?xml version="1.0" encoding="utf-8" ?>
<!--
*** WARNING ***
This file is cached by visual studio and changes won't take effect until
visual studio is restarted. When editing this file, it is better to run the
build step for packaging from the command line (a VS command prompt).
There are some problems with dependencies not being correctly identified that
way, but at least the archive.xml file can be verified from the command prompt.
msbuild orderportal.csproj /t:package /p:Configuration=SysTest /p:DeployOnBuild=true;DeployTarget=Package
-->
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<IncludeRunMigrations>TRUE</IncludeRunMigrations>
<AfterAddIisSettingAndFileContentsToSourceManifest Condition="'$(AfterAddIisSettingAndFileContentsToSourceManifest)'==''">
$(AfterAddIisSettingAndFileContentsToSourceManifest);
RunMigrations;
ServiceInstall;
</AfterAddIisSettingAndFileContentsToSourceManifest>
<IncludeServiceInstall>TRUE</IncludeServiceInstall>
<BeforeAddContentPathToSourceManifest Condition="'$(BeforeAddContentPathToSourceManifest)' == ''">
$(BeforeAddContentPathToSourceManifest);
ServiceUnInstall;
</BeforeAddContentPathToSourceManifest>
<DeploymentDir Condition="'$(Configuration)'=='SysTest' AND '$(DeploymentDir)'==''">c:\inetpub\wwwroot\SysTest\</DeploymentDir>
<DeploymentDir Condition="'$(Configuration)'=='IntTest' AND '$(DeploymentDir)'==''">c:\inetpub\wwwroot\IntTest\</DeploymentDir>
<DeploymentDir Condition="'$(Configuration)'=='Prod' AND '$(DeploymentDir)'==''">c:\inetpub\wwwroot\</DeploymentDir>
<CopyAllFilesToSingleFolderForPackageDependsOn>
IncludeServicesAppConfig;
$(CopyAllFilesToSingleFolderForPackageDependsOn);
</CopyAllFilesToSingleFolderForPackageDependsOn>
</PropertyGroup>
<Target Name="RunMigrations" Condition="'$(IncludeRunMigrations)' == 'TRUE'">
<Message Text="Adding migration running"/>
<ItemGroup>
<MsDeploySourceManifest Include="runCommand">
<path>$(DeploymentDir)bin\migrate.exe /startupdirectory:$(DeploymentDir)bin Topsi.Core.dll /startUpConfigurationFile:$(DeploymentDir)web.config</path>
<waitAttempts>1</waitAttempts>
<waitInterval>60000</waitInterval>
<dontUseCommandExe>true</dontUseCommandExe>
<AdditionalProviderSettings>waitInterval;waitAttempts;dontUseCommandExe</AdditionalProviderSettings>
</MsDeploySourceManifest>
</ItemGroup>
</Target>
<Target Name="ServiceUnInstall" Condition="'$(IncludeServiceInstall)' == 'TRUE'">
<Message Text="Adding service uninstall" />
<ItemGroup>
<MsDeploySourceManifest Include="runCommand">
<path>net stop "Topsi Schedule Service $(Configuration)"</path>
<waitAttempts>1</waitAttempts>
<waitInterval>60000</waitInterval>
<dontUseCommandExe>true</dontUseCommandExe>
<AdditionalProviderSettings>waitInterval;waitAttempts;dontUseCommandExe</AdditionalProviderSettings>
</MsDeploySourceManifest>
<MsDeploySourceManifest Include="runCommand">
<path>C:\Windows\Microsoft.NET\Framework\v4.0.30319\installutil.exe /u $(DeploymentDir)bin\Topsi.Services.exe</path>
<waitAttempts>1</waitAttempts>
<waitInterval>60000</waitInterval>
<dontUseCommandExe>true</dontUseCommandExe>
<AdditionalProviderSettings>waitInterval;waitAttempts;dontUseCommandExe</AdditionalProviderSettings>
</MsDeploySourceManifest>
</ItemGroup>
</Target>
<Target Name="ServiceInstall" Condition="'$(IncludeServiceInstall)' == 'TRUE'">
<Message Text="Adding service install"/>
<ItemGroup>
<MsDeploySourceManifest Include="runCommand">
<path>C:\Windows\Microsoft.NET\Framework\v4.0.30319\installutil.exe $(DeploymentDir)bin\Topsi.Services.exe</path>
<waitAttempts>1</waitAttempts>
<waitInterval>60000</waitInterval>
<dontUseCommandExe>true</dontUseCommandExe>
<AdditionalProviderSettings>waitInterval;waitAttempts;dontUseCommandExe</AdditionalProviderSettings>
</MsDeploySourceManifest>
<MsDeploySourceManifest Include="runCommand">
<path>net start "Topsi Schedule Service $(Configuration)"</path>
<waitAttempts>1</waitAttempts>
<waitInterval>60000</waitInterval>
<dontUseCommandExe>true</dontUseCommandExe>
<AdditionalProviderSettings>waitInterval;waitAttempts;dontUseCommandExe</AdditionalProviderSettings>
</MsDeploySourceManifest>
</ItemGroup>
</Target>
<Target Name="IncludeServicesAppConfig">
<ItemGroup>
<_CustomFiles Include="..\Services\bin\$(Configuration)\Topsi.Services.exe.config">
<DestinationRelativePath>%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
</_CustomFiles>
<FilesForPackagingFromProject Include="%(_CustomFiles.Identity)">
<DestinationRelativePath>bin\%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
</FilesForPackagingFromProject>
</ItemGroup>
</Target>
</Project>