推荐官方开源 PInvoke 库 包含大量 win32 封装
在调用 win32 库的时候,小伙伴会遇到的问题是不知道对应的 win32 函数应该如何写。或者在网上抄了的代码的实现都有些诡异,想要自己封装发现工作量太大。好消息是官方将 PInvoke 库在 dotnet 基金会完全开源,包含了大量的 Win32 库,如 gdi32.dll 和 kernel32.dll 和 user32.dll 等
使用官方的库的优势是什么呢?第一个就是减少从网上复制粘贴有趣的 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:windowsnotepad.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 ,以避免陈旧错误知识的误导,同时有更好的阅读体验。
- 【腾讯云的1001种玩法】十分钟轻松搞定云架构之二:更好的网络
- 【腾讯云的1001种玩法】十分钟轻松搞定云架构之三:更大的存储
- Socket学习总结系列(一) -- IM & Socket
- 【腾讯云的1001种玩法】十分钟轻松搞定云架构 之四:替你分心的负载均衡
- 【腾讯云的1001种玩法】十分钟搞定云架构 · 什么是Bucket、什么是Object
- 【腾讯云的1001种玩法】十分钟轻松搞定云架构 · 负载均衡的最佳实践
- 【黑客浅析】像黑客一样思考
- 【腾讯云的1001种玩法】 十分钟轻松搞定云架构 · 负载均衡的几种均衡模式
- ASP.NET Web API的Controller是如何被创建的?
- 【腾讯云的1001种玩法】十分钟轻松搞定云架构:COS的两种上传模式
- 物流行业迎变革,云计算是基础,大数据是关键
- Socket学习总结系列(二) -- CocoaAsyncSocket
- 比特币勒索病毒肆虐,腾讯云安全专家给你支招
- HTML5 直播协议之 WebSocket 和 MSE
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Qt Designer设置背景图片、颜色不影响其它组件小技巧,控件层级设置,组件的继承,styleSheet设置样式。
- 搭建高可用的Harbor
- PyQt5 技术篇-控件长宽度、高度设置,组件大小设置,组件尺寸查看。
- python基本数据类型
- Python 技术篇-PyQt5动画功能演示,组件移动、尺寸改变动画演示
- 搭建k8s高可用集群 - 二进制方式
- DeepWalk:图网络与NLP的巧妙融合
- 基于kubeadm搭建k8s高可用集群
- 扑克牌例题与Collections工具类
- 快速了解Kubernetes
- PyQt5 技巧篇-按钮竖排显示方法,Qt Designer设置按钮竖排显示。
- Kafka集群监控、安全机制与最佳实践
- PyQt5 技术篇-设置输入框的placeholder方法,Qt Designer设置Line Edit、Text Edit编辑框的placeholder
- Kafka集群搭建及必知必会
- Python 技术篇-打开指定文件夹、目录、路径方法,运行指定文件演示