File.Move System.IO.IOException:"不能再与这台远程计算机建立连接......"

时间:2012-03-27 15:07:58

标签: c# windows-7 connection ioexception file-move

File.Move System.IO.IOException:“此时不能再与此远程计算机建立连接,因为已经有计算机可以接受的连接数。”

我在SYS帐户下运行了一个进程。它正在处理本地HD上的文件,并使用模拟将它们移动到域上的远程驱动器。

编辑,添加代码示例:

重复调用方法(模拟是我用来模拟的实用程序类,这与问题无关)。

private void moveFileUsingImpersonation(string srcFilePath, string dstFilePath, string userName, string passWord)
        {
                WindowsImpersonationContext wic = null;
                // move it to destination 
                try
                {
                    wic = Impersonation.Impersonate(userName, passWord);
                    if (wic != null)
                    {
                        File.Move(srcFilePath, dstFilePath);
                    }
                    else
                    {
                        Console.WriteLine("moveFileUsingImpersonation, Failure to impersonate!");
                    }
                }
                catch(Exception ex)
                {
                    Console.WriteLine("moveFileUsingImpersonation, Exception={0}", ex.ToString());
                }
                finally
                {
                    Impersonation.UndoImpersonate(wic);
                }
            }

修改,添加了代码示例。

当进程在XP计算机上运行且远程驱动器在XP或Win7计算机上时,对File.Move的调用可以正常工作并移动所需的文件。但是当进程在Win7上运行并且远程驱动器在Win7机器上时,在移动了20个文件后抛出了所提到的异常。

我还尝试使用MOVEFILE_REPLACE_EXISTING&调用win32 API MoveFileEx。 MOVEFILE_COPY_ALLOWED& MOVEFILE_WRITE_THROUGH标志,结果相同 - ERROR_REQ_NOT_ACCEP 71(0x47)。

似乎在Win7上没有正确关闭对File.Move调用所产生的底层连接。

有没有办法克服这个问题?

我在这里缺少什么?

谢谢,Ilan

1 个答案:

答案 0 :(得分:3)

根据您的代码,您可能正在使用UNC路径进行复制。我总是遇到这样的问题,而且我已经知道最好只是映射然后根据需要断开代码中的驱动器。它使我免于处理权限问题,以及您正在描述的问题。

我们有一个类为我们处理这个问题。我们已经使用它超过5年没有任何问题,包括在代码和远程端的Win7机器上。可悲的是它也适合你。

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

    }