2010-07-02 5 views
14

J'ai ce code pour charger un fichier de configuration et lire toutes les valeurs. Il fonctionne correctement lors de l'exécution de l'application mais échoue bien sur city city car le répertoire de base de l'appdomain est le script de démarrage. Je sais que je peux changer de répertoire dans le répertoire de construction avant d'exécuter les tests, mais j'ai pensé qu'il est préférable de charger le fichier de configuration à tout moment.Meilleure façon d'obtenir le répertoire de base?

XDocument.Load(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, cfgFile)); 

Y at-il une autre façon d'obtenir le « BaseDirectory » qui fonctionne vraiment tout le temps? J'ai essayé le ci-dessous et avec les mêmes résultats:

string path = Path.GetDirectoryName(Assembly.GetExecutingAssembly().CodeBase); 
XDocument.Load(Path.Combine(path, cfgFile)); 

EDIT 1 Le problème est le suivant. Le répertoire de base de mes solutions est "C: \ Project", tous les fichiers compilés sont copiés dans "C: \ Project \ build". Maintenant, dans le script de construction de psake Je le code suivant:

task Test -depends PrepareTests { 
    try { 
     #$old = pwd 
     #cd $build_dir 
     &$mspec $mspec_projects --teamcity 
     #cd $old 
    } 
    catch { 
     &echo "Error starting test runner" 
     Exit 1; 
    }  
} 

Comme vous pouvez le voir, je commentais le changement des répertoires qui rend le BaseDirectory l'emplacement du fichier de construction/solution au lieu du répertoire de construction, peu importe comment J'essaie d'y accéder. Un peu déroutant si vous me demandez.

MISE À JOUR J'aime vraiment savoir s'il est possible d'obtenir le répertoire de l'assembly quel que soit le répertoire dans lequel se trouve l'application qui a démarré le domaine de l'application. Comment?

+2

Que voulez-vous dire "répertoire de base"? Où se trouve le fichier de configuration par rapport à l'assemblage? Votre deuxième exemple devrait fonctionner si le fichier de configuration est dans le même répertoire que la DLL ... –

+0

Ajouté plus d'infos – mhenrixon

+0

Vous voulez donc le répertoire où se trouve le fichier .exe? – Craig

Répondre

5
string origAssemblyLocation = Assembly.GetExecutingAssembly().CodeBase; 

Par MSDN:

Assembly.CodeBase Propriété

Obtient l'emplacement de l'ensemble comme spécifié à l'origine

+0

J'ai dû supprimer le nom de la DLL mais il me fait en effet l'emplacement sur le disque de l'assemblage! – mhenrixon

+2

Attention, cela donne une chaîne de type uri, c'est-à-direfile: ///foo/bar/baz.DLL – knocte

5

Votre question est un peu floue. Je ne sais pas vraiment si c'est ce que tu veux.

J'utilise généralement AppDomain.CurrentDomain.BaseDirectory

Alternatives

  • Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)
  • Environment.CurrentDirectory
+0

Merci pour cette suggestion mais elle produit le même résultat. – mhenrixon

1

essayer celui-ci:

Module[] modules = Assembly.GetExecutingAssembly().GetModules(); 
    return Path.GetDirectoryName(modules[0].FullyQualifiedName); 
+0

Merci je n'ai pas essayé celui-là avant. Il essaie toujours de trouver le fichier xml dans le répertoire de la solution à la place du répertoire de construction. – mhenrixon

+0

vous pouvez enregistrer le fichier d'assemblage dans la construction directe après les avoir copiés. – Arseny

1

avez-vous essayé d'obtenir le FileName du processus en cours 'MainModule?

System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName 

ou GetEntryAssembly()?

System.Reflection.Assembly.GetEntryAssembly().Location 
8

Il semble donc/ressemble que vous essayez d'obtenir le fichier de configuration pour un assemblage. Ce qui suit devrait accomplir cette tâche en accédant à la propriété « Localisation » de l'ensemble et l'utiliser pour récupérer le chemin de configuration:

static string GetConfigFileByType(Type type) 
{ 
    Configuration config = 
     ConfigurationManager.OpenExeConfiguration(type.Assembly.Location); 

    if (config.HasFile) 
     return config.FilePath; 
    throw new FileNotFoundException(); 
} 
1

J'aime faire mes classes configurable - par exemple, ils obtiennent le nom du dossier en tant que paramètre dans leur constructeur. Cela permet de tester avec différents fichiers de configuration.

Dans le code de test que nous utilisons:

TestContext.TestDeploymentDir 

C'est le dossier TestRun, où tous les ensembles pour un essai sont copiés, ainsi que les éléments de déploiement de test. Nous 'déployons' nos fichiers de configuration de test d'unité dans le dossier d'exécution de test - ceci peut être spécifié dans la boîte de dialogue de testrunconfig dans Visual Studio.

Pour notre code de production nous passons

Assembly.GetExecutingAssembly().Location 

au constructeur, qui travaille pour nous.

+0

"Si le fichier chargé a été copié, l'emplacement est celui du fichier après avoir été copié."/La propriété Location ne donnera pas au PO ce qu'il recherche dans ce cas. – hemp

+0

En note, c'est mieux si vous envisagez d'utiliser le pont de bureau – Alexander

1

que diriez-vous:

Application.StartupPath; 
16

différents moyens d'obtenir le répertoire de base

  1. AppDomain.CurrentDomain.BaseDirectory

  2. Directory.GetCurrentDirectory() // ne pas fonctionner sur l'application mobile

  3. Environment.CurrentDirectory // appelle ce Directory.GetCurrentDirectory()

  4. this.GetType().Assembly.Location// Assembly.location

  5. Application.StartupPath // pour Windows Forms applications

  6. Application.ExecutablePath // même que Application.StartupPath

Questions connexes