2008-11-12 20 views
0

Je travaille sur une application dans laquelle j'ai un dossier images relatif à ma racine d'application. Je veux être en mesure de spécifier ce chemin relatif dans le concepteur Propriétés -> Paramètres par exemple. "\Images\". Le problème que je rencontre est dans les cas où le Environment.CurrentDirectory est changé via un OpenFileDialog le chemin relatif ne se résout pas au bon endroit. Existe-t-il un moyen de spécifier dans le fichier Settings un chemin qui impliquera de toujours partir du répertoire de l'application par opposition au répertoire courant? Je sais que je peux toujours concaténer dynamiquement le chemin de l'application au début du chemin relatif, mais je voudrais que ma propriété Settings soit capable de se résoudre elle-même. Pour autant que je sache, il n'y a pas de fonctionnalité intégrée qui permette ce type de résolution de chemin.Paramètres .NET Chemin relatif

Répondre

1

Votre meilleure option est de déterminer dynamiquement les applications en train d'exécuter le répertoire et de concaténer le chemin de votre image. Vous ne voulez pas utiliser Environment.CurrentDirectory spécifiquement pour les raisons que vous mentionnez - le répertoire actuel n'est pas toujours correct pour cette situation.

Le code plus sûr que j'ai trouvé pour trouver l'emplacement de montage d'exécution est la suivante:

public string ExecutingAssemblyPath() 
{ 
    Assembly actualAssembly = Assembly.GetEntryAssembly(); 
    if (this.actualAssembly == null) 
    { 
     actualAssembly = Assembly.GetCallingAssembly(); 
    } 
    return actualAssembly.Location; 
} 
+0

Vous avez un 'this.' qui ressemble à un bug - et dans quelles circonstances avez-vous réellement besoin de cette instruction' if'? BTW, sachez que 'GetCallingAssembly' peut faire des choses surprenantes si l'appelant conceptuel est incorporé par le moteur d'exécution. J'évite cette méthode pour cette raison, et recherche simplement un assembly par 'Type' à la place. C'est au moins sûr. –

0

2 options:

  • Le code qui utilise le paramètre peut résoudre le réglage par rapport au répertoire de l'assembly en cours d'exécution.
  • Vous pouvez créer votre propre type sérialisé en tant que chaîne par rapport à l'assembly en cours d'exécution, et dispose d'un accesseur pour le chemin d'accès complet qui sera résolu par rapport au répertoire de l'assembly en cours d'exécution.

Exemple de code:

string absolutePath = Settings.Default.ImagePath; 
if(!Path.IsPathRooted(absolutePath)) 
{ 
    string root = Assembly.GetEntryAssembly().Location; 
    root = Path.GetDirectoryName(root); 
    absolutePath = Path.Combine(root, absolutePath); 
} 

La bonne chose à propos de ce code est qu'il permet un chemin complet ou un chemin relatif, dans les paramètres. Si vous avez besoin que le chemin soit relatif à un assemblage différent, vous pouvez changer l'emplacement de l'assemblage que vous utilisez - GetExecutingAssembly() vous donnera l'emplacement de l'assemblage avec le code que vous utilisez, et GetCallingAssembly() serait bien si vous allez avec l'option 2

1

Vous recherchez Application.ExecutablePath? Cela devrait vous indiquer où se trouve l'exécutable de l'application, supprimer le nom de l'exécutable, puis ajouter votre chemin d'accès.

+0

Cela ne fonctionnera que s'il s'agit d'une application Windows Forms. Il renvoie également le chemin du fichier exécutable qui a démarré l'application, y compris le nom de l'exécutable, de sorte que vous ne devez supprimer que la partie du chemin. –

+0

J'ai fait l'hypothèse qu'il s'agissait d'une application .NET en raison de la mention de Environment.CurrentDirectory. –

+0

.NET! = WinForms –

0

Cela semble fonctionner dans les deux WinForms et ASP.NET (donne le chemin vers le fichier de configuration ):

new System.IO.FileInfo(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile).Directory; 

Pour les applications Windows et de la console, la manière évidente est à l'aide:

Application.StartupPath 
0

I suggest you à utiliser Assembly.CodeBase, comme indiqué ci-dessous:

public static string RealAssemblyFilePath() 
{ 
    string dllPath=Assembly.GetExecutingAssembly().CodeBase.Substring(8); 
    return dllPath; 
} 

Vous pouvez essayer Application.ExecutablePath. Mais vous devez faire référence à System.Windows.Forms. Cela peut ne pas être une bonne idée si vous souhaitez que votre bibliothèque de classes évite les formulaires et les problèmes d'interface utilisateur.

Vous pouvez essayer le Assembly.GetExecutingAssembly().Location. Mais si, d'une manière ou d'une autre, vous faites une «copie fantôme» avant d'exécuter votre application (comme le comportement NUnit par défaut), cette propriété vous renvoie l'emplacement de la copie miroir et non l'emplacement physique réel.La meilleure façon consiste à implémenter une fonction qui appelle la propriété CodeBase de l'objet Assembly et couper la partie non pertinente de la chaîne.

0

J'utilise les deux méthodes suivantes pour aider à ce que:

public static IEnumerable<DirectoryInfo> ParentDirs(this DirectoryInfo dir) { 
    while (dir != null) { 
     yield return dir; 
     dir = dir.Parent; 
    } 
} 
public static DirectoryInfo FindDataDir(string relpath, Assembly assembly) { 
    return new FileInfo((assembly).Location) 
     .Directory.ParentDirs() 
     .Select(dir => Path.Combine(dir.FullName + @"\", relpath)) 
     .Where(Directory.Exists) 
     .Select(path => new DirectoryInfo(path)) 
     .FirstOrDefault(); 
} 

La raison de regarder dirs parents pour être plus facile à utiliser au cours du développement lorsque les scripts différents de construction finissent par coller des choses dans des répertoires comme bin\x64\Release\NonsensePath\.