Windows Hizmeti: Geçerli çalışma dizinini yapılandırabilir miyim?


11

Varsayılan olarak, Windows hizmetleri sytem32 dizininde (genellikle C:\WINDOWS\system32) başlar.

Farklı bir çalışma dizini oluşturmanın bir yolu var mı? Altında bazı kayıt defteri parametresi düşünüyorum HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SomeService.

Peki - bu yapılabilir mi?


3
@Tomalak: Yazdığınız bir hizmet mi? Bunu kod üzerinden yapabilirsiniz, ancak hizmet ayarlarında bir yol olduğunu düşünmüyorum.
MattB

Hayır, yazdığım bir hizmet değil. Burada az bilinen bir kayıt defteri ayarı umuyordum.
Tomalak

Bunu yapmanın amacı nedir?
user35115

@ user35115: Dürüst olmak gerekirse… Procmon ile ilgisiz bir sorunu takip ederken, belirli bir G / Ç-ağır hizmetinin (tam metin dizinleyici) sürekli olarak yanlış konumlardaki kendi dosyalarını kontrol ettiğini fark ettim (oldukça aptal). System32'de başlar, birkaç konum daha dener ve sonunda kendi dizinini dener. Hemen kendi dizininde ne zaman çalışacağını düşündüm, daha az gereksiz dosya kontrolleri yapacaktı. Şu anda işe yaramayacağı değil , yine de iyileştirme için yer olup olmadığını merak ettim.
Tomalak

1
@ user35115, (Apache söylemek, vb), hepsi hangi Belirli bir uygulama kütle değişim yapılandırma ayarları zorunda kalmamak için göreli çalışma dizinine.
Pacerier

Yanıtlar:


5

SetCurrentDirectoryİşlem zaten başlatıldıktan sonra aramak için DLL enjeksiyonu kullanabilirsiniz . Bu bir enjektör uygulaması, artı enjekte etmek DLL oluşturmak gerekir. Bazı eğiticiler var; muhtemelen bulduğum en iyi iki şey:

Bunu başarmak için iyi miktarda C ++ programlama arka planına (ve çalışan bir yapı ortamına) ihtiyacınız olacaktır.

Ancak, bu hizmetin geçerli dizine baktığını varsayar. Başka bir olasılık da kullanıyor olması %path%. "Başlıyor, system32birkaç konum daha ve sonunda kendi dizini çalışıyor " diyorsunuz, bu yüzden bu benim için daha olası görünüyor.

Eğer gördüğünüz dizinleri karşılaştırın procmoninizle %path%. Bunlar aynıysa, hizmeti çalıştıran kullanıcının SYSTEM %path%ya %path%da kullanıcının değiştirilmesini düşünün , böylece aramasını istediğiniz dizin önce olur.

Fred'in haklı olduğuna inanıyorum - çok sık olmadıkça, bunlardan herhangi birini yaparak önemli bir performans avantajı görmeniz olası değildir . Basit dosya açma işlemleri, özellikle yerel bir yolsa ve dosya gerçekten mevcut değilse, özellikle pahalı değildir.


Sistem PATH ortam değişkeni benim için ilk akla gelen şeydi. PATH değişkeninin başlangıcında hizmet yolunun eklenmesi, ancak hemen hemen her uygulamanın performansı üzerinde olumsuz bir etkiye sahip olacaktır, bu yüzden bunu tavsiye etmem.
Marnix van Valen

Bunu her iki şekilde de destekleyecek zor sayılarım yok, ama sezgilerim yolu değiştirerek hiçbir pratik performans kazancı veya kaybının olmayacağını söylüyor. Bu oldukça yaygın bir senaryodur; kurulum sırasında yolu değiştirdiğinde sistem performansını olumsuz etkilediği için kimse Windows Destek Araçları'nı veya SQL Server'ı suçlamaz. Bu, birisinin procmon'a baktığını ve "omg, tüm bu dosya erişimlerine bakın!" İ ilk gördüğüm değil, çoğu uygulama için tipik olduğunu fark etmiyor.
fizyon

Yaratıcılık için +1. :-) Ben tamamen bu dosya işlemleri performans ölçülebilir etkilemez anlamak, bu yüzden aslında bir DLL enjeksiyon çözüm yazma rahatsız etmeyeceğim. Değiştirme %PATH%olsa iyi bir fikir altında hizmet çalışır kullanıcı için hesabı.
Tomalak

1
Yalnızca bu hizmeti çalıştırmak için özel bir kullanıcı oluşturmak ve bu kullanıcı için% PATH% değerini değiştirmek çok iyi bir yol gibi görünüyor. +1
Güneşli

@fission: Evet, bu cevabınızı kabul ettiğim anlamına geliyor. ;) Umduğum gibi değil ama sanırım olabildiğince yakın.
Tomalak

1

MattB gibi, kaynak koduna erişim olmadan hizmetin çalışma dizinini değiştirmenin herhangi bir yolunu bilmiyorum. Bu özel senaryo için, fazladan dizin denetimleri, tam metin dizinleme işlemi için gereken g / Ç miktarına göre bu gereksiz disk etkinliğini dayatmaz. Onları optimize edebilseniz bile, tam metin dizini canavarın doğası gereği disk yoğun olacaktır.


1

Parametreler Anahtarına bir "AppDirectory" dize değeri ekleyin ve değeri istediğiniz çalışma dizinine ayarlayın.


Hm. Yeni test edildi, çalışmıyor gibi görünüyor (Windows 7'de REG_EXPAND_SZ veri türü kullanılır). Bunun sizin için gerçekten işe yaradığını tekrar teyit edebilir misiniz, lütfen?
Kasım'da Tomalak

Bu, kullanırken işe yarar srvany. Normal servislerden emin değilim.
Konstantin Spirin

1

Bunu Hizmet ana işlevi içinde yapın:

  • İçin çağrı yapın GetModuleFilename. Modül (exe) dosya adını yol da dahil olmak üzere formda alır C:\path\to\exe\your_service.exe.
  • Son ters eğik çizgiyi bulmak için dize manipülasyonları kullanın (belki std::stringişlevi kullanarak find_last_of()). Modülünüzün yolunu ve dolayısıyla exe'nizin dizinini elde etmek için dizeyi oradan sıyırın / kesin.
  • İşlevi çağırın SetCurrentDirectoryve işte!

1
GetModuleFilename işlev çağrısında HMODULE parametresine null iletmeyi unutmayın :)
uprightech
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.