views:

507

answers:

3

I have a GlobalAssemblyInfo.cs file in the root of my solution, and I have something like the following entry in it to enable strong naming of my output assemblies.

#pragma warning disable 1699
[assembly : AssemblyKeyFile("..\\keyfile.snk")]
#pragma warning restore 1699

This approach has two drawbacks. Firstly, AssemblyKeyFileAttribute is deprecated, and so to avoid compilation warnings I need the pragma lines you see above. Secondly, I either need to keep all my projects at the same depth relative to the root to use the relative path, or use an absolute path, which dictates a checkout location on other users' machines (and on continuous integration servers/build agents).

Does anyone have a better solution than this, other than going through each project setting strong naming in the project file?

+1  A: 

Well, to avoid the path problem you can use [assembly:AssemblyKeyName(...)] instead (although IIRC this is also deprecated); use sn -i to install a named key. Each machine (that does builds) would need this key adding.

Other than that; yes, you'd probably need to edit the project files.

Marc Gravell
Agreed, that gets me round the second issue.
David M
+1  A: 

Those attributes for key signing were deprecated for good reason (information leakage), which is another reason to go the project route.

If you have a lot of projects it might be possible to set them via a recorded macro, or even directly manipulating the .csproj files (ensure they are unloaded from VS first).

Richard
+1  A: 

Richard makes a good point about information leakage - I've now found posts from Microsoft's .NET team where they describe this. So I've gone for his suggestion and come up with the following NAnt target:

  <target name="strongName" description="Strong names the output DLLs">
    <foreach item="File" property="filename">
      <in>
        <items>
          <include name="**/*.csproj"></include>
          <exclude name="**/*.Test.csproj"></include>
        </items>
      </in>
      <do>
        <echo message="${filename}" />
        <xmlpoke file="${filename}" xpath="/m:Project/m:PropertyGroup/m:SignAssembly" value="false">
          <namespaces>
            <namespace prefix="m" uri="http://schemas.microsoft.com/developer/msbuild/2003" />
          </namespaces>
        </xmlpoke>
        <xmlpoke file="${filename}" xpath="/m:Project/m:PropertyGroup/m:AssemblyOriginatorKeyFile" value="..\keyfile.snk">
          <namespaces>
            <namespace prefix="m" uri="http://schemas.microsoft.com/developer/msbuild/2003" />
          </namespaces>
        </xmlpoke>
      </do>
    </foreach>
  </target>

The <namespaces> element is necessary for the XPath to be resolved in the csproj file - note that this is for VS2008, and something slightly different may be needed in VS2005.

David M