Using SetDefaultDllDirectories breaks Font handling

夙愿已清 提交于 2019-12-11 03:25:08

问题


I recently got a problem in a program that used to work fine. I tracked it down to the following code:

using System.Drawing;
using System.Runtime.InteropServices;

namespace Foo
{
    static class CProgram
    {
        [DllImport("kernel32.dll", CallingConvention = CallingConvention.StdCall)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool SetDefaultDllDirectories(int directoryFlags);

        public const int LOAD_LIBRARY_SEARCH_DEFAULT_DIRS = 0x000001000;

        private static void Main()
        {
            SetDefaultDllDirectories(LOAD_LIBRARY_SEARCH_DEFAULT_DIRS);
            Font font = SystemFonts.DefaultFont;
        }
    }
}

Once I use SetDefaultDllDirectories with anything but zero as a parameter the program crashes. I traced it to SafeNativeMethods.Gdip.GdipGetGenericFontFamilySansSerif(out fontfamily); which simply calls "GdipGetGenericFontFamilySansSerif". But this call fails with an FontFamilyNotFound error.

It works without the SetDefaultDllDirectories. And it even works, if I place the font assignment before AND after that call.

Is there anything on my system that causes this or was it an update from MS that causes this bug?

System: Win7 x64, fully updated, AMD Radeon HD with latest beta drivers used

Background: I need that function to use AddDllDirectory to add a subdirectory of my executables path (something like C:/MyProgram/myLibrariesX)


回答1:


I can not reproduce the problem with Visual Studio 2013 in Windows 8.1 x64, while I could reproduce it on Windows 7. So it seems to be fixed now.




回答2:


I ran into the same problem as I needed native libraries to be found within an architecture folder under the base folder, i.e. x86 and x64. The work around I used was to instead append the architecture specific folder to the PATH environment variable.

var archPath = $"{AppDomain.CurrentDomain.BaseDirectory}{Environment.Is64BitProcess ? "x64" : "x86"}\\";
var pathVariable = Environment.GetEnvironmentVariable("PATH");
pathVariable = $"{archPath};{pathVariable}";
Environment.SetEnvironmentVariable("PATH", pathVariable);

The PATH isn't used for assembly probing but is used for native DLL probing. For assemblies I used the AppDomain.CurrentDomain.AssemblyResolve event.



来源:https://stackoverflow.com/questions/25818073/using-setdefaultdlldirectories-breaks-font-handling

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!