2010-11-09 18 views
11

Aby wyjaśnić: Pytanie brzmi naprawdę: Jak zlokalizować klienta wiersza polecenia Mercurial. Jeśli odpowiedź dotyczy dowolnego pliku wykonywalnego, tym lepiej, ale naprawdę interesuje mnie plik wykonywalny hg.exe.Jak znaleźć pełną ścieżkę do pliku wykonywalnego Mercurial, gdy system Windows jest w stanie go zlokalizować?

Jeśli znam nazwę pliku wykonywalnego, na przykład hg.exe, klienta wiersza polecenia Mercurial i systemu Windows wie, gdzie to jest, ponieważ mogę wykonać tylko hg log z wiersza polecenia i wykonuje, jakie kroki są zaangażowane w celu dla mnie znaleźć ten plik wykonywalny w taki sam sposób, w jaki robi to wiersz polecenia i system Windows?

Zasadniczo, jeśli system Windows jest w stanie go zlokalizować, chcę, aby mój program mógł go zlokalizować.

Czy istnieje funkcja WinAPI lub podobna? Kod będzie działał w .NET, napisanym w C#, więc jeśli jest coś wbudowanego w .NET, to byłoby to preferowane rozwiązanie, ale poza tym nie mam nic przeciwko używaniu P/Invoke do tego.

Widziałem jeden potencjalny duplikat tego pytania: c# Check if an executable exists in the windows path, ale czy wszystko w nim jest? Po prostu powtórzenie zawartości zmiennej środowiskowej PATH i przejrzenie w każdym z tych katalogów pliku wykonywalnego?

Mam niejasne wyobrażenie, że jest to tylko jeden z kroków i prawdopodobnie istnieją nadpisania rejestru, z których Windows może korzystać, o których powinienem wiedzieć, więc opublikuję tutaj pytanie.

Jeśli, z drugiej strony, rzeczywiście istnieje tutaj tylko zmienna PATH, prawdopodobnie można ją bezpiecznie zamknąć jako duplikat.

Odpowiedz

3

To zależy od sposobu zarejestrowania programu w systemie. Ponieważ hg jest generalnie uruchamiany z obu narzędzi lub wiersza poleceń, nie zostanie zarejestrowany w systemie. Jeśli tak, istnieje zestaw kluczy rejestru, który ma nazwę exe i ścieżkę. W przeciwnym razie wystarczy przejrzeć ścieżkę od pierwszego wpisu do ostatniego, aż znajdziesz potrzebny plik. Pierwszy znaleziony na ścieżce wygrywa.

Przykłady takiego "zarejestrowanego" programu, programu Excel lub Winword.

EDIT:

@BillyONeal sprawia, że ​​dobry punkt poniżej, które działa tylko dla „run” programów sterujących, ale mój punkt tam było drugie miejsce spojrzeć.

Dodatkowo, dla tych, którzy nie widzieli tego, oto install procedures:

Alternatywny system, który działa lepiej dla niektórych jest poszukiwanie Hg na ścieżce

+0

Ok, to jest to, co zrobię. Kod i tak nie jest ustawiony w kamieniu, więc jeśli dowiem się więcej później, zawsze mogę to zmienić. Metoda PATH działa teraz dobrze na komputerach, na których ją testowałem, więc na razie będę to robiła. Dzięki. –

+1

Niezupełnie. "Rejestracja" (lub raczej klucz rejestru Ścieżki aplikacji) jest używana tylko podczas uruchamiania procesu za pomocą powłoki ShellExecute (zgodnie z metodą "Uruchom ..."), ale nie przez proces CreateProcess (jak zostało to wykonane przez procesor poleceń) –

+0

@BillyOneal good punkt, ale miałem zamiar opublikować adres URL z grupy hg o tym, jak to jest zależne od% PATH%. – jcolebrand

2

wykonywalne obciążenia określonego do pierwszej zgodnej instancji ścieżki systemowej. Jeśli jest wykonywany ze skrótu lub innego trybu, który używa bezwzględnej ścieżki, to oczywiście jest to wersja, która działa.

Pliki DLL są nieco bardziej skomplikowane - w przypadku natywnych bibliotek DLL istnieją przesłonięcia, być może o tym myślisz? Zobacz here.

+0

nie, współpracuje z hg (mercurial), więc DLL nie działają. – jcolebrand

+0

@drachenstern - próbując tylko porozmawiać z tym, o czym może świadczyć mgliste pojęcie. –

+0

~ To prawda. I dla bibliotek dll nie próbowałbym na każdym kroku patrzeć na ścieżkę, czy to nawet zadziała? ścieżka systemowa TAK, patrząc ręcznie na% ścieżka% tho? – jcolebrand

5

można oszukać i użyj polecenia

public GetFullPath(string program) 
{ 
    string result; 

    Process myProcess = new Process() 
    { 
     UseShellExecute = false, 
     RedirectStandardOutput = true, 
     StartInfo = new ProcessStartInfo(@"%SYSTEMDIR%\where.exe") 
    }; 

    using (StreamReader sr = myProcess.StandardOutput) 
    { 
     myProcess.Start(); 
     result = myStreamReader.ReadLine(); 
     myProcess.Close(); 
    } 

    return result; 
} 
+0

powiedział, że próbował uniknąć polecenia where: – jcolebrand

+1

@drachenstern na czacie SO, ale nie w samym pytaniu. –

+0

: p ~ yah yah yah – jcolebrand

1

System Windows udostępnia funkcję SearchPathwhere.exe. Jeśli podasz NULL jako parametr lpPath, użyje ścieżki wyszukiwania systemu. W twoim przypadku należy zadzwonić: deklaracja

SearchPath(NULL, "hg", NULL, ...) 

C# jest:

[DllImport("kernel32.dll", CharSet=CharSet.Auto, SetLastError=true)] 
internal static extern int SearchPath(string path, string fileName, string extension, int numBufferChars, StringBuilder buffer, int[] filePart); 
Powiązane problemy