2009-09-08 8 views
2

J'introduis IronPython dans un programme C#. Je comprends que j'ai besoin d'appeler ScriptEngine.SetSearchPaths avec une liste de chemins de recherche afin que mon code Python puisse importer des modules. En particulier, je dois le faire savoir où les modules de la bibliothèque standard sont, dans mon cas sont ici:Comment accéder au répertoire IronPython Lib à partir du moteur intégré?

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

Ma question est, comment ce chemin se trouve programatically?

Il peut évidemment être fait parce que la console IronPython le sait:

>>> 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'] 

Répondre

2

Une solution possible serait d'expédier une copie du dossier Lib avec votre application. Je crois que la licence IronPython (Microsoft Public License (Ms-PL)) et la licence Python (Python License) le permettront.

Avantages pour ce plan:

  1. Il sera facile pour l'application pour trouver le dossier Lib.

  2. L'installation sera plus facile puisqu'il y aura un installateur de moins à traiter.

  3. La taille totale de l'installateur sera plus petite. Si les assemblys IronPython que l'application utilise sont copiés localement, il est logique de copier aussi Lib, de sorte que les deux ne seront pas désynchronisés comme ils le feraient si le Lib de Program Files était utilisé.

Les licences ne semblent pas imposer d'obligations onéreuses. Le Ms-PL exige que vous incluiez une copie complète de la Ms-PL dans les distributions, mais ce n'est pas une grosse affaire.

Edit: Voici le code

Voici ce que je faisais.

Le dossier Lib est copié dans la cible AfterBuild de mon fichier .csproj. Je ne pouvais pas savoir comment utiliser la commande de copie MSBuild intégrée, car tout ce qui concerne MSBuild est conçu pour être extrêmement douloureux, j'ai donc utilisé robocopy à la place. (robocopy est le remplacement de xcopy, vous pouvez utiliser xcopy à la place).

<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> 

Il copie les fichiers de licence (tel que requis par la licence) et exclut les dossiers de subversion (svn de).

Le dossier "3rdParty" se trouve au niveau racine de ma solution Visual Studio. C'est là que je garde les bibliothèques tierces.

J'ignore le code de sortie pour robocopy parce que <Exec> ne peut pas traiter les codes de sortie de robocopy. Ce n'est pas idéal, mais je suppose que la copie simple dans la ligne suivante ramassera n'importe quels problèmes.

Voilà comment je trouve le chemin Lib dans le code:

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

Pour copier Lib dans un test unitaire, faire quelque chose comme ceci:

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

Essayez de regarder:

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

Le GUID doit être la même (je pense, atleast pour la même version de IronPython), alors ça devrait aller. Cela vous donnera le répertoire d'installation, vous pouvez simplement ajouter @"\Lib"

+0

Suggérez-vous que l'OP change son code chaque fois que la version d'IronPython change? – Gabe

2

ipy.exe calcule cette base sur le fichier EXE qui a commencé le processus:

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"); 
    ... 

Vous pouvez aussi regarder l'emplacement de la place IronPython.dll :

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

Je ne pense pas que cela fonctionnera car les assemblys IronPython vont vivre dans le dossier de mon application. Cela me donne une idée si ... (je vais l'écrire.) –

0

Créer une variable d'environnement, et l'accès que variable d'environnement d'IronPython. Cela devrait être la façon la plus directe de le faire.

Questions connexes