I have an AfterBuild task which signs the dll using signtool.exe via the NuGet package MSBuild.ExtensionPack
<MSBuild.ExtensionPack.Framework.CommandLine Command=""C:\Program Files (x86)\Microsoft SDKs\Windows\v7.1A\Bin\signtool.exe" sign "/n" "MY CERTIFICATE" "/t" "http://timestamp.comodoca.com/authenticode" "$(TargetPath)."" Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " />
Due to some differences between build environments (some remote build agents have different versions of Visual Studio and therefore the Windows SDK) this task fails when an agent has SDK version 8.0 installed.
Is it possible to trigger a different task if and only if a task fails?
i.e. if the above task fails, run an alternative task which has a different path to signtool.exe
As an alternative solution, I have come up with the following to check possible paths and use the latest version found:
<PropertyGroup>
<SignToolPath Condition="'$(Configuration)' == 'Release' And '$(SignToolPath)' == '' And Exists('C:\Program Files (x86)\Windows Kits\8.1\bin\x64\signtool.exe')">C:\Program Files (x86)\Windows Kits\8.1\bin\x64\signtool.exe</SignToolPath>
<SignToolPath Condition="'$(Configuration)' == 'Release' And '$(SignToolPath)' == '' And Exists('C:\Program Files (x86)\Windows Kits\8.1\bin\x86\signtool.exe')">C:\Program Files (x86)\Windows Kits\8.1\bin\x86\signtool.exe</SignToolPath>
<SignToolPath Condition="'$(Configuration)' == 'Release' And '$(SignToolPath)' == '' And Exists('C:\Program Files (x86)\Windows Kits\8.0\bin\x64\signtool.exe')">C:\Program Files (x86)\Windows Kits\8.0\bin\x64\signtool.exe</SignToolPath>
<SignToolPath Condition="'$(Configuration)' == 'Release' And '$(SignToolPath)' == '' And Exists('C:\Program Files (x86)\Windows Kits\8.0\bin\x86\signtool.exe')">C:\Program Files (x86)\Windows Kits\8.0\bin\x86\signtool.exe</SignToolPath>
<SignToolPath Condition="'$(Configuration)' == 'Release' And '$(SignToolPath)' == '' And Exists('C:\Program Files (x86)\Microsoft SDKs\Windows\v7.1A\Bin\signtool.exe')">C:\Program Files (x86)\Microsoft SDKs\Windows\v7.1A\Bin\signtool.exe</SignToolPath>
<SignToolPath Condition="'$(Configuration)' == 'Release' And '$(SignToolPath)' == '' And Exists('C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\signtool.exe')">C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\signtool.exe</SignToolPath>
<SignToolPath Condition="'$(Configuration)' == 'Release' And '$(SignToolPath)' == '' And Exists('C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\signtool.exe')">C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\signtool.exe</SignToolPath>
<SignToolPath Condition="'$(Configuration)' == 'Release' And '$(SignToolPath)' == '' And Exists('C:\Program Files\Microsoft SDKs\Windows\v6.0A\Bin\signtool.exe')">C:\Program Files\Microsoft SDKs\Windows\v6.0A\Bin\signtool.exe</SignToolPath>
</PropertyGroup>
<Error Condition="'$(Configuration)' == 'Release' And '$(SignToolPath)' == ''" Text="Unable to determine signtool path" />
<MSBuild.ExtensionPack.Framework.CommandLine Command=""$(SignToolPath)" sign "/n" "MY CERTIFICATE" "/t" "http://timestamp.comodoca.com/authenticode" "$(TargetPath)."" Condition=" '$(Configuration)' == 'Release' " />
You can mark your task with ContinueOnError="true" and then use MSBuildLastTaskResult reserved property to check whether you task succeeded.
Something like that:
<MSBuild.ExtensionPack.Framework.CommandLine
ContinueOnError="true"
Command="path_to_signtool.exe"
.... />
<MSBuild.ExtensionPack.Framework.CommandLine
Condition="'$(MSBuildLastTaskResult)' == 'False'"
Command="another_path_to_signtool.exe"
.... />
See also this answer
Related
I am trying to build my project using MSbuild. The solution builds perfectly fine if I hardcode the configurations
<MSBuild Projects="%(SolutionsToBuild.Identity)" Properties="Configuration=Debug" ContinueOnError="false"/>
<MSBuild Projects="%(SolutionsToBuild.Identity)" Properties="Configuration=Release" ContinueOnError="false"/>
but if I use batching like this the values are not assigned
<MSBuild Projects="%(SolutionsToBuild.Identity)" Properties="Configuration=%(ConfigList.Identity)" ContinueOnError="false"/>
where ConfigList
<ItemGroup>
<ConfigList Condition=" '#(ConfigList)' == '' and $(Configuration) != '' " Include="$(Configuration.Split(';'))" />
<!-- parse all requested configurations into a list -->
<ConfigList Condition=" '#(ConfigList)' == '' " Include="Debug" />
<!-- if no configurations were specified, default to Debug -->
</ItemGroup>
and Configurations are provided from CLI
msbuild build.proj -p:Configuration="Release;Debug"
Also interestingly I am getting the value in
<Message Text="Build for configuration %(ConfigList.Identity)"/>
Whole Code
<Target Name="BuildApplication">
<ItemGroup>
<ConfigList Condition=" '#(ConfigList)' == '' and $(Configuration) != '' " Include="$(Configuration.Split(';'))" />
<!-- parse all requested configurations into a list -->
<ConfigList Condition=" '#(ConfigList)' == '' " Include="Debug" />
<!-- if no configurations were specified, default to Debug -->
</ItemGroup>
<Message Text="Build for configuration %(ConfigList.Identity)"/>
<MSBuild Projects="%(SolutionsToBuild.Identity)" Properties="Configuration=%(ConfigList.Identity)" ContinueOnError="false"/>
<!--<MSBuild Projects="%(SolutionsToBuild.Identity)" Properties="Configuration=Debug" ContinueOnError="false"/>-->
</Target>
I am not sure what I am doing wrong. Any help would be appreciated. Thanks !
Sources referred:
Using MSBuild to Build Multiple Configurations
Passing properties to MSBUILD Task
I am setting up wix without installing on build machine by keeping Wix binaries in the source code directory itself. When i configure the wixproj file based on the steps mentioned in the wix website
<PropertyGroup>
<WixToolPath>$(SourceCodeControlRoot)\wix\[[Version]]\</WixToolPath>
<WixTargetsPath>$(WixToolPath)Wix.targets</WixTargetsPath>
<WixTasksPath>$(WixToolPath)wixtasks.dll</WixTasksPath>
</PropertyGroup>
, it is not locating the local binary files When i change the WixTarget paths to local directory because in Wix.tagets file has the follwing
<?xml version="1.0" encoding="utf-8"?>
<Project
xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<!-- All common targets/items/properties -->
<!-- Version specific targets/items/properties -->
<PropertyGroup>
<WixTargetsImported>true</WixTargetsImported>
<!-- MSBuild 4.0 -->
<!-- MSBuild does not do short circuit evaluation of the AND operator, so we cannot have
something like '$(MSBuildToolsVersion)' != '' AND '$(MSBuildToolsVersion)' >= '4.0'
instead set as default and override -->
<WixVersionTargetsPath>wix2010.targets</WixVersionTargetsPath>
<!-- MSBuild 2.0 - 3.5 -->
<WixVersionTargetsPath Condition=" '$(MSBuildToolsVersion)' == '' OR '$(MSBuildToolsVersion)' < '4.0' ">wix200x.targets</WixVersionTargetsPath>
</PropertyGroup>
<Import Project="$(WixVersionTargetsPath)" />
</Project>
commands which invokes wix2010.targets.
In wix2010.targets,
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. -->
<Project
xmlns="http://schemas.microsoft.com/developer/msbuild/2003"
DefaultTargets="Build"
InitialTargets="_CheckForInvalidConfigurationAndPlatform;
_CheckRequiredProperties">
<PropertyGroup>
<WixInstallPath Condition=" '$(WixInstallPath)' == ''">$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Installer XML\3.11#InstallRoot)</WixInstallPath>
<WixInstallPath Condition=" '$(WixInstallPath)' == ''">$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows Installer XML\3.11#InstallRoot)</WixInstallPath>
</PropertyGroup>
<!--
//////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////
Extension Points
//////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////
-->
<!-- Allow a user-customized targets files to be used as part of the build. -->
<PropertyGroup>
<UserTargetsPath>$(MSBuildProjectFullPath).user</UserTargetsPath>
</PropertyGroup>
<Import Project="$(UserTargetsPath)" Condition="Exists('$(UserTargetsPath)')" />
<Import Project="$(CustomBeforeWixTargets)" Condition=" '$(CustomBeforeWixTargets)' != '' and Exists('$(CustomBeforeWixTargets)')" />
<!-- These properties can be overridden to support non-default installations. -->
<PropertyGroup>
<WixTargetsPath Condition=" '$(WixTargetsPath)' == '' AND '$(MSBuildExtensionsPath32)' != '' ">$(MSBuildExtensionsPath32)\Microsoft\WiX\v3.x\Wix.targets</WixTargetsPath>
<WixTargetsPath Condition=" '$(WixTargetsPath)' == '' ">$(MSBuildExtensionsPath)\Microsoft\WiX\v3.x\Wix.targets</WixTargetsPath>
<WixTasksPath Condition=" '$(WixTasksPath)' == '' ">$(WixInstallPath)\WixTasks.dll</WixTasksPath>
<LuxTargetsPath Condition=" '$(LuxTargetsPath)' == '' AND '$(MSBuildExtensionsPath32)' != '' ">$(MSBuildExtensionsPath32)\Microsoft\WiX\v3.x\Lux.targets</LuxTargetsPath>
<LuxTargetsPath Condition=" '$(LuxTargetsPath)' == '' ">$(MSBuildExtensionsPath)\Microsoft\WiX\v3.x\Lux.targets</LuxTargetsPath>
<LuxTasksPath Condition=" '$(LuxTasksPath)' == '' ">$(WixInstallPath)\LuxTasks.dll</LuxTasksPath>
</PropertyGroup>
<!-- This makes the project files a dependency of all targets so that things rebuild if they change -->
<PropertyGroup>
<MSBuildAllProjects Condition="Exists('$(MSBuildProjectFullPath)')">$(MSBuildAllProjects);$(MSBuildProjectFullPath)</MSBuildAllProjects>
<MSBuildAllProjects Condition="Exists('$(WixTargetsPath)')">$(MSBuildAllProjects);$(WixTargetsPath)</MSBuildAllProjects>
<MSBuildAllProjects Condition="Exists('$(LuxTargetsPath)')">$(MSBuildAllProjects);$(LuxTargetsPath)</MSBuildAllProjects>
<MSBuildAllProjects Condition="Exists('$(UserTargetsPath)')">$(MSBuildAllProjects);$(UserTargetsPath)</MSBuildAllProjects>
<MSBuildAllProjects Condition="Exists('$(CustomBeforeWixTargets)')">$(MSBuildAllProjects);$(CustomBeforeWixTargets)</MSBuildAllProjects>
<MSBuildAllProjects Condition="Exists('$(CustomAfterWixTargets)')">$(MSBuildAllProjects);$(CustomAfterWixTargets)</MSBuildAllProjects>
</PropertyGroup>
<!--
//////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////
Property Declarations
//////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////
-->
<!-- These tasks can be used as general-purpose build tasks. -->
<UsingTask TaskName="Candle" AssemblyFile="$(WixTasksPath)" />
<UsingTask TaskName="Insignia" AssemblyFile="$(WixTasksPath)" />
<UsingTask TaskName="Lit" AssemblyFile="$(WixTasksPath)" />
<UsingTask TaskName="Light" AssemblyFile="$(WixTasksPath)" />
<UsingTask TaskName="Torch" AssemblyFile="$(WixTasksPath)" />
<!-- These tasks are extensions for harvesting WiX source code from other sources. -->
<UsingTask TaskName="HeatFile" AssemblyFile="$(WixTasksPath)" />
<UsingTask TaskName="HeatDirectory" AssemblyFile="$(WixTasksPath)" />
<UsingTask TaskName="HeatProject" AssemblyFile="$(WixTasksPath)" />
<!-- These tasks are specific to the build process defined in this file, and are not considered general-purpose build tasks. -->
<UsingTask TaskName="AssignProjectConfiguration" AssemblyName="Microsoft.Build.Tasks.v4.0, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<UsingTask TaskName="AssignTargetPath" AssemblyName="Microsoft.Build.Tasks.v4.0, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<UsingTask TaskName="ResolveNonMSBuildProjectOutput" AssemblyName="Microsoft.Build.Tasks.v4.0, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<UsingTask TaskName="ResolveVCProjectOutput" AssemblyName="Microsoft.Build.Tasks.v4.0, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<UsingTask TaskName="CreateItemAvoidingInference" AssemblyFile="$(WixTasksPath)" />
<UsingTask TaskName="CreateProjectReferenceDefineConstants" AssemblyFile="$(WixTasksPath)" />
<UsingTask TaskName="WixAssignCulture" AssemblyFile="$(WixTasksPath)" />
<UsingTask TaskName="ResolveWixReferences" AssemblyFile="$(WixTasksPath)"/>
<UsingTask TaskName="ReplaceString" AssemblyFile="$(WixTasksPath)"/>
<UsingTask TaskName="GetCabList" AssemblyFile="$(WixTasksPath)" />
<UsingTask TaskName="GetLooseFileList" AssemblyFile="$(WixTasksPath)" />
<UsingTask TaskName="RefreshGeneratedFile" AssemblyFile="$(WixTasksPath)"/>
<UsingTask TaskName="RefreshBundleGeneratedFile" AssemblyFile="$(WixTasksPath)"/>
<UsingTask TaskName="GenerateCompileWithObjectPath" AssemblyFile="$(WixTasksPath)"/>
<!-- WiX tools are 32bit EXEs, so run them out-of-proc when MSBuild is not 32bit. -->
<PropertyGroup>
<RunWixToolsOutOfProc Condition=" '$(PROCESSOR_ARCHITECTURE)'!='x86' ">true</RunWixToolsOutOfProc>
</PropertyGroup>
<!--
Several properties must be set in the main project file, before using this .targets file.
However, if the properties are not set, we pick some defaults.
OutDir:
Indicates the final output location for the project or solution. When building a solution,
OutDir can be used to gather multiple project outputs in one location. In addition,
OutDir is included in AssemblySearchPaths used for resolving references.
OutputPath:
This property is usually specified in the project file and is used to initialize OutDir.
OutDir and OutputPath are distinguished for legacy reasons, and OutDir should be used if at all possible.
BaseIntermediateOutputPath:
This is the top level folder where all configuration specific intermediate output folders will be created.
Default value is obj\
IntermediateOutputPath:
This is the full intermediate Output Path, and is derived from BaseIntermediateOutputPath, if none specified
(eg. obj\debug). If this property is overridden, then setting BaseIntermediateOutputPath has no effect.
-->
<PropertyGroup>
<!-- Ensure any OutputPath has a trailing slash, so it can be concatenated -->
<OutputPath Condition="'$(OutputPath)' != '' and !HasTrailingSlash('$(OutputPath)')">$(OutputPath)\</OutputPath>
<AssemblyName Condition=" '$(AssemblyName)'=='' ">$(MSBuildProjectName)</AssemblyName>
<!--
Be careful not to give OutputPath a default value in the case of an invalid Configuration/Platform.
We use OutputPath specifically to check for invalid configurations/platforms.
-->
<OutputPath Condition=" '$(Platform)'=='' and '$(Configuration)'=='' and '$(OutputPath)'=='' ">bin\Debug\</OutputPath>
<_OriginalConfiguration>$(Configuration)</_OriginalConfiguration>
<_OriginalPlatform>$(Platform)</_OriginalPlatform>
<Configuration Condition=" '$(Configuration)'=='' ">Debug</Configuration>
<ConfigurationName Condition=" '$(ConfigurationName)' == '' ">$(Configuration)</ConfigurationName> <!-- Example, Debug -->
<Platform Condition=" '$(Platform)'=='' ">AnyCPU</Platform>
<_OriginalOutputType>$(OutputType)</_OriginalOutputType>
<OutputType Condition=" '$(OutputType)' == '' ">Package</OutputType>
<BuildProjectReferences Condition="'$(BuildProjectReferences)' == ''">true</BuildProjectReferences>
</PropertyGroup>
<PropertyGroup Condition=" '$(OutputPath)' == '' ">
<!--
A blank OutputPath at this point means that the user passed in an invalid Configuration/Platform
combination. Whether this is considered an error or a warning depends on the value of
$(SkipInvalidConfigurations).
-->
<_InvalidConfigurationError Condition=" '$(SkipInvalidConfigurations)' != 'true' ">true</_InvalidConfigurationError>
<_InvalidConfigurationWarning Condition=" '$(SkipInvalidConfigurations)' == 'true' ">true</_InvalidConfigurationWarning>
</PropertyGroup>
<!-- Properties for the intermediate object output -->
<PropertyGroup>
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">obj\</BaseIntermediateOutputPath>
<BaseIntermediateOutputPath Condition="!HasTrailingSlash('$(BaseIntermediateOutputPath)')">$(BaseIntermediateOutputPath)\</BaseIntermediateOutputPath>
<IntermediateExt Condition=" '$(IntermediateExt)' == '' ">.wixobj</IntermediateExt>
<CleanFile Condition=" '$(CleanFile)' == '' ">$(MSBuildProjectFile).FileList.txt</CleanFile>
<BindContentsFilePrefix Condition=" '$(BindContentsFilePrefix)' == '' ">$(MSBuildProjectFile).BindContentsFileList</BindContentsFilePrefix>
<BindContentsFileExtension Condition=" '$(BindContentsFileExtension)' == '' ">.txt</BindContentsFileExtension>
<BindOutputsFilePrefix Condition=" '$(BindOutputsFilePrefix)' == '' ">$(MSBuildProjectFile).BindOutputsFileList</BindOutputsFilePrefix>
<BindOutputsFileExtension Condition=" '$(BindOutputsFileExtension)' == '' ">.txt</BindOutputsFileExtension>
<BindBuiltOutputsFilePrefix Condition=" '$(BindBuiltOutputsFilePrefix)' == '' ">$(MSBuildProjectFile).BindBuiltOutputsFileList</BindBuiltOutputsFilePrefix>
<BindBuiltOutputsFileExtension Condition=" '$(BindBuiltOutputsFileExtension)' == '' ">.txt</BindBuiltOutputsFileExtension>
<SignedFile Condition=" '$(SignedFile)' == '' ">$(MSBuildProjectFile).Signed.txt</SignedFile>
</PropertyGroup>
<PropertyGroup Condition=" $(IntermediateOutputPath) == '' ">
<IntermediateOutputPath Condition=" '$(PlatformName)' == 'AnyCPU' ">$(BaseIntermediateOutputPath)$(Configuration)\</IntermediateOutputPath>
<IntermediateOutputPath Condition=" '$(PlatformName)' != 'AnyCPU' ">$(BaseIntermediateOutputPath)$(PlatformName)\$(Configuration)\</IntermediateOutputPath>
</PropertyGroup>
<PropertyGroup>
<IntermediateOutputPath Condition="!HasTrailingSlash('$(IntermediateOutputPath)')">$(IntermediateOutputPath)\</IntermediateOutputPath>
</PropertyGroup>
<PropertyGroup>
<CabinetCachePath Condition=" '$(CabinetCachePath)'=='' and '$(ReuseCabinetCache)'=='true' ">$(IntermediateOutputPath)cabcache\</CabinetCachePath>
</PropertyGroup>
<ItemGroup>
<IntermediateAssembly Include="$(IntermediateOutputPath)$(TargetName)$(TargetExt)"/>
<FinalDocFile Include="#(DocFileItem->'$(OutDir)%(Filename)%(Extension)')"/>
</ItemGroup>
<PropertyGroup>
<WixToolPath Condition=" '$(WixToolPath)' == ''">$(WixInstallPath)</WixToolPath>
<WixExtDir Condition=" '$(WixExtDir)' == ''">$(WixToolPath)</WixExtDir>
</PropertyGroup>
</Project>
it is looking C:\programfiles directory to invoke light.exe, heat.exe and all
How do i point the local wix files dirctory in wix2010.targets to run wix projects.
Previously I had configured:
<WixTargetsPath>$(SourceCodeControlRoot)\wix\[[Version]]\Wix.targets</WixTargetsPath>
<WixTasksPath>$(SourceCodeControlRoot)\wix\[[Version]]\wixtasks.dll</WixTasksPath>
Then I changed as per the document i.e I added:
<WixToolPath>$(SourceCodeControlRoot)\wix\[[Version]]\</WixToolPath>
into the property group.
Once added, everything works fine.
I'm Trying to Transform T4 Template using MSBUILD , but I'm getting the following error
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Microsoft\VisualStudio\v16.0\TextTemplating\Micro
soft.TextTemplating.targets(224,5): error MSB4175: The task factory "CodeTaskFactory" could not be loaded from the asse
mbly "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Current\Bin\Microsoft.Build.Tasks.Cores.dll
". Could not load file or assembly 'file:///C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Curre
nt\Bin\Microsoft.Build.Tasks.Cores.dll' or one of its dependencies. The system cannot find the file specified. [E:\csha
rpprojects\Automateodessa\Automateodessa\Automateodessa.csproj]
My .tt file content
<## template debug="false" hostspecific="false" language="C#" #>
<## assembly name="System.Core" #>
<## import namespace="System.Linq" #>
<## import namespace="System.Text" #>
<## import namespace="System.Collections.Generic" #>
<## output extension=".txt" #>
<#
for(int i = 0; i < 10; i++)
WriteLine($"Hello World {i}");
#>
Hello$(classname)
My .csproj file content
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="16.0">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<builtdir>E:\BuiltApp</builtdir>
<FileUpgradeFlags>
</FileUpgradeFlags>
<UpgradeBackupLocation>
</UpgradeBackupLocation>
<OldToolsVersion>2.0</OldToolsVersion>
</PropertyGroup>
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{58C4A28E-C37D-4D95-BBEE-6427A3F3129D}</ProjectGuid>
<OutputType>WinExe</OutputType>
<RootNamespace>Automateodessa</RootNamespace>
<AssemblyName>Automateodessa</AssemblyName>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<WarningLevel>4</WarningLevel>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<Deterministic>true</Deterministic>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Configuration" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xaml">
<RequiredTargetFramework>4.0</RequiredTargetFramework>
</Reference>
<Reference Include="WindowsBase" />
<Reference Include="PresentationCore" />
<Reference Include="PresentationFramework" />
</ItemGroup>
<ItemGroup>
<T4ParameterValues Include="classname">
<Value>asdsd</Value>
<Visible>False</Visible>
</T4ParameterValues>
</ItemGroup>
<ItemGroup>
<ApplicationDefinition Include="App.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</ApplicationDefinition>
<Page Include="MainWindow.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Compile Include="App.xaml.cs">
<DependentUpon>App.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Include="MainWindow.xaml.cs">
<DependentUpon>MainWindow.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
</ItemGroup>
<ItemGroup>
<Compile Include="Properties\AssemblyInfo.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<Compile Include="Properties\Settings.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Settings.settings</DependentUpon>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile>
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
</ItemGroup>
<ItemGroup>
<Service Include="{508349B6-6B84-4DF5-91F0-309BEEBAD82D}" />
</ItemGroup>
<ItemGroup>
<Content Include="TextTemplate1.tt">
<Generator>TextTemplatingFileGenerator</Generator>
<LastGenOutput>TextTemplate1.txt</LastGenOutput>
</Content>
<Resource Include="TextTemplate1.txt">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>TextTemplate1.tt</DependentUpon>
</Resource>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Microsoft\VisualStudio\v16.0\TextTemplating\Microsoft.TextTemplating.targets" />
<Target Name="AfterBuild">
<Message Text="The output file is hhahah" />
</Target>
</Project>
And my command for MSbuild is
MSBuild.exe E:\csharpprojects\Automateodessa\Automateodessa\Automateodessa.csproj /t:Transform /p:TransformFile="TextTemplate1.tt"
Can Someone tell me why am I getting this error?
P.S
My MSBUILD Variable got by /v:diag
MSBuildBinPath = C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Current\Bin
MSBuildExtensionsPath = C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild
MSBuildExtensionsPath32 = C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild
MSBuildExtensionsPath64 = C:\Program Files\MSBuild
MSBuildFrameworkToolsPath = C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\
MSBuildFrameworkToolsPath32 = C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\
MSBuildFrameworkToolsPath64 = C:\WINDOWS\Microsoft.NET\Framework64\v4.0.30319\
MSBuildFrameworkToolsRoot = C:\WINDOWS\Microsoft.NET\Framework\
MSBuildLoadMicrosoftTargetsReadOnly = true
MSBuildNodeCount = 1
MSBuildProgramFiles32 = C:\Program Files (x86)
MSBuildProjectDefaultTargets = Build
MSBuildProjectDirectory = E:\csharpprojects\StudySnippets
MSBuildProjectDirectoryNoRoot = csharpprojects\StudySnippets
MSBuildProjectExtension = .csproj
MSBuildProjectExtensionsPath = E:\csharpprojects\StudySnippets\obj\
MSBuildProjectFile = Testing.csproj
MSBuildProjectFullPath = E:\csharpprojects\StudySnippets\Testing.csproj
MSBuildProjectName = Testing
MSBuildRuntimeType = Full
MSBuildRuntimeVersion = 4.0.30319
MSBuildSDKsPath = C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Sdks
MSBuildStartupDirectory = C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Current\Bin
MSBuildToolsPath = C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Current\Bin
MSBuildToolsPath32 = C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Current\Bin
MSBuildToolsPath64 = C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Current\Bin\amd64
MSBuildToolsRoot = C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild
MSBuildToolsVersion = Current
MSBuildUserExtensionsPath = C:\Users\admin\AppData\Local\Microsoft\MSBuild
MSBuildVersion = 16.2.37902
MsTestToolsTargets = C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Microsoft\VisualStudio\v16.0
\TeamTest\Microsoft.TeamTest.targets
NetFrameworkPropsPath = C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Current\Bin\Microsoft.NET
Framework.CurrentVersion.props
NetFrameworkTargetsPath = C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Current\Bin\Microsoft.N
ETFramework.CurrentVersion.targets```
Not able to Transform T4 Template using MSBUILD toolset=“16.0”
I think you just use msbuild.exe from an old framework or just use an old version of MSBuild like VS2017. Since you have set MSBUILD toolset="16.0", it means that you should use MSBuild v16.0 to build your project.
1) Please use C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Current\Bin\MSBuild.exe rather than any other old version of MSBuild.exe
2) just use Developer Command Prompt for VS2019
Update 1
Besides, if you still face the issue after the solution, I think there are something wrong with your project or VS Environment.
Solution
1) I think you have create a new VS2019 project and then migrate the old project into it to test whether it is your old project's problem.
2) Please do a repair in VS Installer or update your VS to the latest version to test whether it is the issue of your VS Environment.
Hope this could help you.
I am trying to build a project in ANSI-C on Microsoft Windows [Version 10.0.14393] with msbuild version Microsoft (R)-Buildmodul, Version 15.1.1012.6693
I get to compile everything correct, with the setup shown below.
Project Strcuture
The projectfolder is structed like this:
- projectfolder
- a.vcxproj
- main.c
- main.h
- other.c
- other.h
- test.c
- test.h
main.c
#include <stdio.h>
#include "main.h"
#include "test.h"
int main() {
printf("Hello World\n");
test_printf();
return 0;
}
main.h
#ifndef MAIN_H_
#define MAIN_H_
#endif // !MAIN_H_
other.c
#include "other.h"
#ifdef dummy
int some_number = 3;
#endif // dummy
other.h
#ifndef OTHER_H_
#define OTHER_H_
#define dummy
#ifdef dummy
extern int some_number;
#endif // dummy
#endif // OTHER_H_
test.c
#include <stdio.h>
#include "test.h"
extern int test_printf(void) {
printf("Hello from test.c");
return 0;
}
test.h
#ifndef TEST_H_
#define TEST_H_
extern int test_printf(void);
#endif // !TEST_H_
The build script a.vcxproj looks like this (Generated by Visual Studio 2017 Community and then adapted to my needs in an editor):
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>15.0</VCProjectVersion>
<ProjectGuid>{25F5E5F8-5F52-4BFC-A822-766DCFC1F5BA}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>a</RootNamespace>
<WindowsTargetPlatformVersion>10.0.15063.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
<OutDir>bin\$(Configuration)\</OutDir>
<IntDir>bin\$(Configuration)\obj\</IntDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
</Link>
<BuildLog>
<Path>bin\$(Configuration)\$(MSBuildProjectName).log</Path>
</BuildLog>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="other.c">
<DisableLanguageExtensions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</DisableLanguageExtensions>
<CompileAs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">CompileAsC</CompileAs>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClCompile Include="test.c">
<DisableLanguageExtensions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</DisableLanguageExtensions>
<CompileAs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">CompileAsC</CompileAs>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClCompile Include="main.c">
<DisableLanguageExtensions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</DisableLanguageExtensions>
<CompileAs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">CompileAsC</CompileAs>
</ClCompile>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
</Project>
** This compiles fine without warnings/rrors to a *.exe **
What I Want To Achieve
But I want to spefcify for each object file that gets generated (main.obj, other.obj and test.obj) the sources the compiler is allowed to use fot the compile step.
If I change the <ItemGroup> of each to this (every to be generated *.obj files, gets the *.c files it should use for the compile step:
<ItemGroup>
<ClCompile Include="other.c"> <!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<DisableLanguageExtensions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</DisableLanguageExtensions>
<CompileAs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">CompileAsC</CompileAs>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClCompile Include="test.c;other.c"> <!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<DisableLanguageExtensions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</DisableLanguageExtensions>
<CompileAs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">CompileAsC</CompileAs>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClCompile Include="main.c;other.c;test.c"> <!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<DisableLanguageExtensions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</DisableLanguageExtensions>
<CompileAs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">CompileAsC</CompileAs>
</ClCompile>
</ItemGroup>
I then get following compiler and linker warnings:
InitializeBuildStatus:
"bin\Debug\obj\a.tlog\unsuccessfulbuild" wird erstellt, da "AlwaysCreate" angegeben wurde.
C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\IDE\VC\VCTargets\Microsoft.CppBuild.targets(937,5): warning MSB8027: Two or more files
with the name of other.c will produce outputs to the same location. This can lead to an incorrect build result. The files involved are other.c, other.c, o
ther.c. [C:\Users\user\Desktop\question\a\a.vcxproj]
C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\IDE\VC\VCTargets\Microsoft.CppBuild.targets(937,5): warning MSB8027: Two or more files
with the name of test.c will produce outputs to the same location. This can lead to an incorrect build result. The files involved are test.c, test.c.
Link:
bin\Debug\obj\other.obj : warning LNK4042: object specified more than once; extras ignored [C:\Users\user\Desktop\question\a\a.vcxproj]
bin\Debug\obj\other.obj : warning LNK4042: object specified more than once; extras ignored [C:\Users\user\Desktop\question\a\a.vcxproj]
bin\Debug\obj\test.obj : warning LNK4042: object specified more than once; extras ignored [C:\Users\user\Desktop\question\a\a.vcxproj]
Build succeeded:
"C:\Users\user\Desktop\question\a\a.vcxproj" (Standardziel) (1) ->
(WarnCompileDuplicatedFilename Ziel) ->
C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\IDE\VC\VCTargets\Microsoft.CppBuild.targets(937,5): warning MSB8027: Two or more fil
es with the name of other.c will produce outputs to the same location. This can lead to an incorrect build result. The files involved are other.c, other.c,
other.c. [C:\Users\user\Desktop\question\a\a.vcxproj]
C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\IDE\VC\VCTargets\Microsoft.CppBuild.targets(937,5): warning MSB8027: Two or more fil
es with the name of test.c will produce outputs to the same location. This can lead to an incorrect build result. The files involved are test.c, test.c. [C
:\Users\user\Desktop\question\a\a.vcxproj]
"C:\Users\user\Desktop\question\a\a.vcxproj" (Standardziel) (1) ->
(Link Ziel) ->
bin\Debug\obj\other.obj : warning LNK4042: object specified more than once; extras ignored [C:\Users\user\Desktop\question\a\a.vcxproj]
bin\Debug\obj\other.obj : warning LNK4042: object specified more than once; extras ignored [C:\Users\user\Desktop\question\a\a.vcxproj]
bin\Debug\obj\test.obj : warning LNK4042: object specified more than once; extras ignored [C:\Users\user\Desktop\question\a\a.vcxproj]
5 Warnung(en)
0 Fehler
Is there a way in in msbuild to achive what I like to do: Telling msbuild for each source file what it allowed to use for the compile step?
I currently have to have two separate property groups with only two differences between them, that are set to have one or the other trigger depending on a condition. Here's what I have:
<!--CAME FROM TEAMBUILD-->
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' != 'Debug|AnyCPU' AND '$(Configuration)|$(Platform)' != 'Release|AnyCPU' AND '$(BuildingInsideVisualStudio)' != 'true' ">
<PreBuildEvent>
</PreBuildEvent>
<PostBuildEvent>
set MAGE="C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\NETFX 4.0 Tools\mage.exe"
set APPFILE=$(TargetDir)$(TargetName).application
set MANIFEST=$(TargetPath).manifest
set CERT=$(ProjectDir)$(TargetName).pfx
set PROJECTNAME=$(TargetName)
set CONFIGURATION=$(ConfigurationName)
set TARGETDIR=$(TargetDir)
set TEAMBUILD=$True
Powershell -File "$(ProjectDir)POSTBUILD.ps1"
</PostBuildEvent>
</PropertyGroup>
<!--CAME FROM PUBLISH COMMAND-->
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' != 'Debug|AnyCPU' AND '$(Configuration)|$(Platform)' != 'Release|AnyCPU' AND '$(BuildingInsideVisualStudio)' == 'true' ">
<PreBuildEvent>
</PreBuildEvent>
<PostBuildEvent>
set MAGE="C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\NETFX 4.0 Tools\mage.exe"
set APPFILE=$(TargetDir)$(TargetName).application
set MANIFEST=$(TargetPath).manifest
set CERT=$(ProjectDir)$(TargetName).pfx
set PROJECTNAME=$(TargetName)
set CONFIGURATION=$(ConfigurationName)
set TARGETDIR=$(TargetDir)
set TEAMBUILD=$False
Powershell -File "$(ProjectDir)POSTBUILD.ps1"
</PostBuildEvent>
</PropertyGroup>
Is there a way to set the teambuild value based on the $(BuildingInsideVisualStudio) value inside the post build event?
Something like
If ($(BuildingInsideVisualStudio) == 'true')
set TEAMBUILD = $True
or
even something like
set TEAMBUILD = $$(BuildingInsideVisualStudio) ?
You're already using it: Condition. You just have to extract an extra step to create a property that will be used as the TEAMBUILD value. For example:
<PropertyGroup Condition='$(BuildingInsideVisualStudio)' != 'true' ">
<TeamBuildValue>FALSE</TeamBuildValue>
</PropertyGroup>
<PropertyGroup Condition='$(BuildingInsideVisualStudio)' == 'true' ">
<TeamBuildValue>TRUE</TeamBuildValue>
</PropertyGroup>
<PropertyGroup>
<PreBuildEvent>
</PreBuildEvent>
<PostBuildEvent>
...
set TEAMBUILD=$(TeamBuildValue)
...
</PostBuildEvent>
</PropertyGroup>
I would probably try a Choose/Otherwise.......instead of a == !=
Just a preference.
Because one day.....you may have a third option.
the "Otherwise" clause (aka , use some default values) is more explicit.
<Choose>
<When Condition=" '$(Computername)'=='MySuperComputer01' ">
<PropertyGroup>
<FavoriteFood>Peanuts</FavoriteFood>
<FavoriteColor>Red</FavoriteColor>
</PropertyGroup>
</When>
<When Condition=" '$(Computername)'=='MySuperComputer02' ">
<PropertyGroup>
<FavoriteFood>Apples</FavoriteFood>
<FavoriteColor>Yellow</FavoriteColor>
</PropertyGroup>
</When>
<Otherwise>
<PropertyGroup>
<FavoriteFood>CrackersDefault</FavoriteFood>
<FavoriteColor>OrangeDefault</FavoriteColor>
</PropertyGroup>
</Otherwise>
</Choose>