Skip to content

Instantly share code, notes, and snippets.

@rickbrew
Last active October 22, 2021 15:29
Show Gist options
  • Save rickbrew/4790d0a032040e3809bbb1f5839afe6c to your computer and use it in GitHub Desktop.
Save rickbrew/4790d0a032040e3809bbb1f5839afe6c to your computer and use it in GitHub Desktop.
// Idea 1: SHELLEXECUTEINFOW with nested structs, Windows is flat
public static class SHELLEXECUTEINFOW
{
[StructLayout(..., Pack = 1)]
public struct X86 { ... }
[StructLayout(...)]
public struct X64 { ... }
[StructLayout(...)]
public struct Arm64 { ... }
}
public static class Windows
{
[DllImport("shell32", ExactSpelling = true, SetLastError = true)]
public unsafe static extern int ShellExecuteExW(SHELLEXECUTEINFOW.X86* pExecInfo);
[DllImport("shell32", ExactSpelling = true, SetLastError = true)]
public unsafe static extern int ShellExecuteExW(SHELLEXECUTEINFOW.X64* pExecInfo);
[DllImport("shell32", ExactSpelling = true, SetLastError = true)]
public unsafe static extern int ShellExecuteExW(SHELLEXECUTEINFOW.ARM64* pExecInfo);
}
// Idea 2: SHELLEXECUTEINFOW with nested structs (same as above), and Windows also. This also provides a pattern for dispatching anything else in Windows (e.g. consts) that may need arch-specific differences
public static class Windows
{
public static class X86
{
[DllImport("shell32", ExactSpelling = true, SetLastError = true)]
public unsafe static extern int ShellExecuteExW(SHELLEXECUTEINFOW.X86* pExecInfo);
}
public static class X64
{
[DllImport("shell32", ExactSpelling = true, SetLastError = true)]
public unsafe static extern int ShellExecuteExW(SHELLEXECUTEINFOW.X64* pExecInfo);
}
public static class Arm64
{
[DllImport("shell32", ExactSpelling = true, SetLastError = true)]
public unsafe static extern int ShellExecuteExW(SHELLEXECUTEINFOW.ARM64* pExecInfo);
}
}
// Idea 3 ... use interfaces to simplify something
namespace TerraFX.Interop
{
public unsafe interface SHELLEXECUTEINFOW
{
ref uint cbSize { get; }
ref uint fMask { get; }
ref IntPtr hwnd { get; }
ref ushort* lpVerb { get; }
ref ushort* lpFile { get; }
ref ushort* lpParameters { get; }
ref ushort* lpDirectory { get; }
ref int nShow { get; }
ref IntPtr hInstApp { get; }
ref void* lpIDList { get; }
ref ushort* lpClass { get; }
ref IntPtr hkeyClass { get; }
ref uint dwHotKey { get; }
ref IntPtr hIcon { get; }
ref IntPtr hMonitor { get; }
ref IntPtr hProcess { get; }
public struct X64 : SHELLEXECUTEINFOW
{
...
}
}
public static class Windows
{
[DllImport("shell32", ExactSpelling = true, SetLastError = true)]
public unsafe static extern int ShellExecuteExW(SHELLEXECUTEINFOW.X86* pExecInfo);
[DllImport("shell32", ExactSpelling = true, SetLastError = true)]
public unsafe static extern int ShellExecuteExW(SHELLEXECUTEINFOW.X64* pExecInfo);
[DllImport("shell32", ExactSpelling = true, SetLastError = true)]
public unsafe static extern int ShellExecuteExW(SHELLEXECUTEINFOW.ARM64* pExecInfo);
public unsafe static int ShellExecuteExW<TSHELLEXECUTEINFOW>(TSHELLEXECUTEINFOW* pExecInfo)
where TSHELLEXECUTEINFOW : unmanaged, SHELLEXECUTEINFOW
{
return _ShellExecuteExW(pExecInfo);
[DllImport("shell32", ExactSpelling = true, SetLastError = true)]
unsafe static extern int _ShellExecuteExW(void* pExecInfo);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment