微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在 Windows 7 上使用带有 NSIS 的 Dotnet 失败

如何解决在 Windows 7 上使用带有 NSIS 的 Dotnet 失败

我正在使用非托管 C# dll(使用 DllExport 和 dotnet framework 4.0)向 NSIS 安装程序添加 UI 功能,但基本控件构造函数在 Windows 7 上抛出 font '?' cannot be found. 异常。代码示例:

[DllExport]
public static void CreateRichTextBox()
{
    try
    {
        RichTextBox myRichTextBox = new RichTextBox();
        MessageBox.Show("RichTextBox created on windows 10");
    }
    catch (Exception ex)
    {
        MessageBox.Show("RichTextBox contractor Failed on windows 7 with " + ex.Message);
    }
}

所以经过一番挖掘,我得出的结论是,这是因为 NSIS 使用的一个函数会混淆 Dotnet 的内部路径:SetDefaultDllDirectories

出于安全原因添加了该功能explaind by the NSIS team

使用 SetDefaultDllDirectories 我们可以全局改变行为 LoadLibraryEx 以便它只查看 System32 文件夹和任何 使用 AddDllDirectories 显式添加的目录。

我只是猜测这是一个 Gdiplus 错误,最终得到了解决,但我仍然想知道是否有人知道使其在 Windows 7 上运行的解决方法

解决方法

public Microsoft bug report 声称该错误存在于 Windows (GDI+) 中,从技术上讲并非 .NET 特定问题。

不幸的是,MSDN 对 SetDefaultDllDirectories 是这样说的:

无法恢复到标准 DLL 搜索路径或从搜索路径中删除任何由 SetDefaultDllDirectories 指定的目录。 ...

这意味着唯一的解决方法是首先不调用该函数。在 NSIS 中做到这一点的唯一方法是使用十六进制编辑器并修改 NSIS\Stubs 中的存根。在相关存根中搜索 SetDefaultDllDirectories 并将其更改为类似 SetDefaultxxxxxxxxxxxxxx 的内容(根据需要替换任意数量的字符,但长度必须保持不变!)。

这当然意味着您的安装程序在某种程度上容易受到恶意 .DLL 植入攻击。您可以尝试通过以下方式恢复功能:

!include WinVer.nsh
!include LogicLib.nsh

Function .onInit
${If} ${AtLeastWin8}
  System::Call 'KERNEL32::SetDefaultDllDirectories(i 0x800|0x400)'
${EndIf}
FunctionEnd

但是这种保护方式的效果稍差,并且在 Windows 7 上没有任何作用。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。