2009-09-08 86 views
2

我在C#程序中嵌入IronPython。我知道我需要用一系列搜索路径调用ScriptEngine.SetSearchPaths,以便我的Python代码可以导入模块。我特别要让它知道在哪里的标准库模块,这在我的情况在这里:如何从嵌入式引擎进入IronPython Lib目录?

C:\Program Files (x86)\IronPython 2.0.2\Lib 

我的问题是,如何可以在路径编程发现了什么?

它显然可以做到,因为IronPython的控制台知道它:

>>> import sys 
>>> sys.path 
['C:\\Windows\\system32', 'C:\\Program Files (x86)\\IronPython 2.0.2\\Lib', 'C:\\Program Files (x86)\\IronPython 2.0.2', 'C:\\Program Files (x86)\\IronPython 2.0.2\\lib\\site-packages'] 

回答

2

一个可能的解决方案是将一个Lib文件夹的副本与您的应用程序一起发送。我相信IronPython许可证(Microsoft Public License (Ms-PL))和Python许可证(Python License)都会允许这样做。

好处这个计划:

  1. 这将是容易的应用程序,找到lib文件夹。

  2. 由于安装人员较少,因此安装将变得更加容易。

  3. 安装程序的总大小将变小。

  4. 如果应用程序使用的IronPython程序集在本地复制,那么复制Lib也是有意义的,这样它们就不会像使用程序文件的Lib时那样不同步。

许可证似乎没有施加任何繁重的义务。 Ms-PL要求您在发行版中包含Ms-PL的完整副本,但这并不重要。

编辑:下面的代码

下面是我做的。

Lib文件夹被复制到我的.csproj文件的AfterBuild目标中。我无法弄清楚如何使用内置的MSBuild复制命令,因为所有与MSBuild有关的操作都是最大的痛苦,所以我使用了robocopy。 (robocopy是xcopy的替代品;您可以改为使用xcopy)。

<Target Name="AfterBuild"> 
    <Exec Command="robocopy $(ProjectDir)..\3rdParty\IronPython\IronPython2.0.2\Lib $(OutputPath)IronPython\Lib /E /XD .svn" IgnoreExitCode="true" /> 
    <Exec Command="copy $(ProjectDir)..\3rdParty\IronPython\IronPython2.0.2\license.* $(OutputPath)IronPython\" /> 
</Target> 

它复制许可证文件(根据许可证的要求),它不包括颠覆文件夹(.svn)。

“3rdParty”文件夹位于我的Visual Studio解决方案的根级别。这是我保存第三方库的地方。

我忽略了robocopy的退出代码,因为<Exec>无法处理robocopy的退出代码。这并不理想,但我认为下一行中的简单副本会带来任何问题。

这是我找到的代码库路径:

var assemblyPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); 
var libPath = Path.Combine(assemblyPath, @"IronPython\Lib"); 

要在单元测试复制库,做这样的事情:

[TestMethod()] 
[DeploymentItem(@"3rdParty\IronPython\IronPython2.0.2\Lib", @"IronPython\Lib")] 
public void MyTest() 
{ 
    // ... 
1

试着看一下:

 
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{80B8E2FB-A8AB-4CBF-836A-B43DE3B3C3F6}\InstallLocation 

的GUID应该是相同的(我认为,至少为同一版本IronPython),所以你应该没问题。这会给你的安装目录,那么你可以追加@"\Lib"

+0

您是否建议OP在每次IronPython版本更改时更改其代码? – Gabe 2012-02-06 22:41:02

2

ipy.exe这个计算基于EXE赖以起家的过程:

Assembly entryAssembly = Assembly.GetEntryAssembly(); 
// Can be null if called from unmanaged code (VS integration scenario) 
if (entryAssembly != null) { 
    string entry = Path.GetDirectoryName(entryAssembly.Location); 
    string lib = Path.Combine(entry, "Lib"); 
    ... 

你也可以看看IronPython.dll的位置,而不是:

Assembly entryAssembly = typeof(Hosting.Python).Assembly; 
+0

我不认为这将工作,因为IronPython程序集将生活在我的应用程序的文件夹中。这虽然给了我一个想法......(我会写出来的。) – 2009-09-09 12:15:09

0

创建一个环境变量,并访问来自IronPython的环境变量。这应该是最直接的方式。