Версия для печати
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум на Исходниках.RU > Delphi: Сетевое программирование > создать нехватающие папки в сетевом пути


Автор: Voice 08.02.17, 16:57
допустим, задан путь для подключения сетевого диска: \\Share\Folder\MyDocs\Pum-purum\Param-pam-pam
но на шаре есть только \\Share\Folder\
есть ли готовая функция для автоматического создания недостающих папок (при условии наличия прав)?

Автор: ^D^ima 08.02.17, 17:24
Уверен такой нет, напиши свою, 10 строк кода

Автор: Voice 08.02.17, 21:20
Цитата ^D^ima @
напиши свою, 10 строк кода

немножко больше
делаю так:
1. подключаю сет.папку (БЕЗ задания диска) с помощью WNetAddConnection2 с заданным логином и паролем к сет.папке
2. если не удалось (часто встречается ошибка о множественном подключении к одной шаре разными пользователями (код ERROR_SESSION_CREDENTIAL_CONFLICT), что в винде недопустимо), задаю логин и пароль как nil, чтобы подключение шло под пользователем по умолчанию (под которым запущен текущий процесс).
3. если и предыдущий шаг не удался, меняю имя сервера на IP

(все, что выше, так я стандартно подключаю шары)

теперь дальше с отсутствующими папками
4. если все шаги выше привели к ошибкам, считаю, что папка не существует
5. вырезаю имя последней папки (было \\Share\Folder\MyDocs\Pum-purum\, стало \\Share\Folder\MyDocs\) и рекурсивно вызываю процедуру подключения (goto 1) с передачей имени отсутствующей папки

т.е. далее опять пытаемся подключить шару (без последней папки) 3-мя способами. Если опять ошибка, то убираем след.папку (будет \\Share\Folder\) и опять пытаемся подключить диск.

Когда наконец что-то подключается, создаем папку (рекурсия же).

т.е. очень вкратце процедура выглядит так:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    function ConnectToUNC(APath, ALogin, APass: string; ACreateFolderName: string = ''): string;
    begin
    m := WNetAddConnection2(NetResource,
                                  PAnsiChar(APass), {пароль, если нужно (или пусто (nil))}
                                  PAnsiChar(ALogin), {имя юзера, если нужно (или пусто (nil))}
                                  0 {CONNECT_UPDATE_PROFILE {восстановить соед. при входе в систему});
    if (m = ERROR_SESSION_CREDENTIAL_CONFLICT) and // такой сет.диск уже подключен под другим логином - в винде это недопустимо (2 раза под разными логинами)...
       (ALogin <> '') then // ... и при этом у нас задан логин для подключения, то теперь пытаемся подключиться под текущим пользователем (под которым запущен этот процесс)
       begin
       m := WNetAddConnection2(NetResource,
             nil, //PAnsiChar(APath.Pass), {пароль, если нужно (или пусто (nil))}
             nil, //PAnsiChar(APath.Login), {имя юзера, если нужно (или пусто (nil))}
             0 {CONNECT_UPDATE_PROFILE {восстановить соед. при входе в систему});
       end;
    // если все равно не удалось, меняем имя компьютера на его IP
    if (m <> NO_ERROR) {and (m <> ERROR_SESSION_CREDENTIAL_CONFLICT)} then
       begin
       APath := ChangeShareNameToIP(APath); // меняем имя на IP: \\Share\Folder -> \\192.168.1.2\Folder
       m := WNetAddConnection2(NetResource,
                                   PAnsiChar(APass), {пароль, если нужно (или пусто (nil))}
                                   PAnsiChar(ALogin), {имя юзера, если нужно (или пусто (nil))}
                                   0 {CONNECT_UPDATE_PROFILE {восстановить соед. при входе в систему});
       end;
     
    if m in [NO_ERROR] then // если наконец подключили
       begin
       Result := IncludeTrailingPathDelimiter(APath) + ACreateFolderName; // запоминаем подключенный сетевой путь
       end else
       begin
       // если подключить не удалось, убираем последнюю папку (возможно ее не было) и подключаемся на уровень выше
       TmpLastFolder := GetLastFolder(APath); // запоминаем недостающую ПОСЛЕДНЮЮ папку
       APath := DelLastFolder(APath); // убираем последнюю папку: \\Share\Folder\MyDocs\Pum-purum -> \\Share\Folder\MyDocs
     
       ConnectToUNC(ExcludeTrailingPathDelimiter(APath), ALogin, APass, TmpStr);
       if TmpStr <> '' then // если задана папка на создание, создаем
          begin
          TmpStr := IncludeTrailingPathDelimiter(APath) + TmpStr;
          if not DirectoryExists(TmpStr) then
             if not CreateDir(TmpStr) then
                Print('Не удалось создать папку')
                else Result := TmpStr;
          end;
       end;
    end;


и проблема в том, что при подключении к несуществующей папке иногда появляется ошибка не 53 (Не найден сетевой путь.), а 5 (Отказано в доступе.). При этом папка нормально создается.
Закономерность пока не уловил.

Приложил тестовый проектCreateNetFoldersEx.rar (, : 194)

Powered by Invision Power Board (https://www.invisionboard.com)
© Invision Power Services (https://www.invisionpower.com)