Pregunta

Estamos trabajando en un servicio web que tiene que ejecutar un proceso de terceros que interactúa con una unidad de red asignada. Por lo tanto, tenemos que asignar esta unidad mediante programación desde el servicio web.

Ya he envuelto WNetAddConnection2, etc. en una clase más agradable para otro proyecto, así que agregué el código directamente.

Nuestro servicio web se ejecuta bajo UltiDev Cassini (en lugar de IIS) que se ejecuta bajo la cuenta del sistema. Obtenemos el código de error para: " el nombre del dispositivo especificado no es válido " cada vez. También intenté suplantar a otros usuarios en el archivo web.config, con los mismos resultados.

La unidad se correlacionará bien cuando ejecuto mi código desde un programa de consola con una cuenta de usuario normal.

También he intentado ejecutar el equivalente "uso neto" comando de C # con exactamente los mismos resultados que WNetAddConnection.

¿Alguien sabe por qué un servicio de Windows o un usuario del sistema no podría asignar unidades de red?

¿Alguien sabe una solución? Simplemente mapear el disco en el inicio del sistema sería una solución, pero ¿cómo podría el sistema / usuario suplantado acceder a él?

Enlace para UltiDev Cassini: UltiDev

SOLUCIÓN: configuré el servicio UltiDev Cassini para iniciar sesión en Administrador y todo funciona. La suplantación de ASP .Net no debe funcionar según lo planeado.

¿Fue útil?

Solución

La cuenta LOCAL_SYSTEM presenta credenciales en la red . Puede utilizar un recurso compartido de red UNC para acceder a esta información, siempre que anónimo (Todos) tenga acceso al recurso compartido.

También puede instalar Cassini como un servicio de Windows que puede configurar ejecutar bajo un usuario diferente.

Otros consejos

Si está utilizando la cuenta del sistema local, entonces creo que es inherentemente incapaz de acceder a la red [foo]. Yo diría que la suplantación es tu único camino viable. Técnicamente, podría reducir los controles de acceso en el recurso compartido hasta el punto de que cualquiera podría leer / escribir en el recurso compartido, pero eso trae más problemas que soluciones.

Tuvimos el mismo problema. El problema ocurre debido a la cuenta con la que se ejecuta el código. Puede evitar esto como lo hicimos utilizando la siguiente clase. Debe asignar la unidad en el mismo código que está utilizando para acceder / copiar archivos. El patrón que utilizamos es verificar siempre si la unidad está conectada primero. si es así, lo desconectamos y luego lo volvemos a conectar. si no, solo lo conectamos. Parece aclarar el problema que está describiendo.

public static class NetworkDrives
    {
        public static bool  MapDrive(string DriveLetter, string Path, string Username, string Password)
        {

            bool ReturnValue = false;

            if(System.IO.Directory.Exists(DriveLetter + ":\\"))
            {
                DisconnectDrive(DriveLetter);
            }
            System.Diagnostics.Process p = new System.Diagnostics.Process();
            p.StartInfo.UseShellExecute = false;
            p.StartInfo.CreateNoWindow = true;
            p.StartInfo.RedirectStandardError = true;
            p.StartInfo.RedirectStandardOutput = true;

            p.StartInfo.FileName = "net.exe";
            p.StartInfo.Arguments = " use " + DriveLetter + ": " + '"' + Path + '"' + " " + Password + " /user:" + Username;
            p.Start();
            p.WaitForExit();

            string ErrorMessage = p.StandardError.ReadToEnd();
            string OuputMessage = p.StandardOutput.ReadToEnd();
            if (ErrorMessage.Length > 0)
            {
                throw new Exception("Error:" + ErrorMessage);
            }
            else
            {
                ReturnValue = true;
            }
            return ReturnValue;
        }
        public static bool DisconnectDrive(string DriveLetter)
        {
            bool ReturnValue = false;
            System.Diagnostics.Process p = new System.Diagnostics.Process();
            p.StartInfo.UseShellExecute = false;
            p.StartInfo.CreateNoWindow = true;
            p.StartInfo.RedirectStandardError = true;
            p.StartInfo.RedirectStandardOutput = true;

            p.StartInfo.FileName = "net.exe";
            p.StartInfo.Arguments = " use " + DriveLetter + ": /DELETE";
            p.Start();
            p.WaitForExit();

            string ErrorMessage = p.StandardError.ReadToEnd();
            string OuputMessage = p.StandardOutput.ReadToEnd();
            if (ErrorMessage.Length > 0)
            {
                throw new Exception("Error:" + ErrorMessage);
            }
            else
            {
                ReturnValue = true;
            }
            return ReturnValue;
        }

    }

En lugar de una unidad asignada, ¿podría conectarse utilizando el recurso compartido UNC?

Todavía suplantaría a un usuario que tiene acceso al recurso compartido.

Realmente he hecho esto antes, pero fue hace mucho tiempo, como 1997, y Win NT 3.51 con Delphi 2

Me estoy quedando sin memoria, pero creo que es algo así: Utiliza la API de Win:

WNetAddConnection2 ()

Información sobre la llamada: http: // msdn .microsoft.com / es-es / library / aa385413 (VS.85) .aspx

Puede obtener la firma c # de pInvoke.net: http: // www.pinvoke.net/default.aspx/mpr/WNetAddConnection2.html

Nota sobre la configuración: Creo que necesitará configurar una cuenta de dominio para el servicio y ejecutar el servicio con la identidad de esa cuenta en lugar del sistema local. Creo que pasa nulo como nombre de usuario y contraseña.

Usted podría ser capaz de ejecutar el servicio a medida que el sistema local pasa el nombre de usuario y la contraseña de una cuenta de dominio. No sé si la cuenta del sistema tiene acceso a la red.

El concepto general a tener en cuenta es que las 'letras de unidad mapeadas' son un concepto de Usuario, no un concepto de Sistema. Entonces, cuando Joe inicia sesión en la computadora con Windows, las unidades asignadas se adjuntan a la cuenta de usuario de Joe. Cuando se ejecuta un servicio de Windows, generalmente se ejecuta bajo la 'cuenta de usuario' LOCAL_SYSTEM, lo que significa que LOCAL_SYSTEM no conoce las letras de unidad asignadas de Joe.

Por lo tanto, el acceso UNC a los recursos compartidos de red es el camino a seguir cuando se intenta acceder a cualquier recurso remoto desde un Servicio de Windows. Tenga en cuenta que puede ejecutar el Servicio de Windows en el contexto de la cuenta de usuario 'Joe', o puede crear una cuenta de AD ficticia llamada algo así como 'MyServiceAccount' y otorgarle derechos de cuenta a la UNC, o puede usar Suplantación y tener el Servicio de Windows inicie sesión en la estación de trabajo local utilizando la función NetLogon () con un identificador de suplantación y luego acceda a la UNC desde allí.

Hay muchas maneras de hacerlo, pero todo se reduce a cuentas de usuario asociadas con unidades asignadas y acceso UNC.

¡Buena suerte, espero que esta información ayude!

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top