How can I disable code signing for debug builds in Visual Studio 2013?
Asked Answered
U

1

19

We recently upgraded Visual Studio from 2010 to 2013 and everything seems to be working the same as before except for one thing. In 2010 code signing was only performed when publishing the project, but in 2013 it wants to sign the output assembly every time we build the project.

I'm having issues trying to find any results online about this, everything only points to how to setup signing in the first place, not how to prevent it signing during normal debug builds.


I created a new project and started playing with the settings to determine what single setting may be triggering the signing requirement during normal builds. In the project properties page under the Security tab, if the "Enable ClickOnce security settings" check box is checked then 2013 requires the signing step but 2010 doesn't seem to have that requirement.

I still need to confirm whether or not this is the single decision point for this behavior.


Confirmed.

I created two solutions each with a single empty WinForms application. One solution was created in Visual Studio 2010 and the other was created in Visual Studio 2013. I went into the project properties on each and enabled signing via the signing tab and then checked the "Enable ClickOnce security settings" in the security tab with "This is a full trust application". Note that the projects are being signed with a certificate on a smart-card which is PIN enabled.

VS 2013 prompts for the smart card PIN during a normal build in debug mode, 2010 does not. Now the question is basically why there is a difference between the two versions and how to fix this in 2013 to behave like 2010.


I'm including the project files for the test solutions I created below. Comparing the differences doesn't point to anything obviously different. I also attempted to change the VS 2013 project to target the same framework as the VS 2010 project to minimize the differences between the projects - this doesn't change the behavior difference.

Visual Studio 2010 Project File

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    <Platform Condition=" '$(Platform)' == '' ">x86</Platform>
    <ProductVersion>8.0.30703</ProductVersion>
    <SchemaVersion>2.0</SchemaVersion>
    <ProjectGuid>{E31DA60C-E444-4E34-AF6D-5B4588CC1F8E}</ProjectGuid>
    <OutputType>WinExe</OutputType>
    <AppDesignerFolder>Properties</AppDesignerFolder>
    <RootNamespace>SigningTest1</RootNamespace>
    <AssemblyName>SigningTest1</AssemblyName>
    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
    <TargetFrameworkProfile>Client</TargetFrameworkProfile>
    <FileAlignment>512</FileAlignment>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
    <PlatformTarget>x86</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|x86' ">
    <PlatformTarget>x86</PlatformTarget>
    <DebugType>pdbonly</DebugType>
    <Optimize>true</Optimize>
    <OutputPath>bin\Release\</OutputPath>
    <DefineConstants>TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
  </PropertyGroup>
  <PropertyGroup>
    <SignManifests>true</SignManifests>
  </PropertyGroup>
  <PropertyGroup>
    <ManifestCertificateThumbprint>22E252B5076264F4F2CD88983A9053D554CCD185</ManifestCertificateThumbprint>
  </PropertyGroup>
  <PropertyGroup>
    <TargetZone>LocalIntranet</TargetZone>
  </PropertyGroup>
  <PropertyGroup>
    <GenerateManifests>true</GenerateManifests>
  </PropertyGroup>
  <PropertyGroup>
    <ApplicationManifest>Properties\app.manifest</ApplicationManifest>
  </PropertyGroup>
  <ItemGroup>
    <Reference Include="System" />
    <Reference Include="System.Core" />
    <Reference Include="System.Xml.Linq" />
    <Reference Include="System.Data.DataSetExtensions" />
    <Reference Include="Microsoft.CSharp" />
    <Reference Include="System.Data" />
    <Reference Include="System.Deployment" />
    <Reference Include="System.Drawing" />
    <Reference Include="System.Windows.Forms" />
    <Reference Include="System.Xml" />
  </ItemGroup>
  <ItemGroup>
    <Compile Include="Form1.cs">
      <SubType>Form</SubType>
    </Compile>
    <Compile Include="Form1.Designer.cs">
      <DependentUpon>Form1.cs</DependentUpon>
    </Compile>
    <Compile Include="Program.cs" />
    <Compile Include="Properties\AssemblyInfo.cs" />
    <EmbeddedResource Include="Properties\Resources.resx">
      <Generator>ResXFileCodeGenerator</Generator>
      <LastGenOutput>Resources.Designer.cs</LastGenOutput>
      <SubType>Designer</SubType>
    </EmbeddedResource>
    <Compile Include="Properties\Resources.Designer.cs">
      <AutoGen>True</AutoGen>
      <DependentUpon>Resources.resx</DependentUpon>
    </Compile>
    <None Include="Properties\app.manifest" />
    <None Include="Properties\Settings.settings">
      <Generator>SettingsSingleFileGenerator</Generator>
      <LastGenOutput>Settings.Designer.cs</LastGenOutput>
    </None>
    <Compile Include="Properties\Settings.Designer.cs">
      <AutoGen>True</AutoGen>
      <DependentUpon>Settings.settings</DependentUpon>
      <DesignTimeSharedInput>True</DesignTimeSharedInput>
    </Compile>
  </ItemGroup>
  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
       Other similar extension points exist, see Microsoft.Common.targets.
  <Target Name="BeforeBuild">
  </Target>
  <Target Name="AfterBuild">
  </Target>
  -->
</Project>

Visual Studio 2013 Project File

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
    <ProjectGuid>{732A657C-452D-4942-8832-89A14314739C}</ProjectGuid>
    <OutputType>WinExe</OutputType>
    <AppDesignerFolder>Properties</AppDesignerFolder>
    <RootNamespace>SigningTest2013</RootNamespace>
    <AssemblyName>SigningTest2013</AssemblyName>
    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
    <TargetFrameworkProfile>Client</TargetFrameworkProfile>
    <FileAlignment>512</FileAlignment>
  </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>
  <PropertyGroup>
    <SignManifests>true</SignManifests>
  </PropertyGroup>
  <PropertyGroup>
    <ManifestCertificateThumbprint>22E252B5076264F4F2CD88983A9053D554CCD185</ManifestCertificateThumbprint>
  </PropertyGroup>
  <PropertyGroup>
    <TargetZone>LocalIntranet</TargetZone>
  </PropertyGroup>
  <PropertyGroup>
    <GenerateManifests>true</GenerateManifests>
  </PropertyGroup>
  <PropertyGroup>
    <ApplicationManifest>Properties\app.manifest</ApplicationManifest>
  </PropertyGroup>
  <ItemGroup>
    <Reference Include="System" />
    <Reference Include="System.Core" />
    <Reference Include="System.Xml.Linq" />
    <Reference Include="System.Data.DataSetExtensions" />
    <Reference Include="Microsoft.CSharp" />
    <Reference Include="System.Data" />
    <Reference Include="System.Deployment" />
    <Reference Include="System.Drawing" />
    <Reference Include="System.Windows.Forms" />
    <Reference Include="System.Xml" />
  </ItemGroup>
  <ItemGroup>
    <Compile Include="Form1.cs">
      <SubType>Form</SubType>
    </Compile>
    <Compile Include="Form1.Designer.cs">
      <DependentUpon>Form1.cs</DependentUpon>
    </Compile>
    <Compile Include="Program.cs" />
    <Compile Include="Properties\AssemblyInfo.cs" />
    <EmbeddedResource Include="Properties\Resources.resx">
      <Generator>ResXFileCodeGenerator</Generator>
      <LastGenOutput>Resources.Designer.cs</LastGenOutput>
      <SubType>Designer</SubType>
    </EmbeddedResource>
    <Compile Include="Properties\Resources.Designer.cs">
      <AutoGen>True</AutoGen>
      <DependentUpon>Resources.resx</DependentUpon>
      <DesignTime>True</DesignTime>
    </Compile>
    <None Include="Properties\app.manifest" />
    <None Include="Properties\Settings.settings">
      <Generator>SettingsSingleFileGenerator</Generator>
      <LastGenOutput>Settings.Designer.cs</LastGenOutput>
    </None>
    <Compile Include="Properties\Settings.Designer.cs">
      <AutoGen>True</AutoGen>
      <DependentUpon>Settings.settings</DependentUpon>
      <DesignTimeSharedInput>True</DesignTimeSharedInput>
    </Compile>
  </ItemGroup>
  <ItemGroup>
    <None Include="App.config" />
  </ItemGroup>
  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
       Other similar extension points exist, see Microsoft.Common.targets.
  <Target Name="BeforeBuild">
  </Target>
  <Target Name="AfterBuild">
  </Target>
  -->
</Project>

I'll attempt to upload a full solution for each when I can. I'm unable to do it from my current computer due to most file sharing websites being blocked.

Urushiol answered 17/2, 2015 at 18:24 Comment(7)
I have no post-build events in the project properties. We have seen this happening for three different solutions on two different computers.Urushiol
@@Urushiol Have you tried Project Designer, click the Security tab,Click the Advanced button.Select the Debug this application with the selected permission set check box, and then click OK.?Garrido
Could you share both project files somewhere? I mean, the two projects (and solutions) you created to reproduce and compare both VS2010 and VS2013 behaviors. If you open the project files with a simple text editor (Notepad might do), you will be able to compare them and maybe determine which project properties might be affecting the signing behavior.Thence
@LeandroTaset I've included the project file (csproj) for each project in my question. Unable to upload full solution due to most upload sites being blocked where I'm currently at.Urushiol
Well, there are minor differences between both project files. They are close to nothing, actually. Sadly, I can't do my own tweaking and testing around here right now, but I would bet good money (if I had it) about the project property <SignManifests> being your best clue about solving the mystery. How about moving its definition inside the debug and release sections and setting its value to false and true, respectively?Thence
@LeandroTaset Moving the <SignManifests> property like you suggested does give me the behavior I want. It causes the VS2013 project properties window to show an unchecked option for 'Sign the ClickOnce manifests' under the signing tab, but it does still prompt for signing when compiling in release (which isn't nearly as annoying) which isn't the same behavior which 2010 has (where it only prompts for signing when you actually are publishing ClickOnce application). If you'd like to post an actual answer for rep, this may be the best I can expect - otherwise I'll community wiki the solution.Urushiol
@Anthony: That's good to hear. Signing only for release was the behavior I intended. To make it only for publish, I guess you'd have to delve into tweaking some build tasks by yourself. I would give an answer if I had true insight of what's going on, but it was only a guess. Anyway, it's still a good thing that you were able to (somewhat) solve it for this particular scenario of yours. Go ahead and make it a community wiki, it is fine by me. Maybe some others can share a thorough explanation on the matter.Thence
U
19

This post contains the best solution found so far for the change in behavior. The solution was suggested by Leandro Taset in a comment to the original question:

For the project which requires code signing, open its associated .csproj file. You should be able to find a SignManifests node inside of a PropertyGroup node listed in that file listed as follows:

<PropertyGroup>
  <SignManifests>true</SignManifests>
</PropertyGroup>

This property shows up in both the VS2010 and VS2013 project files and is listed at the project scope. You should be able to find two different Property Group nodes that look similar to the following:

<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
  <!-- There may be several properties already in the PropertyGroup node -->
</PropertyGroup>

<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
  <!-- There may be several properties already in the PropertyGroup node -->
</PropertyGroup>

These PropertyGroup nodes define project properties which are conditionally applied based on the current configuration and platform being targeted when you build the project.

You'll want to remove the SignManifests node you first found and place a new SignManifests node in each of the conditional PropertyGroup nodes:

<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
  <!--  -->
  <SignManifests>false</SignManifests>
</PropertyGroup>

<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
  <!--  -->
  <SignManifests>true</SignManifests>
</PropertyGroup>

This will cause VS2013 to behave a little better. During Release builds (well, in the example Release builds targeting AnyCPU) VS2013 will attempt to sign the manifest and in Debug modes it will not.

A couple caveats to this solution:

  1. This isn't exactly how VS2010 behaves when ClickOnce signing is enabled. VS2010 will only sign during ClickOnce publishing, it doesn't sign during a build (regardless of the configuration and target platform).
  2. If you open the Signing tab of the project properties in VS2013 it will appear that ClickOnce signing is not enabled (regardless of the configuration and target platform). Don't let this fool you, it will still property sign during Release builds. Checking the checkbox on this tab will re-add the SignManifests node at the Project level without any conditionals on it putting us back where we started. Changing project settings in other tabs doesn't appear re-add the node, so you're free to make needed project property changes elsewhere.
Urushiol answered 17/2, 2015 at 18:24 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.