Servicio de Windows: ¿Puedo configurar el directorio de trabajo actual?

11

De manera predeterminada, los servicios de Windows comienzan en el directorio sytem32 (generalmente C:\WINDOWS\system32).

¿Hay alguna manera de configurar un directorio de trabajo diferente? Estoy pensando en algún parámetro de registro a continuación HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SomeService.

Entonces, ¿se puede hacer esto?

Tomalak
fuente
3
@Tomalak: ¿Es un servicio que escribiste? Puede hacerlo a través del código, pero no creo que haya una forma de configurar el servicio.
MattB
No, no es un servicio que escribí. Esperaba alguna configuración de registro poco conocida aquí.
Tomalak
¿Cuál es el propósito de hacerlo?
user35115
@ user35115: Bueno, para ser sincero ... Mientras rastreaba un problema no relacionado con procmon, noté que cierto servicio pesado de E / S (un indexador de texto completo) comprueba constantemente sus propios archivos en las ubicaciones incorrectas (bastante tonto). Comienza en system32, intenta algunas ubicaciones más y, finalmente, su propio directorio. Pensé que cuando se ejecutaría en su propio directorio de inmediato, haría menos verificaciones de archivos innecesarias. No es que no funcione actualmente, sin embargo, me hizo preguntarme si había margen de mejora.
Tomalak
1
@ user35115, para evitar tener que cambiar en masa los ajustes de configuración de una determinada aplicación (por ejemplo, Apache, etc.), que son todos relativos al directorio de trabajo.
Pacerier

Respuestas:

5

Puede usar la inyección DLL para llamar SetCurrentDirectorydespués de que el proceso ya se haya iniciado. Esto requeriría que creara una aplicación de inyector, más la DLL para inyectar. Existen algunos tutoriales; Probablemente los dos mejores que he encontrado son:

Necesitará una buena cantidad de antecedentes de programación en C ++ (y un entorno de compilación de trabajo) para superar eso.

Sin embargo, esto supone que el servicio está mirando el directorio actual. Otra posibilidad es que esté usando %path%. Usted dice que "comienza en system32, intenta algunas ubicaciones más y, finalmente, su propio directorio", por lo que me parece más probable.

Compare los directorios que ve procmoncon su %path%. Si son iguales, considere modificar el usuario SYSTEM %path%o el %path%usuario que ejecuta el servicio, de modo que el directorio que desea que busque sea el primero.

Sin embargo, creo que Fred tiene razón: es poco probable que veas un beneficio de rendimiento significativo al hacer esto, a menos que ocurra con mucha frecuencia. Las operaciones simples de apertura de archivos no son particularmente costosas, especialmente si se trata de una ruta local y el archivo en realidad no existe.

fisión
fuente
La variable de entorno PATH del sistema fue lo primero que se me ocurrió. Sin embargo, insertar la ruta del servicio al comienzo de la variable PATH tendrá un efecto negativo en el rendimiento de casi cualquier otra aplicación, por lo que no lo recomendaría.
Marnix van Valen
No tengo números difíciles para respaldar esto de ninguna manera, pero mi intuición me dice que no se produciría una ganancia o pérdida práctica de rendimiento al modificar la ruta. Este es un escenario bastante común; nadie culpa, digamos, a las herramientas de soporte de Windows o SQL Server, por afectar negativamente el rendimiento del sistema cuando modifica la ruta durante la instalación. Esta no es la primera vez que veo a alguien mirar procmon y decir "¡Dios mío, mira todos esos accesos a archivos!", Sin darse cuenta de que es típico para la mayoría de las aplicaciones.
fisión
+1 para la creatividad. :-) Entiendo completamente que estas operaciones de archivo no afectan el rendimiento de manera medible, por lo que no me voy a molestar en escribir una solución de inyección de DLL. Sin %PATH%embargo, modificar para la cuenta de usuario con la que se ejecuta el servicio es una idea decente.
Tomalak
1
Crear un usuario especial para ejecutar este servicio solamente y modificar el% PATH% para este usuario parece una muy buena manera de hacerlo. +1
Soleado
@fission: Sí, significa que acepto tu respuesta. ;) No es lo que esperaba, pero creo que es lo más cercano posible.
Tomalak
1

Al igual que MattB, no conozco ninguna forma de cambiar el directorio de trabajo del servicio sin acceso al código fuente. Para este escenario específico, es probable que las comprobaciones de directorio adicionales no impongan tanta actividad de disco innecesaria en relación con la cantidad de E / S requerida para la operación de indexación de texto completo. Incluso si pudiera optimizarlos, el índice de texto completo requerirá un disco intensivo por la naturaleza de la bestia.

Fred
fuente
1

Agregue un valor de cadena "AppDirectory" a la Clave de parámetros y establezca el valor en el directorio de trabajo deseado.

marca
fuente
Hm. Recién probado, no parece funcionar (en Windows 7, usó el tipo de datos REG_EXPAND_SZ). ¿Puede volver a confirmar que esto realmente funciona para usted, por favor?
Tomalak
Esto funciona cuando se usa srvany. No estoy seguro acerca de los servicios normales.
Konstantin Spirin
1

Haga esto dentro de la función principal del Servicio:

  • Haz una llamada a GetModuleFilename. Recuperará el nombre de archivo del módulo (el exe), incluida la ruta, en el formulario C:\path\to\exe\your_service.exe.
  • Use manipulaciones de cadena (tal vez usando la std::stringfunción find_last_of()), para encontrar la última barra invertida. Pele / recorte la cadena a partir de ahí para obtener la ruta a su módulo y, por lo tanto, el directorio de su exe.
  • Llame a la función SetCurrentDirectoryy listo!
levantamiento
fuente
1
no olvide pasar nulo al parámetro HMODULE en la llamada de función GetModuleFilename :)
uprightech