在调用 win32 库的时候,小伙伴会遇到的问题是不知道对应的 win32 函数应该如何写。或者在网上抄了的代码的实现都有些诡异,想要自己封装发现工作量太大。好消息是官方将 PInvoke 库在 dotnet 基金会完全开源,包含了大量的 Win32 库,如 gdi32.dll 和 kernel32.dll 和 user32.dll 等
更新: 现在推荐 使用 CsWin32 库简化 Win32 函数调用逻辑
使用官方的库的优势是什么呢?第一个就是减少从网上复制粘贴有趣的 PInvoke 调用实现,其次是质量上能保底。虽然官方的实现也不够完美,例如 User32 的 GetWindowLong 方法依然有坑。但是因为此项目是在 github 开源 因此也会有大量的小伙伴入坑不断的修复,相对来说应该会比自己实现的好一些
现在官方已经将大量的 dll 进行了封装
已经实现的 dll 如下
Library | Package name | NuGet | Description |
---|---|---|---|
advapi32.dll | PInvoke.AdvApi32 |
Windows Advanced Services | |
bcrypt.dll | PInvoke.BCrypt |
Windows Cryptography API: Next Generation | |
cabinet.dll | PInvoke.Cabinet |
Cabinet API Functions | |
cfgmgr32.dll | PInvoke.CfgMgr32 |
Device and Driver Installation | |
crypt32.dll | PInvoke.Crypt32 |
Windows Cryptography API | |
DwmApi.dll | PInvoke.DwmApi |
Desktop Window Manager | |
fusion.dll | PInvoke.Fusion |
.NET Framework Fusion | |
gdi32.dll | PInvoke.Gdi32 |
Windows Graphics Device Interface | |
hid.dll | PInvoke.Hid |
Windows Human Interface Devices | |
iphlpapi.dll | PInvoke.IPHlpApi |
IP Helper | |
kernel32.dll | PInvoke.Kernel32 |
Windows Kernel API | |
magnification.dll | PInvoke.Magnification |
Windows Magnification API | |
mscoree.dll | PInvoke.MSCorEE |
.NET Framework CLR host | |
msi.dll | PInvoke.Msi |
Microsoft Installer | |
ncrypt.dll | PInvoke.NCrypt |
Windows Cryptography API: Next Generation | |
netapi32.dll | PInvoke.NetApi32 |
Network Management | |
newdev.dll | PInvoke.NewDev |
Device and Driver Installation | |
ntdll.dll | PInvoke.NTDll |
Windows NTDll | |
psapi.dll | PInvoke.Psapi |
Windows Process Status API | |
setupapi.dll | PInvoke.SetupApi |
Windows setup API | |
SHCore.dll | PInvoke.SHCore |
Windows Shell | |
shell32.dll | PInvoke.Shell32 |
Windows Shell | |
user32.dll | PInvoke.User32 |
Windows User Interface | |
userenv.dll | PInvoke.Userenv |
Windows User Environment | |
uxtheme.dll | PInvoke.UxTheme |
Windows Visual Styles | |
winusb.dll | PInvoke.WinUsb |
USB Driver | |
WtsApi32.dll | PInvoke.WtsApi32 |
Windows Remote Desktop Services |
那如何使用这个库?在 dotnet 里面使用库都是统一使用 NuGet 的方法,在 NuGet 里面按照自己的需要安装对应的库就可以了
如我想要调用 Kernel32 的 CreateProcess 方法,这个方法里面包含了很多结构体等的实现,如果要我自己去找这些结构体的实现,那么我也许会复制到坑代码。而在使用库的时候,我可以在 csproj 添加下面代码安装 NuGet 库
<ItemGroup>
<PackageReference Include="PInvoke.Kernel32" Version="0.6.49" />
</ItemGroup>
此时我就可以通过 Kernel32 类拿到对应的函数和结构体,请看代码
using PInvoke;
var startupInfo = new Kernel32.STARTUPINFO()
{
dwX = 300, // X
dwY = 300, // Y
dwXSize = 1000, // 宽度
dwYSize = 300, // 高度
dwFlags = Kernel32.StartupInfoFlags.STARTF_USESHOWWINDOW,
};
Kernel32.PROCESS_INFORMATION processInformation;
var creationFlag = Kernel32.CreateProcessFlags.NORMAL_PRIORITY_CLASS | Kernel32.CreateProcessFlags.CREATE_UNICODE_ENVIRONMENT;
var processSecurityAttribute = Kernel32.SECURITY_ATTRIBUTES.Create();
var threadAttribute = Kernel32.SECURITY_ATTRIBUTES.Create();
Kernel32.CreateProcess
(
lpApplicationName: @"C:\windows\notepad.exe",
lpCommandLine: " ",
lpProcessAttributes: processSecurityAttribute,
lpThreadAttributes: threadAttribute,
bInheritHandles: false,
dwCreationFlags: creationFlag,
lpEnvironment: IntPtr.Zero,
lpCurrentDirectory: null,
lpStartupInfo: ref startupInfo,
lpProcessInformation: out processInformation
);
Console.WriteLine(Kernel32.GetLastError());
var process = Process.GetProcessById(processInformation.dwProcessId);
Console.WriteLine(process.Id);
本文代码放在 github 欢迎小伙伴访问
本文会经常更新,请阅读原文: https://blog.lindexi.com/post/%E6%8E%A8%E8%8D%90%E5%AE%98%E6%96%B9%E5%BC%80%E6%BA%90-PInvoke-%E5%BA%93-%E5%8C%85%E5%90%AB%E5%A4%A7%E9%87%8F-win32-%E5%B0%81%E8%A3%85.html ,以避免陈旧错误知识的误导,同时有更好的阅读体验。
如果你想持续阅读我的最新博客,请点击 RSS 订阅,推荐使用RSS Stalker订阅博客,或者收藏我的博客导航
本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。欢迎转载、使用、重新发布,但务必保留文章署名林德熙(包含链接: https://blog.lindexi.com ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请 与我联系 。
无盈利,不卖课,做纯粹的技术博客
以下是广告时间
推荐关注 Edi.Wang 的公众号
欢迎进入 Eleven 老师组建的 .NET 社区
以上广告全是友情推广,无盈利