Skip to content

Instantly share code, notes, and snippets.

@neontorrent
Last active July 25, 2021 23:14
Show Gist options
  • Save neontorrent/55daf1308b0f9f5a1ee482000c7e90c6 to your computer and use it in GitHub Desktop.
Save neontorrent/55daf1308b0f9f5a1ee482000c7e90c6 to your computer and use it in GitHub Desktop.
ChangeDisplaySettings in C# and Powershell, pass byte array as struct pointer
# Version 1. Unsafe C Style
$cp = [System.CodeDom.Compiler.CompilerParameters]::new()
$cp.CompilerOptions = '/unsafe'
$Display = Add-Type -TypeDefinition @'
using System;
using System.Runtime.InteropServices;
public unsafe class Display
{
[DllImport("User32.dll")]
public static extern bool EnumDisplaySettings(
char* lpszDeviceName,
int iModeNum,
void* lpDevMode);
[DllImport("User32.dll")]
public static extern long ChangeDisplaySettings(
void* lpDevMode,
int flags);
static void CopyInt32(Int32 v, byte[] arr, int offset)
{
byte* vp = (byte*)&v;
for (int i = 0; i < sizeof(Int32); i++)
arr[offset + i] = vp[i];
}
public static byte[] ChangeResolution(int bits, int width, int height, int refreshRate)
{
byte[] dm = new byte[156];
fixed (void* dmPtr = dm)
{
Console.WriteLine(EnumDisplaySettings(null, -1, dmPtr));
CopyInt32(0x5c0000, dm, 40);
if (bits > 0)
CopyInt32(bits, dm, 104);
if (width > 0)
CopyInt32(width, dm, 108);
if (height > 0)
CopyInt32(height, dm, 112);
if (refreshRate > 0)
CopyInt32(refreshRate, dm, 120);
Console.WriteLine(ChangeDisplaySettings(dmPtr, 0));
}
return dm;
}
}
'@ -Pas -CompilerParameters $cp
# Version 2 - byte array marshal
$Display = Add-Type -TypeDefinition @'
using System;
using System.Runtime.InteropServices;
public class Display
{
[DllImport("User32.dll")]
public static extern bool EnumDisplaySettings(
[param: MarshalAs(UnmanagedType.LPTStr)]
string lpszDeviceName,
[param: MarshalAs(UnmanagedType.U4)]
int iModeNum,
[param: MarshalAs(UnmanagedType.LPArray)]
byte[] lpDevMode);
[DllImport("User32.dll")]
public static extern long ChangeDisplaySettings(
[param: MarshalAs(UnmanagedType.LPArray)]
byte[] lpDevMode,
[param: MarshalAs(UnmanagedType.U4)]
int flags);
static void CopyInt32(Int32 v, byte[] arr, int offset)
{
byte[] vBytes = BitConverter.GetBytes(v);
for (int i = 0; i < sizeof(Int32); i++)
arr[offset + i] = vBytes[i];
}
public static byte[] ChangeResolution(int bits, int width, int height, int refreshRate)
{
byte[] dm = new byte[156];
Console.WriteLine(EnumDisplaySettings(null, -1, dm));
CopyInt32(0x5c0000, dm, 40);
if (bits > 0)
CopyInt32(bits, dm, 104);
if (width > 0)
CopyInt32(width, dm, 108);
if (height > 0)
CopyInt32(height, dm, 112);
if (refreshRate > 0)
CopyInt32(refreshRate, dm, 120);
Console.WriteLine(ChangeDisplaySettings(dm, 0));
return dm;
}
}
'@ -Pas
# Execute
#$Display::ChangeResolution(0, 1280, 720, 60)
$Display::ChangeResolution(32, 1920, 1080, 144)
#$Display::ChangeResolution(0, 0, 0, 144)
#$host.ui.RawUI.ReadKey("NoEcho,IncludeKeyDown")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment