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

C#中导入Shell32.dll的ShellAboutA函数报错求助

解决ShellAboutA P/Invoke的两个错误

错误1:MarshalDirectiveException 原因及修复

你遇到的Cannot marshal 'parameter #1': Generic types cannot be marshaled错误,是因为P/Invoke声明里用了可空值类型(比如IntPtr?、UInt64?)。CLR的封送器不支持处理可空泛型类型作为非托管函数的参数。

修复方式是把所有可空参数改成非可空类型:

  • 窗口句柄hWnd、图标句柄hIcon用IntPtr,空句柄用IntPtr.Zero表示;
  • 字符串参数szApp、szOtherStuff不用手动转IntPtr,直接用string类型,同时指定CharSet.Ansi匹配ShellAboutA的ANSI版本。

错误2:FormatException 原因及修复

你尝试把"test string"转十六进制Int64完全是错误方向——这个字符串不是十六进制数字,自然会抛出格式错误。实际上根本不需要手动转换字符串到IntPtr,CLR会自动帮你完成ANSI字符串的封送。

正确的代码示例

using System.Runtime.InteropServices;

class Program
{
    [DllImport("shell32.dll", CharSet = CharSet.Ansi)]
    public static extern int ShellAboutA(
        IntPtr hWnd,
        string szApp,
        string szOtherStuff,
        IntPtr hIcon);

    static void Main()
    {
        // 调用示例:只传应用名称,其他参数用默认空值
        ShellAboutA(IntPtr.Zero, "我的C#测试应用", null, IntPtr.Zero);
        
        // 也可以传入额外信息和图标句柄(比如当前窗口图标)
        // ShellAboutA(this.Handle, "我的应用", "版本 1.0.0", this.Icon.Handle);
    }
}

基础P/Invoke要点

  • 针对Windows API的A(ANSI)/W(Unicode)版本,要在DllImport中指定对应CharSet;
  • 所有窗口、图标等句柄类型,统一用IntPtr表示,空句柄用IntPtr.Zero;
  • 避免在P/Invoke参数中使用可空值类型,封送器不支持这类泛型类型的转换。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 15:57:18