2016-06-03 1 views
0

J'essaie de créer un domaine d'application dans VB/VS2015 en utilisant .net Framework 4, 64 bits, mais je reçois une exception OutOfMemoryException.Création d'AppDomain à l'aide de .net Framework 4 donne OutOfMemoryException

domain = AppDomain.CreateDomain("mydomain") 

Il fonctionne très bien si je le fais dans un formulaire d'application Windows, mais je suis en train de le faire dans une bibliothèque de classes (pour être appelée à partir d'une application 3ème partie), et il échoue à chaque fois. Je voudrais savoir s'il est légal de créer un domaine dans ces circonstances (après tout, je ne crée pas d'application), et le message d'erreur est trompeur, ou y a-t-il autre chose qui me manque? (preuve de sécurité?).

Microsoft admet un bogue dans cadre 4.5 qui donne cette erreur (see this), mais je l'aide du cadre 4.

Pour donner un peu plus de fond, j'utilise un appdomain pour charger et décharger dynamiquement une DLL que je crée, donc je peux décharger, recompiler et recharger pendant le développement, car l'application tierce qui appelle ma DLL est très lente à démarrer et charger des documents. J'aimerais me rapprocher le plus possible de Edit and Continue!

Répondre

0

J'ai eu la même erreur et j'ai suivi un peu à l'intérieur de clr.dll. La fonction appelle en interne GetSystemInfo (kernel32) pour vérifier la granularité de l'allocation.

Une solution rapide et sale pour ce numéro: Detour GetSystemInfo

voir exemple de code ici (j'ai utilisé Process.NET pour le détour, il est rapide et facile)

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(); 
     } 
    } 
} 

Cordialement

+0

Vous mentionnez Process.Net, voulez-vous dire https://github.com/lolp1/Process.NET? –

+0

J'essaye de voir pourquoi vous avez "using ProcessDotNet" ... devrait-il être "using Process.NET"? Même alors, je ne peux pas donner un sens à "Process.GetCurrentProcess()". Est-ce que je manque quelque chose? –

+0

Oui, vous avez raison. J'ai déplacé toute la bibliothèque dans un autre espace de noms. Cela peut aussi être la raison pour laquelle vous rencontrez des problèmes avec 'Process.GetCurrentProcess()'. Essayez 'System.Diagnostics.Process.GetCurrentProcess()' – sneusse