Various cmdlets that can be used to dynamically define C# structs and methods for PInvoking native Win32 APIs.
Cmdlets included with this module are;
- Get-Win32ErrorMessage: Converts an Win32 Error code to a human readable error message.
- Import-Enum: Import an enum.
- Import-PInvokeMethod: Import a Win32 API function as a static method.
- Import-Struct: Import a struct for use in a Win32 API.
- New-DynamicModule: Simple helper function to create a dynamic module required by the above cmdlets.
As well as generating these cmdlets, importing this module will also define
the class PInvokeHelper.SafeNativeHandle
. This class can be used as a
substitution for System.IntPtr
in PInvoke methods that return a handle. The
benefits of using this is that you are able to guarantee the closing of the
native handle when the object is garbage collected or .Dispose()
is manually
called.
An example of how to use this for a PInvoke method would be;
$module_builder = New-DynamicModule -Name 'Process'
$type_builder = $module_builder.DefineType('NativeMethods', 'Public, Class')
Import-PInvokeMethod -TypeBuilder $type_builder `
-DllName 'Kernel32.dll' `
-Name 'OpenProcess' `
-ReturnType ([PInvokeHelper.SafeNativeHandle]) `
-ParameterTypes @([System.UInt32], [System.Boolean], [System.UInt32]) `
-SetLastError
$type_builder.CreateType() > $null
$h_process = [NativeMethods]::OpenProcess(
0x0400,
$false,
$PID
); $err_code = [System.Runtime.InteropServices.Marshal]::GetLastWin32Error()
if ($h_process.IsInvalid) {
$msg = Get-Win32ErrorMessage -ErrorCode $err_code
throw "Failed to open process '$PID': $msg"
}
try {
[System.Int64][System.IntPtr]$h_process
} finally {
# Not necessary but it is recommended to manually dispose the handle when
# it is no longer needed.
$h_process.Dispose()
}
These cmdlets have the following requirements
- PowerShell v3.0 or newer
- Windows PowerShell (not PowerShell Core)
- Windows Server 2008 R2/Windows 7 or newer
The easiest way to install this module is through PowerShellGet. This is installed by default with PowerShell 5 but can be added on PowerShell 3 or 4 by installing the MSI here.
Once installed, you can install this module by running;
# Install for all users
Install-Module -Name PInvokeHelper
# Install for only the current user
Install-Module -Name PInvokeHelper -Scope CurrentUser
If you wish to remove the module, just run
Uninstall-Module -Name PInvokeHelper
.
If you cannot use PowerShellGet, you can still install the module manually, here are some basic steps on how to do this;
- Download the latext zip from GitHub here
- Extract the zip
- Copy the folder
PInvokeHelper
inside the zip to a path that is set in$env:PSModulePath
. By default this could beC:\Program Files\WindowsPowerShell\Modules
orC:\Users\<user>\Documents\WindowsPowerShell\Modules
- Reopen PowerShell and unblock the downloaded files with
$path = (Get-Module -Name PInvokeHelper -ListAvailable).ModuleBase; Unblock-File -Path $path\*.psd1;
- Reopen PowerShell one more time and you can start using the cmdlets
Note: You are not limited to installing the module to those example paths, you can add a new entry to the environment variable PSModulePath
if you want to use another path.
Contributing is quite easy, fork this repo and submit a pull request with the
changes. To test out your changes locally you can just run .\build.ps1
in
PowerShell. This script will ensure all dependencies are installed before
running the test suite.
Note: this requires PowerShellGet or WMF 5 to be installed
- Fix up doc generation to product a correct markdown file