如何在 Visual Studio 2013 中禁用调试版本的代码签名?

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

我们最近将 Visual Studio 从 2010 升级到 2013,除一件事外,一切似乎都和以前一样工作。 2010年代码签名只在发布项目时进行,2013年每次构建项目时都要对输出程序集进行签名。

我在尝试在线查找与此相关的任何结果时遇到问题,所有内容仅指向如何首先设置签名,而不是如何在正常调试构建期间防止签名。


我创建了一个新项目并开始使用这些设置来确定在正常构建期间哪个设置可能会触发签名要求。在安全选项卡下的项目属性页面中,如果选中 "Enable ClickOnce security settings" 复选框,则 2013 需要签名步骤,但 2010 似乎没有该要求。

我还需要确认这是否是该行为的唯一决策点。


已确认。

我创建了两个解决方案,每个解决方案都有一个空的 WinForms 应用程序。一个解决方案是在 Visual Studio 2010 年创建的,另一个是在 Visual Studio 2013 年创建的。我进入了每个项目的属性并通过签名选项卡启用了签名,然后检查了 "Enable ClickOnce security settings" "This is a full trust application" 的安全选项卡。请注意,项目正在使用启用 PIN 的智能卡上的证书进行签名。

VS 2013 在调试模式下的正常构建期间提示输入智能卡 PIN,而 2010 不会。现在的问题基本上是为什么这两个版本之间存在差异以及如何在 2013 年修复此问题以使其表现得像 2010 年一样。


我在下面包含了我创建的测试解决方案的项目文件。比较差异并不能说明任何明显不同。我还尝试将 VS 2013 项目更改为以与 VS 2010 项目相同的框架为目标,以最大限度地减少项目之间的差异 - 这不会改变行为差异。

Visual Studio 2010 项目文件

<?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 项目文件

<?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>

我会尽可能为每个问题上传完整的解决方案。由于大多数文件共享网站被阻止,我无法从我当前的计算机执行此操作。

此 post 包含迄今为止针对行为更改找到的最佳解决方案。 Leandro Taset in a :

建议的解决方案

对于需要代码签名的项目,打开其关联的 .csproj 文件。您应该能够在该文件中列出的 PropertyGroup 节点内找到一个 SignManifests 节点,如下所示:

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

此 属性 出现在 VS2010 和 VS2013 项目文件中,并列在项目范围内。您应该能够找到两个不同的 Property Group 节点,它们看起来类似于以下内容:

<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>

这些 PropertyGroup 节点定义项目属性,这些属性根据当前配置和构建项目时的目标平台有条件地应用。

您需要删除您第一次找到的 SignManifests 节点,并在每个条件 PropertyGroup 节点中放置一个新的 SignManifests 节点:

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

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

这将使 VS2013 的表现更好一些。在发布构建期间(嗯,在示例发布构建目标 AnyCPU 中)VS2013 将尝试签署清单,而在调试模式下它不会。

关于此解决方案的几点注意事项:

  1. 这并不是启用 ClickOnce 签名时 VS2010 的行为方式。 VS2010 只会在 ClickOnce 发布期间签名,它不会在构建期间签名(无论配置和目标平台如何)。
  2. 如果您在 VS2013 中打开项目属性的签名选项卡,将显示未启用 ClickOnce 签名(无论配置和目标平台如何)。不要被这个骗了,它仍然会 属性 在发布构建期间签名。选中此选项卡上的复选框将在 Project 级别重新添加 SignManifests 节点,没有任何条件,让我们回到开始的地方。在其他选项卡中更改项目设置不会出现重新添加节点,因此您可以自由地在其他地方进行所需的项目 属性 更改。