关于本文
本文是通过利用生成式 AI 的自动化流程创建的。我们查阅了微软 Win32、COM 和 Windows Runtime 的官方文档,并以小示例的形式整理了它们在 PowerShell 中调用方式的差异,方便进行对比。验证状态:📘 已确认微软官方规范,未在 Windows 实机上验证
Windows API 并非一块铁板。从 PowerShell 的视角来看,可以发现三个不同的入口:Win32 是 P/Invoke,COM 是自动化对象(Automation object),而 WinRT 则是 Windows Runtime 类型。
首先了解这三个入口
Win32:Add-Type / P/Invoke
Add-Type @'
using System;
using System.Runtime.InteropServices;
public static class NativeDemo {
[DllImport("user32.dll")]
public static extern int GetSystemMetrics(int nIndex);
}
'@
"Win32 result = $([NativeDemo]::GetSystemMetrics(0))"
如果返回了屏幕宽度的像素值,说明你正在调用本机 DLL 的函数。
COM:ProgID
try {
$shell = New-Object -ComObject WScript.Shell
"COM type = $($shell.GetType().FullName)"
} finally {
if ($shell) { [void][Runtime.InteropServices.Marshal]::FinalReleaseComObject($shell) }
}
WinRT:Windows Runtime 类型
对于 WinRT,其类型和 API 在 PowerShell 中的使用条件各不相同。在此我们不会强行用一句话概括“所有内容都能调用”,而是先从微软的 Windows Runtime 文档中确认目标 API 的支持条件,然后再进行个别尝试。
重点关注这里
flowchart TD P[PowerShell] --> W[Win32 / PInvoke] P --> C[COM / Automation] P --> R[WinRT / Runtime metadata] W --> OS[Windows native API] C --> APP[OfficeやAutomation component] R --> MOD[Modern Windows API]
即使是相同的 Windows 功能,它们的调用约定、类型、生命周期以及错误呈现方式也各不相同。我们不应盲目追求“新旧优劣”,而应首先查看目标功能是通过哪种 API 模型公开的。
尝试修改一处
将 Win32 示例中的GetSystemMetrics(0)更改为GetSystemMetrics(1)。数值会从宽度变为高度,这表明整数常量决定了本机 API 的具体含义。
如果在工作中应用
在办公和 IT 系统的自动化中,操作 Excel 时使用 COM,检查 Windows 底层状态时使用 Win32,面对较新的 Windows 功能时考虑 WinRT,这可以作为一条技术选型指南来使用。当请求 AI 生成代码时,如果询问“这里使用的是 Win32、COM 还是 WinRT?”“是否需要 64 位类型或善后处理?”,将更有利于对生成的代码进行二次审查。
失败与边界
Win32 的指针/句柄不能忽视 32 位和 64 位的差异。
COM 需要确认对象生命周期以及进程残留情况。
WinRT 需要确认每个 API 的契约(contract)、操作系统版本以及来自 PowerShell/.NET 的投影(projection)。
切勿将 Windows App SDK/WinUI 3 与 WinRT 本身混为一谈。
