I have an application which I want to publish with ClickOnce via command line. I have a test and a live version. It should be allowed to have both installed at the same time, which means that I need to change the assemble name (and preferably also the product name) for one of the builds. I would like to do this in the build settings.
I have managed to make some build settings, which works fine, but I cannot figure out how to change the assembly and product name, for just one of them.
I have added the following code to my .csproj
file, which I call with the command msbuild /target:Test
or msbuild /target:Live
. But where do I implement the assembly and product name change?
<PropertyGroup>
<ProjLocation>$(ProjectDir)</ProjLocation>
<ProjLocationReleaseDir>$(ProjLocation)\bin\Debug</ProjLocationReleaseDir>
<ProjPublishLocation>$(ProjLocationReleaseDir)\app.publish</ProjPublishLocation>
<DeploymentFolder>C:\MyProjects\Software\Publish\</DeploymentFolder>
</PropertyGroup>
<!-- Build settings for live version -->
<Target Name="Live" DependsOnTargets="Clean">
<MSBuild Projects="$(ProjLocation)\$(ProjectName).csproj"
Properties="$(DefaultBuildProperties)"
Targets="Publish"/>
<ItemGroup>
<SetupFiles Include="$(ProjPublishLocation)\*.*"/>
<UpdateFiles Include="$(ProjPublishLocation)\Application Files\**\*.*"/>
</ItemGroup>
<Copy SourceFiles="@(SetupFiles)" DestinationFolder="$(DeploymentFolder)\Live\" />
<Copy SourceFiles="@(UpdateFiles)" DestinationFolder="$(DeploymentFolder)\Live\Application Files\%(RecursiveDir)"/>
</Target>
<!-- Build settings for test version -->
<Target Name="Test" DependsOnTargets="Clean">
<MSBuild Projects="$(ProjLocation)\$(ProjectName).csproj"
Properties="$(DefaultBuildProperties)"
Targets="Publish"/>
<ItemGroup>
<SetupFiles Include="$(ProjPublishLocation)\*.*"/>
<UpdateFiles Include="$(ProjPublishLocation)\Application Files\**\*.*"/>
</ItemGroup>
<Copy SourceFiles="@(SetupFiles)" DestinationFolder="$(DeploymentFolder)\Public Test\" />
<Copy SourceFiles="@(UpdateFiles)" DestinationFolder="$(DeploymentFolder)\Public Test\Application Files\%(RecursiveDir)"/>
</Target>
You can add "AssemblyName" property to the PropertyGroup. like this:
<PropertyGroup>
<AssemblyName>YourAppName</AssemblyName>
</PropertyGroup>
or you can use the MSBuild command line switch. like this :
msbuild /property:AssemblyName=YourAppName
I had almost the same task (need to distinguish between Staging and Production) and I solved it with the following MSBuild-Target:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<!-- call "nuget restore Deployment\packages.config" before executing this script -->
<Import Project="..\packages\MSBuildTasks.1.5.0.235\build\MSBuildTasks.targets" />
<PropertyGroup>
<Configuration>Release</Configuration>
<ClientProject>..\MyProject\MyProject.vbproj</ClientProject>
<ClientPublishDir Condition="$(Environment) == 'Staging'">\\deployment-staging\MyProject\</ClientPublishDir>
<ClientPublishDir Condition="$(Environment) == 'Production'">\\deployment\MyProject\</ClientPublishDir>
</PropertyGroup>
<ItemGroup>
<ClientModifiedAppConfig Include="$(ClientProject)\..\App.$(Environment).config" />
</ItemGroup>
<Target Name="DeployClient">
<Error Condition="$(Environment) == ''" Text="The Property 'Environment' has not been set." />
<Error Condition="$(Environment) != 'Staging' AND $(Environment) != 'Production'" Text="The Property 'Environment' has not been set properly. Valid values are 'Staging' and 'Production'." />
<!-- Sets different assembly names for INT and PRD applications. Due to this, both INT and PRD applications with the
same version number can be installed on the same system. -->
<XmlUpdate Condition="$(Environment) == 'Staging'" Prefix="n" Namespace="http://schemas.microsoft.com/developer/msbuild/2003" XmlFileName="$(ClientProject)" Xpath="/n:Project/n:PropertyGroup/n:AssemblyName" Value="MyProjectStaging" />
<XmlUpdate Condition="$(Environment) == 'Staging'" Prefix="n" Namespace="http://schemas.microsoft.com/developer/msbuild/2003" XmlFileName="$(ClientProject)" Xpath="/n:Project/n:PropertyGroup/n:ProductName" Value="MyProject Staging" />
<XmlUpdate Condition="$(Environment) == 'Production'" Prefix="n" Namespace="http://schemas.microsoft.com/developer/msbuild/2003" XmlFileName="$(ClientProject)" Xpath="/n:Project/n:PropertyGroup/n:AssemblyName" Value="MyProject" />
<XmlUpdate Condition="$(Environment) == 'Production'" Prefix="n" Namespace="http://schemas.microsoft.com/developer/msbuild/2003" XmlFileName="$(ClientProject)" Xpath="/n:Project/n:PropertyGroup/n:ProductName" Value="MyProject" />
<!-- Overwrites the original App.config with the environment-dependent App.config.
Reason: ClickOnce only uses App.config and does not apply transformations, as it is done in Web Projects. -->
<Copy
SourceFiles="@(ClientModifiedAppConfig)"
DestinationFiles="$(ClientProject)\..\App.config"
OverwriteReadOnlyFiles="true"
/>
<!-- Publish -->
<MSBuild
Projects="$(ClientProject)"
Targets="Publish"
Properties="
PublishDir=$(ClientPublishDir);
Configuration=$(Configuration);
Platform=x86" />
</Target>
</Project>
To make this work, you have to restore the NuGet package MSBuildTasks.
Finally, all I have to call is msbuild Deployment.targets /t:DeployClient /p:Environment=Staging
Hope that helps!