Only sign assemblies with strong name during release build - visual-studio-2010

The scenario is: I'm building my solution with TeamCity, I'm not running the build account as an administrator; so I get problems with the strong name keys.
I know of a few solutions out there, like running the build as an administrator and registering the certificates in the proper container.
Is there anyway to sign the assemblies within a solution file only during a release build and not during a debug build. Or are there any similar solutions?
I think it is strange that there isn't a MSBuild parameter that can be set wether the assemblies should be signed or not. Because if you look at the csproj-files there is an option there for signed or not signed

Another option is to edit the project file. By default if you enable assembly signing in Visual Studio it will be used for all build configurations. The project file contains an element like the following.
<PropertyGroup>
<SignAssembly>true</SignAssembly>
</PropertyGroup>
<PropertyGroup>
<AssemblyOriginatorKeyFile>YourKeyFile.pfx</AssemblyOriginatorKeyFile>
</PropertyGroup>
If you only want to sign the assemblies during a specifc build configuration, such as RELEASE. You can put the <SignAssembly> and <AssemblyOriginatorKeyFile> in the PropertyGroup element with the Condition that identifies your build configuration.
So if you want to sign your assembly during a release build, you can change your project file to the following.
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<!-- other element of this PropertyGroup -->
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>YourKeyFile.pfx</AssemblyOriginatorKeyFile>
</PropertyGroup>
Note: When you change your project file, to the following. you cannot change the signing settings of the Project Properties in Visual Studio. That means in Visual Studio is signing of the assembly disabled, also if you change the build configuration in Visual Studio.

Here's a solution where the assembly is signed in Release configuration, but not in Debug configuration. It uses the signing facilities from the project, not using the [AssemblyKeyFile] attribute. It's basically the same as Jehof's answer but in other words.
Set up the project for signing in the Signing tab in project preferences.
Unload the project, and edit it in the XML editor. Locate the SignAssembly property. Move that property into the two configuration dependent property groups. In the Debug configuration, set the property to false.
This will look something like this:
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
<!-- ... -->
<SignAssembly>false</SignAssembly>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
<SignAssembly>true</SignAssembly>
</PropertyGroup>
Visual Studio works correctly even when changing build configurations, with the exception of the Sign the assembly check box in the Signing tab. I tested with Visual Studio 2008.
Cave-Eats:
You need to remove the [AssemblyKeyFile] attribute for this to work.
If you have [InternalsVisibleTo] attributes, you need to maintain two versions, like this:
#if DEBUG
[assembly: InternalsVisibleTo("MyLib.NUnit")]
#else
[assembly: InternalsVisibleTo("MyLib.NUnit, PublicKey=<your public key>")]
#endif
In other words, MyLib.NUnit must also be signed in Release configuration.

You can use preprocessor directives:
#if SIGN
//Only the Release build is signed
#pragma warning disable 1699 //We can't use the compiler switch
[assembly: AssemblyKeyName("KeyContainerName")]
#pragma warning restore 1699
#endif
Then define the SIGN symbol in the Release configuration.
You must install the key into a key container using sn.exe. Alternatively, you can use [AssemblykeyFile] to specify a path.
The #pragma suppresses this warning.

Related

Create a new configuration for Visual Studio Project from command line

I want to create a configuration for a Visual Studio projectfrom command line in order to automate my release process. Typically you would go into Visual Studio, create a new configuration, select in the dropdown menu which build to copy from (in my case, this would be Release) and select the platforms. I want to do the same from command line.
I have tried the following:
MSBuild <mysolution>.sln -p:Configuration=<newconfigname>
But I get MSB4126 error, telling me that the configuration is not valid. I have also read the documentation on MSBuild, but it does not say anything about this. I am not even sure that this can be achieved using MSBuild. I am using Wix Installer in order to compile a .msi, and that works flawlessly, but it's building the Release configuration, instead of the one I want to build (custom release).
Can anyone shed some light on this issue?
I solved it by modifying some files.
You need to modify your .sln file to add your release type:
NewRelease|Any CPU = NewRelease|Any CPU
NewRelease|ARM = NewRelease|ARM
NewRelease|x64 = NewRelease|x64
NewRelease|x86 = NewRelease|x86
If you have submodules, add them as well. Create a new configuration in Visual Studio if you have doubts of what you need to add, and copy-paste from the configuration you created with Visual Studio, changing just the name of the configuration where needed.
You need to modify your .csproj file of the main project (not the WixInstaller one), for example:
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'NewRelease|AnyCPU'">
<OutputPath>bin\NewRelease\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>AnyCPU</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<Prefer32Bit>true</Prefer32Bit>
</PropertyGroup>
And, then again, if you have submodules, you have to modify every .csproj file to include your new release (copy from the other releases).
Finally, compile it with:
MSBuild <yourmainproject>.csproj -p:Configuration=NewRelease.

Unable to use Visual Studio Code Coverage with Azure Functions

I am using Visual Studio 15.3.5 and Microsoft.NET.Sdk.Functions 1.0.6.
I can run tests fine, but when I analyze the tests with Code Coverage the assembly which contains the Azure Functions is not analyzed. It is not listed in the Code Coverage assembly list. Other assemblies are listed, only the Azure Functions assembly is omitted.
Have anyone got it working?
The reason is that for new project types, the default <DebugType> is portable, which means that the pdb's generated would not have required info needed for CodeCoverage.
Here is how you can change this: in your .csproj, add <DebugType>full</DebugType> to the <PropertyGroup>. e.g. you should have:
<PropertyGroup>
<TargetFramework>net461</TargetFramework>
<DebugType>full</DebugType>
</PropertyGroup>
Or you can change this from VS:
go to properties on the project
go to the build tab, then the “Advanced…” button at the bottom
there’s a dropdown for Debugging Information. Setting that to “Full” updates the project with the necessary property

Specify value for ~remoteAppUrl in an Office add-in manifest

I'm writing an add-in for Outlook using the new framework. The manifest in the project template uses ~remoteAppUrl to represent the location of the web files. It works great during development, but to publish to the Office Store I need the production URL there. If I save the production URL to the manifest, the production server gets used during debugging, and so local changes don't show up.
The documentation mentions Visual Studio filling in this value during debugging:
Next, Visual Studio does the following:
1. Modifies the SourceLocation element of the XML manifest file by replacing the ~remoteAppUrl token with the fully qualified address of the start page (for example, http://localhost/MyAgave.html).
Is there a built-in way to have Visual Studio fill in the production URL at the appropriate time (before/during Office Store submittal), and not break debugging?
Yes, there is a built-in way to have Visual Studio replace the ~remoteAppUrl symbolic reference token by the target URL of your choice.
From Visual Studio, access the "Publish..." option of the add-in
project, then click on the "Package the add-in" button
You can then enter the URL in the modal dialog that pops up
A build is then triggered that will inject the URL in the produced Manifest XML file
A Windows Explorer window will conveniently open to show the
produced file.
The following ways are not built-in but may be useful as well.
If you want this in an automated build, you need to specify values for the build parameters IsPackaging (True) and RemoteAppUrl.
If you want this in the standard Visual Studio Build, given that Visual Studio does not provide an easy way to specify Build parameters (see How to emulate /p msbuild parameter in Visual Studio build?) you will need to edit your project file to set the values of the same build parameters.
For instance like this:
...
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
...
<IsPackaging>True</IsPackaging>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
...
<RemoteAppUrl>https://localhost:44300</RemoteAppUrl>
</PropertyGroup>
...
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
...
<RemoteAppUrl>https://your.own.url</RemoteAppUrl>
</PropertyGroup>
...
Edit:
Visual Studio will not fill in the production URL, however you can copy your current manifest and replace the ~remoteAppUrl with your appropriate host manually, thus giving you a production and debug version of your add-in.
Original for posterity
~remoteAppUrl is a placeholder for wherever your files are hosted. For instance, if you have uploaded your add-in to an Azure Web App, your remote app url would be something along the lines of myWebApp.azurewebsites.net
I would like to bring the light on where the value comes from to replace the ~remoteAppUrl parameter. Add-in .csproj file contains the reference to the WebApp project:
<ItemGroup>
<ProjectReference Include="..\OutlookWebAddIn1Web\OutlookWebAddIn1Web.csproj">
<Project>{57AC33A8-A364-4084-B41F-319C5DBB9FB4}</Project>
<Name>OutlookWebAddIn1Web</Name>
<Private>True</Private>
<RoleType>Web</RoleType>
<OutputItemType>SharePointWebProjectOutput</OutputItemType>
<RoleName>OutlookWebAddIn1Web</RoleName>
<ReferenceOutputAssembly>False</ReferenceOutputAssembly>
</ProjectReference>
</ItemGroup>
I think it takes the URL from the WebApp .csproj file:

Using MSBuild Conditions on COMReferences

How can I specify a Condition for a COMReference in my *.csproj file? The following does not appear to work:
<COMReference Include="SomeComLib" Condition=" '$(Configuration)' == 'Debug' ">
...
</COMReference>
I have some COM references in a C# project in Visual Studio 2008. I would like them to automatically use non-isolation mode when I am in Debug, but automatically switch to Isolation mode when I make a Release build. I thought I could achieve this by specifying two different COMReferences in my *.csproj file, which are selected based on the Condition.
I think your strategy should work, but if not, you could also move the Condition to the ItemGroup that encloses the ComReferences.

How to get t4 files to build in visual studio?

When I build my c# solution the .tt files will not create the .cs file outputs. But if I right click the .tt files one at a time in solution explorer and select "Run Custom Tool" the .cs is generated, so the build tool setting is correct. What do I do to get the overall solution build to force the custom tool to run on the .tt files?
Paul, you can also generate code at build time with TextTransform.exe or Elton Stoneman's MSBuild task. Just keep in mind that behavior of the built-in directives, like assembly and include is different when T4 runs in Visual Studio vs. the command-line host.
Answering my own question, they are supposed to be generated at design time as per this discussion:
https://web.archive.org/web/20081227142303/http://www.olegsych.com/2008/02/t4-template-directive/
In Visual Studio 2017 (probably next versions too), you should add this in Pre-build event:
"$(DevEnvDir)TextTransform.exe" -out "$(ProjectDir)YourTemplate.cs" "$(ProjectDir)YourTemplate.tt"
p.s. The only solution that worked for me.
p.s.s. Change path to your template if it's located not in root project directory.
In Visual Studio 2013, I was able to get the .tt files to regenerate their targets by just adding these lines to the .csproj file:
<PropertyGroup>
<!-- Get the Visual Studio version – defaults to 10: -->
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
<!-- Keep the next element all on one line: -->
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
</PropertyGroup>
<!-- To enable build tasks on your development computer, install Modeling SDK for Visual Studio. https://www.microsoft.com/en-us/download/details.aspx?id=40754 -->
<Import Project="$(VSToolsPath)\TextTemplating\Microsoft.TextTemplating.targets" />
<!-- Run the Transform task at the start of every build -->
<PropertyGroup>
<TransformOnBuild>true</TransformOnBuild>
</PropertyGroup>
<!-- Overwrite files that are read-only, for example because they are not checked out -->
<PropertyGroup>
<OverwriteReadOnlyOutputFiles>true</OverwriteReadOnlyOutputFiles>
</PropertyGroup>
<!-- Transform every template every time -->
<PropertyGroup>
<TransformOutOfDateOnly>false</TransformOutOfDateOnly>
</PropertyGroup>
However, for this to work, you'll need to have installed the Modeling SDK for Visual Studio. I found all of this information, along with a more complete description of the options available, on this page: Code Generation in a Build Process.

Resources