Next up... using dlls with Powershell. In the past we've used a number of methods including the DynamicWrapper.dll(Dynawrap). The problem I had with dynawrapper is it was so complicated and cryptic to read, especially after I hadn't looked at the code lately. I had read it was possible to import dlls in PS. So I decided to see if I could convert some of the dynawrap udfs to ps.

The first one I decided to translate was the SetKeyState UDF. And after much trial and error, I got it to work. (I can't say that about the second one, which will be the topic of another post)

You can find the $sig or signature to use the dll at http://www.pinvoke.net The C# sigs work with Powershell. Powershell uses the @ to define a multi-line string (called a here string) and all the powershell examples defined the sig this way. Unfortunately, the ActiveXPosh dll doesn't like here strings, so I had to break each line down and add the @CRLF.

The lines with the -memberdefintion basically take the $sig and assigns it to a var. The namespace and name values seem to be completely up to the coder, with (as far as I can tell) little to no value. I think they can contain just about any value, they just can't be the same value, and they have to be there.

function PSSetKeyState($Key, $toggle, optional $PSObject)
if $PSobject=""
$PSObject=CreateObject("SAPIEN.ActiveXPoSH")
endif
if $toggle="on"
$toggle="1"
endif
if $toggle="off"
$toggle="0"
endif
Select
Case $key="ScrollLock"
$key="0x91"
Case $key="CapsLock"
$key="0x14"
Case $key="NumLock"
$key="0x90"
endselect
if $PSObject.init(not 0)
$PSObject.Execute("$sig='" + '[DllImport("user32.dll")]' + @CRLF +
'public static extern short GetKeyState(int keyCode);' + "'")


$PSObject.Execute('$GetKeyState=Add-Type -memberDefinition $sig -namespace Win32Functions -name "Win32GetKeyState" -passThru')


$PSObject.Execute("$sig='" + '[DllImport("user32.dll")]' + @CRLF +
'public static extern void keybd_event(byte bVk, byte bScan, uint dwFlags, int dwExtraInfo);' + "'")


$PSObject.Execute('$keybdevent=Add-Type -memberDefinition $sig -namespace Win32Functions -name "Win32keybd_event" -passThru')


$PSSetKeyState=$PSObject.GetValue('$GetKeyState::GetKeyState(' + $key + ')')
if $PSSetKeyState<>$toggle
$PSObject.Execute('$keybdevent::keybd_event(' + $key + ',0,0,0)') ; Press the key
$PSObject.Execute('$keybdevent::keybd_event(' + $key + ',0,2,0)') ; Release the key
endif
endif
endfunction