首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >没有执行代码的ScriptControl.AddCode?

没有执行代码的ScriptControl.AddCode?
EN

Stack Overflow用户
提问于 2015-01-15 07:27:10
回答 2查看 1.9K关注 0票数 1

我正在C#中进行一个项目,该项目从EA数据库获取脚本(VBScript、Jscript和JavaScript),并在特定时刻执行某些功能。

为了能够做到这一点,我使用微软ScriptControl

首先,我使用ScriptControl将所有脚本代码添加到ScriptControl.AddCode中,然后使用特定的名称进行函数。

将代码添加到脚本控件的代码如下所示:

代码语言:javascript
复制
//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:

代码语言:javascript
复制
sub main
    MsgBox("main executed")
end sub

main

一旦我使用ScriptControl将这个脚本的代码添加到AddCode中,就会执行子程序,并看到消息框出现。

有谁知道在这种情况下避免执行子程序的简单方法吗?

我目前的解决方案(目前只为VBScript实现)包括解析脚本代码和删除调用函数或过程的行,但这非常繁琐,而且容易出错。

代码语言:javascript
复制
/// <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;
}

任何更好的主意都是欢迎的。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-01-15 09:03:42

  1. 如果希望脚本代码模块充当代码库而不使用任何静态初始化器,则可以通过在编码约定中声明它来强制执行它。
  2. 如果希望静态初始化程序和其他副作用直到运行时才出现,则可以通过延迟脚本激活,在第一次需要脚本时延迟加载脚本。
  3. 如果您希望对脚本环境拥有更细粒度的控制,那么实现脚本主机并更直接地与脚本引擎交互(例如,使用IActiveScriptParse接口可能不会触发任何意外的副作用)。 MSDN: Windows脚本接口 ...To使主机的实现尽可能灵活,提供了OLE自动化包装器用于Windows脚本。但是,使用此包装器对象实例化脚本引擎的主机对运行时名称空间、持久性模型等没有控制的程度,如果它直接使用Windows脚本的话。 Windows设计将仅在创作环境中所需的接口元素隔离开来,以便使非创作主机(如浏览器和查看器)和脚本引擎(例如VBScript)可以保持轻量级.
票数 1
EN

Stack Overflow用户

发布于 2015-01-15 11:34:11

Main之所以执行,是因为您从顶层命令调用它。任何不在子/函数中的内容都会被执行。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27958553

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档