Last active
February 7, 2026 20:24
-
-
Save joshooaj/5b1bc3b44bd8c90ae5a3f761843aa987 to your computer and use it in GitHub Desktop.
Easily call the SetDllDirectory Win32 API function from PowerShell
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| function addDllDirectoryManager { | |
| $csharp = @' | |
| using System; | |
| using System.Text; | |
| using System.Runtime.InteropServices; | |
| public static class DllDirectoryManager | |
| { | |
| [DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)] | |
| [return: MarshalAs(UnmanagedType.Bool)] | |
| private static extern bool SetDllDirectory(string lpPathName); | |
| [DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)] | |
| private static extern uint GetDllDirectory(uint nBufferLength, StringBuilder lbBuffer); | |
| public static bool SetDirectory(string path) | |
| { | |
| if (SetDllDirectory(path)) return true; | |
| throw new Exception(string.Format("The call to SetDllDirectory failed. LastWin32Error = {0}", Marshal.GetLastWin32Error())); | |
| } | |
| public static string GetDirectory() | |
| { | |
| uint bufferLength = 260; | |
| var buffer = new StringBuilder((int)bufferLength); | |
| var result = GetDllDirectory(bufferLength, buffer); | |
| return result == 0 ? string.Empty : buffer.ToString(); | |
| } | |
| } | |
| '@ | |
| Add-Type -TypeDefinition $csharp | |
| } | |
| function Get-DllDirectory { | |
| <# | |
| .SYNOPSIS | |
| Retrieves the application-specific portion of the search path used to locate DLLs. | |
| .DESCRIPTION | |
| The Get-DllDirectory function retrieves the application-specific portion of | |
| the DLL search path that was previously set using Set-DllDirectory. This | |
| path is searched after the directory from which the application loaded, but | |
| before the system directory and other standard search locations. | |
| If no custom DLL directory has been set, or if the default search order has | |
| been restored, this function returns an empty string. | |
| .EXAMPLE | |
| Get-DllDirectory | |
| Returns the current application-specific DLL search path, or an empty string | |
| if none is set. | |
| .EXAMPLE | |
| Set-DllDirectory -Path "C:\MyLibs" | |
| $dllPath = Get-DllDirectory | |
| Write-Host "DLLs will be searched in: $dllPath" | |
| Sets a custom DLL directory and then retrieves it to confirm the setting. | |
| .OUTPUTS | |
| System.String | |
| Returns the application-specific DLL search path, or an empty string if no | |
| custom path is set or if the function fails. | |
| .NOTES | |
| See the Microsoft Win32 API documentation for GetDllDirectory below for more | |
| information. | |
| .LINK | |
| https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-getdlldirectorya | |
| #> | |
| [CmdletBinding()] | |
| [OutputType([string])] | |
| param() | |
| [DllDirectoryManager]::GetDirectory() | |
| } | |
| function Set-DllDirectory { | |
| <# | |
| .SYNOPSIS | |
| Adds the directory to the DLL search path for the current process. | |
| .DESCRIPTION | |
| The Set-DllDirectory function adds the specified directory to the search | |
| path used to locate DLLs for the current process. This is useful when | |
| working with native assemblies in PowerShell, as it allows you to load DLLs | |
| from a specific directory without having to change your current working | |
| directory. | |
| The function invokes the Windows SetDllDirectory API from kernel32.dll. When | |
| a directory is set using this function, the system searches for DLLs in the | |
| following order: | |
| 1. The directory from which the application loaded | |
| 2. The directory specified by the lpPathName parameter (this function) | |
| 3. The system directory | |
| 4. The 16-bit system directory | |
| 5. The Windows directory | |
| 6. The directories listed in the PATH environment variable | |
| .PARAMETER Path | |
| The path to the directory to add to the DLL search path. If a non-empty path | |
| is provided, it must exist and will be resolved to an absolute path. If an | |
| empty string is provided, the current directory is removed from the default | |
| DLL search order. | |
| .PARAMETER RestoreDefaults | |
| Restore the default DLL search order. This also restores safe DLL search | |
| mode based on the SafeDllSearchMode registry value. | |
| .EXAMPLE | |
| Set-DllDirectory -Path "C:\Program Files\MyApp\bin" | |
| Adds "C:\Program Files\MyApp\bin" to the DLL search path, allowing DLLs in | |
| that directory to be loaded without specifying the full path. | |
| .EXAMPLE | |
| Set-DllDirectory -Path .\lib | |
| Add-Type -Path .\lib\MyNativeWrapper.dll | |
| Adds the relative "lib" directory to the DLL search path, then loads a | |
| managed assembly that depends on native DLLs located in that same directory. | |
| .EXAMPLE | |
| Set-DllDirectory | |
| Removes the current directory from the default DLL search order. | |
| .EXAMPLE | |
| Set-DllDirectory -RestoreDefaults | |
| Restores the default DLL search order. | |
| .OUTPUTS | |
| System.Boolean | |
| Returns $true if the operation succeeded, or $false if it failed. | |
| .NOTES | |
| See the Microsoft Win32 API documentation for SetDllDirectory below for more | |
| information. | |
| .LINK | |
| https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-setdlldirectorya | |
| #> | |
| [CmdletBinding(DefaultParameterSetName = 'Path')] | |
| [OutputType([bool])] | |
| param ( | |
| [Parameter(Position = 0, ParameterSetName = 'Path')] | |
| [AllowEmptyString()] | |
| [string] | |
| $Path, | |
| [Parameter(ParameterSetName = 'RestoreDefaults')] | |
| [switch] | |
| $RestoreDefaults | |
| ) | |
| if ($Path.Length -gt 0) { | |
| $Path = (Resolve-Path $Path).Path | |
| } | |
| if ($RestoreDefaults) { | |
| [DllDirectoryManager]::SetDirectory($null) | |
| } else { | |
| [DllDirectoryManager]::SetDirectory($Path) | |
| } | |
| } | |
| addDllDirectoryManager | |
| Export-ModuleMember -Function Get-DllDirectory, Set-DllDirectory |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment