69 votes

c # Vérifier si un exécutable existe dans le chemin de Windows

Si je lance un processus en ShellExecute (ou dans .net avec System.Diagnostics.Process.Start()) le nom de fichier du processus de démarrage n'a pas besoin d'être un chemin d'accès complet.

Si je veux démarrer le bloc-notes, je peux l'utiliser

Process.Start("notepad.exe");

au lieu de

Process.Start(@"c:\windows\system32\notepad.exe");

parce que le répertoire c:\windows\system32 fait partie de la variable d'environnement PATH.

comment puis-je vérifier si un fichier existe sur le CHEMIN sans l'exécution du processus et sans l'analyse de la variable de CHEMIN d'accès?

System.IO.File.Exists("notepad.exe"); // returns false
(new System.IO.FileInfo("notepad.exe")).Exists; // returns false

mais j'ai besoin de quelque chose comme ceci:

System.IO.File.ExistsOnPath("notepad.exe"); // should return true

et

System.IO.File.GetFullPath("notepad.exe"); // (like unix which cmd) should return
                                           // c:\windows\system32\notepad.exe

Est-il un prédéfini classe pour faire cette tâche à la disposition de la BCL?

70voto

digEmAll Points 24336

Je pense qu'il n'y a rien d'intégré, mais vous pouvez faire quelque chose comme ceci avec System.IO.File.Exists :

 public static bool ExistsOnPath(string fileName)
{
    if (GetFullPath(fileName) != null)
        return true;
    return false;
}

public static string GetFullPath(string fileName)
{
    if (File.Exists(fileName))
        return Path.GetFullPath(fileName);

    var values = Environment.GetEnvironmentVariable("PATH");
    foreach (var path in values.Split(';'))
    {
        var fullPath = Path.Combine(path, fileName);
        if (File.Exists(fullPath))
            return fullPath;
    }
    return null;
}
 

32voto

Hans Passant Points 475940

C'est risqué, il ya beaucoup plus à lui que juste à rechercher les répertoires dans le CHEMIN d'accès. Essayez ceci:

 Process.Start("wordpad.exe");

L'exécutable est stocké dans c:\Program Files\Windows NT\Accessoires sur ma machine, ce répertoire est pas sur le chemin. La clé HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths clé joue un rôle dans la recherche des fichiers exécutables. Je suis assez sûr il y a d'autres mines terrestres de ce genre partout, répertoire de la virtualisation dans les versions 64 bits de Windows pourraient vous passionner par exemple.

Pour le rendre plus fiable, je pense que vous devez pinvoke AssocQueryString(). Pas sûr, n'a jamais eu le besoin. La meilleure approche est certainement de ne pas avoir à se poser la question.

21voto

Dunc Points 4360

Ok, une meilleure façon je pense ...

Ceci utilise la commande where , disponible au moins sur Windows 7 / Server 2003:

 public static bool ExistsOnPath(string exeName)
{
    try
    { 
        Process p = new Process();
        p.StartInfo.UseShellExecute = false;
        p.StartInfo.FileName = "where";
        p.StartInfo.Arguments = exeName;
        p.Start();
        p.WaitForExit();
        return p.ExitCode == 0; 
    }
    catch(Win32Exception)
    {
        throw new Exception("'where' command is not on path");
    }   
}


public static string GetFullPath(string exeName)
{
    try
    { 
        Process p = new Process();
        p.StartInfo.UseShellExecute = false;
        p.StartInfo.FileName = "where";
        p.StartInfo.Arguments = exeName;
        p.StartInfo.RedirectStandardOutput = true;
        p.Start();
        string output = p.StandardOutput.ReadToEnd();
        p.WaitForExit();

        if (p.ExitCode != 0)
            return null;

        // just return first match
        return output.Substring(0, output.IndexOf(Environment.NewLine));
    }
    catch(Win32Exception)
    {
        throw new Exception("'where' command is not on path");
    }   
}
 

2voto

alleey Points 21

Je suis après la même chose et je pense que la meilleure option que j'ai à présent est d'utiliser l'appel natif à CreateProcess pour créer un processus suspendu et veiller au succès. mettre fin au processus immédiatement après. Mettre fin à un processus suspendu ne devrait entraîner aucune perte de ressources [citation nécessaire :)]

Je ne saurais peut-être pas trouver le chemin qui a été utilisé, mais pour une simple exigence telle que ExistsOnPath (), cela devrait être le cas - jusqu'à ce qu'il y ait une meilleure solution.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X