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

PowerShell中C#嵌套Struct引用及New-Object使用实践问询

问题解答

1. 嵌套结构体(MyClass内部的MyRECT)的正确引用方式

当结构体嵌套在类内部时,PowerShell中不能用[MyClass]::MyRECT作为New-Object的参数,因为New-Object需要的是类型的完全限定名称或者System.Type对象。对于.NET嵌套类型,其完全限定名称的格式是外层类型名+内层类型名(用+连接,而非.)。

正确的两种引用方式:

  • 使用类型名称字符串:
    $Rectangle = New-Object -TypeName MyClass+MyRECT
    
  • 先获取Type对象再实例化:
    $rectType = [MyClass+MyRECT]
    $Rectangle = New-Object $rectType
    

2. Struct是否必须与Class同级?

不需要。Struct完全可以嵌套在Class内部,这是.NET允许的类型组织方式,嵌套结构体可以访问外层类的私有成员(如果业务需要),也能起到封装作用,只是引用时要遵循嵌套类型的命名规则。

3. 调用GetWindowRect的两种实践建议

实践一:自定义RECT结构体 + 显式声明P/Invoke方法

这种方式灵活性高,适合需要直接操作RECT字段的场景:

Add-Type @"
using System;
using System.Runtime.InteropServices;

public class WindowApiHelper
{
    // 嵌套结构体
    public struct MyRECT
    {
        public int Left;
        public int Top;
        public int Right;
        public int Bottom;
    }

    [DllImport("user32.dll")]
    public static extern bool GetWindowRect(IntPtr hWnd, ref MyRECT lpRect);
}
"@

# 获取窗口句柄(示例:记事本窗口)
$notepadHandle = (Get-Process notepad).MainWindowHandle

# 实例化嵌套结构体
$rect = New-Object WindowApiHelper+MyRECT

# 调用API
[WindowApiHelper]::GetWindowRect($notepadHandle, [ref]$rect)

# 输出结果
Write-Host "窗口位置:Left=$($rect.Left), Top=$($rect.Top), Right=$($rect.Right), Bottom=$($rect.Bottom)"

实践二:利用.NET内置类型 + 内存分配读取

这种方式无需自定义结构体,直接用Marshal类分配非托管内存并读取数据,适合临时调用的场景:

Add-Type @"
using System;
using System.Runtime.InteropServices;

public class WindowApiHelper
{
    [DllImport("user32.dll")]
    public static extern bool GetWindowRect(IntPtr hWnd, IntPtr lpRect);
}
"@

# 获取窗口句柄
$notepadHandle = (Get-Process notepad).MainWindowHandle

# 分配非托管内存(RECT结构体大小为16字节:4个int,每个4字节)
$rectPtr = [System.Runtime.InteropServices.Marshal]::AllocHGlobal(16)

try {
    # 调用API
    if ([WindowApiHelper]::GetWindowRect($notepadHandle, $rectPtr)) {
        # 读取每个字段的值
        $left = [System.Runtime.InteropServices.Marshal]::ReadInt32($rectPtr, 0)
        $top = [System.Runtime.InteropServices.Marshal]::ReadInt32($rectPtr, 4)
        $right = [System.Runtime.InteropServices.Marshal]::ReadInt32($rectPtr, 8)
        $bottom = [System.Runtime.InteropServices.Marshal]::ReadInt32($rectPtr, 12)
        Write-Host "窗口位置:Left=$left, Top=$top, Right=$right, Bottom=$bottom"
    }
}
finally {
    # 释放非托管内存
    [System.Runtime.InteropServices.Marshal]::FreeHGlobal($rectPtr)
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 06:39:35