如何解决在 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 举报,一经查实,本站将立刻删除。