178

Supongamos que algunos servicios de Windows usan código que quiere unidades de red mapeadas y sin rutas UNC. ¿Cómo puedo hacer que la asignación de unidades esté disponible para la sesión del servicio cuando se inicia el servicio? Iniciar sesión como el usuario del servicio y crear una asignación persistente no establecerá la asignación en el contexto del servicio real.Asignar una unidad de red para ser utilizada por un servicio

+6

Consulte la respuesta de ForcePush, su solución funciona. – Ubikuity

Respuesta

37

Deberá modificar el servicio o envolverlo dentro de un proceso de ayuda: aparte de los problemas de acceso a la sesión/unidad, las asignaciones de unidades persistentes solo se restauran en un inicio de sesión interactivo, que los servicios normalmente no funcionan.

El enfoque del proceso de ayuda puede ser bastante simple: simplemente cree un nuevo servicio que mapee la unidad e inicie el servicio "real". Las únicas cosas que no son completamente triviales acerca de esto son:

  • El servicio de ayuda tendrá que pasar sobre todo SMC apropiada comandos (inicio/parada, etc.) para el servicio real. Si el servicio real acepta comandos SCM personalizados, recuerde pasarlos también (no espero que un servicio que considere las rutas UNC exóticas usen tales comandos, aunque ...)

  • Las cosas pueden ser un poco complicadas credencial-sabio Si el servicio real se ejecuta bajo una cuenta de usuario normal, también puede ejecutar el servicio auxiliar bajo esa cuenta, y todo debe estar bien siempre que la cuenta tenga acceso apropiado al recurso compartido de red. Si el servicio real solo funciona cuando se ejecuta como LOCALSYSTEM o algo así, las cosas se vuelven más interesantes, ya que no será capaz de 'ver' la unidad de red en absoluto, o requerirá algunos malabarismos de credenciales para hacer que las cosas funcionen.

+2

Muy informativo ... ¿Estoy en lo cierto al suponer que las secuencias de comandos de inicio de sesión también se ejecutan solo para las sesiones de inicio de sesión interactivas y no para las sesiones de servicio? – VoidPointer

1

No desea cambiar el usuario que ejecuta el Servicio desde "Sistema" o encontrar una manera furtiva de ejecutar su asignación como Sistema.

Lo curioso es que esto es posible mediante el uso del comando "at", simplemente programe su asignación de unidad en el futuro y se ejecutará bajo la cuenta del sistema, haciendo que la unidad sea visible para su servicio.

+0

el servicio no se ejecuta como "Sistema". Está configurado para ejecutarse bajo una cuenta local específica. Incluso cuando inicio sesión con esa cuenta, creo una asignación de red persistente, cierro sesión y reinicio del servicio, la asignación no estará disponible para el servicio. – VoidPointer

9

Usted podría nosotros el comando 'net use':

var p = System.Diagnostics.Process.Start("net.exe", "use K: \\\\Server\\path"); 
var isCompleted = p.WaitForExit(5000); 

Si eso no funciona en un servicio, pruebe los Winapi y PInvoke WNetAddConnection2

Editar: Obviamente entendido mal - se no puede cambiar el código fuente del servicio, ¿verdad? En ese caso, seguiría la sugerencia por mdb, pero con un pequeño giro: cree su propio servicio (llamémoslo servicio de mapas) que mapee la unidad y agregue este servicio de mapeo a las dependencias para el primer servicio (el trabajo real). De esta forma, el servicio que funciona no se iniciará antes de que el servicio de mapas haya comenzado (y haya mapeado el disco).

+0

con esta configuración del servicio de mapas, creo que la asignación de unidades establecida por el servicio de mapas no estaría disponible en el contexto del servicio original, ¿o sí? – VoidPointer

+0

Creo que debería - solo hay un entorno para cada sesión de winlogon. – Treb

+0

Su código SI trabaja en un servicio. Vine aquí con el mismo problema que el OP pero soy el autor del Servicio. Tu respuesta resolvió mi problema. –

2

La razón por la que son capaces de acceder a la unidad en cuando normalmente ejecuta el archivo ejecutable de línea de comandos es que cuando u está ejecutando como exe normal, está ejecutando la aplicación en la cuenta del usuario desde el que se tiene sesión iniciada . Y ese usuario tiene los privilegios para acceder a la red. Pero cuando instala el ejecutable como un servicio, de forma predeterminada, si ve en la administración de tareas, se ejecuta en la cuenta 'SISTEMA'. Y es posible que sepa que el 'SISTEMA' no tiene derechos para acceder a los recursos de la red.

Puede haber dos soluciones a este problema.

  1. Para asignar el disco persistente como ya se señaló anteriormente.

  2. Hay un enfoque más que se puede seguir. Si abre el administrador de servicios al escribir en 'services.msc', puede ir a su servicio y en las propiedades de su servicio hay una pestaña de inicio de sesión donde puede especificar la cuenta como cualquier otra cuenta que no sea 'Sistema'. inicie el servicio desde su propia cuenta de usuario registrada o a través de 'Servicio de red'. Cuando hace esto ... el servicio puede acceder a cualquier componente de red y unidad incluso si no son persistentes también. Para lograr esto mediante programación, puede consultar la función 'Crear servicio' en http://msdn.microsoft.com/en-us/library/ms682450(v=vs.85).aspx y puede establecer el parámetro 'lServiceStartName' en 'NT AUTHORITY \ NetworkService'. Esto iniciará su servicio en la cuenta 'Servicio de red' y luego habrá terminado.

  3. También puede intentar haciendo que el servicio sea interactivo especificando SERVICE_INTERACTIVE_PROCESS en el indicador de parámetro de tipo de servicio de su función CreateService() pero esto estará limitado solo hasta XP como Vista y 7 no admitan esta característica.

Espero que las soluciones lo ayuden ... Háganme saber si esto funcionó para usted.

189

Utilice esto bajo su propio riesgo. (Lo he probado en XP y Server 2008 x64 R2)

Para este corte tendrá que SysinternalsSuite by Mark Russinovich:

Primer paso: Abra un indicador de cmd.exe elevada (Ejecutar como administrador)

Paso dos: elevarán de nuevo a raíz utilizando psexec.exe: Vaya a la carpeta que contiene SysinternalsSuite y ejecutar el siguiente comando psexec -i -s cmd.exe está ahora nside de un mensaje que es nt authority\system y puede probarlo escribiendo whoami. El -i es necesaria porque las asignaciones de unidades necesitan interactuar con el usuario

Paso tres: Crear la unidad asignada persistente como la cuenta del sistema con el siguiente comando net use z: \\servername\sharedfolder /persistent:yes

Es así de fácil!

ADVERTENCIA: Solo puede eliminar esta asignación de la misma manera que la creó, desde la cuenta SYSTEM. Si necesita eliminarlo, siga los pasos 1 y 2, pero cambie el comando en el paso 3 al net use z: /delete.

NOTA: La unidad asignada recién creada ahora aparecerá para TODOS los usuarios de este sistema, pero la verán como "Unidad de red desconectada (Z :)". No dejes que el nombre te engañe. Puede afirmar que está desconectado, pero funcionará para todos. Así es como puedes ver que este pirateo no es compatible con M $.

+2

Estaba tratando de usar esta solución y me encontré con este problema: la unidad asignada aparece como desconectada de los usuarios (incluso los administradores). ¿Alguna sugerencia? –

+1

¡Funciona como un encanto! ¡Gracias! He estado luchando con esto por un tiempo – Tommy

+0

Tengo el mismo problema que Constantin: ¿alguna idea de cómo compartir tanto para el sistema como para los usuarios? – Nik

49

Encontré una solución que es similar a la de psexec pero funciona sin herramientas adicionales y sobrevive a un reinicio.

Sólo añadir una tarea sheduled, inserte "sistema" en el "Ejecutar como" campo y el punto de la tarea a un archivo por lotes con el comando sencilla

net use z: \servername\sharedfolder /persistent:yes 

A continuación, seleccione "ejecutar al iniciar el sistema" (o similar, no tengo una versión en inglés) y listo.

+0

¿qué comienza primero? un servicio de Windows o esta tarea programada? nuestro servicio muere al inicio si la ruta no está disponible. Tendríamos que reconstruir esto si el servicio se inicia por última vez. – Thomas

+1

Intenté esto en 2008 R2, crea una unidad asignada desconectada y cuando intento abrir la misma, dice "z: \ no es accesible. Error de inicio de sesión: nombre de usuario desconocido o contraseña incorrecta". Pero pude crear una unidad mapeada exitosamente ejecutando el mismo archivo bat manualmente. ¿Percepciones de Ny? –

+1

@Thomas no importa que comience primero, siempre que la tarea se haya ejecutado al menos una vez debido al '/ persistent: yes' – Edd

36

Una mejor manera sería usar un enlace simbólico usando mklink.exe. Solo puede crear un enlace en el sistema de archivos que cualquier aplicación puede usar. Ver http://en.wikipedia.org/wiki/NTFS_symbolic_link.

+0

Tan simple y funciona bien. Como es parte del sistema de archivos, el enlace está disponible para todas las cuentas. Solo asegúrese de que el servicio se esté ejecutando como una cuenta que tenga acceso a los recursos de la red (que podría no ser el caso para el Sistema, etc.). –

+2

Lástima que no funciona en 2000/XP. – To1ne

+1

Definitivamente esta es la mejor respuesta a la pregunta, ¡muchas gracias! –

5

ForcePush,

NOTA: La unidad asignada recién creado aparecerá ahora para todos los usuarios de este sistema, pero lo verá muestra como "Unidad de red desconectada (Z :)". No dejes que el nombre te engañe. Puede afirmar que está desconectado, pero funcionará para todos. Así es como se puede ver que este truco no es compatible con M $ ...

Todo depende de los permisos compartidos. Si tiene Todos los permisos compartidos, otros usuarios podrán acceder a esta unidad asignada. Pero si solo tiene un usuario en particular cuyas credenciales utilizó en su secuencia de comandos por lotes y esta secuencia de comandos por lotes se agregó a las secuencias de comandos de inicio, solo la cuenta del sistema tendrá acceso a esa acción ni siquiera al administrador. Así que si usa, por ejemplo, un trabajo ntbackuo programado, la cuenta del sistema debe usarse en 'Ejecutar como'. Si su servicio es 'Iniciar sesión como: cuenta del sistema local' debería funcionar.

Lo que hice, no asignar cualquier letra de unidad en mi script de inicio, solo se usa net use \\\server\share ... y se utiliza ruta UNC en mis trabajos programados. Se agregó una secuencia de comandos de inicio de sesión (o simplemente agregar un archivo por lotes a la carpeta de inicio) con la asignación al mismo recurso compartido con alguna letra de unidad: net use Z: \\\... con las mismas credenciales. Ahora el usuario registrado puede ver y acceder a esa unidad mapeada. Hay 2 conexiones para el mismo recurso compartido. En este caso, el usuario no ve esa molesta "Unidad de red desconectada ...". Pero si realmente necesita acceso a ese recurso compartido mediante la letra de la unidad, no solo UNC, haga un mapa que comparta con las diferentes letras de unidad, p. Y para System y Z para usuarios.

3

Encontré una forma de otorgar acceso de servicio de Windows a la unidad de red.

Take Windows Server 2012 con el disco NFS, por ejemplo:

Paso 1: escribir un archivo por lotes para montaje.

escribir un archivo por lotes, por ejemplo: C: \ mount_nfs.bat

echo %time% >> c:\mount_nfs_log.txt 
net use Z: \\{your ip}\{netdisk folder}\ >> C:\mount_nfs_log.txt 2>&1 

Paso 2: Montaje de discos como NT AUTHORITY/SYSTEM.

abierto "Programador de tareas", crear una nueva tarea:

  1. Ejecutar como "SISTEMA", en "Inicio del sistema".
  2. Crear acción: Ejecute "C: \ mount_nfs.bat".

Después de estos dos sencillos pasos, mi servicio Windows ActiveMQ se ejecuta en el privilegio "Sistema local" y funciona perfectamente sin iniciar sesión.

6

Hay una buena respuesta aquí: https://superuser.com/a/651015/299678

es decir, Puede usar un enlace simbólico, p.

mklink /D C:\myLink \\127.0.0.1\c$ 
+0

¿Qué sucede si después de intentar crear un directorio desde el servicio se produce un error de permiso? – tyoc213

+0

Debería llevar esto fuera de línea a una sala de chat y luego dar detalles del mensaje de error. Probablemente necesites ejecutar los comandos con permisos elevados. – philu

0

que no puedo comentar todavía (trabajo en la reputación), pero crea una cuenta sólo para responder @Tech tirón @ spankmaster79 (bonito nombre lol) y las cuestiones @NMC informaron en respuesta a la "he encontrado una solución eso es similar al de psexec pero funciona sin herramientas adicionales y sobrevive a un reinicio ". publicar que @Larry había hecho.

La solución a esto es simplemente navegar a la carpeta desde que inició la sesión en la cuenta, es decir:

\\servername\share 

y se deja pronta para iniciar sesión, y entrar en las mismas credenciales que se utilizaron para la UNC en psexec . Después de eso, comienza a funcionar. En mi caso, creo que esto se debe a que el servidor con el servicio no es miembro del mismo dominio que el servidor al que estoy mapeando. Estoy pensando si el UNC y la tarea programada ambos se refieren a la IP en lugar del nombre de host

\\123.456.789.012\share 

puede evitar el problema por completo.

Si alguna vez obtengo suficientes puntos de reputación aquí, lo agregaré como respuesta.

0
net use Q: \\share.domain.com\share 
forfiles /p Q:\myfolder /s /m *.txt /d -0 /c "cmd /c del @path" 
net use Q: /delete 

Esto funciona para mí.

Cuestiones relacionadas