如何添加对 C# 脚本的引用
本文关键字:脚本 引用 何添加 添加 | 更新日期: 2023-09-27 17:57:05
我正在使用CS-Script库来执行动态代码。与其将其用作脚本引擎,不如使用它来动态地将功能插入到应用程序中。这是托管代码...
using System;
using CSScriptLibrary;
using System.Reflection;
using System.IO;
namespace CSScriptTester
{
class Program
{
static void Main(string[] args)
{
// http://www.csscript.net/
Console.WriteLine("Running Script.");
CSScript.Evaluator.ReferenceAssembly(Assembly.GetAssembly(typeof(System.Windows.Forms.MessageBox)));
string code = File.ReadAllText("SomeCode/MyScript.cs");
dynamic block = CSScript.Evaluator.LoadCode(code);
block.ExecuteAFunction();
Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}
}
以下是SomeCode/MyScript的内容.cs...
using System;
using System.Windows.Forms;
namespace CSScriptTester.SomeCode
{
class MyScript
{
public void ExecuteAFunction()
{
MessageBox.Show("Hello, world!");
}
}
}
这工作正常。在宿主代码中,我不希望宿主代码负责指定程序集引用。所以我注释掉CSScript.Evaluator.ReferenceAssembly(Assembly.GetAssembly(typeof(System.Windows.Forms.MessageBox)));
并运行它,我得到错误......
错误 CS0234:系统
Forms' does not exist in the namespace
Windows'的类型或命名空间名称。是否缺少程序集引用?
我知道如果我使用命令行工具执行此操作,我可以将其添加到脚本顶部以添加引用......
//css_reference System.Windows.Forms.dll
但是,在 .NET 应用程序的上下文中执行它时,这似乎被忽略了。如何让它正确解析引用?
通了。
string code = File.ReadAllText("SomeCode/MyScript.cs");
CSScript.Evaluator.ReferenceAssembliesFromCode(code);
dynamic block = CSScript.Evaluator.LoadCode(code);
block.ExecuteAFunction();
我很惊讶它不会自动执行此操作。
我已经以另一种方式解决了这个问题,我将所需的引用程序集"复制本地"属性设置为 true,并在加载脚本之前将它们加载到我的评估器中。
我建议这样做,因为它将预编译和存储加载的程序集,从而更快地临时加载脚本。它不是每次加载脚本时都从 GAC 或其他位置查找引用的程序集,而是只需拥有它们并尽可能高效地加载脚本。
CSScript.Evaluator.ReferenceAssembly("<local path to dependency>.dll");
IScript script = CSScript.Evaluator.LoadFile<IScript>("<local path to script file");
其中,"依赖项的本地路径"只是引用对象的名称,可以在项目中作为任何引用程序集的"Description"字符串找到。
这是预期的使用模式:
IScript script = CSScript.Evaluator.ReferenceAssembly("<local path to dependency>.dll");
.LoadFile<IScript>("<local path to script file");
或
string code = File.ReadAllText("SomeCode/MyScript.cs");
dynamic block = CSScript.Evaluator
.ReferenceAssembliesFromCode(code)
.LoadCode(code);
block.ExecuteAFunction();
至于"我会对它不会自动完成的原因非常感兴趣",那是因为这个电话可能很昂贵。如果这样做,脚本引擎将分析每个using
语句,并尝试在所有已知位置和 GAC 中查找它。它将对所有可能的//css_*
指令进行分析。
这就是为什么预期的用例是使用显式 API 方法引用程序集,而不是通过脚本代码引用程序集,即使可以通过方法 ReferenceAssembliesFromCode
引用。
但更重要的是,如果脚本引擎自动执行此操作,则用户无法指定程序集探测目录。
这就是为什么您最好使用以下任何专用方法引用 asseblies:
IEvaluator ReferenceAssembliesFromCode(string code, params string[] searchDirs);
IEvaluator ReferenceAssembly(string assembly);
IEvaluator ReferenceAssembly(Assembly assembly);
IEvaluator ReferenceAssemblyByName(string assemblyPartialName);
IEvaluator TryReferenceAssemblyByNamespace(string @namespace, out bool resolved);
IEvaluator ReferenceAssemblyByNamespace(string @namespace);
IEvaluator ReferenceAssemblyOf(object obj);
IEvaluator ReferenceAssemblyOf<T>();
IEvaluator ReferenceDomainAssemblies(DomainAssemblies assemblies = DomainAssemblies.AllStaticNonGAC);