只在发布构建期间使用强名称对程序集进行签名。

15

场景如下:我正在使用TeamCity构建我的解决方案,我不是以管理员身份运行构建帐户;因此我遇到了强名称密钥的问题。

我知道有一些解决方案,比如以管理员身份运行构建并在正确的容器中注册证书。

是否有任何方法可以仅在发布构建期间而不是在调试构建期间仅为解决方案文件签名程序集。或者是否有类似的解决方案?

我认为很奇怪,居然没有MSBuild参数可以设置程序集是否应该签名。因为如果你看一下csproj文件,那里有一个选项用于签名或未签名。


5
有一个名为 Msbuild 参数:msbuild (你的解决方案/项目) /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=yourKey.snk - SvenG
3个回答

15

另一个选项是编辑项目文件。默认情况下,在Visual Studio中启用程序集签名后,它将用于所有构建配置。项目文件包含以下类似的元素。

<PropertyGroup>
  <SignAssembly>true</SignAssembly>
</PropertyGroup>
<PropertyGroup>
  <AssemblyOriginatorKeyFile>YourKeyFile.pfx</AssemblyOriginatorKeyFile>
</PropertyGroup>

如果你只想在特定的构建配置(例如RELEASE)中签署程序集,你可以将<SignAssembly><AssemblyOriginatorKeyFile>放置在PropertyGroup元素中,并设置条件以标识您的构建配置。

因此,如果您想在发布构建期间签署程序集,则可以将项目文件更改为以下内容。

<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
  <!-- other element of this PropertyGroup -->
  <SignAssembly>true</SignAssembly>      
  <AssemblyOriginatorKeyFile>YourKeyFile.pfx</AssemblyOriginatorKeyFile>
</PropertyGroup>

注意: 当你更改项目文件为以下内容时,你不能在 Visual Studio 的项目属性中更改签名设置。这意味着在 Visual Studio 中,程序集的签名被禁用,即使你在 Visual Studio 中更改了构建配置。


7
以下是一种解决方案,其中程序集在Release配置中进行签名,但在Debug配置中未进行签名。 它使用项目的签名工具,而不使用[AssemblyKeyFile]属性。 基本上与Jehof的答案相同,只是用其他措辞表述。
  1. 在项目首选项的签名选项卡中设置项目以进行签名。
  2. 卸载该项目,并在XML编辑器中编辑它。 找到SignAssembly属性。 将该属性移动到两个配置相关的属性组中。 在Debug配置中,将属性设置为false。
这将看起来像这样:
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
    <!-- ... -->
    <SignAssembly>false</SignAssembly>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
    <SignAssembly>true</SignAssembly>
</PropertyGroup>

Visual Studio即使在更改构建配置时也能正常工作,但在“签名”选项卡中的“签署程序集”复选框除外。我使用Visual Studio 2008进行了测试。
注意事项: - 为使其正常工作,您需要删除[AssemblyKeyFile]属性。 - 如果您有[InternalsVisibleTo]属性,则需要维护两个版本,如下所示:
#if DEBUG
[assembly: InternalsVisibleTo("MyLib.NUnit")]
#else
[assembly: InternalsVisibleTo("MyLib.NUnit, PublicKey=<your public key>")]
#endif

换句话说,MyLib.NUnitRelease 配置下也必须被签名。

Visual Studio 2008似乎不支持以这种方式将SignAssembly属性设置为条件。由于Visual Studio 2008在不应该签署其中一个库时签署了其中一个库,反之亦然,因此在应用程序启动时会出现许多FileLoadException。然后我需要重新构建应用程序。不确定Visual Studio的后续版本是否也暴露了这种行为。 - tm1

4
您可以使用预处理指令:
#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

然后在Release配置中定义SIGN标志。

您必须使用sn.exe将密钥安装到密钥容器中。或者,您可以使用[AssemblykeyFile]指定路径。

#pragma抑制此警告


我应该把预处理指令放在哪里?我认为很奇怪的是没有一个MSBuild参数可以设置程序集是否应该签名。因为如果你看一下csproj文件,那里有一个选项用于签名或未签名。 - Felix
1
一般情况下可以在AssemblyInfo.cs文件中找到。不过可能也可以通过MSBuild实现,但我不太确定。 - SLaks

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接