Fetching asmv1:assemblyIdentity from manifest - c#

After compilation the following is present in the app manifest, if I publish it by hand in VS the version picked is the first one, i.e. 3.9.0.3
<asmv1:assemblyIdentity name="MyApp.exe" version="3.9.0.3" publicKeyToken="0000000000000000" language="neutral" processorArchitecture="x86" type="win32" />
<description asmv2:iconFile="Logo.ico" xmlns="urn:schemas-microsoft-com:asm.v1" />
<application />
<entryPoint>
<assemblyIdentity name="MyApp" version="3.8.0.25806" language="neutral" processorArchitecture="x86" />
If instead I try running it in a MSBuild script and use
<Target Name="GetVersion">
<Message Text="Getting version info..."/>
<GetAssemblyIdentity AssemblyFiles="#(GetVersionAssembly)">
<Output TaskParameter="Assemblies"
ItemName="GetVersionAssemblyInfo"/>
</GetAssemblyIdentity>
<Message Text="%(GetVersionAssemblyInfo.Version)..."/>
</Target>
Where #(GetVersionAssembly) is the path to the executable, the 3.8.0.25806 version is picked, how do I get the published version rather than assembly version extracted in MSBuild, to make it match the manual publish?

What I ended up doing was use the MSBuild.Community.Tasks library and in the GetVersion target add below line, to allow the published version to be stored in the version.txt file. Not sure if there is a way of accessing the publish number within Visual Studio and increment that one when publishing with msbuild, which would prevent having to manually update these versions if you switch between the two ways of publishing. I would characterize this as a half solution since it still involve a manual step.
<Version VersionFile="version.txt" RevisionType="Increment"> <Output TaskParameter="Major" PropertyName="Major" /> <Output TaskParameter="Minor" PropertyName="Minor" /> <Output TaskParameter="Build" PropertyName="Build" /> <Output TaskParameter="Revision" PropertyName="Revision" /> </Version>
Within the script I then changed all %(GetVersionAssemblyInfo.Version) references to $(Major).$(Minor).$(Build).$(Revision)

Related

Unable to get autocomplete to work after installing vsix

I am working on a completionprovider project, which will be published as a visual studio extension. The completionprovider code is taken from https://github.com/PacktPublishing/Roslyn-Cookbook/blob/master/Chapter03/CodeSamples/Recipe%205%20-%20CompletionProvider/CompletionProvider.zip.
When I was debugging the vsix, I can get it to work properly. Installation also worked using the vsix file generated in the bin folder after building the project. However, I can't get it to work by testing the extension in the project I used during debugging. I have tried all possible ways to change the vsixmanifest but simply could not get it to work after installation. Below is a sample of the manifest file.
<?xml version="1.0" encoding="utf-8"?>
<PackageManifest Version="2.0.0" xmlns="http://schemas.microsoft.com/developer/vsx-schema/2011" xmlns:d="http://schemas.microsoft.com/developer/vsx-schema-design/2011">
<Metadata>
<Identity Id="MyCompletionProviderVsix.2f4985a4-6bc6-46fc-9082-2c45d3d8ac3f" Version="1.0" Language="en-US" Publisher="ABC" />
<DisplayName>MyCompletionProviderVsix</DisplayName>
<Description>Auto complete test.</Description>
</Metadata>
<Installation AllUsers="true">
<InstallationTarget Id="Microsoft.VisualStudio.Community" Version="[16.0, 17.0)" />
</Installation>
<Dependencies>
<Dependency Id="Microsoft.Framework.NDP" DisplayName="Microsoft .NET Framework" d:Source="Manual" Version="[4.5,)" />
</Dependencies>
<Prerequisites>
<Prerequisite Id="Microsoft.VisualStudio.Component.CoreEditor" Version="[15.0,17.0)" DisplayName="Visual Studio core editor" />
<Prerequisite Id="Microsoft.VisualStudio.Component.Roslyn.LanguageServices" Version="[16.0,17.0)" DisplayName="Roslyn Language Services" />
</Prerequisites>
<Assets>
<Asset Type="Microsoft.VisualStudio.MefComponent" d:Source="Project" d:ProjectName="MyCompletionProvider" Path="|MyCompletionProvider|" />
<Asset Type="Microsoft.VisualStudio.Analyzer" d:Source="Project" d:ProjectName="MyCompletionProvider" Path="|MyCompletionProvider|" />
</Assets>
</PackageManifest>

Why doesn't AutogenerateBindingRedirects work for a Web.config in Visual Studio 2017

I have a reference to a .Net Standard 2.0 library that requires Microsoft.AspNet.WebApi.Client 5.2.4. This has a lot of dependencies that need to be redirected to use newer versions.
To avoid package/dependency explosion I've updated the first PropertyGroup in the csproj file:
<RestoreProjectStyle>PackageReference</RestoreProjectStyle>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<GenerateBindingRedirectsOutputType>true</GenerateBindingRedirectsOutputType>
I'm expecting AutoGenerateBindingRedirects to prevent me from needing to change the Web.config to match the versions added.
Why do I still need to add binding redirects to my Web.config to resolve assembly conflicts?
It appears that AutoGenerateBindingRedirects will not work for web projects per https://learn.microsoft.com/en-us/dotnet/framework/configure-apps/how-to-enable-and-disable-automatic-binding-redirection.
Inspecting the output from the build shows that binding redirects are generated just not in the Web.config. Instead, they are in $(AssemblyName).dll.config. This file has the original configuration from Web.config as well as the binding redirects.
To put it all together you can have MSBuild copy the resulting config back to the Web.config. To do this you would add the following to the csproj:
<Target Name="AfterBuild">
<Copy SourceFiles="$(TargetDir)\$(AssemblyName).dll.config" DestinationFiles="Web.config" />
</Target>
For iis express: In Web.config replace section assemblyBinding with
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<linkedConfiguration href="file:{AssemblyName}.dll.config"/>
</assemblyBinding>
For iis and iis express:
add to project Scripts\CopyRuntimeSection.ps1
param ($from, $to)
$projectPath = Resolve-Path "$($PSScriptRoot)\..\"
$fromFilePath = "$projectPath\$from";
$toFilePath = "$projectPath\$to";
$fromFileXml = [xml](Get-Content -Path $fromFilePath -Raw)
$toFileXml = [xml](Get-Content -Path $toFilePath -Raw)
$toFileXml.configuration.runtime.InnerXml = $fromFileXml.configuration.runtime.InnerXml
$toFileXml.Save($toFilePath)
add to csproj
<Target Name="CopyRuntimeSection" AfterTargets="Build">
<Exec Command="PowerShell -File Scripts\CopyRuntimeSection.ps1 -from $(OutDir)\$(AssemblyName).dll.config -to Web.config" />
</Target>
Expanding on the other answer from this question, here's a solution that supports incremental builds and uses absolute paths for greater flexibility:
Add this somewhere in your solution (I named it UpdateBindingRedirect.ps1):
param ($from, $to)
$fromFileXml = [xml](Get-Content -Path $from -Raw)
$toFileXml = [xml](Get-Content -Path $to -Raw)
if ( $toFileXml.configuration.runtime.InnerXml -Ne $fromFileXml.configuration.runtime.InnerXml ) {
$toFileXml.configuration.runtime.InnerXml = $fromFileXml.configuration.runtime.InnerXml
$toFileXml.Save($to)
}
Add this to your csproj:
<Target Name="UpdateBindingRedirects" AfterTargets="Build" Inputs="$(OutDir)$(AssemblyName).dll.config" Outputs="$(ProjectDir)Web.config">
<Message Text="Update binding redirects from $(ProjectDir)$(OutDir)$(AssemblyName).dll.config" />
<Exec Command="PowerShell -NoLogo -NoProfile -File ..\UpdateBindingRedirects.ps1 -from $(ProjectDir)$(OutDir)$(AssemblyName).dll.config -to $(ProjectDir)Web.config" />
</Target>
There is a recipe from
https://github.com/CZEMacLeod/MSBuild.SDK.SystemWeb
that you can repurpose to update binding redirects on Web.config automatically.
Warning: not tested
Add a property
<PropertyGroup>
<OverwriteAppConfigWithBindingRedirects>true</OverwriteAppConfigWithBindingRedirects>
</PropertyGroup>
Use the build target UpdateConfigWithBindingRedirects as defined here https://github.com/CZEMacLeod/MSBuild.SDK.SystemWeb/blob/main/src/MSBuild.SDK.SystemWeb/Sdk/Sdk.targets
<Target Name="UpdateConfigWithBindingRedirects" AfterTargets="AfterBuild" Condition="'$(OverwriteAppConfigWithBindingRedirects)'=='true'">
<ItemGroup>
<_DllConfig Remove="#(_DllConfig)" />
<_AppConfig Remove="#(_AppConfig)" />
<_ConfigFile Remove="#(_ConfigFileHash)" />
<_DllConfig Include="$(OutDir)$(AssemblyName).dll.config" />
<_AppConfig Include="web.config" />
</ItemGroup>
<GetFileHash Files="#(_DllConfig)">
<Output TaskParameter="Hash" PropertyName="_DllConfigHash" />
<Output TaskParameter="Items" ItemName="_DllConfigFileHash" />
</GetFileHash>
<GetFileHash Files="#(_AppConfig)">
<Output TaskParameter="Hash" PropertyName="_AppConfigHash" />
<Output TaskParameter="Items" ItemName="_AppConfigFileHash" />
</GetFileHash>
<ItemGroup>
<_ConfigFileHash Include="#(_DllConfigFileHash)" />
<_ConfigFileHash Include="#(_AppConfigFileHash)" />
</ItemGroup>
<Message Text="%(_ConfigFileHash.Identity): %(_ConfigFileHash.FileHash)" />
<Warning Text="Replacing web.config due to changes during compile - This should clear warning MSB3276 on next compile" File="web.config" Condition="'$(_DllConfigHash)'!='$(_AppConfigHash)'" />
<Copy SourceFiles="$(OutDir)$(AssemblyName).dll.config" DestinationFiles="web.config" Condition="'$(_DllConfigHash)'!='$(_AppConfigHash)'" />
</Target>

sonar-dotnet-shared-library does not compile due non-existing dependencies, How to make it work?

I am trying to compile in my machine the sonar-csharp-plugin, but in the pom.xml file there is two dependencies that do not exist in the Maven public repositories:
<dependency>
<groupId>org.sonarsource.dotnet</groupId>
<artifactId>sonar-dotnet-tests-library</artifactId>
<version>1.5.0.393</version>
</dependency>
<dependency>
<groupId>org.sonarsource.dotnet</groupId>
<artifactId>sonar-dotnet-shared-library</artifactId>
<version>1.0.1.138</version>
</dependency>
I download the code of both projects and try to compile them and generate the .jar files for each one.
Trying to compile sonar-dotnet-shared-library-1.0.1.138, I installed the https://www.nuget.org/packages/SonarAnalyzer.CSharp/1.20.0 package and proceed to install it in my maven local repository then when I compile sonar-dotnet-shared-library-1.0.1.138 I get :
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-antrun-plugin:1.7:run (unzip-nuget) on project sonar-dotnet-shared-library: An Ant Build Exception has occured: C:\Temp\sonar-dotnet-shared-library-1.0.1.138\target\analyzer\SonarAnalyzer.Scanner\protobuf does not exist.
[ERROR] around Ant part ...<copy todir="src/main/protobuf">... # 8:35 in C:\Temp\sonar-dotnet-shared-library-1.0.1.138\target\antrun\build-main.xml
I think I am in Maven hell.
What should I do to build the code from the latest release sonar-csharp-plugin??
Edit: when I installed the SonarAnalyzer I used
mvn install:install-file -DgroupId=org.sonarsource.dotnet -DartifactId=SonarAnalyzer.Scanner -Dversion=1.20.0 -Dpackaging=nupkg -Dfile="C:\Temp\SonarAnalyzer.CSharp.1.20.0-RC1.nupkg"
I disable the tasks that generate the error, now the java code start its compilation but I get errors related to
import org.sonarsource.dotnet.protobuf.SonarAnalyzer;
I think that it is a reference to the SonarAnalyzer Dll's, but neither Eclipse nor Maven are able to find it (protobuf is missing)
Edit2:
the POM.XML includes these tasks:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<id>unzip-nuget</id>
<phase>validate</phase>
<configuration>
<exportAntProperties>true</exportAntProperties>
<tasks>
<unzip src="${sonarAnalyzer.workDirectory}/SonarAnalyzer.Scanner.nupkg" dest="${sonarAnalyzer.workDirectory}/SonarAnalyzer.Scanner/" />
<delete>
<fileset dir="src/main/protobuf" excludes=".gitignore"></fileset>
</delete>
<copy todir="src/main/protobuf">
<fileset dir="${sonarAnalyzer.workDirectory}/SonarAnalyzer.Scanner/protobuf">
<include name="*.proto"/>
</fileset>
</copy>
</tasks>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
<execution>
<id>compile-protobuf-sources</id>
<phase>generate-sources</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<target>
<fileset id="fileset" dir="${project.basedir}/src/main/protobuf">
<include name="*.proto" />
</fileset>
<pathconvert refid="fileset" property="protos" pathsep=" " />
<mkdir dir="${project.build.directory}/generated-sources/protobuf" />
<chmod file="${protobuf.compiler}" perm="u+x" />
<exec failonerror="true" executable="${protobuf.compiler}">
<arg value="proto_path=${project.basedir}/src/main/protobuf" />
<arg value="java_out=${project.build.directory}/generated-sources/protobuf" />
<arg line="${protos}" />
</exec>
</target>
</configuration>
</execution>
</executions>
As I understand, in the SonarAnalyzer.Scanner.nupkg should be a protobuf folder, and the content of that folder is copied to src/main/protobuf.....well the SonarAnalyzer.Scanner.nupkg downloaded from Nuget does not contain that folder....so....
guys from Sonar...... Where do I get that nupkg?
I had the same problem, I've found the solution on this thread from SonarQube's Google group.
You need to fetch the missing artifacts from sonarsource's Artifactory server. As suggested by Duarte Meneses, you can add these lines to [user_home]/.m2/settings.xml :
<profiles>
<profile>
<id>sonarsource-repo</id>
<activation>
<property>
<name>!skip-sonarsource-repo</name>
</property>
</activation>
<repositories>
<repository>
<id>sonarsource</id>
<name>SonarSource Central Repository</name>
<url>https://repox.sonarsource.com/sonarsource</url>
<releases>
<enabled>true</enabled>
<updatePolicy>interval:60</updatePolicy>
<checksumPolicy>fail</checksumPolicy>
</releases>
<snapshots>
<enabled>false</enabled>
<updatePolicy>never</updatePolicy>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>sonarsource</id>
<name>SonarSource Central Repository</name>
<url>https://repox.sonarsource.com/sonarsource</url>
<releases>
<enabled>true</enabled>
<!-- no need to always check if new versions are available when
executing a maven plugin without specifying the version -->
<updatePolicy>interval:60</updatePolicy>
<checksumPolicy>fail</checksumPolicy>
</releases>
<snapshots>
<enabled>false</enabled>
<updatePolicy>never</updatePolicy>
</snapshots>
</pluginRepository>
</pluginRepositories>
</profile>
</profiles>
I used the above configuration.I also had mirrors declared in my settings.xml, so I had to exclude sonarsource from the mirrored repositories :
<mirrors>
<mirror>
<id>nexus</id>
<mirrorOf>*,!sonarsource</mirrorOf>
<url>http://ci-server/nexus/content/groups/public</url>
</mirror>
</mirrors>
Of course there are other ways to achieve the same result, for example by declaring a proxy repository in your company's Nexus server.
With this configuration, I built SonarQube successfully.

How to read values from a config file while building a project?

I have programmed a bootstrapper-project with WiX 3.8 and VS 2013 (C#).
In the project file You can create properties like that one for getting the build version from the EXE-file which shall be installed:
<Target Name="BeforeBuild">
<!-- Set the Variable BuildVersion -->
<GetAssemblyIdentity AssemblyFiles="../FilesForSetup/MyApp.exe">
<Output TaskParameter="Assemblies" ItemName="AsmInfo" />
</GetAssemblyIdentity>
<CreateProperty Value="%(AsmInfo.Version)">
<Output TaskParameter="Value" PropertyName="BuildVersion" />
</CreateProperty>
<CreateProperty Value="$(DefineConstants)">
<Output TaskParameter="Value" PropertyName="DefineConstantsOriginal" />
</CreateProperty>
<CreateProperty Value="$(DefineConstants);BuildVersion=$(BuildVersion)">
<Output TaskParameter="Value" PropertyName="DefineConstants" />
</CreateProperty>
</Target>
Now i want to put some properties for a webserver login (url, user, pw) into a config file, read the properties while build and put them into project properties.
Can this be done and which type of config file would be the best choice (p.e. XML)?
Thanks in advance!
Yes, it can be done and the best choice for the config file type is XML.
Per example you can write a config file for web server access like that:
<?xml version="1.0" encoding="utf-8" ?>
<parameters>
<parameter name="webserverurl" value="http://deviis.myCompany.net/release/" />
<parameter name="webserveruser" value="administrator" />
<parameter name="webserverpassword" value="myPassword" />
</parameters>
Then we define some varaibles in the bundle file:
<Variable Name="WebServerUrl"
Value="$(var.WebServerUrl)"></Variable>
<Variable Name="WebServerUser"
Value="$(var.WebServerUser)"></Variable>
<Variable Name="WebServerPassword"
Value="$(var.WebServerPassword)"></Variable>
At least we have to insert a few lines in the bootstrapper project file to read the properties from the config and set the bundle variables.
Here just one example: the web server url
<XmlPeek Namespaces="<Namespace Prefix='myNamespace' Uri='http://schemas.microsoft.com/developer/msbuild/2003'/>" XmlInputPath="..\AppConfig\appconfig.xml" Query="/parameters/parameter[#name='webserverurl']/#value">
<Output TaskParameter="Result" PropertyName="webserverurlResult" />
</XmlPeek>
<CreateProperty Value="$(webserverurlResult)">
<Output TaskParameter="Value" PropertyName="WebServerUrlProp" />
</CreateProperty>
<CreateProperty Value="$(DefineConstants);WebServerUrl=$(WebServerUrlProp)">
<Output TaskParameter="Value" PropertyName="DefineConstants" />
</CreateProperty>
At first we read the property with the XmlPeek-tag and put it into the property webserverurlResult.
Then we create the property WebServerUrlProp with the value webserverurlResult and put it into the bundle variable WebServerUrl.
Alternatively we don't have to create the property WebServerUrlProp.
A few lines less in our project file.
This would look like that:
<XmlPeek Namespaces="<Namespace Prefix='myNamespace' Uri='http://schemas.microsoft.com/developer/msbuild/2003'/>" XmlInputPath="..\AppConfig\appconfig.xml" Query="/parameters/parameter[#name='webserverurl']/#value">
<Output TaskParameter="Result" PropertyName="webserverurlResult" />
</XmlPeek>
<CreateProperty Value="$(DefineConstants);WebServerUrl=$(webserverurlResult)">
<Output TaskParameter="Value" PropertyName="DefineConstants" />
</CreateProperty>
Each time the bootstrapper project builds, it reads the properties from the config file and puts them into the bundle variables.
If you have a self-made UI, you can access the variable values like that:
UrlWebapi = Bootstrapper.Engine.StringVariables["WebServerUrl"];
UrlWebapi is in that case a property of type string.
I hope this helps.

How to set up TeamCity/NAnt/Gallio/PartCover to show test results?

This is my first time setting up teamcity and I am running into some issues displaying results. I want to have a build step that runs an NAnt script. The script should run my unit tests through PartCover and display results. The results should be:
Tests that pass/Tests that fail
Coverage report
But I don't really know how to set up the script or the settings or even where I should view these results (the artifacts section I'm guessing?). Using the following script below, everything runs ok but I am not able to view any reports.
<project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<loadtasks assembly="C:\Program Files\Gallio\bin\Gallio.NAntTasks.dll" />
<target name="test">
<gallio result-property="exitCode" failonerror="false" >
<runner-extension value="TeamCityExtension,Gallio.TeamCityIntegration" />
<files>
<include name="%system.teamcity.build.checkoutDir%\Trunk\MyLibrary.Testing\bin\Release\MyLibrary.Testing.dll"/>
</files>
</gallio>
<fail if="${exitCode != '0'}" >One or more tests failed. Please check the log for more details</fail>
</target>
</project>
For the .Net Coverage section, I have PartCover (2.2 or 2.3) selected but I don't have anything in the PartCover Arguments (should I?)
Thanks for your help!
In my experience you should not run Gallio directly. Instead you should run PartCover and specify in its command-line parameters Gallio as target.
You can find some advices on Nant+PartCover here:
Integrating PartCover.NET with NAnt
I ran into issues with NAnt and decided to just use MSBuild. MSBuild was easier to work with and gave very descriptive error messages. (I also found our license for NCover so used that as well). Here is my script for anyone interested. I found the code for it from various spots on the net.
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<CoverageDir>.\Tests\Output\Coverage</CoverageDir>
<CoverageFilesDir>.\Tests\Output\Coverage\files</CoverageFilesDir>
<BinDir>Testing\bin\x86\Release</BinDir>
<NCoverDir>C:\Program Files (x86)\NCover</NCoverDir>
<GallioDir>C:\Program Files (x86)\Gallio\bin</GallioDir>
</PropertyGroup>
<UsingTask TaskName="NCover" AssemblyFile="$(NCoverDir)\Build Task Plugins\NCover.MSBuildTasks.dll" />
<UsingTask TaskName="NCoverExplorer" AssemblyFile="$(NCoverDir)\Build Task Plugins\NCoverExplorer.MSBuildTasks.dll"/>
<!-- Specify the tests assemblies -->
<ItemGroup>
<TestAssemblies Include="$(BinDir)\library.Testing.dll" />
<CoverageAssemblies Include="$(BinDir)\library.dll" />
</ItemGroup>
<Target Name="Coverage">
<Message Text="Creating $(CoverageFilesDir)" />
<MakeDir Directories="$(CoverageFilesDir)"/>
<Message Text="##-------------------- Running Coverage Reports --------------------##" />
<Message Text="Coverage Assemblies #(TestAssemblies)" />
<!--Run NCover to gather coverage information-->
<NCover
ToolPath="$(NCoverDir)"
TestRunnerExe="$(GallioDir)\Gallio.Echo.exe"
TestRunnerArgs="%(TestAssemblies.FullPath)"
IncludeAssemblies="#(CoverageAssemblies)"
LogFile="$(CoverageFilesDir)\%(TestAssemblies.Filename)-ncover.log"
RegisterProfiler="false"
CoverageFile="$(CoverageFilesDir)\%(TestAssemblies.Filename)-coverage.xml"/>
<CreateItem Include="$(CoverageFilesDir)\*-coverage.xml">
<Output TaskParameter="Include" ItemName="CoverageReports"/>
</CreateItem>
<!--Generate coverage report-->
<NCoverExplorer
ToolPath="$(NCoverDir)"
ProjectName="Library Coverage"
ReportType="4"
Sort="CoveragePercentageAscending"
Filter="None"
OutputDir="$(CoverageDir)"
XmlReportName="CoverageReport.xml"
HtmlReportName="CoverageReport.html"
ShowExcluded="True"
SatisfactoryCoverage="15"
FailMinimum="False"
CoverageFiles="#(CoverageReports)"/>
<!-- In case one of the tests fails, make sure to stop TypeMock and unregister NCover. -->
<OnError ExecuteTargets="test-finally"/>
</Target>
<!-- Stopping unregistering NCover is a separate target because it has to happen -->
<!-- regardless of success or failure of the unit tests. Like the "finally" in a "try/finally" block. -->
<Target Name="test-finally">
<Exec Command="regsvr32 /u /s "$(NCoverDir)\CoverLib.dll"" ContinueOnError="true"/>
</Target>
</Project>

Categories