File.Move System.IO.IOException: «Больше никаких подключений к этому удаленному компьютеру ...» - PullRequest
1 голос
/ 27 марта 2012

File.Move System.IO.IOException: «В настоящее время невозможно установить больше соединений с этим удаленным компьютером, потому что уже существует столько соединений, сколько может принять компьютер».

У меня есть процесс, работающий под учетной записью SYS. Он обрабатывает файлы на локальном жестком диске и перемещает их на удаленный диск в домене, используя олицетворение

Редактировать, добавлен пример кода:

Метод ниже вызывается неоднократно (Олицетворение - это служебный класс, который я использую для олицетворения, это не имеет отношения к проблеме).

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 файлов.

Я также пытался вызвать win32 API MoveFileEx с флагами MOVEFILE_REPLACE_EXISTING & MOVEFILE_COPY_ALLOWED & MOVEFILE_WRITE_THROUGH, с тем же результатом - ERROR_REQ_NOT_ACCEP 71 (0x47).

Похоже, что основное соединение, созданное при вызове File.Move, не закрывается должным образом в Win7.

Есть ли способ преодолеть это?

Что мне здесь не хватает?

Спасибо, Илан

1 Ответ

3 голосов
/ 27 марта 2012

Исходя из вашего кода, вы, вероятно, копируете, используя 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;
        }

    }
...