【发布时间】:2015-01-15 07:27:10
【问题描述】:
我正在开发一个 C# 项目,该项目从 EA 数据库获取脚本(VBScript、Jscript 和 JavaScript)并在特定时刻执行某些功能。
为了能够做到这一点,我使用Microsoft ScriptControl。
首先,我使用 ScriptControl.AddCode 将所有脚本代码添加到 ScriptControl,然后使用特定名称运行。
将代码添加到脚本控件的代码如下所示:
//create new scriptcontroller
this.scriptController = new ScriptControl();
this.scriptController.Language = this.language.name;
this.scriptController.AddObject("Repository", model.getWrappedModel());
//Add the actual code. This must be done in a try/catch because a syntax error in the script will result in an exception from AddCode
try
{
//first add the included code
string includedCode = this.IncludeScripts(this._code);
//then remove any statements that execute a function or procedure because scriptControl.AddCode actually executes those statements
string cleanedCode = this.language.removeExecutingStatements(includedCode);
//then add the cleaned code to the scriptcontroller
this.scriptController.AddCode(cleanedCode);
问题是显然 AddCode 也以某种方式执行脚本代码,这不是我想要的。
假设我有以下 VBScript:
sub main
MsgBox("main executed")
end sub
main
只要我使用 AddCode 将此脚本的代码添加到 ScriptControl 中,就会执行 main 子程序,我会看到消息框出现。
有人知道在这种情况下避免执行 main 子的简单方法吗?
我当前的解决方法(目前仅针对 VBScript 实现)涉及解析脚本代码并剥离调用函数或过程的行,但这非常繁琐且容易出错。
/// <summary>
/// removes the statements that execute a function/procedure from the code
/// </summary>
/// <param name="code">the code with executing statements</param>
/// <returns>the code without executing statements</returns>
public override string removeExecutingStatements(string code)
{
StringReader reader = new StringReader(code);
string cleanedCode = code;
string line;
bool functionStarted = false;
bool subStarted = false;
while (null != (line = reader.ReadLine()))
{
if (line != string.Empty)
{
if (line.StartsWith(this.functionStart))
{
functionStarted = true;
}else if (line.StartsWith(this.subStart))
{
subStarted = true;
}else if (functionStarted && line.StartsWith(this.functionEnd))
{
functionStarted = false;
}
else if (subStarted && line.StartsWith(this.subEnd))
{
subStarted = false;
}else if (!functionStarted && !subStarted)
{
//code outside of a function or sub, figure out if this code calls another sub or function
foreach (string linepart in line.Split(new char[] {' ' , '(' },StringSplitOptions.RemoveEmptyEntries))
{
if (cleanedCode.Contains(this.functionStart + linepart)
||cleanedCode.Contains(this.subStart + linepart))
{
//found a line that calls an existing function or sub, replace it by an empty string.
cleanedCode = cleanedCode.Replace(Environment.NewLine +line + Environment.NewLine,
Environment.NewLine + string.Empty + Environment.NewLine);
}
}
}
}
}
return cleanedCode;
}
欢迎任何更好的想法。
【问题讨论】:
标签: javascript c# vbscript jscript enterprise-architect