【问题标题】:Could not find a part of the path :While copying file on Mapped drive using Windows Service找不到路径的一部分:使用 Windows 服务在映射驱动器上复制文件时
【发布时间】:2012-03-26 13:04:28
【问题描述】:

我有一个 Windows 服务,它可以更新网络上的一些文件,这些文件映射为驱动器“Z:\”。当我以管理员身份从 VS 运行代码时,我可以将文件复制到映射驱动器上,但是当它从在管理员帐户下运行的服务运行时,同样的事情会失败。 映射驱动器是从运行服务的同一帐户创建的。有点令人费解,为什么它在从 VS 运行而不是从服务运行时工作。 使用UNC比使用网络驱动器更好吗? 下面的论坛有一个解决方法 http://support.microsoft.com/default.aspx?scid=kb;en-us;827421#appliesto 但它使用了 UNC 未映射的驱动器。

【问题讨论】:

    标签: c# .net


    【解决方案1】:

    我们也遇到过这种情况,虽然我不能告诉你为什么我们的解决方案有效,但我可以告诉你什么有效。

    在代码中映射驱动器。不要仅仅因为您使用的是同一个帐户而依赖被映射的驱动器。

    根据我们看到的行为,这就是我猜想在我们的情况下发生的事情以及在您的情况下发生的事情。

    我们遇到问题的服务使用了登录脚本中映射的驱动器。如果我们让机器以服务使用的同一用户身份登录,它可以工作,但如果不是,它将无法工作。基于此,我推测驱动器根本没有被映射,因为服务并没有真正“登录”。

    在代码中映射驱动器修复了它。

    附带说明,您也可以直接引用 UNC 路径,但我们也遇到了权限问题。映射驱动器、传递用户名和密码对我们来说效果更好。

    我们这样做的代码:

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

    使用上述类,您可以随意映射和断开驱动器。如果这是一项服务,我建议您在需要驱动器之前映射驱动器,并在需要后立即断开驱动器的连接。

    【讨论】:

    • 这不适用于多个同时连接尝试。
    • 真的救了我!就像 Sachin 提到的,小心多次连接尝试。所以要注意一些事情。
    【解决方案2】:

    我建议 UNC 是一个更好的主意。

    如果映射的驱动器在登录时被映射怎么办?服务可能在没有用户登录的情况下运行,因此可能永远不会创建映射。

    【讨论】:

      【解决方案3】:

      为了解决同样的问题,我费了很大的力气(约 3 天)。似乎它与 NTFS 和文件级权限更相关。最好使用共享位置而不是驱动器。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-01-10
        • 2016-08-14
        • 1970-01-01
        • 1970-01-01
        • 2011-06-26
        • 2018-03-14
        相关资源
        最近更新 更多