Generating a setup.exe (bootstrapper) during deployment

793 views Asked by At

I'm trying to automate the deployment of a ClickOnce application. The compilation is pretty straight forward (as far as I can tell), however I never see a setup.exe get generated. I'm not even sure if the setup.exe should be generated at build time, or at deploy time, I'm pretty sure it should be at deployment. (I generate and sign manifests during my deployment so that they're unique per environment dev/qual/production)

note: I've never worked on ClickOnce before, and I haven't developed this project, I'm just tasked with automating it's deployment. If I've missed anything, please ask in the comments.

Here's how I compile

# https://github.com/transcanada/poshBAR/blob/master/src/poshBAR/MSBuild.ps1#L136
Invoke-CleanMSBuild $this.solutions.uiShell

# https://github.com/transcanada/poshBAR/blob/master/src/poshBAR/MSBuild.ps1#L63
Invoke-MSBuild "$($this.artifactsDir.output)\ClickOnce" `
        $this.solutions.uiShell `
        -target 'package' `
        -toolsVersion 4.0 `
        -maxCpuCount 8 `
        -VisualStudioVersion 12.0 `
        -logPath $this.artifactsDir.logs `
        -namespace 'TransCanada.MCA' `
        -customParameters @('/p:BootstrapperEnabled=true')

And here's my csproj file (excluding dependencies).

<?xml version="1.0" encoding="Windows-1252"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="12.0">
  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
    <ProductVersion>9.0.30729</ProductVersion>
    <SchemaVersion>2.0</SchemaVersion>
    <ProjectGuid>{62B89443-7C08-4753-9C43-F53DABF7549D}</ProjectGuid>
    <OutputType>WinExe</OutputType>
    <AppDesignerFolder>Properties</AppDesignerFolder>
    <RootNamespace>TransCanada.MCA.UI.Shell</RootNamespace>
    <AssemblyName>TransCanada.MCA.UI.Shell</AssemblyName>
    <SccProjectName>
    </SccProjectName>
    <SccLocalPath>
    </SccLocalPath>
    <SccAuxPath>
    </SccAuxPath>
    <SccProvider>
    </SccProvider>
    <StartupObject>TransCanada.MCA.UI.Shell.ShellApplication</StartupObject>
    <IsWebBootstrapper>true</IsWebBootstrapper>
    <ManifestCertificateThumbprint>98073FFOOBARBAZFIZZBUZZ19CD2F1A4</ManifestCertificateThumbprint>
    <ManifestKeyFile>
    </ManifestKeyFile>
    <GenerateManifests>true</GenerateManifests>
    <SignManifests>false</SignManifests>
    <TargetZone>LocalIntranet</TargetZone>
    <ApplicationIcon>Resources\MCAIcon.ico</ApplicationIcon>
    <FileUpgradeFlags>
    </FileUpgradeFlags>
    <OldToolsVersion>3.5</OldToolsVersion>
    <UpgradeBackupLocation>
    </UpgradeBackupLocation>
    <TargetFrameworkVersion>v4.5.1</TargetFrameworkVersion>
    <TargetFrameworkProfile />
    <Install>true</Install>
    <InstallFrom>Web</InstallFrom>
    <UpdateEnabled>true</UpdateEnabled>
    <UpdateMode>Foreground</UpdateMode>
    <UpdateInterval>7</UpdateInterval>
    <UpdateIntervalUnits>Days</UpdateIntervalUnits>
    <UpdatePeriodically>false</UpdatePeriodically>
    <UpdateRequired>false</UpdateRequired>
    <MapFileExtensions>true</MapFileExtensions>
    <InstallUrl>http://localhost/</InstallUrl>
    <TargetCulture>en</TargetCulture>
    <ProductName>MCA - Dev</ProductName>
    <PublisherName>TransCanada</PublisherName>
    <MinimumRequiredVersion>0.1.1.1</MinimumRequiredVersion>
    <CreateWebPageOnPublish>true</CreateWebPageOnPublish>
    <WebPage>publish.htm</WebPage>
    <ApplicationRevision>0</ApplicationRevision>
    <ApplicationVersion>0.1.1.1</ApplicationVersion>
    <UseApplicationTrust>false</UseApplicationTrust>
    <CreateDesktopShortcut>true</CreateDesktopShortcut>
    <PublishWizardCompleted>true</PublishWizardCompleted>
    <BootstrapperEnabled>true</BootstrapperEnabled>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    <DebugSymbols>true</DebugSymbols>
    <DebugType>full</DebugType>
    <Optimize>false</Optimize>
    <OutputPath>bin\Debug\</OutputPath>
    <DefineConstants>DEBUG;TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
    <UseVSHostingProcess>false</UseVSHostingProcess>
    <PlatformTarget>AnyCPU</PlatformTarget>
    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
    <Prefer32Bit>false</Prefer32Bit>
    <CreateDesktopShortcut>true</CreateDesktopShortcut>
    <BootstrapperEnabled>true</BootstrapperEnabled>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
    <DebugType>pdbonly</DebugType>
    <Optimize>true</Optimize>
    <OutputPath>bin\Release\</OutputPath>
    <DefineConstants>
    </DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
    <UseVSHostingProcess>false</UseVSHostingProcess>
    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
    <Prefer32Bit>false</Prefer32Bit>
    <PlatformTarget>AnyCPU</PlatformTarget>
    <CreateDesktopShortcut>true</CreateDesktopShortcut>
    <BootstrapperEnabled>true</BootstrapperEnabled>
  </PropertyGroup>
  <PropertyGroup>
    <NoWin32Manifest>true</NoWin32Manifest>
  </PropertyGroup>

The solution also has a customized.targets file, but I'm not sure if it's even getting picked up.

<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">

 <Target Name="UpdateCommonAssemblyInfo">
    <AssemblyInfo  
                    CodeLanguage="CS"
                    OutputFile="@(AssemblyInfoFiles)"
                   AssemblyVersion="$(VersionNum)"
                   AssemblyFileVersion="$(VersionNum)"
                   />
  </Target>


<PropertyGroup>
    <BuildEnvironment>Debug</BuildEnvironment>
</PropertyGroup>

<Choose>
    <When Condition=" '$(BuildEnvironment)' == 'Debug' ">
      <PropertyGroup>       
        <PublishDir>publish\$(BuildEnvironment)\</PublishDir>
      </PropertyGroup>
    </When>
    <When Condition=" '$(BuildEnvironment)' == 'Dev' ">
      <PropertyGroup>       
        <!--<PublishDir>publish\$(BuildEnvironment)\</PublishDir>-->
        <PublishDir>C:\inetpub\wwwroot\apps\MCA\Client\Azure\</PublishDir>
      </PropertyGroup>
    </When>
    <When Condition=" '$(BuildEnvironment)' == 'Azure' ">
      <PropertyGroup>
        <PublishDir>\\xxxxxxxxxxx\apps\MCA\client\$(BuildEnvironment)\</PublishDir>
      </PropertyGroup>
    </When>
    <When Condition=" '$(BuildEnvironment)' == 'Qual' ">
      <PropertyGroup>
        <PublishDir>\\xxxxxxxxxxx\cal\APPS\MCA\Client\$(BuildEnvironment)\</PublishDir>
      </PropertyGroup>
    </When>
    <When Condition=" '$(BuildEnvironment)' == 'Qual2MatrixProd' ">
      <PropertyGroup>
        <PublishDir>\\xxxxxxxxxxx\cal\APPS\MCA\Client\$(BuildEnvironment)\</PublishDir>
      </PropertyGroup>
    </When>
    <When Condition=" '$(BuildEnvironment)' == 'Prod' ">
      <PropertyGroup>
        <PublishDir>\\xxxxxxxxxxx\cal\APPS\MCA\Client\$(BuildEnvironment)\</PublishDir>
      </PropertyGroup>
    </When> 
</Choose>

<PropertyGroup>
        <!-- Note this must be done AFTER the above Choose (so PublishDir is set)-->
    <PublishFilePath>$(PublishDir)publish.html</PublishFilePath>
    </PropertyGroup>

<ItemGroup>
        <Tokens Include="PublisherName">
          <ReplacementValue>$(PublisherName)</ReplacementValue>
          <Visible>false</Visible>
        </Tokens>
        <Tokens Include="ProductName">
          <ReplacementValue>$(ProductName)</ReplacementValue>
          <Visible>false</Visible>
        </Tokens>
        <Tokens Include="ApplicationVersion">
          <ReplacementValue>$(ApplicationVersion)</ReplacementValue>
          <Visible>false</Visible>
        </Tokens>
        <Tokens Include="Prerequsites">
          <ReplacementValue>@(BootstrapperPackage->'&lt;li&gt;%(ProductName)&lt;/li&gt;','%0D%0A')</ReplacementValue>
          <Visible>false</Visible>
        </Tokens>
        <Tokens Include="Username">
          <ReplacementValue>$(Username)</ReplacementValue>
          <Visible>false</Visible>
        </Tokens>
    </ItemGroup> 
<!--<Target Name="AfterPublish">
    <Time Format="dd/MM/yyyy HH:mm">
        <Output TaskParameter="FormattedTime" PropertyName="PublishTime" />
    </Time>
    <TemplateFile Template="publish\publish.template.html" Tokens="@(Tokens)" OutputFilename="$(PublishFilePath)" />
    <FileUpdate Files="$(PublishFilePath)" Regex="\${PublishTime}" ReplacementText="$(PublishTime)" /> 
</Target> -->
</Project>

What am I missing in getting the bootstrapper generated?

1

There are 1 answers

5
codeConcussion On BEST ANSWER

I would just manually generate a bootstrapper for each environment through a Visual Studio publish and then be done. Is there a reason why that won't work?

The only reason you'd need to regenerate the bootstrapper is if your prerequisites change or if your application's deployment url changes. Both seem like pretty rare occurrences.