Home > other >  How to use [Microsoft.Win32.RegistryValueKind]::TryParse
How to use [Microsoft.Win32.RegistryValueKind]::TryParse

Time:03-06

I can't seem to get [Microsoft.Win32.RegistryValueKind]::TryParse to work properly. Each solution I try always returns Cannot find an overload for "TryParse" and the argument count: "2". (or "3") despite the fact it shows the following.

PS C:\Windows\system32> [Microsoft.Win32.RegistryValueKind]::TryParse

OverloadDefinitions                                                                                                                          
-------------------                                                                                                                          
static bool TryParse[TEnum](string value, [ref] TEnum result)                                                                                
static bool TryParse[TEnum](string value, bool ignoreCase, [ref] TEnum result)

In my experience any of the following should normally work just fine.

[Microsoft.Win32.RegistryValueKind]::TryParse('dword',[ref]$Null)
[Microsoft.Win32.RegistryValueKind]::TryParse('dword',$true,[ref]$Null)

In the meantime I can just cast the string as [Microsoft.Win32.RegistryValueKind] but I am curious as to what I am doing wrong.

CodePudding user response:

The [Microsoft.Win32.RegistryValueKind]::TryParse() method by itself will return either $true or $false, depending if the parsing succeeded or not.

  • The first parameter is the string value you want parsed converted to one of the RegistryValueKind enum types.
  • The last parameter is the variable containing the RegistryValueKind type of choice.
    The method then tries to convert the given string value to that registry kind.
  • Optionally, there is an overload with a second parameter in between you can set to $true to have it work case-insensitive on the given string value.

example:

[Microsoft.Win32.RegistryValueKind]::TryParse('12345', [ref][Microsoft.Win32.RegistryValueKind]::DWord)

returns True because '12345' can be converted to integer DWord valuekind.

You can also read back the parsed value like this

$result = [Microsoft.Win32.RegistryValueKind]::DWord   # 4
if ([Microsoft.Win32.RegistryValueKind]::TryParse('12345', [ref]$result)) {
    Write-Host "The value can be stored as $result (DWord)"
}

Anyway, if your intention is to read registry values and try to determine if the RegistryKind of that entry is correct, I think the RegistryKey.GetValueKind() method would be easier to use

CodePudding user response:

TryParse is actually implemented by System.Enum, and is a generic method. It returns a bool whether the parse succeeded, and the second parameter is an out with the actual parse result.

You have a number of issues if you want to use TryParse.

Firstly, you cannot call a generic method directly in Powershell unless you are using PS 7.3 or above

[System.Enum]::TryParse<Microsoft.Win32.RegistryValueKind>('DWord', [ref]$prm)

For versions of Powershell which use .Net Core or .Net 5 (I don't if there are any), you could also use the non-generic version of TryParse

[System.Enum]::TryParse([Microsoft.Win32.RegistryValueKind], 'DWord', [ref]$prm)

Be that as it may, in earlier versions you need to use reflection.

$arrParams =  @('DWord', $null)

$method = ([System.Enum].GetMethods() | where {($_.Name -eq "TryParse") -and ($_.GetParameters().Length -eq 2) })[0].MakeGenericMethod(@([Microsoft.Win32.RegistryValueKind]))

$method.Invoke($null, $arrParams);

$arrParams[1]

Note that the string parameter is case-sensitive, and therefore must be 'DWord'

  • Related