How can I programmatically create a .snk
file and save it to my desktop?
I understand everything but how to create the .snk
file from within my code and not opening the visual studio command prompt. But being able to click a button on my form and generate this key to the desktop.
Asked
Active
Viewed 796 times
1

Seyedraouf Modarresi
- 1,213
- 9
- 14

Swoomie
- 11
- 1
-
Take a look at: https://stackoverflow.com/questions/692565/how-do-you-programmatically-resign-a-net-assembly-with-a-strong-name It might give you some pointers – JayV May 31 '18 at 21:24
-
related, probably dup https://stackoverflow.com/questions/6183051/ – enkryptor May 31 '18 at 21:25
-
@enkryptor I have already looked at this and the code doesn't work. – Swoomie May 31 '18 at 21:34
-
@Swoomie mind adding the details to the question? – enkryptor May 31 '18 at 22:03
1 Answers
1
Here is some C# utility code that can create a valid .snk file:
Sample usage:
...
// write a .snk file
StrongNameUtilities.GenerateKeyFile("test.snk"); // default key size is 1024 bits
// reread an check it worked
var pk = StrongNameUtilities.GetPublicKey("test.snk");
...
Utility code:
public sealed class StrongNameUtilities
{
public static byte[] GetPublicKeyToken(byte[] publicKey)
{
if (publicKey == null)
throw new ArgumentNullException(nameof(publicKey));
var blob = IntPtr.Zero;
try
{
if (!StrongNameTokenFromPublicKey(publicKey, publicKey.Length, out blob, out var size))
throw new Win32Exception(StrongNameErrorInfo());
var bytes = new byte[size];
Marshal.Copy(blob, bytes, 0, size);
return bytes;
}
finally
{
if (blob != IntPtr.Zero)
{
StrongNameFreeBuffer(blob);
}
}
}
public static byte[] GetPublicKeyToken(string snkFile)
{
if (snkFile == null)
throw new ArgumentNullException(nameof(snkFile));
return GetPublicKeyToken(GetPublicKey(snkFile));
}
public static byte[] GetPublicKey(string snkFile)
{
if (snkFile == null)
throw new ArgumentNullException(nameof(snkFile));
var bytes = File.ReadAllBytes(snkFile);
var blob = IntPtr.Zero;
try
{
if (!StrongNameGetPublicKey(null, bytes, bytes.Length, out blob, out var size))
throw new Win32Exception(StrongNameErrorInfo());
var pkBlob = new byte[size];
Marshal.Copy(blob, pkBlob, 0, size);
return pkBlob;
}
finally
{
if (blob != IntPtr.Zero)
{
StrongNameFreeBuffer(blob);
}
}
}
public static void GenerateKeyFile(string snkFile, int keySizeInBits = 1024)
{
if (snkFile == null)
throw new ArgumentNullException(nameof(snkFile));
var bytes = GenerateKey(keySizeInBits);
File.WriteAllBytes(snkFile, bytes);
}
public static byte[] GenerateKey(int keySizeInBits = 1024)
{
if (!StrongNameKeyGenEx(null, 0, keySizeInBits, out var blob, out var size))
throw new Win32Exception(StrongNameErrorInfo());
try
{
var bytes = new byte[size];
Marshal.Copy(blob, bytes, 0, size);
return bytes;
}
finally
{
if (blob != IntPtr.Zero)
{
StrongNameFreeBuffer(blob);
}
}
}
[DllImport("mscoree")]
private extern static void StrongNameFreeBuffer(IntPtr pbMemory);
[DllImport("mscoree", CharSet = CharSet.Unicode)]
private static extern bool StrongNameGetPublicKey(
string szKeyContainer,
[MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] byte[] pbKeyBlob,
int cbKeyBlob,
out IntPtr ppbPublicKeyBlob,
out int pcbPublicKeyBlob);
[DllImport("mscoree")]
private static extern bool StrongNameTokenFromPublicKey(
[MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] byte[] pbPublicKeyBlob,
int cbPublicKeyBlob,
out IntPtr ppbStrongNameToken,
out int pcbStrongNameToken);
[DllImport("mscoree", CharSet = CharSet.Unicode)]
private static extern bool StrongNameKeyGenEx(string wszKeyContainer, int dwFlags, int dwKeySize, out IntPtr ppbKeyBlob, out int pcbKeyBlob);
[DllImport("mscoree")]
private static extern int StrongNameErrorInfo();
}

Simon Mourier
- 132,049
- 21
- 248
- 298