Visual Studio Hacks [Electronic resources]

Andrew Lockhart

نسخه متنی -صفحه : 172/ 85
نمايش فراداده

Hack 54. Quickly Sign Assemblies

Use a macro to sign an assembly with a strong name.

Strongly signing assemblies is one of the more tedious processes that you have to perform when developing with the .NET Framework. The normal process to strongly sign an assembly is as follows:

Create a .snk file using the sn.exe command prompt utility.

Move the .snk file into your project.

Point to the .snk file using the AssemblyKeyFile attribute.

This is the process that you will reproduce using a macro. Follow these steps to create a macro that will automatically sign assemblies for you:

Open the Macro IDE.

Create a new module.

Copy the following code into the module:

Imports EnvDTE
Imports System.Diagnostics
Imports Microsoft.VisualBasic
Imports Microsoft.VisualBasic.ControlChars
Imports System.Windows
Imports System.Windows.Forms
Imports System
Public Module Module1
Public Class WinWrapper
Implements System.Windows.Forms.IWin32Window
Overridable ReadOnly Property Handle( ) As System.IntPtr Implements _
System.Windows.Forms.IWin32Window.Handle
Get
Dim iptr As New System.IntPtr(DTE.MainWindow.HWnd)
Return iptr
End Get
End Property
End Class
Sub AddStrongNameToProject( )
Dim init_dir, outfile_name, outdirectory As String
Dim stemp, Macroprojname As String
Dim prjSolution As EnvDTE.Project
Dim prjVSProject As VSLangProj.VSProject
Dim openfile As Forms.FileDialog
Dim result As Forms.DialogResult
Dim snPath As Microsoft.Win32.RegistryKey
Dim winptr As WinWrapper
Dim myProj As EnvDTE.Project
Try
winptr = New WinWrapper( )
openfile = New Forms.OpenFileDialog( )
' set the initial directory to SystemDrive
init_dir = System.Environment.SystemDirectory( )
init_dir = Left(init_dir, InStr(init_dir, "\", _
CompareMethod.Text))
openfile.InitialDirectory = init_dir
If openfile.ShowDialog(winptr) = result.OK Then
' create the output filename
outfile_name = Right(openfile.FileName, _
Len(openfile.FileName) - _
Len(System.Environment.CurrentDirectory) - 1)
outfile_name = Left(outfile_name, InStr(outfile_name, ".", _
CompareMethod.Text) - 1)
outfile_name = outfile_name & ".dll"
' set the output directory to the VsMacros dir
outdirectory = Left(DTE.FullName, InStr(DTE.FullName, _
"devenv.exe", CompareMethod.Text) - 1)
outdirectory = outdirectory & "PublicAssemblies\"
snPath = _
Microsoft.Win32.Registry.LocalMachine.OpenSubKey( _
"software\microsoft\.NETFramework")
If Not snPath Is Nothing Then
stemp = snPath.GetValue("sdkinstallroot", ") & "bin"
End If
If stemp = "bin" Then
MsgBox("Unable to get sn.exe location from registry")
Exit Sub
End If
Dim strsnkFileName As String
strsnkFileName = openfile.FileName.Replace(".dll", ".snk")
Microsoft.VisualBasic.ChDir(stemp)
' Shell out to the CMD sn.exe file
Microsoft.VisualBasic.Shell("cmd /c sn.exe -k "" & _
strsnkFileName & "", AppWinStyle.NormalFocus, True)
' Add the snk file to the project
DTE.ItemOperations.AddExistingItem(strsnkFileName)
' Navigate to the AssemblyInfo file
Dim projItem As ProjectItem
projItem = DTE.Solution.FindProjectItem("AssemblyInfo.cs")
projItem.Open(EnvDTE.Constants.vsViewKindTextView).Activate( )
'Update the Assembly file with the location here
Dim ts As TextSelection = DTE.ActiveWindow.Selection
ts.SelectAll( )
Dim strNewStrongNameLoc As String
strNewStrongNameLoc = "[assembly: AssemblyKeyFile(@" & _
Chr(34) & strsnkFileName & Chr(34) & ")]"
ts.ReplacePattern("[assembly: AssemblyKeyFile("")]", _
strNewStrongNameLoc)
End If
Catch err As System.Exception
MsgBox(err.Message)
End Try
End Sub
End Module

Save and close the macro

Before running the macro, be sure to compile the project whose assembly you want to sign and make sure the project is selected in the Solution Explorer. When you run the macro, it will first prompt you for the location of your assembly. Then the macro will execute sn.exe for you, copy the .snk file to your project, and then populate the AssemblyKeyFile attribute for your assembly.

Once you have used this macro, you won't ever want to go back to manually signing assemblies again.

Thanks to Doug Doedens for writing this macro and posting at the C# Corner, which is located at http://www.c-sharpcorner.com/Code/2002/July/AddStrongNamesMacro.asp.