3 people like it.
Like the snippet!
Tiny F# EDSL for creating system / hardware IDs on Windows using WMI classes
A quick and reconfigurable way to create system or hardware IDs based on WMI Win32 classes for software licensing or similar purposes. (Perhaps a perfect fit for type providers in F# 3.0!)
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
|
// Part of PortFusion (http://portfusion.sourceforge.net)
// Test at tryfs.net :)
#r "System.Management.dll"
module SystemID =
open System
open System.Management
type ClassName = string
type PropertyKey = string
type PropertyValue = obj
type IDComponent = ClassName * PropertyKey []
type IDQueryResult = ClassName * (PropertyKey * PropertyValue)[][]
let private prefix = "Win32_" // !! Win32_* : CIM_*
let inline (!/) x = prefix + x
let internal qs (t:ClassName) (ps:PropertyKey[]) =
try use mos = new ManagementObjectSearcher("Select "+String.Join(",",ps)+" From "+t)
let col = mos.Get()
let arr = Seq.toArray
seq { for o in col do
yield seq { for p in o.Properties do yield p.Name, p.Value } |> arr } |> arr
with _ -> [|[||]|]
let internal fs = Array.map (Array.filter (snd >> (<>) null))
let internal gs (t, ps) = (t:ClassName).Substring prefix.Length, fs <| qs t ps
let query : IDComponent[] -> IDQueryResult[] = Array.map gs
module Conversions =
let inline private bytes (raw:string) = System.Text.Encoding.UTF8.GetBytes raw
let text rs =
let b = System.Text.StringBuilder()
rs |> Array.iter (sprintf "%A" >> b.AppendLine >> ignore)
b.ToString()
let sha (raw:string) =
let sha = System.Security.Cryptography.SHA1.Create()
raw |> bytes |> sha.ComputeHash |> Convert.ToBase64String
let hex = bytes >> BitConverter.ToString >> fun x -> x.Replace("-", "")
//
// Create custom system ID based on operating system serial number:
//
open SystemID
open SystemID.Conversions
let soft = [| !/"OperatingSystem", [| "SerialNumber" |] |] |> query
// val soft : IDQueryResult [] =
// [|("OperatingSystem",
// [|[|("SerialNumber", "92577-082-2500446-76172")|]|])|]
let softID = soft |> text |> sha |> hex
// val it : string = "6C6A4876452F306677496E692B4A2F486D743769346F647972646B3D"
//
// Create custom hardware ID based-on processor and BIOS information:
//
let hard = [|
!/"Processor", [| "Architecture"; "Caption" ; "Name" |]
!/"BIOS", [| "ReleaseDate" ; "SerialNumber" |]
|] |> query
// val hard : IDQueryResult [] =
// [|("Processor",
// [|[|("Architecture", 9us);
// ("Caption", "x64 Family 6 Model 26 Stepping 5");
// ("Name", "Intel(R) Xeon(R) CPU E5507 @ 2.27GHz")|]|]);
// ("BIOS",
// [|[|("ReleaseDate", "20090731000000.000000+000");
// ("SerialNumber", "00000000-0000-0000-0000-ec2170945350")|]|])|]
let hardID = hard |> text |> sha |> hex
// val it : string = "4F6B654F6353336E4D3638534C4E6C5545727174676A3032716E673D"
|
namespace System
namespace System.Management
type ClassName = string
Full name: Script.SystemID.ClassName
Multiple items
val string : value:'T -> string
Full name: Microsoft.FSharp.Core.Operators.string
--------------------
type string = String
Full name: Microsoft.FSharp.Core.string
type PropertyKey = string
Full name: Script.SystemID.PropertyKey
type PropertyValue = obj
Full name: Script.SystemID.PropertyValue
type obj = Object
Full name: Microsoft.FSharp.Core.obj
type IDComponent = ClassName * PropertyKey []
Full name: Script.SystemID.IDComponent
type IDQueryResult = ClassName * (PropertyKey * PropertyValue) [] []
Full name: Script.SystemID.IDQueryResult
val private prefix : string
Full name: Script.SystemID.prefix
val x : string
val internal qs : t:ClassName -> ps:PropertyKey [] -> (string * obj) [] []
Full name: Script.SystemID.qs
val t : ClassName
val ps : PropertyKey []
val mos : ManagementObjectSearcher
Multiple items
type ManagementObjectSearcher =
inherit Component
new : unit -> ManagementObjectSearcher + 6 overloads
member Get : unit -> ManagementObjectCollection + 1 overload
member Options : EnumerationOptions with get, set
member Query : ObjectQuery with get, set
member Scope : ManagementScope with get, set
Full name: System.Management.ManagementObjectSearcher
--------------------
ManagementObjectSearcher() : unit
ManagementObjectSearcher(queryString: string) : unit
ManagementObjectSearcher(query: ObjectQuery) : unit
ManagementObjectSearcher(scope: string, queryString: string) : unit
ManagementObjectSearcher(scope: ManagementScope, query: ObjectQuery) : unit
ManagementObjectSearcher(scope: string, queryString: string, options: EnumerationOptions) : unit
ManagementObjectSearcher(scope: ManagementScope, query: ObjectQuery, options: EnumerationOptions) : unit
Multiple items
type String =
new : value:char -> string + 7 overloads
member Chars : int -> char
member Clone : unit -> obj
member CompareTo : value:obj -> int + 1 overload
member Contains : value:string -> bool
member CopyTo : sourceIndex:int * destination:char[] * destinationIndex:int * count:int -> unit
member EndsWith : value:string -> bool + 2 overloads
member Equals : obj:obj -> bool + 2 overloads
member GetEnumerator : unit -> CharEnumerator
member GetHashCode : unit -> int
...
Full name: System.String
--------------------
String(value: nativeptr<char>) : unit
String(value: nativeptr<sbyte>) : unit
String(value: char []) : unit
String(c: char, count: int) : unit
String(value: nativeptr<char>, startIndex: int, length: int) : unit
String(value: nativeptr<sbyte>, startIndex: int, length: int) : unit
String(value: char [], startIndex: int, length: int) : unit
String(value: nativeptr<sbyte>, startIndex: int, length: int, enc: Text.Encoding) : unit
String.Join(separator: string, values: Collections.Generic.IEnumerable<string>) : string
String.Join<'T>(separator: string, values: Collections.Generic.IEnumerable<'T>) : string
String.Join(separator: string, [<ParamArray>] values: obj []) : string
String.Join(separator: string, [<ParamArray>] value: string []) : string
String.Join(separator: string, value: string [], startIndex: int, count: int) : string
val col : ManagementObjectCollection
ManagementObjectSearcher.Get() : ManagementObjectCollection
ManagementObjectSearcher.Get(watcher: ManagementOperationObserver) : unit
val arr : (seq<'a> -> 'a [])
module Seq
from Microsoft.FSharp.Collections
val toArray : source:seq<'T> -> 'T []
Full name: Microsoft.FSharp.Collections.Seq.toArray
Multiple items
val seq : sequence:seq<'T> -> seq<'T>
Full name: Microsoft.FSharp.Core.Operators.seq
--------------------
type seq<'T> = Collections.Generic.IEnumerable<'T>
Full name: Microsoft.FSharp.Collections.seq<_>
val o : ManagementBaseObject
val p : PropertyData
property ManagementBaseObject.Properties: PropertyDataCollection
property PropertyData.Name: string
property PropertyData.Value: obj
val internal fs : ((string * obj) [] [] -> (string * obj) [] [])
Full name: Script.SystemID.fs
type Array =
member Clone : unit -> obj
member CopyTo : array:Array * index:int -> unit + 1 overload
member GetEnumerator : unit -> IEnumerator
member GetLength : dimension:int -> int
member GetLongLength : dimension:int -> int64
member GetLowerBound : dimension:int -> int
member GetUpperBound : dimension:int -> int
member GetValue : [<ParamArray>] indices:int[] -> obj + 7 overloads
member Initialize : unit -> unit
member IsFixedSize : bool
...
Full name: System.Array
val map : mapping:('T -> 'U) -> array:'T [] -> 'U []
Full name: Microsoft.FSharp.Collections.Array.map
val filter : predicate:('T -> bool) -> array:'T [] -> 'T []
Full name: Microsoft.FSharp.Collections.Array.filter
val snd : tuple:('T1 * 'T2) -> 'T2
Full name: Microsoft.FSharp.Core.Operators.snd
val internal gs : t:ClassName * ps:PropertyKey [] -> string * (string * obj) [] []
Full name: Script.SystemID.gs
property String.Length: int
val query : (IDComponent [] -> IDQueryResult [])
Full name: Script.SystemID.query
module Conversions
from Script.SystemID
val private bytes : raw:string -> byte []
Full name: Script.SystemID.Conversions.bytes
val raw : string
namespace System.Text
type Encoding =
member BodyName : string
member Clone : unit -> obj
member CodePage : int
member DecoderFallback : DecoderFallback with get, set
member EncoderFallback : EncoderFallback with get, set
member EncodingName : string
member Equals : value:obj -> bool
member GetByteCount : chars:char[] -> int + 3 overloads
member GetBytes : chars:char[] -> byte[] + 5 overloads
member GetCharCount : bytes:byte[] -> int + 2 overloads
...
Full name: System.Text.Encoding
property Text.Encoding.UTF8: Text.Encoding
Text.Encoding.GetBytes(s: string) : byte []
Text.Encoding.GetBytes(chars: char []) : byte []
Text.Encoding.GetBytes(chars: char [], index: int, count: int) : byte []
Text.Encoding.GetBytes(chars: nativeptr<char>, charCount: int, bytes: nativeptr<byte>, byteCount: int) : int
Text.Encoding.GetBytes(s: string, charIndex: int, charCount: int, bytes: byte [], byteIndex: int) : int
Text.Encoding.GetBytes(chars: char [], charIndex: int, charCount: int, bytes: byte [], byteIndex: int) : int
val text : rs:'a [] -> string
Full name: Script.SystemID.Conversions.text
val rs : 'a []
val b : Text.StringBuilder
Multiple items
type StringBuilder =
new : unit -> StringBuilder + 5 overloads
member Append : value:string -> StringBuilder + 18 overloads
member AppendFormat : format:string * arg0:obj -> StringBuilder + 4 overloads
member AppendLine : unit -> StringBuilder + 1 overload
member Capacity : int with get, set
member Chars : int -> char with get, set
member Clear : unit -> StringBuilder
member CopyTo : sourceIndex:int * destination:char[] * destinationIndex:int * count:int -> unit
member EnsureCapacity : capacity:int -> int
member Equals : sb:StringBuilder -> bool
...
Full name: System.Text.StringBuilder
--------------------
Text.StringBuilder() : unit
Text.StringBuilder(capacity: int) : unit
Text.StringBuilder(value: string) : unit
Text.StringBuilder(value: string, capacity: int) : unit
Text.StringBuilder(capacity: int, maxCapacity: int) : unit
Text.StringBuilder(value: string, startIndex: int, length: int, capacity: int) : unit
val iter : action:('T -> unit) -> array:'T [] -> unit
Full name: Microsoft.FSharp.Collections.Array.iter
val sprintf : format:Printf.StringFormat<'T> -> 'T
Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.sprintf
Text.StringBuilder.AppendLine() : Text.StringBuilder
Text.StringBuilder.AppendLine(value: string) : Text.StringBuilder
val ignore : value:'T -> unit
Full name: Microsoft.FSharp.Core.Operators.ignore
Text.StringBuilder.ToString() : string
Text.StringBuilder.ToString(startIndex: int, length: int) : string
val sha : raw:string -> string
Full name: Script.SystemID.Conversions.sha
val sha : Security.Cryptography.SHA1
namespace System.Security
namespace System.Security.Cryptography
type SHA1 =
inherit HashAlgorithm
static member Create : unit -> SHA1 + 1 overload
Full name: System.Security.Cryptography.SHA1
Security.Cryptography.SHA1.Create() : Security.Cryptography.SHA1
Security.Cryptography.SHA1.Create(hashName: string) : Security.Cryptography.SHA1
Security.Cryptography.HashAlgorithm.ComputeHash(buffer: byte []) : byte []
Security.Cryptography.HashAlgorithm.ComputeHash(inputStream: IO.Stream) : byte []
Security.Cryptography.HashAlgorithm.ComputeHash(buffer: byte [], offset: int, count: int) : byte []
type Convert =
static val DBNull : obj
static member ChangeType : value:obj * typeCode:TypeCode -> obj + 3 overloads
static member FromBase64CharArray : inArray:char[] * offset:int * length:int -> byte[]
static member FromBase64String : s:string -> byte[]
static member GetTypeCode : value:obj -> TypeCode
static member IsDBNull : value:obj -> bool
static member ToBase64CharArray : inArray:byte[] * offsetIn:int * length:int * outArray:char[] * offsetOut:int -> int + 1 overload
static member ToBase64String : inArray:byte[] -> string + 3 overloads
static member ToBoolean : value:obj -> bool + 17 overloads
static member ToByte : value:obj -> byte + 18 overloads
...
Full name: System.Convert
Convert.ToBase64String(inArray: byte []) : string
Convert.ToBase64String(inArray: byte [], options: Base64FormattingOptions) : string
Convert.ToBase64String(inArray: byte [], offset: int, length: int) : string
Convert.ToBase64String(inArray: byte [], offset: int, length: int, options: Base64FormattingOptions) : string
val hex : (string -> string)
Full name: Script.SystemID.Conversions.hex
type BitConverter =
static val IsLittleEndian : bool
static member DoubleToInt64Bits : value:float -> int64
static member GetBytes : value:bool -> byte[] + 9 overloads
static member Int64BitsToDouble : value:int64 -> float
static member ToBoolean : value:byte[] * startIndex:int -> bool
static member ToChar : value:byte[] * startIndex:int -> char
static member ToDouble : value:byte[] * startIndex:int -> float
static member ToInt16 : value:byte[] * startIndex:int -> int16
static member ToInt32 : value:byte[] * startIndex:int -> int
static member ToInt64 : value:byte[] * startIndex:int -> int64
...
Full name: System.BitConverter
BitConverter.ToString(value: byte []) : string
BitConverter.ToString(value: byte [], startIndex: int) : string
BitConverter.ToString(value: byte [], startIndex: int, length: int) : string
String.Replace(oldValue: string, newValue: string) : string
String.Replace(oldChar: char, newChar: char) : string
module SystemID
from Script
val soft : IDQueryResult []
Full name: Script.soft
val softID : string
Full name: Script.softID
val hard : IDQueryResult []
Full name: Script.hard
val hardID : string
Full name: Script.hardID
More information