C# csscript卸载与接口一起使用的程序集
我试图在一个目录a循环中执行cs脚本。每次脚本更改(或者是新的)时,都会加载并执行它。但我在第二次尝试加载脚本时收到错误:C# csscript卸载与接口一起使用的程序集,c#,C#,我试图在一个目录a循环中执行cs脚本。每次脚本更改(或者是新的)时,都会加载并执行它。但我在第二次尝试加载脚本时收到错误: 对路径“C:\Users\Admin\AppData\Local\Temp\CSSCRIPT\Cache\647885655\hello.cs.compiled”的访问被拒绝。 我想做的是: static Dictionary<string, string> mFilePathFileHashes = new Dictionary<string, stri
对路径“C:\Users\Admin\AppData\Local\Temp\CSSCRIPT\Cache\647885655\hello.cs.compiled”的访问被拒绝。
我想做的是:
static Dictionary<string, string> mFilePathFileHashes = new Dictionary<string, string>();
public static void LoadFromDir(string dir)
{
foreach (string filepath in Directory.GetFiles(dir))
{
string hash = GetMD5HashFromFile(filepath); //Generate file hash
if (mFilePathFileHashes.Contains(new KeyValuePair<string, string>(filepath, hash))) continue; //Skip if it hasn't changed
if (mFilePathFileHashes.ContainsKey(filepath))
{ //Hash changed
mFilePathFileHashes[filepath] = hash;
}
else //This is the first time this file entered the loop
mFilePathFileHashes.Add(filepath, hash);
//Load the script
IScript script = CSScript.Load(filepath)
.CreateInstance("Script")
.AlignToInterface<IScript>();
//Do stuff
script.AddUserControl();
}
protected static string GetMD5HashFromFile(string fileName)
{
FileStream file = new FileStream(fileName, FileMode.Open);
MD5 md5 = new MD5CryptoServiceProvider();
byte[] retVal = md5.ComputeHash(file);
file.Close();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < retVal.Length; i++)
{
sb.Append(retVal[i].ToString("x2"));
}
return sb.ToString();
}
所以,最后一个错误可能是因为我从未真正与接口对齐,或者因为我正在从主AppDomain之外调用静态方法(我真的不知道)
有什么方法可以让它工作吗?好吧,它通过将我要操作的对象传递到接口的方法来工作,如下所示:
using (var helper = new AsmHelper(CSScript.Compile(filepath), null, false))
{
IScript script = helper.CreateAndAlignToInterface<IScript>("Script");
script.AddUserControl(Form1.frm);
}
MSDN saisMarshallByRefObject允许在支持远程处理的应用程序中跨应用程序域边界访问对象。
所以我想这是有道理的。。但是我有没有办法向脚本公开我的主应用程序的方法呢
从主程序中的MarshalByRefObject
继承似乎是不可能的,如下所示:
public class CTestIt : MarshalByRefObject
{
public static CTestIt Singleton;
internal static void SetSingleton()
{ //This method is successfully executed before we start loading scripts
Singleton = new CTestIt();
Console.WriteLine("CTestIt Singleton set");
}
public static void test()
{
//Null reference when a script calls CSScriptTest.CTestIt.test();
Singleton.test_member();
}
public void test_member()
{
Console.WriteLine("test");
}
}
你的文字肯定是问题所在。确保在另一个程序集中声明了接口类型,该程序集可以加载到主appdomain中。接口本身在主程序中声明。。这怎么会是问题呢?
using (var helper = new AsmHelper(CSScript.Compile(filepath), null, false))
{
IScript script = helper.CreateAndAlignToInterface<IScript>("Script");
script.AddUserControl(Form1.frm);
}
using System;
using System.Windows.Forms;
using CSScriptTest;
class Script : MarshalByRefObject, CSScriptTest.IScript
{
public void AddUserControl(CSScriptTest.Form1 host)
{
host.AddUserControl1(this, "lol2");
}
}
public class CTestIt : MarshalByRefObject
{
public static CTestIt Singleton;
internal static void SetSingleton()
{ //This method is successfully executed before we start loading scripts
Singleton = new CTestIt();
Console.WriteLine("CTestIt Singleton set");
}
public static void test()
{
//Null reference when a script calls CSScriptTest.CTestIt.test();
Singleton.test_member();
}
public void test_member()
{
Console.WriteLine("test");
}
}