简体   繁体   English

C#-来自Web服务的地图网络驱动器

[英]C# - Map Network drive from Web Service

We are working on a web service that has to run a 3rd party process that interacts with a mapped network drive. 我们正在开发一种Web服务,该服务必须运行与映射的网络驱动器进行交互的第三方过程。 So we have to map this drive programmatically from the web service. 因此,我们必须通过Web服务以编程方式映射此驱动器。

I have already wrapped up WNetAddConnection2, etc. in a nicer class for another project, so I threw the code right in. 我已经在另一个项目的更好的类中包装了WNetAddConnection2等,因此我将代码直接放入了。

Our web service is running under UltiDev Cassini (instead of IIS) which runs under the System account. 我们的Web服务在UltiDev Cassini(而不是IIS)下运行,后者在System帐户下运行。 We get the error code for: "the specified device name is invalid" every time. 我们每次都会得到以下错误代码:“指定的设备名称无效”。 I also tried impersonating other users in the web.config file, with the same results. 我还尝试模拟web.config文件中的其他用户,结果相同。

The drive will map just fine when I run my code from a console program under a normal user account. 当我以普通用户帐户从控制台程序运行代码时,驱动器将正常映射。

I have also tried running the equivalent "net use" command from C# with the exact same results as WNetAddConnection. 我还尝试过从C#运行等效的“ net use”命令,其结果与WNetAddConnection完全相同。

Does anyone know why a windows service or System user wouldn't be able to map network drives? 有谁知道为什么Windows服务或系统用户无法映射网络驱动器?

Does anyone know a workaround? 有谁知道解决方法? Simply mapping the drive on system startup would be a solution, but how could the system/impersonated user access it? 仅在系统启动时映射驱动器将是一个解决方案,但是系统/模拟用户如何访问它?

Link for UltiDev Cassini: UltiDev UltiDev卡西尼链接: UltiDev

SOLUTION: I set the UltiDev Cassini service to logon under Administrator and everything is working. 解决方案:我将UltiDev Cassini服务设置为在Administrator下登录,一切正常。 The ASP .Net impersonation must not work as planned. ASP .Net模拟不能按计划进行。

If you're using the Local System account, then I believe it's inherently incapable of accessing network [foo]. 如果您使用的是本地系统帐户,那么我相信它本质上是无法访问网络[foo]的。 I'd say impersonation is your only viable path. 我想说模拟是您唯一可行的方法。 Technically you could reduce access controls on the share to the point that anyone could read/write to the share, but that brings more problems than solutions. 从技术上讲,您可以将共享上的访问控制权减少到任何人都可以对共享进行读/写的程度,但这比解决方案带来了更多的问题。

The LOCAL_SYSTEM account presents Anonymous credentials on the network . LOCAL_SYSTEM帐户在网络上显示匿名凭据 You could use a UNC network share to access this information, provided that anonymous (Everyone) has access to the share. 您可以使用UNC网络共享来访问此信息,前提是匿名(所有人)可以访问该共享。

You can also install Cassini as a windows service which you could configure to run under a different user. 您还可以将Cassini安装为Windows服务 ,可以将其配置为在其他用户下运行。

We had the same issue. 我们有同样的问题。 The problem happens because of the account the code is running under. 发生此问题的原因是在其下运行代码的帐户。 You can get around this as we did by using the following class. 您可以通过使用以下类来解决此问题。 You have to map the drive in the same code you're using to access/copy files. 您必须使用用于访问/复制文件的相同代码映射驱动器。 The pattern we use is to always check t see if the drive is connected first. 我们使用的模式是始终检查是否先连接驱动器。 if so, we disconnect it, and then reconnect it. 如果是这样,我们将其断开连接,然后重新连接。 if not, we just connect it. 如果没有,我们就连接它。 It seems to clear up the issue you're describing. 似乎可以解决您正在描述的问题。

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;
        }

    }

Instead of a mapped drive, could you connect using the UNC share? 您可以使用UNC共享连接而不是映射驱动器吗?

I'd still impersonate a user that has access to the share. 我仍然要模拟有权访问该共享的用户。

I have actually done this before, but it was a VERY long time ago -- like 1997, and Win NT 3.51 with Delphi 2 我以前实际上已经做过,但是那是很久以前的事了,例如1997年,以及带有Delphi 2的Win NT 3.51

I'm running from memory, but I think it goes something like this: You use the Win API: 我从内存中运行,但是我认为它是这样的:您使用Win API:

WNetAddConnection2() WNetAddConnection2()

Info on the call: http://msdn.microsoft.com/en-us/library/aa385413(VS.85).aspx 电话上的信息: http : //msdn.microsoft.com/zh-cn/library/aa385413(VS.85).aspx

You can get the c# signature from pInvoke.net: http://www.pinvoke.net/default.aspx/mpr/WNetAddConnection2.html 您可以从pInvoke.net获取c#签名: http ://www.pinvoke.net/default.aspx/mpr/WNetAddConnection2.html

Note on configuration: I think that you will need to set up a domain account for the service, and run the service with the identity of that account instead of local system. 关于配置的注意事项:我认为您将需要为该服务设置一个域帐户,并使用该帐户的身份而不是本地系统的身份运行该服务。 I think that you pass null as the user name and password. 我认为您将null用作用户名和密码。

You might be able to run the service as local system pass the username and password of a domain account -- I don't know whether the system account is allowed any network access at all. 当本地系统通过域帐户的用户名和密码时,您也许可以运行该服务-我不知道该系统帐户是否完全允许任何网络访问。

The general concept to keep in mind is that 'mapped drive letters' are a User concept, not a System concept. 要记住的一般概念是“映射的驱动器号”是用户概念,而不是系统概念。 So when Joe logs in to the Windows Computer, the mapped drives are attached to the Joe user account. 因此,当Joe登录Windows计算机时,映射的驱动器将附加到Joe用户帐户。 When a Windows Service is running, generally it's running under the LOCAL_SYSTEM 'user account', meaning that LOCAL_SYSTEM does not know about Joe's mapped drive letters. Windows服务运行时,通常会在LOCAL_SYSTEM“用户帐户”下运行,这意味着LOCAL_SYSTEM不了解Joe的映射驱动器号。

Therefore, UNC access to network shares are the way to go when trying to access any remote resource from within a Windows Service. 因此,尝试从Windows服务中访问任何远程资源时,UNC对网络共享的访问是必经之路。 Note that you could run the Windows Service under the context of the 'Joe' user account, or you could create a dummy AD account called something like 'MyServiceAccount' and give that account rights to the UNC, or you could use Impersonation and have the Windows Service log in to the local workstation using the NetLogon() function with an impersonation handle and then access the UNC from there. 请注意,您可以在“ Joe”用户帐户的上下文中运行Windows服务,或者可以创建一个名为“ MyServiceAccount”之类的虚拟AD帐户,并将该帐户的权限授予UNC,或者可以使用“模拟”并拥有Windows服务使用带有模拟句柄的NetLogon()函数登录到本地工作站,然后从那里访问UNC。

There are lots of ways to do it, but the all come down to User accounts are associated with Mapped Drives and UNC access. 有很多方法可以做到这一点,但是全部归结为用户帐户与映射驱动器和UNC访问相关联。

Good Luck, hope this information helps! 祝您好运,希望此信息对您有所帮助!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM