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