Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/289.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/maven/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 卸载AppDomain后删除dll文件_C#_Dll_Mono_.net Assembly_Appdomain - Fatal编程技术网

C# 卸载AppDomain后删除dll文件

C# 卸载AppDomain后删除dll文件,c#,dll,mono,.net-assembly,appdomain,C#,Dll,Mono,.net Assembly,Appdomain,我目前正在尝试制作一个游戏引擎,尝试一块一块地复制unity功能, 对于加载一些脚本,我没有问题,但是当我必须重新加载它们时,mono编译失败,告诉我DLL已经被访问,或者DLL文件无法删除 这是我的密码: using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Reflection; using

我目前正在尝试制作一个游戏引擎,尝试一块一块地复制unity功能, 对于加载一些脚本,我没有问题,但是当我必须重新加载它们时,mono编译失败,告诉我DLL已经被访问,或者DLL文件无法删除

这是我的密码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Reflection;
using System.IO;
using System.Runtime.InteropServices;
using System.Threading;
using System.Diagnostics;
using System.Security.Policy;
using System.Security;
using System.Security.Permissions;

public class Proxy : MarshalByRefObject
{
    public Assembly GetAssembly(string assemblyPath)
    {
        try
        {
            byte[] response = new System.Net.WebClient().DownloadData(assemblyPath);
            return Assembly.ReflectionOnlyLoad(response);
        }
        catch (Exception)
        {
            return null;
        }
    }

    public Assembly GetAssembly2(string assemblyPath, AppDomain domain)
    {
        try
        {
            byte[] bytesDLL = new System.Net.WebClient().DownloadData(assemblyPath);
            return domain.Load(bytesDLL);
        }
        catch (Exception)
        {
            return null;
            // throw new InvalidOperationException(ex);
        }
    }

    public Assembly GetAssemblyByName(AssemblyName name, AppDomain domain)
    {
        return domain.ReflectionOnlyGetAssemblies().
        SingleOrDefault(assembly => assembly.GetName() == name);
    }
}

class Program
{
    public static AppDomain domain;
    public static Assembly assembly;
    public static Type type;
    public static String dllPath;
    public static String scriptPath;
    public static String className;
    public static String file;
    public static dynamic instance;

    private static bool Compile(String path, out String dir)
    {       
        ProcessStartInfo start = new ProcessStartInfo();
        dir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
        dir = Path.Combine(dir, Path.GetFileNameWithoutExtension(path) + ".dll");

        if (File.Exists(dir))
        {
            Console.WriteLine("???????");
            File.Delete(dir);
            Console.WriteLine("???????2");
        }

        start.FileName = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Mono\\lib\\mono\\4.5\\mcs.exe");
        start.UseShellExecute = false;
        start.RedirectStandardError = true;
        start.RedirectStandardOutput = true;
        start.Arguments = "\"" + path + "\" " + "/target:library" + " " + "/out:" + "\"" + dir + "\""; //+ " " + "/reference:OctogonEngine.dll" + " /reference:AssimpNet.dll";

        using (Process process = Process.Start(start))
        {
            using (StreamReader reader = process.StandardError)
            {
                string result = reader.ReadToEnd();
                Console.WriteLine(result);
            }

            using (StreamReader reader = process.StandardOutput)
            {
                string result = reader.ReadToEnd();
                Console.WriteLine(result);
            }
        }

        Console.WriteLine("compilation ok");
        return (true);
    }

    public static void Unload()
    {
        FileStream[] streams = null;

        if (assembly != null)
            streams = assembly.GetFiles();

        instance = null;
        GC.Collect();
        GC.WaitForPendingFinalizers();
        GC.Collect();
        type = null;
        assembly = null;
        AppDomain.Unload(domain);
        assembly = null;

        if (streams != null)
        {
            for (int i = 0; i < streams.Length; i++)
            {
                streams[i].Dispose();
            }
        }

        GC.Collect();
        GC.WaitForPendingFinalizers();
        GC.Collect();
        Directory.Delete(cachePath, true);
        return;
    }

    static Assembly GetAssemblyByName(string name, AppDomain domain)
    {
        return domain.GetAssemblies().
               SingleOrDefault(assembly => assembly.GetName().Name == name);
    }

    public static String cachePath = "./cache/";

    public static void Load()
    {
        Directory.CreateDirectory(cachePath);

        if (Compile(scriptPath, out Program.dllPath))
        {
            if (File.Exists(Program.dllPath))
            {
                className = Path.GetFileNameWithoutExtension(Program.dllPath);

                AppDomainSetup setup = new AppDomainSetup();
                setup.ApplicationBase = AppDomain.CurrentDomain.BaseDirectory;
                setup.ShadowCopyFiles = "true";
                setup.CachePath = cachePath;
                domain = AppDomain.CreateDomain(className, null, setup);
                domain.DoCallBack(() => AppDomain.CurrentDomain.Load(AssemblyName.GetAssemblyName("test.dll")));
                var assemblyLoader = (Proxy)domain.CreateInstanceAndUnwrap(typeof(Proxy).Assembly.FullName, typeof(Proxy).FullName);
                assembly = assemblyLoader.GetAssembly(Program.dllPath);

                /*if (assembly == null)
                {
                    Console.WriteLine("damn");
                }*/

                if (assembly != null)
                {
                    type = assembly.GetType(className);
                }

                if (File.Exists(scriptPath))
                    Program.file = File.ReadAllText(scriptPath);
            }
        }
    }

    static bool check = false;

    static void AppDomainInit(string[] args)
    {
        if (!File.Exists(args[0]))
        {
            return;
        }
    }

    public static void init(String scriptPath)
    {
        if (File.Exists(scriptPath))
        {
            Program.file = File.ReadAllText(scriptPath);
            Program.scriptPath = scriptPath;
            Program.Load();
        }
    }

    static void Main(string[] args)
    {
        Program.init(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "test.cs"));
        Program.Unload();
        //here is the crash :/
        File.Delete(Program.dllPath);
        Console.WriteLine("???");
    }
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用System.Threading.Tasks;
运用系统反思;
使用System.IO;
使用System.Runtime.InteropServices;
使用系统线程;
使用系统诊断;
使用系统、安全、策略;
使用系统安全;
使用System.Security.Permissions;
公共类代理:MarshalByRefObject
{
公共程序集GetAssembly(字符串程序集路径)
{
尝试
{
byte[]response=new System.Net.WebClient().DownloadData(assemblyPath);
返回组件。ReflectionOnlyLoad(响应);
}
捕获(例外)
{
返回null;
}
}
公共程序集GetAssembly2(字符串assemblyPath,AppDomain域)
{
尝试
{
byte[]bytesDLL=new System.Net.WebClient().DownloadData(assemblyPath);
返回domain.Load(bytesDLL);
}
捕获(例外)
{
返回null;
//抛出新的InvalidOperationException(ex);
}
}
公共程序集GetAssemblyByName(程序集名称,AppDomain域)
{
返回domain.ReflectionOnlyGetAssemblies()。
SingleOrDefault(assembly=>assembly.GetName()==name);
}
}
班级计划
{
公共静态AppDomain域;
公共静态装配;
公共静态类型;
公共静态字符串dllPath;
公共静态字符串脚本路径;
公共静态字符串类名称;
公共静态字符串文件;
公共静态动态实例;
私有静态bool编译(字符串路径,输出字符串目录)
{       
ProcessStartInfo start=新的ProcessStartInfo();
dir=Path.GetDirectoryName(Assembly.getExecutionGassembly().Location);
dir=Path.Combine(dir,Path.getfilenamwithoutextension(Path)+“.dll”);
if(File.Exists(dir))
{
Console.WriteLine(“”);
删除(dir);
控制台写入线(“2”);
}
start.FileName=Path.Combine(Path.GetDirectoryName(Assembly.getExecutionGassembly().Location),“Mono\\lib\\Mono\\4.5\\mcs.exe”);
start.UseShellExecute=false;
start.RedirectStandardError=true;
start.RedirectStandardOutput=true;
start.Arguments=“\”“+path+”\”“+”/target:library“+”“+”/out:“+”\”“+dir+”\”;//++++“/reference:octogongengine.dll”+“/reference:AssimpNet.dll”;
使用(Process进程=Process.Start(Start))
{
使用(StreamReader=process.StandardError)
{
字符串结果=reader.ReadToEnd();
控制台写入线(结果);
}
使用(StreamReader=process.StandardOutput)
{
字符串结果=reader.ReadToEnd();
控制台写入线(结果);
}
}
Console.WriteLine(“编译正常”);
返回(真);
}
公共静态无效卸载()
{
FileStream[]streams=null;
如果(程序集!=null)
streams=assembly.GetFiles();
实例=null;
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
type=null;
assembly=null;
卸载(域);
assembly=null;
如果(流!=null)
{
for(int i=0;iassembly.GetName().Name==Name);
}
公共静态字符串cachePath=“./cache/”;
公共静空荷载()
{
CreateDirectory(cachePath);
if(编译(scriptPath,out Program.dllPath))
{
if(File.Exists(Program.dllPath))
{
className=Path.GetFileNameWithoutExtension(Program.dllPath);
AppDomainSetup=新建AppDomainSetup();
setup.ApplicationBase=AppDomain.CurrentDomain.BaseDirectory;
setup.ShadowCopyFiles=“true”;
setup.CachePath=CachePath;
domain=AppDomain.CreateDomain(类名,空,设置);
domain.DoCallBack(()=>AppDomain.CurrentDomain.Load(AssemblyName.GetAssemblyName(“test.dll”));
var assemblyLoader=(代理)domain.CreateInstanceAndUnwrap(typeof(Proxy).Assembly.FullName,typeof(Proxy).FullName);
assembly=assemblyLoader.GetAssembly(Program.dllPath);
/*if(assembly==null)
{
控制台。写线(“该死”);
}*/
如果(程序集!=null)
{
type=assembly.GetType(类名);
}
if(File.Exists(scriptPath))
Program.file=file.ReadAllText(脚本路径);
}
}
}
静态布尔检查=假;
静态void AppDomainInit(字符串[]args)
{
如果(!File.Exists(args[0]))
{
返回;
}
}
公共静态void init(字符串脚本路径)
{
if(File.Exists(scriptPath))
{
Program.file=file.ReadAllText(脚本路径);
Program.scriptPath=脚本路径;
Program.Load();
}
}
静态void Main(字符串[])
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                String pathToAssembly = args[0];
                AppDomain dom = AppDomain.CreateDomain("some");
                AssemblyName assemblyName = new AssemblyName();
                assemblyName.CodeBase = "loader.dll";
                dom.Load(assemblyName);
                object loader = dom.CreateInstanceAndUnwrap("loader", "loader.AsmLoader");
                Type loaderType = loader.GetType();
                loaderType.GetMethod("LoadAssembly").Invoke(loader, new object[] { pathToAssembly });                
                //make sure the given assembly is not loaded in the main app domain and thus would be locked
                AppDomain.CurrentDomain.GetAssemblies().All(a => { Console.WriteLine(a.FullName); return true; });
                AppDomain.Unload(dom);
                GC.Collect();
                GC.WaitForPendingFinalizers();
                GC.Collect();
                File.Delete(pathToAssembly);
            }
            catch(Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }
        }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace loader
{
    public class AsmLoader: MarshalByRefObject
    {
        public AsmLoader()
        {
        }

        public void LoadAssembly(string path)
        {
            AssemblyName n = new AssemblyName();
            n.CodeBase = path;
            AppDomain.CurrentDomain.Load(n);
        }
    }
}
... whatever code....
consoleapplication1.exe testasm.dll
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Reflection;
using System.IO;
using System.Runtime.InteropServices;
using System.Threading;
using System.Diagnostics;
using System.Security.Policy;
using System.Security;
using System.Security.Permissions;
using System.Configuration;

class Program
{
    public static void Main(string[] args)
    {
        String pathToAssembly = args[0];
        AppDomain dom = AppDomain.CreateDomain("some");     
        AssemblyName assemblyName = new AssemblyName();
        assemblyName.CodeBase = pathToAssembly;
        Assembly assembly = dom.Load(assemblyName);
        AppDomain.Unload(dom);
        GC.Collect();
        GC.WaitForPendingFinalizers();
        GC.Collect();
        File.Delete(pathToAssembly);
    }
}
  domain.DoCallBack(() => AppDomain.CurrentDomain.Load(AssemblyName.GetAssemblyName("test.dll")));
CompilerParameters compilerParams = new CompilerParameters
{
GenerateInMemory = true,
GenerateExecutable = false,
IncludeDebugInformation = true
};
byte[] bytes = File.ReadAllBytes("pathtoyourdll");
AppDomain.CurrentDomain.Load(bytes);
AppDomain.Unload(domain);
domain = null;