open System open System.Diagnostics open System.IO open System.Runtime.InteropServices #nowarn "51" // "The use of native pointers may result in unverifiable .NET IL code" -- // for arguments &&keyBlob, &&generatedSize in the call to StrongNameKeyGenEx module NativeMethods = [<DllImport("mscoree.dll")>] extern int StrongNameErrorInfo() [<DllImport("mscoree.dll")>] extern bool StrongNameKeyGenEx( [<MarshalAs(UnmanagedType.LPWStr)>]String wszKeyContainer, int dwFlags, int dwKeySize, IntPtr* ppbKeyBlob, int* pcbKeyBlob) [<DllImport("mscoree.dll")>] extern void StrongNameFreeBuffer(IntPtr pbMemory) let GetLastStrongNameError() = Marshal.GetExceptionForHR(NativeMethods.StrongNameErrorInfo()).Message let GenerateKeyPair (keyK : int) = if keyK < 0 || keyK > 2 then raise (new ArgumentOutOfRangeException("keyK", keyK, "Invalid Key Size -- should be 1 or 2")) // variables that hold the unmanaged key let mutable keyBlob = IntPtr.Zero let mutable generatedSize = 0 // create the key let createdKey = NativeMethods.StrongNameKeyGenEx( null, 0, 1024 * keyK, &&keyBlob, &&generatedSize) try // if there was a problem, translate it and report it if not createdKey || keyBlob = IntPtr.Zero then raise (new InvalidOperationException(GetLastStrongNameError())) // make sure the key size makes sense if generatedSize <= 0 || generatedSize > Int32.MaxValue then raise (new InvalidOperationException("InternalError")) // get the key into managed memory let key = Array.create generatedSize 0uy Marshal.Copy(keyBlob, key, 0, generatedSize) key finally // release the unmanaged memory the key resides in if keyBlob <> IntPtr.Zero then NativeMethods.StrongNameFreeBuffer(keyBlob) // path to generate new string name key let keypath = fsi.CommandLineArgs.[1] // write the key to the specified file if it is not already present if not (File.Exists(keypath)) then let key = GenerateKeyPair 1 use snkStream = new FileStream(keypath, FileMode.Create, FileAccess.Write) use snkWriter = new BinaryWriter(snkStream) snkWriter.Write(key)