Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Web Setup replacement to create MSI in VS2012?

I have a project in VS2010 that uses Web Setup projects for deployment. I'm now looking into migrating it to VS2012 and have to find a replacement setup routine.

The requirements I have:

  • One-step build to create a deploy package/installer on a dev machine.
  • Setup program/routine that can be run on the server - without Visual Studio available.
  • No direct interaction between Visual Studio and the server. I have to copy the setup files over through an RDP session.
  • Setup of web applications (MVC) and Windows Services, preferably bundled in one single installer (new requirement currently not solve din Web Setup project).
  • Possibility to run EF Migrations as part of setup (currently done through a custom action).

Where should I start? Should I look into the improved publishing features in VS2012? Should I look at Wix? Something else?

like image 948
Anders Abel Avatar asked Sep 13 '12 09:09

Anders Abel


People also ask

How do I create a MSI file with WiX?

Adding a WiX setup project In Visual Studio, open your solution, and add a WiX project to it: go to the Visual Studio main menu and click File -> Add -> New Project to open the Add New Project dialog. Choose the Setup Project item in the Windows Installer XML node, specify the project name and click OK.

How do I create an MSI file in Visual Studio?

Go to Extensions > Manage Extensions > Online > Search, find, download and install Microsoft Visual Studio Installer Projects extension. 2). Add a new Setup Project in your solution > right-click Application Folder > Add > Project Output… > choose the corresponding Project > select Primary output > OK.


1 Answers

Looking deeper into Visual Studio 2012 and trying to work with it the way it was intended, instead of against it, we ended up using web deploy packages. It doesn't create an MSI file, but instead a zip file that can be easily imported into IIS on the target machine.

The Windows service project was added as a reference to the web site project. That way the binaries for the service are included in the bin directory of the web site. The migrate.exe file from Entity framework was added as a link from the bin directory which means it is deployed too.

Finally we added a project.wpp.targets file to the project that runs the required commands to install and start the service and to get the service's config file included in the deploy. This worked for us, but is not really that elegant (e.g. the install paths of the site for different configurations is hard coded).

The project.wpp.targets file:

<?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>
like image 84
Anders Abel Avatar answered Sep 29 '22 11:09

Anders Abel