Создание AppDomain с использованием .net Framework 4 дает OutOfMemoryException

Я пытаюсь создать домен приложения в VB/VS2015, используя .net Framework 4, 64-разрядную версию, но получаю исключение OutOfMemoryException.

domain = AppDomain.CreateDomain("mydomain")

Он отлично работает, если я делаю это в приложении Windows Form, но я пытаюсь сделать это в библиотеке классов (для вызова из стороннего приложения), и каждый раз это терпит неудачу.

Я хотел бы знать, является ли законным создание домена приложения в этих обстоятельствах (в конце концов, я не создаю приложение), и сообщение об ошибке вводит в заблуждение, или я что-то еще упускаю (доказательства безопасности? ).

Microsoft признает ошибку в Framework 4.5, которая вызывает эту ошибку (см. это), но я использую Framework 4.

Чтобы дать немного больше информации, я использую appdomain для динамической загрузки и выгрузки dll, которую я создаю, поэтому я могу выгружать, перекомпилировать и перезагружать во время разработки, так как стороннее приложение, которое вызывает мою dll, очень медленно работает. загрузиться и загрузить документы. Я хотел бы максимально приблизиться к Редактировать и продолжить!


person Andrew Spalding    schedule 03.06.2016    source источник


Ответы (1)


Я получил ту же ошибку и немного отследил ее внутри clr.dll. Функция внутренне вызывает GetSystemInfo (kernel32) для проверки гранулярности распределения.

Быстрое и грязное решение этой проблемы: Объезд GetSystemInfo

см. пример кода здесь (я использовал Process.NET для обхода, это быстро и просто)

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.InteropServices;
using System.IO;
using ProcessDotNet;
using ProcessDotNet.Applied.Detours;

namespace Bootstrap
{

    [UnmanagedFunctionPointer(CallingConvention.Winapi)]
    public delegate void GetSystemInfoDelegate(ref SYSTEM_INFO info);

    [StructLayout(LayoutKind.Sequential)]
    public struct SYSTEM_INFO
    {
        public ushort processorArchitecture;
        ushort reserved;
        public uint pageSize;
        public IntPtr minimumApplicationAddress;
        public IntPtr maximumApplicationAddress;
        public IntPtr activeProcessorMask;
        public uint numberOfProcessors;
        public uint processorType;
        public uint allocationGranularity;
        public ushort processorLevel;
        public ushort processorRevision;
    }

    class Loader
    { 
        static void GetSystemInfoDetoured(ref SYSTEM_INFO info)
        {
            info = new SYSTEM_INFO();
            GetSystemInfoDetour.Disable();
            GetSystemInfo(ref info);


            info.allocationGranularity = 1000000;

            GetSystemInfoDetour.Enable();
        }

        static Detour GetSystemInfoDetour;
        static GetSystemInfoDelegate GetSystemInfo;

        static void Main(string[] args)
        {
            TestDomainCreation();
        }

        static void TestDomainCreation()
        {
            AppDomainSetup setup = new AppDomainSetup();

            ProcessSharp s = new ProcessSharp(Process.GetCurrentProcess(), ProcessDotNet.Memory.MemoryType.Local);

            GetSystemInfo = s["kernel32"]["GetSystemInfo"].GetDelegate<GetSystemInfoDelegate>();
            DetourManager dtm = new DetourManager(s.Memory);
            GetSystemInfoDetour = dtm.CreateAndApply(GetSystemInfo, new GetSystemInfoDelegate(GetSystemInfoDetoured), "GetSystemInfoDetour");

            var tempDomain = AppDomain.CreateDomain("HappyDomain", null, setup);

            GetSystemInfoDetour.Disable();
            GetSystemInfoDetour.Dispose();
        }
    }
}

С уважением

person sneusse    schedule 12.09.2016
comment
Вы упоминаете Process.Net, вы имеете в виду github.com/lolp1/Process.NET? - person Andrew Spalding; 14.09.2016
comment
Я пытаюсь понять, почему вы используете ProcessDotNet ... должно ли это использовать Process.NET? Даже тогда я не могу понять Process.GetCurrentProcess(). Я что-то пропустил? - person Andrew Spalding; 14.09.2016
comment
Да, ты прав. Я переместил всю библиотеку в другое пространство имен. Это также может быть причиной того, что у вас возникают проблемы с Process.GetCurrentProcess(). Попробуйте System.Diagnostics.Process.GetCurrentProcess() - person sneusse; 11.10.2016