Service Windows: puis-je configurer le répertoire de travail actuel?

11

Par défaut, les services Windows démarrent dans le répertoire sytem32 (généralement C:\WINDOWS\system32).

Existe-t-il un moyen de configurer un répertoire de travail différent? Je pense à un paramètre de registre ci-dessous HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SomeService.

Alors - cela peut-il être fait?

Tomalak
la source
3
@Tomalak: Est-ce un service que vous avez écrit? Vous pouvez le faire via du code, mais je ne pense pas qu'il existe un moyen de passer par les paramètres de service.
MattB
Non, ce n'est pas un service que j'ai écrit. J'espérais un paramètre de registre peu connu ici.
Tomalak
Quel est le but de le faire?
user35115
@ user35115: Eh bien, pour être honnête ... Lors de la recherche d'un problème sans rapport avec procmon, j'ai remarqué qu'un certain service lourd d'E / S (un indexeur de texte intégral) vérifie systématiquement ses propres fichiers aux mauvais emplacements (assez stupide). Il commence à system32, essaie quelques emplacements supplémentaires et éventuellement son propre répertoire. J'ai pensé que quand il s'exécuterait dans son propre répertoire immédiatement, il ferait moins de vérifications de fichiers inutiles. Non pas que cela ne fonctionnerait pas actuellement, mais cela m'a fait me demander s'il y avait matière à amélioration.
Tomalak
1
@ user35115, pour éviter d'avoir à modifier en masse les paramètres de configuration d'une certaine application (par exemple Apache, etc.), qui sont tous relatifs au répertoire de travail.
Pacerier

Réponses:

5

Vous pouvez utiliser l'injection de DLL pour appeler une SetCurrentDirectoryfois le processus lancé. Cela vous obligerait à créer une application injecteur, plus la DLL à injecter. Certains tutoriels existent; probablement les deux meilleurs que j'ai trouvés sont:

Vous aurez besoin d'une quantité décente de fond de programmation C ++ (et d'un environnement de construction fonctionnel) pour passer à travers cela.

Cependant, cela suppose que le service consulte le répertoire en cours. Une autre possibilité est qu'il utilise %path%. Vous dites qu'il "commence à system32, essaie quelques emplacements supplémentaires et éventuellement son propre répertoire", donc cela me semble plus probable.

Comparez les répertoires que vous voyez procmonavec votre %path%. S'ils sont identiques, envisagez de modifier le SYSTEM %path%ou le %path%de l'utilisateur exécutant le service, de sorte que le répertoire que vous souhaitez qu'il recherche soit le premier.

Je crois que Fred a raison, cependant - il est peu probable que vous constatiez un avantage significatif en termes de performances en faisant tout cela, sauf si cela se produit très fréquemment. Les opérations simples d'ouverture de fichier ne sont pas particulièrement coûteuses, surtout s'il s'agit d'un chemin local et que le fichier n'existe pas réellement.

fission
la source
La variable d'environnement PATH système a été la première chose qui m'est venue à l'esprit. L'insertion du chemin du service au début de la variable PATH aura cependant un effet négatif sur les performances de presque toutes les autres applications, donc je ne le conseillerais pas.
Marnix van Valen
Je n'ai pas de chiffres précis pour sauvegarder cela de toute façon, mais mon intuition me dit qu'aucun gain ou perte de performance pratique ne se produirait en modifiant le chemin. Il s'agit d'un scénario assez courant; personne ne blâme, par exemple, les outils de support de Windows ou SQL Server, pour avoir un impact négatif sur les performances du système lorsqu'il modifie le chemin d'accès lors de l'installation. Ce n'est pas la première fois que je vois quelqu'un regarder procmon et dire "omg, regardez tous ces accès aux fichiers!", Sans réaliser que c'est typique de la plupart des applications.
fission du
+1 pour la créativité. :-) Je comprends parfaitement que ces opérations sur les fichiers n'affectent pas les performances de manière mesurable, donc je ne vais pas vraiment m'embêter à écrire une solution d'injection de DLL. La modification %PATH%du compte d'utilisateur sous lequel le service est exécuté est une bonne idée, cependant.
Tomalak
1
Créer un utilisateur spécial pour exécuter ce service uniquement et modifier le% PATH% pour cet utilisateur semble être une très bonne façon de procéder. +1
Ensoleillé
@fission: Oui, cela signifie que j'accepte votre réponse. ;) Ce n'est pas ce que j'avais espéré, mais c'est aussi proche que possible, je suppose.
Tomalak
1

Comme MattB, je ne connais aucun moyen de changer le répertoire de travail du service sans accès au code source. Pour ce scénario spécifique, il est probable que les vérifications de répertoire supplémentaires n'imposent pas autant d'activité disque inutile par rapport à la quantité d'E / S requise pour l'opération d'indexation de texte intégral. Même si vous pouvez les optimiser, l'index de texte intégral sera gourmand en disque par la nature de la bête.

Fred
la source
1

Ajoutez une valeur de chaîne "AppDirectory" à la clé de paramètres et définissez la valeur dans votre répertoire de travail souhaité.

marque
la source
Hm. Juste testé, ne semble pas fonctionner (sous Windows 7, type de données REG_EXPAND_SZ utilisé). Pouvez-vous confirmer à nouveau que cela fonctionne réellement pour vous, s'il vous plaît?
Tomalak
Cela fonctionne lors de l'utilisation srvany. Pas sûr des services normaux.
Konstantin Spirin
1

Pour ce faire, dans la fonction principale du service:

  • Faites un appel à GetModuleFilename. Il récupérera le nom de fichier du module (l'exe), y compris le chemin, dans le formulaire C:\path\to\exe\your_service.exe.
  • Utilisez des manipulations de chaînes (peut-être en utilisant la std::stringfonction find_last_of()), pour trouver la dernière barre oblique inverse. Déshabillez / coupez la chaîne à partir de là pour obtenir le chemin vers votre module et donc le répertoire de votre exe.
  • Appelez la fonction SetCurrentDirectoryet le tour est joué!
uprightech
la source
1
n'oubliez pas de passer null au paramètre HMODULE dans l'appel de fonction GetModuleFilename :)
uprightech