ИВАН КОРОБКО
Переход от VBScript к ASP и ASP.NET
Часть II: дописываем Framework на примере сетевых папок
Программисты Microsoft, создававшие Framework, явно не ориентировались на системных и сетевых программистов, поэтому в нем отсутствуют функции по управлению DFS, сетевыми папками и т. д. Рассмотрим возможные пути решения возникших проблем.
К сожалению, в Microsoft Framework отсутствуют функции по управлению DFS, сетевыми папками и т. д. Возникает вопрос – а как же решить данную проблему, ведь, например, в VBScript можно было без особых усилий управлять сетевыми папками (Shared Folders). Неужели в VB.NET это невозможно сделать?
Существует два варианта: адаптировать сценарий на VBScript под VB.NET или, используя WIN API-функции, дописать Framework по своему усмотрению.
WINAPI, или адаптация VBScript
Рассмотрим преимущества и недостатки предлагаемых вариантов. Если говорить о трудоемкости, то предпочтительным является, конечно же, первый вариант, поскольку все ограничивается подключением библиотеки и незначительным изменением синтаксиса, по сравнению с VBScript. Однако стоит учесть, что скорость работы адаптированных сценариев оставляет желать лучшего, по сравнению с API-функциями. Использование APIфункций – занятие трудоемкое и требует много внимания, поскольку в MSDN приведены описания функций, годящиеся для VB, а как известно, типы данных VB и VB.NET не совпадают, так что придется заняться их преобразованием. Это еще не все. Для простоты написанный программный код рекомендуется поместить в отдельную библиотеку, которую опять же, чтобы использовать, необходимо подключить к проекту и вызывать нужную функцию. Итак, если для вас скорость не критична и не хочется тратить время – выбирайте адаптацию скрипта под VB.NET, если же есть желание отмучиться один раз, создав библиотеку, и каждый раз наслаждаться высокой скоростью работы созданных приложений – вам придется использовать API-функции.
Рассмотрим преимущества и недостатки предлагаемых вариантов. Если говорить о трудоемкости, то предпочтительным является, конечно же, первый вариант, поскольку все ограничивается подключением библиотеки и незначительным изменением синтаксиса, по сравнению с VBScript. Однако стоит учесть, что скорость работы адаптированных сценариев оставляет желать лучшего, по сравнению с API-функциями. Использование APIфункций – занятие трудоемкое и требует много внимания, поскольку в MSDN приведены описания функций, годящиеся для VB, а как известно, типы данных VB и VB.NET не совпадают, так что придется заняться их преобразованием. Это еще не все. Для простоты написанный программный код рекомендуется поместить в отдельную библиотеку, которую опять же, чтобы использовать, необходимо подключить к проекту и вызывать нужную функцию. Итак, если для вас скорость не критична и не хочется тратить время – выбирайте адаптацию скрипта под VB.NET, если же есть желание отмучиться один раз, создав библиотеку, и каждый раз наслаждаться высокой скоростью работы созданных приложений – вам придется использовать API-функции.
Сетевые папки: от VBScript к VB.NET
С сетевыми папками можно проделывать следующие операции:
- предоставлять к папкам доступ из сети;
- удалять сетевые папки;
- просматривать свойства выбранной сетевой папки;
- получать список доступных сетевых папок на указанном компьютере.
Рассмотрим пример создания сетевой папки на VBScript (см. пример 1). Пример можно разделить условно на две логические части: в первой из них осуществляется проверка существования папки с помощью объекта FSO. В том случае, если папки нет, она создается. Во второй части предоставляют сетевой доступ к существующей папке, для чего необходимо указать несколько обязательных параметров: имя компьютера, путь к папке, название папки в сети. Полный список и описания параметров см. в таблице 1.
Пример 1. Создание сетевой папки на VBScript
' Обработчик ошибок
On Error Resume Next
' Объявление констант
PathToFolder="С:\Test"
ShareName="Test"
ObjectType="Fileshare"
MaxUsers=10
' Проверка существования каталога
set fso=wscript.createobject("Scripting.FileSystemObject")
If fso.FolderExists (PathToFolder)=False then
set o=fso.createfolder(PathToFolder)
end If
' Определение имени текущего компьютера
Set WSHNetwork = CreateObject("WScript.Network")
PCName=WSHNetwork.ComputerName
' Создание объекта
Set ShareServiceObj = GetObject("WinNT://"+PCName+ "/LanManServer")
set NewShare = ShareServiceObj.Create(ObjectType,ShareName)
NewShare.Path = PathToFolder
NewShare.MaxUserCount = MaxUsers
NewShare.SetInfo ' сохранение изменений в файловую систему
При переводе данного примера на VB.NET необходимо прежде всего подключить две библиотеки: «Microsoft Scripting Runtime» и «Active DS Type Library».
Таблица 1. Свойства сетевой папки
Параметр
|
Описание
|
MaxUserCount
|
Максимальное число подключенных пользователей
|
AdsPath
|
ADsPath – сетевой путь к ресурсу
|
Class
|
Имя класса, к которому принадлежит объект. Для сетевой папки имя класса – «FileShare»
|
CurrentUserCount
|
Число пользователей, подключенных к сетевой папке в настоящее время
|
|
Описание сетевого ресурса
|
GUID
|
Уникальный идентификатор ресурса
|
Name
|
Имя ресурса
|
Parent
|
Путь в формате AdsPath родительского объекта
|
Path
|
Системный путь к ресурсу, например «c:folder»
|
Scheme
|
Путь в формате AdsPath к схеме класса
|
Управление файловой системой
Для управления файловой системой в VBScript используется объект FSO, содержащийся в библиотеке «Microsoft Scripting Runtime», подключаемый через свойства проекта. Поскольку в VB.NET в отличие от VBScript необходимо:
- объявлять и указывать соответствующий им тип данных;
- в VB.NET отсутствуют операторы SET и LET (все отличия синтаксиса подробно описаны в статье «Переход от VBScript к VB.NET»).
Текст примера, в котором создается заданный каталог, в случае его отсутствия выглядит следующим образом:
' Объявление константы
Dim PathToFolder As String = "C:\Test"
Dim fso As New Scripting.FileSystemObject
If fso.FolderExists(PathToFolder) = False Then
fso.CreateFolder(PathToFolder)
End If
Если использовать объект Microsoft.VisualBasic.FileIO.FileSystem, относящийся к стандартным, то пример создания заданного каталога выглядит так:
' Объявление константы
Dim PathToFolder As String = "C:\Test"
' Проверка существования каталога
Dim fso As New Microsoft.VisualBasic.FileIO.FileSystem
If fso.DirectoryExists(PathToFolder) = False Then
fso.CreateDirectory(PathToFolder)
End If
Определение имени текущего компьютера
Как говорилось ранее, для создания сетевой папки необходимо указать несколько обязательных параметров, среди которых имя компьютера. В том случае, если предоставляется сетевой доступ к локальной папке, то имя компьютера можно определить как с помощью объекта Wscript.Network:
Dim Temp As New WshNetwork
Dim PCName As String = Temp.ComputerName
так и с помощью встроенной функции в VB.NET:
Dim PCName As String = My.Computer.Name
Создание сетевой папки
Для этого необходимо определить обязательные параметры: локальный путь и название папки в сети, тип создаваемого объекта. Оба этих параметра – строки (string):
Dim PathToFolder As String = "C:\Test"
Dim ShareName As String = "Test"
Dim ObjectType As String = "FileShare"
Также используем один необязательный параметр – MaxUserCount, указывающий максимальное количество пользователей, которое может одновременно обращаться к сетевому ресурсу (см. таблицу 1). Тип этого параметра – число (integer):
Dim MaxUsers As Integer = 10
После объявления констант необходимо получить доступ к объекту LanManServer, в данном случае – локального компьютера с помощью функции GetObject(). Подключенная библиотека хранит процедуры и функции в объекте ActiveDS, пространство имен которого можно импортировать в создаваемый проект с помощью команды Imports:
Imports ActiveDS
Для удобства восприятия не будем использовать импорт пространства имен, а каждый раз в примере будем разыменовывать объект.
Итак, пишем:
Dim con As ActiveDS
и в отображаемой нам оболочкой VB.NET подсказкой в свойствах класса не находим функцию GetObject(). Для решения вопроса обратимся к поисковой системе MSDN (http://msdn.microsoft.com), задав в качестве критерия «ActiveDS, GetObject».
Среди найденных страниц остановимся на ссылке «IADsContainer::GetObject», в которой приведен пример чтения объекта (см. рис. 1).
Рисунок 1. Свойства объекта в MSDN
Приняв его за основу, адаптируем его под нашу задачу:
Dim ShareServeceObj As ActiveDs.IADsContainer
ShareServeceObj = GetObject("WinNT://" + PCName + "/LanManServer")
или, что то же самое:
Dim ShareServeceObj As ActiveDs.IADsContainer = GetObject("WinNT://" + PCName + "/LanManServer")
Аналогично адаптируем строку создания объекта типа FileShare и назначаем объекту необходимые свойства. Запись сделанных изменений так же, как и в VBScript, осуществляется с помощью метода SetInfo:
' Создание объекта
Dim ShareServeceObj As ActiveDs.IADsContainer = GetObject("WinNT://" + PCName + "/LanManServer")
Dim NewShare As ActiveDs.IADsFileShare = ShareServeceObj.Create(ObjectType, ShareName)
NewShare.Path = PathToFolder
NewShare.MaxUserCount = MaxUsers
NewShare.SetInfo() ' сохранение изменений в файловую систему
Теперь необходимо создать обработчик ошибок, чтобы созданное приложение выдавало сообщение, например, о том, что создаваемая сетевая папка уже существует. Для этого рекомендуется использовать встроенную процедуру «Try … End Try». Ее шаблон выглядит следующим образом:
Try
' Тестируемый программный код
Catch ex As Exception
MsgBox(ex.Message)
End Try
Таким образом, полный вариант текста адаптированного сценария создания сетевой папки выглядит следующим образом:
Try
' Объявление констант
Dim PathToFolder As String = "C:\Test"
Dim ShareName As String = "Test"
Dim ObjectType As String = "FileShare"
Dim MaxUsers As Integer = 10
' Проверка существования каталога
Dim fso As New Microsoft.VisualBasic.FileIO.FileSystem
If fso.DirectoryExists(PathToFolder) = False Then
fso.CreateDirectory(PathToFolder)
End If
' Определение имени текущего компьютера
Dim PCName As String = My.Computer.Name
' Создание объекта
Dim ShareServeceObj As ActiveDs.IADsContainer = GetObject("WinNT://" + PCName + "/LanManServer")
Dim NewShare As ActiveDs.IADsFileShare = ShareServeceObj.Create(ObjectType, ShareName)
NewShare.Path = PathToFolder
NewShare.MaxUserCount = MaxUsers
NewShare.SetInfo() ' сохранение изменений в файловую систему
Catch ex As Exception
MsgBox(ex.Message)
End Try
Использование WIN API-функций
С помощью API-функций программисту предоставляется возможность доступа ко всему многообразию функций ОС на низком уровне. Это обозначает, что скорость работы и функционал создаваемого приложения увеличится.
Итак, для начала вспомним действия, которые можно осуществлять с сетевыми папками, и приведем в таблице 2 соответствующие им процедуры, хранящиеся в библиотеке Netapi32.dll (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/stgmgmt/fs/netsharesetinfo.asp).
Таблица 2. Используемые функции WIN API для управления сетевыми папками
Действие
|
Функция
|
Предоставить папку в сетевой доступ
|
NetShareAdd
|
Удалить сетевую папку
|
NetShareDel
|
Просмотреть/изменить свойства выбранной сетевой папки
|
NetShareGetInfo/NetShareSetInfo
|
Сформировать список имеющихся сетевых папок на компьютере
|
NetShareEnum
|
Рассмотрим подробно, как и в предыдущем разделе, процесс создания сетевой папки, а остальные функции приведем в приложении.
Маршалинг вызова функций
Все данные, используемые в среде VB.NET, являются управляемыми, то есть их расположением в памяти управляет среда исполнения .NET. Обычная DLL-библиотека ничего не знает о среде исполнения и типах данных, которые используются. Чтобы установить отсутствующую связку, в игру вступает процесс, называемый маршалингом (marshal (англ.) – располагать в определенном порядке, размещать). Этот процесс позволяет перенести вызов из среды .NET на уровень операционной системы, непосредственно к самим библиотекам.
Вызов функции из DLL осуществляется следующим образом:
- поиск указанной в запросе библиотеки;
- загрузка DLL в память;
- поиск необходимой функции;
- перенос параметров в стек и преобразование типов (например, из String в LTPSTR) – этот процесс и называется маршалингом;
- вызов функции из DLL;
- анализ возвращаемых значений и обработка ошибок
- приведение типов возвращаемых значений к типам .NET.
Объявление функции
Синтаксис объявления функций следующий:
Declare Unicode Function NetDfsGetInfo Lib "***.DLL"
(ByVal[ByRef] ParametrName As TypeOfData,…) As Integer
Необходимо помнить, что, указывая название функции, следует различать большие и маленькие буквы. Поскольку в MSDN декларирование функций приведено для VB, а типы данных VB и VB.NET значительно отличаются, то для корректного объявления функций не обойтись без таблицы 3.
Таблица 3. Преобразование типов для функций
Структура в MSDN
|
Описание в VB.NET
|
LPTSTR a
|
ByVal … As String
|
LMSTR a
|
LPWSTR a
|
LPBYTE a
|
ByRef … As StructName
|
LPBYTE a
|
ByRef … As IntPtr
|
DWORD a
|
ByVal … As Integer
|
LPWORD a
|
ByRef … As Integer
|
TCHAR a
|
byRef … As String
|
Описание структуры
Синтаксис объявления структур, используемых функциями, следующий:
<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Auto)> _
Public Structure OSVERSIONINFOEX
…
End Structure
Функция всегда возвращает код ошибки, а манипуляция с данными осуществляется через память чтением или записью данных в структуру. Описание структур в MSDN также требует адаптации для VB.NET (см. таблицу 4).
Таблица 4. Преобразование типов для структур
Структура в MSDN
|
Описание в VB.NET
|
LPCWSTR a
|
Public a as String
|
LMSTR a
|
LPWSTR a
|
Dim a As String
|
TCHAR a[128]
|
<VBFixedString(128), MarshalAs( _
UnmanagedType.ByValTStr, SizeConst:=128)> _
Public szCSDVersion As String
|
BYTE a
|
Public a as Byte
|
FILEOP_FLAGS a
|
Public a as Short
|
BOOL a
|
Public a as Boolean
|
LPVOID a
|
Public a as Integer
|
UINT a
|
LONG a
|
HWND a
|
WORD a
|
Public a as Int16 или Integer
|
DWORD a
|
Public a as Int32 или Integer
|
LPStructureName Storage
|
Public a as IntPtr
|
Вызов функции
Синтаксис вызова функции зависит от нескольких факторов. Рассмотрим некоторые из возможных вариантов.
Вызов API-функции, не обращающейся к структуре
Примером такой функции является API-функция NetShare Check, с помощью которой определяют статус сетевой папки.
На первом этапе необходимо объявить функцию, воспользовавшись MSDN, задав в качестве искомого слова «NetShareCheck» (см. рис. 2), и таблицей 3:
Declare Unicode Function NetShareCheck Lib "NETAPI32.DLL" (ByVal servername As String, ByVal device As String, ByRef type As Integer) As Integer
Рисунок 2. Описание функции NetShareCheck в MSDN
В обработке какого-либо события, например нажатия на кнопку, осуществляется вызов функции:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim server As String = "\\ComputerName"
Dim share As String = "c:\FolderName"
Const STYPE_DISKTREE = 0
Dim err_description As String = ""
Dim err_code As Integer
err_code = NetShareCheck(server, share, STYPE_DISKTREE)
if err_code = 0 then
err_description = "Shared Folder Status: OK "
else
err_description = "Shared Folder Exist: Error"
end if
MsgBox(err_description)
End Sub
В приведенном примере функция не передает никаких данных.
Вызов API-функции, осуществляющей запись в структуру
Рассмотрим такую функцию на примере создания сетевой папки с помощью NetShareAdd, которая объявляется следующим образом:
Declare Unicode Function NetShareAdd Lib "NETAPI32.DLL" (ByVal servername As String, ByVal level As Integer, ByRef buf As _SHARE_INFO_2, ByRef parm_err As Integer) As Integer
Если обратить внимание на описание этой функции в MSDN, то видно, что она при декларировании может ссылаться на одну из структур. В приведенном примере используется структура _SHARE_INFO_2.
Также необходимо описать в тексте VB-файла структуру _SHARE_INFO_2. Воспользовавшись поиском в MSDN найдем ее описание (см. рис. 3) и таблицей 4, корректно опишем структуру в VB-файле VB.NET проекта:
<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Auto)> _
Public Structure _SHARE_INFO_2
<MarshalAs(UnmanagedType.LPWStr)>Public shi2_netname As String
Public shi2_type As Int32
<MarshalAs(UnmanagedType.LPWStr)>Public shi2_remark As String
Public shi2_permissions As Int32
Public shi2_max_uses As Int32
Public shi2_current_uses As Int32
<MarshalAs(UnmanagedType.LPWStr)>Public shi2_path As String
<MarshalAs(UnmanagedType.LPWStr)>Public shi2_passwd As String
End Structure
Рисунок 3. Описание структуры _SHARE_INFO_2 в MSDN
Перед тем как выполнить обращение к функции необходимо присвоить членам, описанным в структуре, соответствующие значения:
Dim a As _SHARE_INFO_2
a.shi2_max_uses = 100
a.shi2_netname = "123"
a.shi2_path = "c:\123"
Затем осуществляется вызов функции, с указанием необходимых параметров:
Dim server As String = "\\1230pc"
Dim err_code As Integer
err_code = NetShareAdd(server, 2, a, Nothing)
Если все типы данных объявлены корректно, то функция возвратит 0, если же нет, необходимо воспользоваться MSDN для определения по коду ошибки ее описания ссылкой (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/debug/base/system_error_codes.asp). Полный вариант текста вызова функции приведен ниже:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim a As _SHARE_INFO_2
a.shi2_max_uses = 100
a.shi2_netname = "123"
a.shi2_path = "c:\123"
Dim server As String = "\\1230pc"
Dim err_description As String = ""
Dim err_code As Integer
err_code = NetShareAdd(server, 2, a, Nothing)
Select Case err_code
Case 0
err_description = "Share Folder Was Created"
Case 2
err_description = "Folder Not Found"
Case 2118
err_description = "Share Folder Is Exist"
End Select
MsgBox(err_description)
End Sub
Вызов API-функции, осуществляющей чтение данных из структуры
Проиллюстрировать данный случай лучше всего на примере функции NetShareGetInfo. Обратите внимание на декларирование этой функции в MSDN: последний параметр является ссылкой на данные, хранящиеся в памяти, который имеет в VB.NET тип IntPtr. При вызове функции осуществляется обращение к структуре и обработка полученных данных. Итак, объявление этой функции в VB.NET выглядит следующим образом:
Declare Unicode Function NetShareGetInfo Lib "NETAPI32.DLL" (ByVal servername As String, ByVal netname As String, ByVal level As Integer, ByRef bufptr As IntPtr) As Integer
Для использования этой функции необходимо описать соответствующую структуру и указать соответствующий ей номер в качестве значения параметра level. Поскольку, как и в прошлом случае будет использована структура _SHARE_INFO_2, то пропустим часть, в которой осуществляется ее декларирование. Данные считываются по следующему алгоритму: сначала осуществляется вызов функции:
Dim server As String = "\\1230pc"
Dim share As String = "123"
Dim err_code As Integer
Dim bufPtf As IntPtr
err_code = NetShareGetInfo(server, share, 2, bufPtf)
затем чтение полученных данных из памяти:
Dim b As _SHARE_INFO_2
b = CType(Marshal.PtrToStructure(bufPtf, GetType(_SHARE_INFO_2)), _SHARE_INFO_2)
MsgBox(b.shi2_netname)
Полный текст процедуры вызова функции приведен ниже:
Private Sub Button6_Click(ByVal sender As System.Object,
ByVal e As System.EventArgs) Handles Button6.Click
Dim server As String = "\\1230pc"
Dim share As String = "123"
Dim err_description As String = ""
Dim err_code As Integer
Dim b As _SHARE_INFO_2
Dim bufPtf As IntPtr
err_code = NetShareGetInfo(server, share, 2, bufPtf)
b = CType(Marshal.PtrToStructure(bufPtf, GetType(_SHARE_INFO_2)), _SHARE_INFO_2)
Select Case err_code
Case 0
MsgBox(b.shi2_netname)
Case 2310
err_description = "Share Is Not Found"
MsgBox(err_description)
End Select
End Sub
Создание собственной библиотеки
Для создания собственных динамических библиотек необходимо создать проект, имеющий тип Class Library.
Библиотека состоит минимум из одного класса, в котором описаны функции, вызов которых и осуществляется из внешних программ:
Imports …
Public Class ClassName1
Public Function Function1(ByVal Type As Integer, …) As String
End Function
Public Function Function2(ByVal Type As Integer, …) As Object
End Function
Function Function1(ByVal Type As Integer, …) As String
End Function
…
End Class
…
Public Class ClassNameK
…
End Class
Обратите внимание на то, что некоторые функции или даже классы можно сделать недоступными из других файлов, например сервисные функции. Чтобы достичь этого эффекта, при декларировании функции или класса необходимо пропустить слово Public. API-функции и необходимые структуры декларируются, как и в обычных проектах: в классе, но вне функции и процедур.
Определяем пространство имен
Намеренно забегу вперед и расскажу об использовании библиотек, чтобы потом вам не пришлось переделывать названия классов и функций. Необходимо определиться с заданием 3-х категорий имен: основным пространством имен всей библиотеки, названиями классов и названиями функций. Рассмотрим поочередно все три категории.
Предположим, что мы создали уже библиотеку и хотим ее использовать в другом проекте. Для получения доступа к библиотеке необходимо сначала подключить ее к проекту, а затем импортировать пространство имен. Присоединение к проекту, как описывалось ранее, осуществляется с помощью пункта меню «Add Reference…» через вкладку «File». После этого необходимо импортировать пространство имен с помощью ключевого слова Imports. Предположим, что мы хотим, чтобы пространство имен было SharedFolders, тогда команда импорта должна выглядеть так:
Imports SharedFolders
Чтобы достичь этого эффекта, необходимо в проекте, где формируется библиотека, в его свойствах изменить заданное значение параметра Root namespace на желаемое, а именно на SharedFolders (см. рис. 4).
Рисунок 4. Задаем пространство имен динамической библиотеки
Замечание: в качестве параметра Assembly name (см. рис. 4) задается название формируемой DLL-библиотеки.
Названия классов, используемые при формировании библиотек, становятся доступными при импорте пространства имен данной библиотеки из другого проекта.
Формирование функций
Приведу пример функции в DLL-библиотеки, создающей сетевую папку. В том случае, если папка отсутствует, то функция, в зависимости от установленного флага, будет ее создавать.
Новая функция должна иметь несколько обязательных параметров:
- Имя компьютера, на котором она должна быть создана.
- Путь к локальной папке, которую необходимо предоставить в сетевой доступ.
- Имя папки в сети. Если этот параметр не задан, то имя сетевой папки должно совпадать с физическим именем папки.
- Описание сетевой папки.
- Флаг: 0/1. Если значение 0 – при физическом отсутствии папки не создавать ее, 1 – создать папку, если ее нет.
Конечно, количество параметров можно расширить или сократить, например, можно уменьшить их количество, объединив первые три в UNC-путь к папке (\\Server\C$\Folder), при условии, что сетевое имя папки берет за основу ее физическое имя.
Теперь придумайте название функции, например, AddShare.
На первом этапе следеут объявить функцию. Первые четыре параметра имеют строковый формат, флаговое значение может быть числовым (0/1) либо булевым(True/False). В данной ситуации остановимся на булевом значении:
Public Function AddShare(ByVal Server As String, ByVal Path As String, ByVal Share As String, ByVal Description As String, ByVal flag As Boolean) As Integer
…
End Function
Для удобства предлагается поместить операцию вызова API-функции в отдельную функцию, например _ AddShare. Чтобы она была не видна из других приложений, она должна иметь тип Private:
Private Function _AddShare(ByVal server As String, ByVal share As String, ByVal path As String, ByVal description As String)
Dim a As _SHARE_INFO_2
a.shi2_netname = share
a.shi2_path = Path
a.shi2_remark = description
_AddShare = NetShareAdd(Server, 2, a, Nothing)
End Function
Рассмотрим тело основной функции. Поскольку условились, что будем проверять булевое значение, то необходимо с помощью объекта FSO проверить наличие каталога, при указанном булевом значении TRUE. В том случае, если значение равно TRUE, т.е. проверка осуществляется, то при отсутствии каталога в указанном месте он создается и предоставляется в сетевой доступ с указанными параметрами.
Если же значение FALSE, то проверка на наличие каталога не осуществляется и подразумевается, что папка существует:
Dim fso As Microsoft.VisualBasic.FileIO.FileSystem
If flag = True Then
Dim path_exist As String = "\\" + Server + "\" + Right(Path, Len(1)) + "$" + Left(Path, Len(Path - 1))
If fso.DirectoryExists(path_exist) = False Then
fso.CreateDirectory(path_exist)
AddShare = _AddShare(Server, Share, Path, Description)
End If
Else
AddShare = _AddShare(Server, Share, Path, Description)
End If
Полный листинг см. на сайте журнала в разделе «Исходный код».
Вызов созданной функции из библиотеки
Создав и скомпилировав библиотеку, необходимо проверить работоспособность всех функций библиотеки, создав тестовый проект и подключив к нему скомпилированную в DLL-файл библиотеку.
В форме нового проекта создадим кнопку, назвав ее, например, Add Share, и в процедуру обработки события добавим следующий текст:
Dim a As SharedFolder.Manipulate
Dim err_code As Integer
err_code = a.AddShare("1230pc","c:\123","123","TestFolder",True)
MsgBox (err_code)
Если в появившемся диалоговом окне вы увидите 0, то на локальном диске С компьютера 1230pc в его корневом каталоге 123 создана сетевая папка 123.
Проверив этот факт, можно убедиться, что скомпилированная библиотека работает корректно.
Вместо заключения
Используя описанные методы, читатель сможет создавать свои библиотеки, объединяя в них часто используемые, если так можно сказать, скрипты. Благодаря этому скорость и качество программирования увеличатся. Вместе с тем он сможет использовать хоть и не быстрые, но хорошо известные и до боли знакомые функции.