首页 文章

C# - 从Web服务映射网络驱动器

提问于
浏览
0

我们正在开发一个必须运行第三方进程的Web服务,该进程与映射的网络驱动器进行交互 . 因此,我们必须以编程方式从Web服务映射此驱动器 .

我已经在另一个项目的更好的类中包装了WNetAddConnection2等,所以我把代码放进去了 .

我们的Web服务在UltiDev Cassini(而不是IIS)下运行,该服务在System帐户下运行 . 我们每次都会收到错误代码:“指定的设备名称无效” . 我还尝试在web.config文件中模仿其他用户,结果相同 .

当我从普通用户帐户下的控制台程序运行代码时,驱动器将正常映射 .

我还尝试从C#运行等效的“net use”命令,其结果与WNetAddConnection完全相同 .

有谁知道为什么Windows服务或系统用户无法映射网络驱动器?

有没有人知道解决方法?简单地在系统启动时映射驱动器将是一个解决方案,但系统/模拟用户如何访问它?

UltiDev Cassini的链接:UltiDev

SOLUTION: 我将UltiDev Cassini服务设置为在Administrator下登录,一切正常 . ASP .Net模仿不得按计划运行 .

6 回答

  • 1

    LOCAL_SYSTEM帐户显示匿名credentials on the network . 您可以使用UNC网络共享来访问此信息,前提是匿名(Everyone)可以访问共享 .

    您还可以将install Cassini as a windows service配置为在其他用户下运行 .

  • 0

    如果您使用的是本地系统帐户,那么我认为它本身无法访问网络[foo] . 我说假冒是你唯一可行的道路 . 从技术上讲,您可以减少对共享的访问控制,以至于任何人都可以读取/写入共享,但这会带来比解决方案更多的问题 .

  • 2

    我们遇到了同样的问题 . 出现问题的原因是代码运行的帐户 . 您可以通过使用以下类来解决这个问题 . 您必须使用与访问/复制文件相同的代码映射驱动器 . 我们使用的模式是始终检查驱动器是否先连接 . 如果是这样,我们断开它,然后重新连接它 . 如果没有,我们只是连接它 . 它似乎清除了你所描述的问题 .

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

    您可以使用UNC共享连接而不是映射驱动器吗?

    我仍然冒充有权访问该共享的用户 .

  • 0

    我之前实际上已经这样做了,但是很久以前 - 就像1997年一样,并且使用Delphi 2赢得NT NT 3.51

    我是从内存运行的,但我认为它是这样的:你使用Win API:

    WNetAddConnection2()

    电话信息:http://msdn.microsoft.com/en-us/library/aa385413(VS.85).aspx

    你可以从pInvoke.net获得c#签名:http://www.pinvoke.net/default.aspx/mpr/WNetAddConnection2.html

    配置注意事项:我认为您需要为该服务设置域帐户,并使用该帐户的身份而不是本地系统运行该服务 . 我认为你传递null作为用户名和密码 .

    您可以运行该服务,因为本地系统会传递域帐户的用户名和密码 - 我不知道系统帐户是否允许任何网络访问 .

  • 2

    要记住的一般概念是“映射驱动器号”是用户概念,而不是系统概念 . 因此,当Joe登录到Windows计算机时,映射的驱动器将附加到Joe用户帐户 . 当Windows服务正在运行时,通常它在LOCAL_SYSTEM'用户帐户'下运行,这意味着LOCAL_SYSTEM不知道Joe的映射驱动器号 .

    因此,尝试从Windows服务中访问任何远程资源时,UNC访问网络共享是一种方法 . 请注意,您可以在“Joe”用户帐户的上下文中运行Windows服务,或者您可以创建一个名为“MyServiceAccount”的虚拟AD帐户,并将该帐户权限授予UNC,或者您可以使用模拟并拥有Windows服务使用具有模拟句柄的NetLogon()函数登录到本地工作站,然后从那里访问UNC .

    有很多方法可以做到这一点,但所有归结为用户帐户都与映射驱动器和UNC访问相关联 .

    祝你好运,希望这些信息有所帮助!

相关问题