Подключить или отключить сетевой диск через LISP

Понадобилось тут мне поиграться с подключениями и отключениями сетевых дисков через LISP. Самое простое решение - использовать shell и стандартную команду Windows "net use ..." не подходило по нескольким причинам:

  1. Появляется (и не всегда гасится) окно cmd.exe. Уже не самое изящное решение
  2. Подключение выполняется под нестандартным пользователем и с указанием пароля. Если окно cmd.exe не закрывается "автоматом", то пользователь может прочитать информацию, не предназначенную для него
  3. Затруднительно отловить момент окончания выполнения net use. Если дальнейший код "завязан" на результат выполнения net use, можно получить очень неприятный результат: подключение выполнено, но не когда оно нужно
  4. И, наконец, последнее: практически нереально отловить ошибку выполнения net use

Непродолжительный поиск по MSDN привел к объекту WScript.Network и его методам MapNetWorkDrive и RemoveNetworkDrive:

MapNetworkDrive
Синтаксис:
MapNetworkDrive(<LocalName>, <RemoteName>, <UpdateProfile>, <User>, <Password>)
Назначение: подключает сетевой диск.
Параметры:

<LocalName> Строка, локальное имя диска
<RemoteName> Строка, имя сетевого ресурса
<UpdateProfile> Необязательный, булево. Если указано True, создаваемое сетевое подключение будет сохранено в профиле пользователя. В LISP используется t или nil
<User> Необязательный, строка. Имя пользователя, если сетевой диск подключается от пользователя, отличного от текущего
<Password> Необязательный, строка. Пароль пользователя, если сетевой диск подключается от пользователя, отличного от текущего

RemoveNetworkDrive
Синтаксис:
RemoveNetworkDrive(<Name>, <Force>, <UpdateProfile>)
Назначение: отключает сетевой диск.
Параметры:

<Name> строка, локальное имя диска (или сетевое имя, если ресурсу не сопоставлена никакая буква)
<Force> необязательный, число (булево). Если указано True, отключение будет произведено вне зависимости от того, используется ресурс в настоящий момент или нет
<UpdateProfile> необязательный, число (булево). Если указано True, сетевое подключение будет удалено из профиля пользователя

Если пробовать написать лисп-код, то получится нечто типа:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
(defun connect-net-drive (local-path net-path save name pwd / wsh)
                         ;|
*    Подключение сетевого диска
*    Параметры:
  local-path    Буква подключаемого диска
  net-path      Серверный путь. Если содержит пробелы, обязательно заключать в кавычки
  save          Сохранять в профиле пользователя (t || nil)
  name          Имя пользователя. nil -> использовать текущий
  pwd           Пароль подключения
*    В принципе, возможна ситуация, когда подключение выполняется с текущим пользователем,
* но пароль должен быть "предопределенным". Поэтому обработка и выполняется именно такми
* методом.
*    В случае успеха подключения сетевого диска возвращает t.
|;

  (setq wsh (vlax-get-or-create-object "WScript.Network")
        res
            (not (vl-catch-all-error-p
                   (vl-catch-all-apply
                     (function
                       (lambda ()

                         (cond
                           ((and name pwd)
                            (vlax-invoke wsh 'mapnetworkdrive local-path net-path save name pwd)
                            )
                           ((and name (not pwd))
                            (vlax-invoke wsh 'mapnetworkdrive local-path net-path save name)
                            )
                           ((and (not name) pwd)
                            (vlax-invoke wsh
                                         'mapnetworkdrive
                                         local-path
                                         net-path
                                         save
                                         (strcat (getenv "username") "@" (getenv "userdomain"))
                                         pwd
                                         ) ;_ end of vlax-invoke
                            )
                           ((and (not name) (not pwd))
                            (vlax-invoke wsh 'mapnetworkdrive local-path net-path save)
                            )
                           ) ;_ end of lambda
                         ) ;_ end of function
                       ) ;_ end of vl-catch-all-apply
                     ) ;_ end of vl-catch-all-apply
                   ) ;_ end of vl-catch-all-error-p
                 ) ;_ end of not
        ) ;_ end of setq
  (vlax-release-object wsh)
  res
  ) ;_ end of defun

Ну и соответственно отключение от диска (предполагаю, что отключать надо независимо ни от чего; подключение, если оно и было сохранено в профиле пользователя, должно быть оттуда удалено):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
(defun disconnect-net-drive (name)
                            ;|
*    Отключение диска
*    Параметры вызова:
  name    имя локального диска
*    Возвращает t, если диск удалось отключить. Если выполняется попытка отключить несуществующий
* диск, или произошла ошибка отлюкчения, возвращает nil.
|;

  (setq wsh (vlax-get-or-create-object "WScript.Network")
        res (not (vl-catch-all-error-p
                   (vl-catch-all-apply
                     (function
                       (lambda ()
                         (vlax-invoke wsh 'removenetworkdrive name t t)
                         ) ;_ end of lambda
                       ) ;_ end of function
                     ) ;_ end of vl-catch-all-apply
                   ) ;_ end of vl-catch-all-error-p
                 ) ;_ end of not
        ) ;_ end of setq
  (vlax-release-object wsh)
  res
  ) ;_ end of defun

Вообще говоря, WScript.Network весьма занятный объект. В качестве примера можно использовать страницу http://www.script-coding.com/WSH/WshNetwork.html#3.3.
P.S. Работа кодов проверена на AutoCAD 2009, 2013 (x64).



Поделитесь своим мнением


Я не робот.