Windows桌面应用(WinUI 3、WPF、WinForms、控制台)有时需要在其托管框架外部调用 API。 此页面可帮助你了解何时发生,并选择正确的技术。
两个 API 图面,两种互操作模式
Windows通过两个主要 API 图面公开功能:
Win32 API — 从系统 DLL
user32.dll(、kernel32.dll等shell32.dll)导出的经典 C 样式函数。 这些操作涵盖低级别操作,例如窗口管理、文件 I/O、进程控制和硬件访问。 自Windows的最早版本以来,它们一直存在,并且仍然是访问许多没有托管等效功能的操作系统功能的方法。Windows 运行时 (WinRT) API — 随 Windows 8 一同推出的现代面向对象 API 体系(命名空间以
Windows.*开头)。 WinRT API 涵盖通知、媒体捕获、蓝牙、地理位置等领域。 大多数 WinRT API 可以直接从.NET访问,无需特别努力,但某些 API 在桌面应用中存在限制,或者需要窗口句柄(HWND)才能正常运行。
何时会遇到互操作
应用框架不直接公开特定 OS 功能时,通常需要互操作。 常见方案包括:
| 情景 | 哪个 API 表面 | Example |
|---|---|---|
| 自定义标题栏或窗口位置 | Win32 |
SetWindowPos、DwmExtendFrameIntoClientArea |
| 将窗口设置为“始终位于顶部”或控制 Z 顺序 | Win32 |
SetWindowPos 与 HWND_TOPMOST |
| 显示 WinUI 3 中的文件选取器或共享对话框 | WinRT (需要 HWND) |
FileOpenPicker 与 InitializeWithWindow |
| 读取系统内存或性能计数器 | Win32 |
GlobalMemoryStatusEx、QueryPerformanceCounter |
| 注册全局热键 | Win32 | RegisterHotKey |
| 发送 Toast 通知(未打包的应用) | WinRT(配合 App SDK) | AppNotificationManager |
在所有这些情况下,都会编写正常的 C# 代码,但通过互操作层调用Windows。 以下主题将引导你逐步了解各种方法。
决策指南
| 我需要... | 建议的方法 | Topic |
|---|---|---|
| 从 C 调用 Win32 API(user32、kernel32、shell32 等)# | 使用 CsWin32 源生成器 - 类型安全,无需手动编写的签名 | 从 C# 调用 Win32 API (CsWin32) |
| 使用窗口句柄初始化 WinRT 对象 (选取器、对话框、共享 UI) | 使用 .NET WinRT COM 互操作类(InitializeWithWindowWindowNative等) |
从 .NET 应用调用互操作 API |
| 检查 WinRT API 在 桌面(非 UWP)应用中是否正常工作 | 查阅限制和替代项列表 | 桌面应用中不支持 WinRT API |
| 请参阅使用 Win32 调用自定义窗口的完整 WinUI 3 示例 | 按照端到端演练指南操作 | 演练:具有 Win32 互操作功能的 WinUI 3 应用 |
快速流程图
Windows.*API 是否位于 WinRT 命名空间中?- 是→检查 桌面应用中不支持的 WinRT API 是否存在限制。 如果 API 需要窗口句柄,请参阅 .NET 应用中的互操作 API 调用。
- 没有→继续执行步骤 2。
它是 Win32/原生 API(在 Windows SDK 头文件中定义)吗?
- 是→使用 CsWin32 生成类型安全的 P/Invoke 绑定。
- 没有 → 它可能是 COM 接口或第三方本地库。 有关常规 P/Invoke 指导,请参阅.NET 与本机代码的互操作。