Skip to content

Instantly share code, notes, and snippets.

@joshooaj
Last active February 7, 2026 20:24
Show Gist options
  • Select an option

  • Save joshooaj/5b1bc3b44bd8c90ae5a3f761843aa987 to your computer and use it in GitHub Desktop.

Select an option

Save joshooaj/5b1bc3b44bd8c90ae5a3f761843aa987 to your computer and use it in GitHub Desktop.
Easily call the SetDllDirectory Win32 API function from PowerShell
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