You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PowerShell 7中使用Add-Type cmdlet无法调用自定义.NET类问题

问题分析

PowerShell 7基于.NET Core/.NET 6+,和PowerShell 5.1依赖的.NET Framework在Windows Forms支持、API兼容性上存在差异,导致你的脚本出现以下核心问题:

  1. Windows Forms默认不可用:PowerShell 7不预装System.Windows.Forms组件,需手动启用兼容性模块。
  2. 进程模块获取API失效:.NET Core中Process.MainModule的行为与.NET Framework不同,原代码调用Process.GetCurrentProcess().MainModule.ModuleName会抛出异常,导致Add-Type加载自定义类型失败(无显式报错但类型未实际注册)。
  3. 钩子初始化逻辑不兼容:部分Win32 API在.NET Core环境下的调用方式需调整。
解决方案

步骤1:安装Windows Forms兼容性模块

在PowerShell 7中执行以下命令(需管理员权限):

Install-Module -Name WindowsFormsCompatibility -Scope CurrentUser -Force

步骤2:使用修复后的脚本

替换原脚本为以下兼容PowerShell 7的版本:

param(
  [string]$quitKey = "F16"
)

# 导入Windows Forms兼容性模块
Import-Module WindowsFormsCompatibility -Force

$keyLogger = @"
using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace KeyLogger{
  public static class Program {
    private const int WH_KEYBOARD_LL = 13;
    private const int WM_KEYDOWN = 0x0100;

    private static HookProc hookProc = HookCallback;
    private static IntPtr hookId = IntPtr.Zero;
    private static int keyCode = 0;

    [DllImport("user32.dll")]
    private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);

    [DllImport("user32.dll")]
    private static extern bool UnhookWindowsHookEx(IntPtr hhk);

    [DllImport("user32.dll")]
    private static extern IntPtr SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hMod, uint dwThreadId);

    [DllImport("kernel32.dll")]
    private static extern IntPtr GetModuleHandle(string lpModuleName);

    public static int WaitForKey() {
        hookId = SetHook(hookProc);
        Application.Run();
        UnhookWindowsHookEx(hookId);
        return keyCode;
    }

    private static IntPtr SetHook(HookProc hookProc) {
        // .NET Core环境下改用GetModuleHandle(null)获取当前进程主模块句柄
        IntPtr moduleHandle = GetModuleHandle(null);
        return SetWindowsHookEx(WH_KEYBOARD_LL, hookProc, moduleHandle, 0);
    }

    private delegate IntPtr HookProc(int nCode, IntPtr wParam, IntPtr lParam);

    private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam) {
        if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN) {
            keyCode = Marshal.ReadInt32(lParam);
            Application.Exit();
        }

        return CallNextHookEx(hookId, nCode, wParam, lParam);
    }
  }
}"@

# 加载自定义类型,确保引用Windows Forms程序集
Add-Type -TypeDefinition $keyLogger -ReferencedAssemblies "System.Windows.Forms"

while ($keyPress -ne $quitKey) {
  # 调整转换顺序:先获取原始按键码,再转为Keys枚举
  $keyCode = [KeyLogger.Program]::WaitForKey()
  $keyPress = [System.Windows.Forms.Keys]$keyCode
}

Write-Host "`nCaught $quitKey, ending recording..." -ForegroundColor Green

exit

关键修改说明

  • 新增Import-Module WindowsFormsCompatibility:启用PowerShell 7对Windows Forms的支持。
  • 替换进程模块获取逻辑:用GetModuleHandle(null)替代原Process.MainModule调用,避免.NET Core环境下的异常。
  • 调整按键转换顺序:拆分类型转换步骤,避免潜在的类型解析冲突。

内容的提问来源于stack exchange,提问作者ninbura

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 18:54:56