Change assembly name for build settings in .csproj

2019-07-29 11:35发布

问题:

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>

回答1:

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


回答2:

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!