Usługa Windows: Czy mogę skonfigurować bieżący katalog roboczy?

11

Domyślnie usługi Windows uruchamiają się w katalogu sytem32 (zwykle C:\WINDOWS\system32).

Czy istnieje sposób na skonfigurowanie innego katalogu roboczego? Mam na myśli poniżej jakiś parametr rejestru HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SomeService.

Więc - czy można to zrobić?

Tomalak
źródło
3
@Tomalak: Czy to napisana przez Ciebie usługa? Możesz to zrobić za pomocą kodu, ale nie sądzę, że istnieje sposób przez ustawienia usługi.
MattB
Nie, to nie jest usługa, którą napisałem. Miałem nadzieję na jakieś mało znane ustawienie rejestru tutaj.
Tomalak
Jaki jest cel tego?
user35115,
@ user35115: Cóż, szczerze mówiąc… Podczas śledzenia niepowiązanego problemu z procmonem zauważyłem, że pewna usługa obciążająca operacje we / wy (indeksator pełnotekstowy) konsekwentnie sprawdza swoje pliki w niewłaściwych lokalizacjach (dość głupie). Zaczyna się od systemu32, próbuje jeszcze kilku lokalizacji i ostatecznie własnego katalogu. Doszedłem do wniosku, że kiedy od razu uruchomi się w swoim katalogu, wykona mniej niepotrzebnych kontroli plików. Nie to, że obecnie nie działałoby , ale zastanawiałem się, czy jest miejsce na poprawę.
Tomalak
1
@ user35115, Aby uniknąć konieczności masowej zmiany ustawień konfiguracyjnych określonej aplikacji (np. Apache itp.), które są względne w stosunku do katalogu roboczego.
Pacerier 11.04.16

Odpowiedzi:

5

Możesz użyć zastrzyku DLL, aby zadzwonić SetCurrentDirectorypo uruchomieniu procesu. Wymagałoby to zbudowania aplikacji wtryskiwacza oraz biblioteki DLL do wstrzyknięcia. Istnieją niektóre samouczki; prawdopodobnie dwie najlepsze, które znalazłem to:

Będziesz potrzebować przyzwoitej wiedzy programistycznej C ++ (i działającego środowiska kompilacji), aby się przez to przejść.

Zakłada się jednak, że usługa szuka bieżącego katalogu. Inną możliwością jest to, że używa %path%. Mówisz, że „zaczyna się od system32, próbuje jeszcze kilku lokalizacji i ostatecznie własnego katalogu”, więc wydaje mi się to bardziej prawdopodobne.

Porównaj katalogi w procmonswoim %path%. Jeśli są takie same, rozważ zmodyfikowanie użytkownika SYSTEM %path%lub %path%usługi obsługującej tę usługę, aby katalog, który chcesz przeszukać, był pierwszy.

Uważam jednak, że Fred ma rację - mało prawdopodobne jest, abyś zauważył jakąkolwiek znaczącą poprawę wydajności, chyba że dzieje się to bardzo często. Proste operacje otwierania plików nie są szczególnie drogie, szczególnie jeśli jest to ścieżka lokalna, a plik tak naprawdę nie istnieje.

rozszczepienie
źródło
Systemowa zmienna środowiskowa PATH była pierwszą rzeczą, która przyszła mi do głowy. Wstawienie ścieżki usługi na początku zmiennej PATH będzie miało jednak negatywny wpływ na wydajność niemal każdej innej aplikacji, więc nie radziłbym tego.
Marnix van Valen
Nie mam twardych liczb, które mogłyby to w jakikolwiek sposób poprzeć, ale moja intuicja podpowiada mi, że modyfikacja ścieżki nie przyniesie żadnego praktycznego wzrostu ani utraty wydajności. To dość powszechny scenariusz; nikt nie obwinia, powiedzmy, narzędzi obsługi systemu Windows lub SQL Server, za negatywny wpływ na wydajność systemu, gdy modyfikuje ścieżkę podczas instalacji. To nie pierwszy raz, kiedy ktoś patrzy na procmon i mówi „omg, spójrz na te wszystkie dostępy do plików!”, Nie zdając sobie sprawy, że jest to typowe dla większości aplikacji.
rozszczepienie
+1 za kreatywność. :-) W pełni rozumiem, że te operacje na plikach nie mają mierzalnego wpływu na wydajność, więc nie zamierzam zawracać sobie głowy pisaniem rozwiązania do wstrzykiwania DLL. Modyfikacja %PATH%konta użytkownika, pod którym działa usługa, jest jednak przyzwoitym pomysłem.
Tomalak
1
Tworzenie specjalnego użytkownika, który będzie uruchamiał tylko tę usługę, i modyfikowanie% PATH% dla tego użytkownika wydaje się bardzo dobrą drogą. +1
Słoneczny
@fission: Tak, to znaczy, że akceptuję twoją odpowiedź. ;) Nie tego oczekiwałem, ale chyba jest tak blisko, jak się da.
Tomalak
1

Podobnie jak MattB, nie znam żadnego sposobu na zmianę katalogu roboczego usługi bez dostępu do kodu źródłowego. W tym konkretnym scenariuszu prawdopodobne jest, że dodatkowe kontrole katalogów nie narzucają tak dużo niepotrzebnej aktywności dysku w stosunku do ilości operacji we / wy wymaganych dla operacji indeksowania pełnotekstowego. Nawet jeśli możesz je zoptymalizować, indeks pełnotekstowy będzie wymagał dużej ilości dysku ze względu na charakter bestii.

Fred
źródło
1

Dodaj wartość ciągu „AppDirectory” do klucza parametrów i ustaw wartość dla żądanego katalogu roboczego.

znak
źródło
Hm Właśnie przetestowany, wydaje się nie działać (w systemie Windows 7 używał typu danych REG_EXPAND_SZ). Czy możesz ponownie potwierdzić, że to naprawdę działa, proszę?
Tomalak
Działa to podczas używania srvany. Nie jestem pewien co do normalnych usług.
Konstantin Spirin
1

Zrób to w ramach głównej funkcji usługi:

  • Zadzwoń do GetModuleFilename. Pobiera nazwę modułu (exe) wraz ze ścieżką w formie C:\path\to\exe\your_service.exe.
  • Użyj operacji na łańcuchach znaków (być może przy użyciu std::stringfunkcji find_last_of()), aby znaleźć ostatni ukośnik odwrotny. Odetnij / odetnij ciąg od tego momentu, aby uzyskać ścieżkę do modułu, a zatem do katalogu swojego pliku exe.
  • Zadzwoń do funkcji SetCurrentDirectoryi voila!
technologia pionowa
źródło
1
nie zapomnij przekazać wartości null do parametru HMODULE w wywołaniu funkcji GetModuleFilename :)
uprightech