如何开始为我的 .NET 应用程序设计和实现脚本接口?
有 VSTA
(.NET 相当于 VBA
用于COM
),但据我了解,我必须为每次安装应用程序支付许可费。它是一个开源的
应用程序,因此这将不起作用。
还有例如解释器的嵌入(IronPython?),但我不明白这如何允许将“对象模型”(见下文)暴露给外部(或内部)脚本。
子问题:
- .NET 中的脚本接口故事是什么?在 .NET 中执行此操作是否很简单?
- 例如,我的应用程序中的某些 .NET 对象及其包含的对象是否可以声明为可在运行时从外部访问?
- 外部脚本如何访问我的应用程序(通过对象模型)?
背景:
我曾经为 Macintosh 应用程序设计并实现了一个相当复杂的脚本接口,用于从 质谱仪(Mac OS,系统 7)以及后来用于 Windows 应用程序的 COM 接口。
两者都是用“对象模型”和类(可以具有属性)设计的。这些都是超载的词语,但是
在脚本接口上下文对象模型中,本质上是特定类的对象的包含层次结构。类具有属性、所包含对象的列表,并且不仅是数据,还可以具有动词(操作/方法)。例如,在 Macintosh 情况下,定义的应用程序对象可以包含一个采集对象,该对象具有仪器中使用的电压属性和一个 fireLater
动词 - 所有这些都可以从外部脚本中看到。
请注意,在这两种情况下,用于实现应用程序的编程语言中的类/对象与脚本对象模型无关。对于 Macintosh 来说,用于实现脚本接口的机制是由 Apple 定义的。 Apple还定义了一些关于如何设计对象模型的标准。例如,类中某些公共属性的标准化名称。
或者像 Microsoft Office 应用程序中公开的 COM 接口一样,其中应用程序对象可用于添加到其文档列表(具有创建文档的 GUI 表示形式的副作用)。
外部脚本可以在容器中创建新对象,并在任何给定时间浏览层次结构的内容。在 Macintosh 中,案例脚本可以用 AppleScript 或 前沿。
在 Macintosh 上,脚本接口的实现非常复杂。
Metroworks 的 C++ 类库(我现在忘记了这个名字)对它的支持让它变得更加重要更简单。
How do I get started designing and implementing a script interface for my .NET application?
There is VSTA
(the .NET equivalent of VBA
for COM
), but as far as I understand I would have to pay a license fee for every installation of my application. It is an open source
the application so this will not work.
There is also e.g. the embedding of interpreters (IronPython?), but I don't understand how this would allow exposing an "object model" (see below) to external (or internal) scripts.
Sub-questions:
- What is the scripting interface story in .NET? Is it somehow trivial to do this in .NET?
- E.g. can some .NET objects in my application and their contained objects be declared to be accessible from the outside at runtime?
- How can external scripts access my application (through the object model)?
Background:
I have once designed and implemented a fairly involved script interface for a Macintosh application for acquisition and analysis of data from a mass spectrometer (Mac OS, System 7) and later a COM interface for a Windows application.
Both were designed with an "object model" and classes (that can have properties). These are overloaded words, but
in a scripting interface context object model is essentially a containment hierarchy of objects of specific classes. Classes have properties, lists of contained objects and are not only data but can have verbs as well (actions/methods). E.g. in the Macintosh case the defined application object can contain an acquisition object that has properties for voltages used in the instrument and a fireLater
verb - all as seen from the external script.
Note that in both cases the classes/objects in the programming language used to implement the application had nothing to do with the scripting object model. For the Macintosh case, the mechanisms used to implement the scripting interface was defined by Apple. There were also some standards defined by Apple on how to design the object model. For instance, standardized names for certain common properties in classes.
Or like in the COM interfaces exposed in Microsoft Office applications, where the application object can be used to add to its list of documents (with the side effect of creating the GUI representation of a document).
External scripts can create new objects in a container and navigate through the content of the hierarchy at any given time. In the Macintosh, case scripts could be written in e.g. AppleScript or Frontier.
On the Macintosh, the implementation of a scripting interface was very complicated.
Support for it in Metroworks' C++ class library (the name escapes me right now) made it much simpler.
发布评论
评论(8)
查看 PowerShell。
它允许您编写可编写脚本的简单 Cmdlet。它还支持分层容器(默认情况下您有文件系统、注册表、证书存储等)。
Take a look at PowerShell.
It allows you to program simple Cmdlets that are scriptable. It also supports hierachical containers (by default you have the file system, the Registry, certificates store, etc.).
[编辑:正如本评论中详细介绍的那样,假设您非常需要启用内部脚本,其中您托管某人为您提供的代码片段或函数来自定义您的应用程序,而不是纯粹的外部场景,其中有人提供外观允许人们在更严格的预定义基础上从您的应用程序中挖掘内容]
IronRuby 和 IronPython 非常简洁并且适合于此(但正如另一个答案所说,如果您有更多基础设施类型的东西,PowerShell 可能更合适) 。
编辑:启用内部脚本的其他想法是
编辑 2011 年 6 月 2 日:IronJS 也可能是合适的候选者,有一个 Hansel 分钟会详细介绍。
[EDIT: As covered at length in the comments in this, assuming you have a significant need to enable internal scripting where you are hosting snippets or functions someone gives you to customise your app, as opposed to a purely external scenario where one is providing a facaade to allow people to dig stuff out of your app on a more rigid predefined basis]
IronRuby and IronPython are very neat and appropriate for this (but as the other answer says, PowerShell may be appropriate if you have a more infrastructure-type thing).
EDIT: Other ideas for enabling internal scripting are
EDIT 2 June 2011: IronJS may also be a suitable candidate, there's a Hanselminutes that talks it thru.
我建议您考虑将动态语言运行时作为实现脚本接口的策略。详细信息:
DLR 目前支持 IronPython 和 IronRuby 以及许多其他语言实现可以可以在 CodePlex 上找到。如果您有兴趣创建特定于您的应用程序的语言,Bitwise 杂志有一本很好的入门书
Dino Viehland 的 PDC09 会议使用动态语言构建可编写脚本的应用程序值得一看。您可以在此处找到演示代码。
I would suggest you consider the Dynamic Language Runtime as a strategy for implementing a scripting interface. Details:
The DLR currently supports IronPython and IronRuby, plus a number of other language implementations can be found on CodePlex. If you are interested in creating a language specific to your application Bitwise Magazine has a good primer article.
Dino Viehland's PDC09 session Using Dynamic Languages to Build Scriptable Applications is worth watching. You can find the demo code here.
Lua 脚本语言是免费的,用于大量商业应用程序,并且可以轻松嵌入到 .NET 应用程序中使用免费的 LuaInterface 库,它允许您公开脚本中的应用程序中的类型和方法您的嵌入式解释器可以利用。
有关如何将 Lua 嵌入到 C# 应用程序中的教程可以在此处。
编辑:可能还值得注意的是,Lua 是从头开始设计的嵌入式脚本语言,因此,解释器是高度可定制的。作为安全模型的一部分,主机应用程序可以限制解释功能的几乎任何方面;例如,允许或阻止脚本建立网络连接或写入文件等。
此外,您还询问了外部脚本。使程序可用于进程外脚本的方式与使其可用于进程外应用程序的方式相同:通过某种通信协议公开标准化自动化接口。在 Windows 上,对于同一机器跨进程通信,最常见的是 COM,但也可能是 WCF、TCP 远程处理、RPC 或任意数量的其他通信标准。您选择做什么在很大程度上取决于您的应用程序的构建方式以及您打算让它执行哪种外部自动化。
The Lua scripting language is free, used in a large number of commercial applications, and is easily embeddable into a .NET application using the freely-available LuaInterface library, which permits you to expose types and methods from your application that scripts in your embedded interpreter can leverage.
A tutorial on how to embed Lua into a C# application can be found here.
Edit: It's probably also worth noting that Lua was designed from the ground up to be an embedded scripting language, and as a result, the interpreter is highly customizable. The host application can restrict almost any aspect of the interpretation capabilities as part of the security model; e.g. allowing or preventing scripts from making network connections or writing to files, etc.
Also, you asked about external scripts. Making your program available to out-of-process scripts is done in the same way you make it available to out-of-process applications: by exposing a standardized automation interface through some sort of communication protocol. On Windows, for same-machine cross-process communication, that will most commonly be COM, but it could also be WCF, TCP remoting, RPC or any number of other communications standards. What you choose to do depends heavily on how your application is built and what kind of external automation you intend for it to do.
我使用 CS-Script 来创建你想要的东西。就我而言,我在应用程序中定义了一个接口。然后只需要一个脚本来实现这个接口,以便它可以从应用程序运行。我的应用程序是关于处理扫描图像的,因此我的界面看起来像这样:
这样我的脚本可以访问我在应用程序中定义的对象模型(在我的例子中是通过 IBatch)。好处是,在开发过程中,我可以为脚本使用普通的类库项目:IntelliSense、调试...我不记得确切的细节,但我基本上在我的应用程序中有一个开关,告诉应用程序使用
引用类库而不是脚本。此外,我还创建了一个允许配置脚本的附加界面:脚本可以定义一组属性,然后由我的应用程序在属性网格中显示这些属性。我想我在此处使用了这个版本,因为这在时间。这样,您不仅可以允许用户配置脚本,还可以以描述、选择、默认值的形式提供帮助...属性网格具有很强的可扩展性:在一种情况下,我们有一个脚本可以显示特殊的表单来定义一些复杂的设置。
编辑:
应用程序当然没有引用“调试”类库。它只需要加载程序集......
I used CS-Script to create something like you want. In my case I defined an interface in my application. A script then just needed to implement this interface so that it could be run from the application. My application was about processing scanned images and therefore my interface looked something like this:
This way my script could access the object model that I defined in my application (in my case through IBatch). The good thing was that during development I could use a normal Class Library project for the script: IntelliSense, debugging... I do not remember the exact details but I basically had a switch in my application that told the app to use the
referencedclass library instead of a script.Furthermore I made an additional interface that allowed the scripts to be configured: A script could define a set of properties which were then displayed by my application in a property grid. I think I used this version here as this seemed a bit more flexible at the time. This way you can not only allow users to configure the script, but you can also provide help in form of descriptions, choices, default values... The property grid is quite extensible: In one case we had a script that would display a special form to define some complex settings.
Edit:
The application of course did not have a reference to "debug" class library. It just need to load the assembly...
对于免费、易于实现的 .NET 脚本语言,请查看 C#。
请参阅我对类似问题的回答。
至于公开数据,看看它是一种.NET语言,您只需将您的程序添加到程序集中即可链接到并使相关类公开。
For a free, easy to implement .NET scripting language, have a look at C#.
See my answer to a similar question.
As for exposing data, seeing how it's a .NET language, you just need to add your program into the assemblies to link into and make the relevant classes public.
我不确定这是否能满足您的需求,但通过反射,您可以编译 C# 代码并在运行时执行它(示例代码 此处)。
所以你可以在例如中编写脚本。 C#,然后“即时编译”并直接在应用程序的上下文中运行它。当然,您必须牢记安全注意事项,但如果脚本是可信的,那么它可能对您有用,并且您可以获得为脚本使用强大的托管语言的好处。
如果您需要高性能或运行数千个脚本,那么它可能会太慢。
I'm not sure this will cover your needs, but via reflection you can compile C# code and execute it at runtime (example code here).
So you could write the script in eg. C# and then compile "it on the fly" and run it directly in the context of your application. Of course you have to keep security considerations in mind, but if the scripts are trusted then it might work for you, and you get the benefits of using a powerful managed language for your scripts.
If you need high performance or running thousands of scripts it might be too slow though.
我实现了 CS-Script 作为我编写的工作流系统的最后一个脚本平台。所需的每个工作流都有不同的条件,这些条件决定了用户将订阅各种任务以及谁将接收电子邮件。通过脚本模型,可以轻松地将新步骤引入工作流程并处理这些任务所需的独特要求。
脚本模型的另一个好处是可以在各种条件下测试工作流,并且可以采用迭代方法来最终确定工作流行为。在质量保证和用户验收测试期间,我在脚本中添加了日志记录功能,以便我可以更轻松地查找问题。
使用 CS-Script,您可以完全访问您的对象;也就是说,当您的脚本导入程序集时,您可以在脚本代码中实例化您的对象。此外,您可以保留已编译的脚本并只需向它们提供参数。如果程序集使用参数对象或字典,则可以传递脚本并在参数对象中包含的对象上执行方法。
I implemented CS-Script as the scripting platform last for a workflow system I wrote. Each wrokflow needed had different conditions that dictated what users would subscribe to various tasks and who would receive emails. With a scripting model it became easy to introduce new steps into the workflows and handle unique requirements that those tasks required.
The other nice by product of the scripting model was that workflows could be tested under a variety of conditions, and an iterative approach could be taken to finalize the workflow behaviors. During QA and user acceptance testing I included logging functions in the scripts to that I could hunt issues more easily.
With CS-Script you have complete access to you objects; that is, when your script imports your assemblies you can instantiate your object in your script code. Furthermore, you can retain your compiled scripts and simply supply parameters to them. If your assemblies use a parameters object or a Dictionary, you can pass that your script and execute methods on the objects contained in the parameter object.