我在我的宠物开源项目RevitPythonShell(建筑建模软件Autodesk Revit Architecture 2010的插件)中尝试了明显的路径:code.interact()使用IronPython引擎设置为STDIN和使用.NET流STDOUT.然后我将这些重定向到TextBox控件.它有点工作,但真的只是一个丑陋的黑客.
主要问题是让所有shell工作正常工作:历史记录的上箭头和下箭头,编辑,复制和粘贴,EOF,语法高亮,工具提示等.要做到这一点需要做很多工作,而且它并不是我想要解决的问题(我正在尝试在Revit中托管交互式shell,而不是制作完美的shell GUI).
如果这不是一个.NET项目,我可能会考虑重用PyCrust/PyWrap,但我不确定是否可以从WinForms项目中完成..NET有什么类似的东西吗?
有没有人实现过IConsole界面,可以展示我需要做什么的例子?看起来这将是正确的路线(而不是使用code模块),但对于我的生活,我无法弄明白.IronPython源代码没有任何评论.
更新:在尝试了一些东西后,我最终选择了精湛的IronLab代码.它包括一个带语法高亮的示例shell和all.代码很好,易于集成.检查有关如何嵌入它的提示的RevitPythonShell代码.
我想要这样做的简短解释:
我正在为Autodesk Revit Architecture 2010编写插件.测试我的插件代码非常麻烦,因为我必须为每个调试会话重新启动Autodesk,手动加载Revit项目,单击Add-Ins选项卡然后启动我的插件.这花了太长时间.
我写了第二个插件来托管IronPython解释器.通过这种方式,我可以使用Revit提供的API.但最终,代码必须在C#中重写 - 并进行调试.
很简单,我想:只需从IronPython脚本加载插件DLL并进行练习即可.这确实有效,但一旦加载,我无法在Visual Studio中重新编译,因为DLL现在已加载到Revits AppDomain中.
很简单,我想(在StackOverflow的帮助下):只需在新的AppDomain中加载DLL即可.唉,RevitAPI对象无法封送到另一个AppDomain,因为它们不会扩展MarshalByRefObject.
我想我可能会使用影子副本.ASP.NET似乎正在这样做.但是阅读MSDN上的文档,似乎我只能在创建 AppDomain 时指定它.
我可以为当前(默认)AppDomain更改此设置吗?我可以强制它使用特定目录中的DLL的卷影副本吗?
好.我们的产品有效.Beta测试人员实际上正在完成他们的工作.下一次迭代的时间.但如何保证质量?我们需要一个测试员!
我如何让新鲜的人在街上开始测试?我不知道如何自己做(我是开发人员,而不是测试人员)!
我们是一个小团队:
我们都不知道如何专业地做这件事.到目前为止,我们有:
我希望我们需要一个测试脚本.但是怎么样?谁?什么?什么时候?
我有一个应用程序,我想嵌入我们的公司CMS.(我被告知)这样做的唯一方法是将其加载到<iframe>.
很简单:只需设置height和width对100%!除此之外,它不起作用.
我没有找到有关设置frameborder到0,所以它至少看起来就像网站的一部分,但我不希望有一个丑陋的滚动条,里面是媒体链接有一个页面.
你知道做这个的任何技巧吗?
编辑:我想我需要在某种程度上澄清我的问题:
<iframe>iframe,所以任何解决方案都必须在引用的页面上工作(根据标签的src属性iframe)我可以从引用的页面访问父页面DOM吗?这可能有所帮助,但我可以看到有些人可能不希望这是可能的......
这种技术似乎有效(从几个来源收集,但受到接受答案的链接的启发:
在父文件中:
<iframe id="MyIFRAME" name="MyIFRAME"
src="http://localhost/child.html"
scrolling="auto" width="100%" frameborder="0">
no iframes supported...
</iframe>
Run Code Online (Sandbox Code Playgroud)
在孩子:
<!-- ... -->
<body>
<script type="text/javascript">
function resizeIframe() {
var docHeight;
if (typeof document.height != 'undefined') {
docHeight = document.height;
}
else if (document.compatMode && document.compatMode != …Run Code Online (Sandbox Code Playgroud) 在Scratch中,感知类别中存在称为触摸的条件,其可以具有边缘作为参数.
鉴于条件返回true,我如何判断哪个边被触摸(即场景的顶部,底部,左侧或右侧边缘)?
或者:如何分辨场景的尺寸?我已经算出位置(x = 0,y = 0)位于场景的中间.四个角点在哪里?
在gcc编译器中sizeof(main),sizeof(printf)和sizeof(scanf)所有这些都是1.我想知道所有这些的大小是多少1.它背后的逻辑是什么?
假设我有第三方应用程序执行后台工作,但将所有错误和消息打印到控制台.这意味着,目前,我们必须让用户登录到服务器,并在每次重新启动时重新启动应用程序(双击).
不太酷.
我很确定,有一种简单的方法可以做到这一点 - 通用服务包装器,可以配置日志文件stdout和stderr.
我做了检查svchost.exe,但根据这个网站,它只用于DLL的东西.可怜.
编辑:应用程序需要从批处理文件启动.FireDaemon似乎可以做到这一点,但我觉得它有点矫枉过正,因为可以在<10行的python代码中完成......哦,不是在这里发明的 ......
加载对程序集的引用后,例如:
import clr
clr.AddRferenceToFileAndPath(r'C:\foo.dll')
Run Code Online (Sandbox Code Playgroud)
如何再次卸载组件?
为什么有人想要这样做?因为我正在重新编译foo.dll并想重新加载它,但编译器给了我一个大惊小怪,因为IronPython已经全部访问了foo.dll.
我试过了明显的事:
var appDomain = AppDomain.CreateDomain("New Domain");
var engine = IronPython.Hosting.Python.CreateEngine(appDomain); // boom!
Run Code Online (Sandbox Code Playgroud)
但我收到以下错误消息:成员'Microsoft.Scripting.Hosting.ScriptRuntimeSetup,Microsoft.Scripting,Version = 0.9.0.0,Culture = neutral,PublicKeyToken = 31bf3856ad364e35'的类型未解析.
谷歌搜索这个错误并没有证明是富有成效的...
编辑#1:
我试图通过将相关内容复制到新的控制台应用程序来创建一个最小的复制项目:
using System;
using Microsoft.Scripting;
namespace PythonHostSamle
{
class Program
{
static void Main(string[] args)
{
AppDomain sandbox = AppDomain.CreateDomain("sandbox");
var engine = IronPython.Hosting.Python.CreateEngine(sandbox);
var searchPaths = engine.GetSearchPaths();
searchPaths.Add(@"C:\Python25\Lib");
searchPaths.Add(@"C:\RevitPythonShell");
engine.SetSearchPaths(searchPaths);
var scope = engine.CreateScope();
//scope.SetVariable("revit", _application);
//engine.Runtime.IO.SetOutput(new ScriptOutputStream(_instance), Encoding.UTF8);
//engine.Runtime.IO.SetErrorOutput(new ScriptOutputStream(_instance), Encoding.UTF8);
var script = engine.CreateScriptSourceFromString("print 'hello, world!'", SourceCodeKind.Statements);
script.Execute(scope);
Console.ReadKey();
}
}
}
Run Code Online (Sandbox Code Playgroud)
这按预期工作!
因此,我得出的结论是,我得到的错误与我注释掉的一行 …