/
RegistryProvider.fs
57 lines (50 loc) · 2.22 KB
/
RegistryProvider.fs
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
module FSharpx.TypeProviders.RegistryProvider
open Samples.FSharp.ProvidedTypes
open FSharpx.TypeProviders.Settings
open FSharpx.TypeProviders.DSL
open Microsoft.Win32
let getAccessibleSubkeys (registryKey:RegistryKey) =
registryKey.GetSubKeyNames()
|> Seq.choose (fun name ->
try
Some (registryKey.OpenSubKey name,name)
with
| enx -> None) // TODO: Handle access violation
let getAccessibleValues (registryKey:RegistryKey) =
registryKey.GetValueNames()
|> Seq.filter (System.String.IsNullOrEmpty >> not)
|> Seq.choose (fun name ->
try
Some (registryKey.GetValueKind name,name)
with
| enx -> None) // TODO: Handle access violation
let registryProperty<'a> key valueName =
provideProperty valueName typeof<'a> (fun args -> <@@ Registry.GetValue(key,valueName,"") :?> 'a @@>)
|> addSetter (fun args -> <@@ Registry.SetValue(key,valueName,(%%args.[0] : 'a)) @@>)
let rec createRegistryNode (registryKey:RegistryKey,subkeyName) () =
runtimeType<obj> subkeyName
|> hideOldMethods
|> addXmlDoc (sprintf "A strongly typed interface to '%s'" registryKey.Name)
|+> (fun () ->
literalField "Path" registryKey.Name
|> addXmlDoc (sprintf "Full path to '%s'" registryKey.Name))
|++!> (
registryKey
|> getAccessibleValues
|> Seq.map (fun (kind,name) ->
match kind with
// TODO: pattern matching
| RegistryValueKind.String -> registryProperty<string> registryKey.Name name
| _ -> registryProperty<obj> registryKey.Name name
|> makePropertyStatic))
|++> (
registryKey
|> getAccessibleSubkeys
|> Seq.map createRegistryNode)
let subNodes =
[Registry.ClassesRoot; Registry.CurrentConfig; Registry.CurrentUser;
Registry.LocalMachine; Registry.PerformanceData; Registry.Users]
|> Seq.map (fun key -> key,key.Name)
let typedRegistry =
erasedType<obj> thisAssembly rootNamespace "Registry"
|++> (Seq.map createRegistryNode subNodes)