C#-脚本-仍在使用的文件

C#-脚本-仍在使用的文件,c#,C#,我正在使用CodeDomProvider类在我正在开发的特定应用程序中编译脚本。这是我正在使用的三种方法 public static void CompileNpcScripts(bool pLoadCompiledScripts) { Dictionary<string, DateTime> compiledScripts = new Dictionary<string, DateTime>(); foreach (var sc

我正在使用CodeDomProvider类在我正在开发的特定应用程序中编译脚本。这是我正在使用的三种方法

public static void CompileNpcScripts(bool pLoadCompiledScripts)
    {
        Dictionary<string, DateTime> compiledScripts = new Dictionary<string, DateTime>();

        foreach (var script in System.IO.Directory.GetFiles("..\\DataSvr\\Script\\Compiled\\", "*.compiled"))
        {
            compiledScripts.Add(System.IO.Path.GetFileNameWithoutExtension(script), System.IO.File.GetLastWriteTime(script));
        }

        List<string> needCompliation = new List<string>();
        foreach (var script in System.IO.Directory.GetFiles("..\\DataSvr\\Script\\", "*.s"))
        {
            var shortname = System.IO.Path.GetFileNameWithoutExtension(script);
            if (!compiledScripts.ContainsKey(shortname) || compiledScripts[shortname] < System.IO.File.GetLastWriteTime(script))
            {
                needCompliation.Add(script);
            }
        }

        foreach (var script in needCompliation)
        {
            var shortname = System.IO.Path.GetFileNameWithoutExtension(script);

            _usableNpcScripts.Remove(shortname);

            CompilerResults results = CompileScript(ScriptType.Npc, script);
        }

        foreach (var script in System.IO.Directory.GetFiles("..\\DataSvr\\Script\\Compiled\\", "*.compiled"))
        {
            var shortname = System.IO.Path.GetFileNameWithoutExtension(script);

            if (!_usableNpcScripts.ContainsKey(shortname))
            {
                _usableNpcScripts.Add(shortname, Assembly.LoadFile(Environment.CurrentDirectory + "\\" + script));
            }
        }

        if (pLoadCompiledScripts)
        {
            foreach (KeyValuePair<string, Assembly> script in _usableNpcScripts)
            {
                GameServer.NpcScripts.Add(script.Key, (INpcScript)ScriptingTools.FindInterface(script.Value, "INpcScript"));
            }
        }
        else
        {
            foreach (var script in needCompliation)
            {
                var shortname = System.IO.Path.GetFileNameWithoutExtension(script);

                if (GameServer.NpcScripts.ContainsKey(shortname))
                {
                    GameServer.NpcScripts[shortname] = (INpcScript)ScriptingTools.FindInterface(_usableNpcScripts[shortname], "INpcScript");
                }
            }
        }
    }

    public static CompilerResults CompileScript(ScriptType pType, string pSource)
    {
        try
        {
            if (_compiler == null)
            {
                _compiler = CodeDomProvider.CreateProvider("CSharp");
                _compilerParams = new CompilerParameters();

                _compilerParams.GenerateExecutable = false;
                _compilerParams.CompilerOptions = "/optimize";
                // TODO: Should it be generated in memory?
                _compilerParams.GenerateInMemory = false;
                _compilerParams.IncludeDebugInformation = false;
                _compilerParams.ReferencedAssemblies.Add("System.dll");
                _compilerParams.ReferencedAssemblies.Add(Assembly.GetExecutingAssembly().Location);
                { }
                int lol;
            }

            _compilerParams.OutputAssembly = "Scripts\\" + pType + "\\Compiled\\" + System.IO.Path.GetFileNameWithoutExtension(pSource) + ".compiled";
            var result = _compiler.CompileAssemblyFromFile(_compilerParams, pSource);

            if (System.IO.File.Exists(_compilerParams.OutputAssembly))
            {
                System.IO.File.SetLastWriteTime(_compilerParams.OutputAssembly, System.IO.File.GetLastWriteTime(pSource));
            }

            return result;
        }
        catch
        {
            // Stil being used by the user.
            return null;
        }
    }

    public static object FindInterface(Assembly pDLL, string pInterface)
    {
        foreach (Type type in pDLL.GetTypes())
        {
            if (type.GetInterface(pInterface, true) != null)
                return pDLL.CreateInstance(type.FullName);
        }

        return null;
    }
publicstaticvoidcompilenpcscripts(boolploadcompiledscripts)
{
字典编译脚本=新字典();
foreach(System.IO.Directory.GetFiles(“..\\DataSvr\\script\\Compiled\\”,“*.Compiled”)中的var脚本)
{
compiledScripts.Add(System.IO.Path.GetFileNameWithoutExtension(script)、System.IO.File.GetLastWriteTime(script));
}
List needCompliation=新列表();
foreach(System.IO.Directory.GetFiles(“..\\DataSvr\\script\\”,“*.s”)中的var脚本)
{
var shortname=System.IO.Path.GetFileNameWithoutExtension(脚本);
如果(!compiledScripts.ContainsKey(shortname)| compiledScripts[shortname]
布尔值“pLoadCompiledScripts”用于告诉程序是否应该重新加载或插入脚本。GameServer的NpcScripts词典只是界面INpcScript的集合


现在。在initla加载时,我调用以下命令:CompileNpcScripts(true),因此它将检查需要编译的文件,将重新编译这些文件,然后将所有文件加载到词典中。我还有一个FileWatcher类,它监视脚本文件夹的更改。一旦引发该事件,我将调用CompileNpcScripts(false),因此它将重新加载现有脚本。但是,CompileScript方法返回null,因为另一个进程正在使用文件“[name].compiled”。为什么它是这样的一个单桅帆船,我可以如何解决它?谢谢。

这个问题可能是两件事之一

首先,检查您的
FileWatcher
类,确保它没有保存任何正在监视的文件(例如访问上次修改的日期属性或任何情况)


其次,编译器在开始编译脚本之后可能仍然保留着这些脚本。每次重新编译脚本时,我都会尝试处理编译器并重建它。

TL;博士随机猜测-“compiled”是程序集的名称,您可以
加载该程序集-因此,如果不通过appDomain unload卸载程序集,您将无法覆盖该程序集的文件。
\u编译器
是一个
IDisposable
资源,因此您应该在其上调用
.Dispose()
(或使用
将其用法包装在
中)。