代码之家  ›  专栏  ›  技术社区  ›  dan-gph

如何从嵌入式引擎获取Ironpython lib目录?

  •  2
  • dan-gph  · 技术社区  · 15 年前

    我正在C程序中嵌入Ironpython。我知道我需要用搜索路径列表调用scripteengine.setsearchpaths,这样我的python代码就可以导入模块。特别是,我必须让它知道标准库模块在哪里,在我的例子中是:

    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'] 
    
    4 回复  |  直到 10 年前
        1
  •  2
  •   Dino Viehland    15 年前

    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;
    
        2
  •  2
  •   dan-gph    10 年前

    一个可能的解决方案是将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 copy命令,因为与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>
    

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

    “第三方”文件夹位于我的Visual Studio解决方案的根级别。这是我存放第三方图书馆的地方。

    我忽略了robocopy的退出代码,因为 <Exec> 无法处理Robocopy的退出代码。这并不理想,但我假设下一行中的普通副本会解决任何问题。

    这是我在代码中查找lib路径的方法:

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

    要在单元测试中复制lib,请执行如下操作:

    [TestMethod()]
    [DeploymentItem(@"3rdParty\IronPython\IronPython2.0.2\Lib", @"IronPython\Lib")]
    public void MyTest()
    {
        // ...
    
        3
  •  1
  •   Matthew Scharley    15 年前

    试试看:

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

    guid应该是相同的(我认为,至少对于同一版本的Ironpython来说是一样的),所以在这里您应该很好。这将为您提供安装目录,然后您可以附加 @"\Lib"

        4
  •  0
  •   ashwnacharya    13 年前

    创建一个环境变量,并从Ironpython访问该环境变量。这应该是最直接的方法。