1

Тема: VBScript: имитация Include для целей повторного использования кода

Простейший пример имитации Include.
Код файла test.vbs, являющегося подключаемой "библиотекой":

Dim param
param = "Test"

Использование "библиотеки":

'/// Файл, код которого включаем
Include "test.vbs"

'/// Переменная, созданая в результате включения
msgbox Param

'/// Функция включения
Function Include(FilePath)
    Set FileSystemObject = CreateObject("Scripting.FileSystemObject")
    ParentFolderName = FileSystemObject.GetParentFolderName(WScript.ScriptFullName)
    FilePath = FileSystemObject.BuildPath(ParentFolderName, FilePath)
    ExecuteGlobal FileSystemObject.OpenTextFile(FilePath, 1).ReadAll
End Function

Автор примера - Xameleon.

Предложения в русском языке начинаются с большой буквы и заканчиваются точкой.
В названии ветки всегда должен быть указан язык программирования или среда исполнения скрипта, если это возможно.

2

Re: VBScript: имитация Include для целей повторного использования кода

Основное ограничение при использовании оператора ExecuteGlobal, на котором, собственно, и покоится вся подобная функциональность - возникновение ошибки при повторном описании классов, констант, переменных, процедур, функций. Ниже приводится пример с классом для включения "библиотек", который имеет специальное свойство SimpleReEntrant. Если перед включением библиотеки установить это свойство в True, дублирующиеся определения не будут добавлены в глобальный контекст скрипта.
Библиотека C:\Мои проекты\My Scripts\MyLib1.vbh:

Option Explicit

' Несколько констант
Const ForReading   = 1
Const ForWriting   = 2
Const ForAppending = 8

' Простая функция
Function Add(intValue1, intValue2)
    Add = intValue1 + intValue2
End Function

Библиотека C:\Program Files\My Scripts\Library\MyLib2.vbh:

Option Explicit

' Опишем простой класс, умеющий складывать и вычитать
Class MyCalc
    Private Sub Class_Initialize
    End Sub
    
    Private Sub Class_Terminate
    End Sub
    
    Public Function Multiply(intArg1, intArg2)
        Multiply = intArg1 + intArg2
    End Function
    
    Public Function Divide(intArg1, intArg2)
        Divide = intArg1 - intArg2
    End Function
End Class

Пример включения и использования библиотек:

Option Explicit

Const ForReading = 100
Const ForWriting = 200

Dim objIncludeLibrary
Set objIncludeLibrary = New IncludeLibrary

With objIncludeLibrary
    .PathToLibraries = "%ProgramFiles%\My Scripts\Library"
    .SimpleReEntrant = True
    
    .LoadLibrary "C:\Мои проекты\My Scripts\MyLib1.vbh"
    .LoadLibrary "MyLib2.vbh"
End With

Set objIncludeLibrary = Nothing

WScript.Echo "ForReading = " & ForReading
WScript.Echo "ForWriting = " & ForWriting
WScript.Echo "Add(2, 2) = " & Add(2, 2)

Dim objMyCalc
Set objMyCalc = New MyCalc

WScript.Echo "objMyCalc.Multiply(3, 2) = " & objMyCalc.Multiply(3, 2)
WScript.Echo "objMyCalc.Divide(3, 2)   = " & objMyCalc.Divide(3, 2)

Set objMyCalc = Nothing

WScript.Quit 0
' ================================================================================

' ================================================================================
Class IncludeLibrary
    Private objFSO
    Private objWshShell
    
    Private strRegKey
    Private blnSimpleReEntrant
    ' ---------------------------------------------------------------------------
    Private Sub Class_Initialize
        Set objFSO = WScript.CreateObject("Scripting.FileSystemObject")
        Set objWshShell = WScript.CreateObject("WScript.Shell")
        
        strRegKey = "HKEY_CURRENT_USER\Software\VBScript\PathToLibraries"
        blnSimpleReEntrant = False
    End Sub
    ' ---------------------------------------------------------------------------
    Private Sub Class_Terminate
        Set objWshShell = Nothing
        Set objFSO = Nothing
    End Sub
    ' ---------------------------------------------------------------------------
    Public Default Sub LoadLibrary(ByVal strFileName)
        Dim objTS
        Dim strValue
        Dim strErrDescription
        
        If Not objFSO.FileExists(strFileName) Then
            If Not objFSO.FileExists(objFSO.BuildPath( _
                objWshShell.ExpandEnvironmentStrings(PathToLibraries()), strFileName)) Then
                
                Err.Raise 53, "IncludeLibrary.LoadLibrary", _
                    "Library [" & strFileName & "] not found"
                Exit Sub
            Else
                strFileName = objFSO.BuildPath(objWshShell.ExpandEnvironmentStrings(PathToLibraries()), strFileName)
            End If
        End If
        
        On Error Resume Next
        
        Set objTS = objFSO.OpenTextFile(strFileName, 1, False, 0)
        
        If Err.Number <> 0 Then
            strErrDescription = Err.Description
            Err.Clear
            On Error Goto 0
            Err.Raise 1200, "IncludeLibrary.LoadLibrary", _
                "Can't open library [" & strFileName & "]:" & strErrDescription
            Exit Sub
        End If
        
        strValue = objTS.ReadAll
        
        If Err.Number <> 0 Then
            strErrDescription = Err.Description
            Err.Clear
            
            objTS.Close
            Set objTS = Nothing
            
            On Error Goto 0
            Err.Raise 1201, "IncludeLibrary.LoadLibrary", _
                "Can't read from library [" & strFileName & "]:" & strErrDescription
            Exit Sub
        End If
        
        strValue = Trim(strValue)
        
        objTS.Close
        Set objTS = Nothing
        
        If Len(strValue) = 0 Then
            On Error Goto 0
            Err.Raise 1202, "IncludeLibrary.LoadLibrary", _
                "Library [" & strFileName & "] is empty"
            Exit Sub
        End If
        
        ExecuteGlobal strValue
        
        If Err.Number <> 0 Then
            If Err.Number = 1041 And SimpleReEntrant Then
                Err.Clear
                ' Nothing to do
            Else
                strErrDescription = Err.Description
                Err.Clear
                On Error Goto 0
                Err.Raise 1002, "IncludeLibrary.LoadLibrary", _
                    "Error found in library [" & strFileName & "] while loading:" & strErrDescription
                Exit Sub
            End If
        End If
        
        On Error Goto 0
    End Sub
    ' ---------------------------------------------------------------------------
    Public Property Let PathToLibraries(strValue)
        Dim strErrDescription
        
        On Error Resume Next
        
        objWshShell.RegWrite strRegKey, strValue, "REG_EXPAND_SZ"
        
        If Err.Number <> 0 Then
            strErrDescription = Err.Description
            Err.Clear
            On Error Goto 0
            Err.Raise 1203, "IncludeLibrary.PathToLibraries", _
                "Can't let PathToLibraries [" & strFileName & "]:" & strErrDescription
            Exit Property
        End If
        
        On Error Goto 0
    End Property
    ' ---------------------------------------------------------------------------
    Public Property Get PathToLibraries()
        Dim strValue
        
        On Error Resume Next
        
        strValue = objWshShell.RegRead(strRegKey)
        
        If Err.Number <> 0 Then
            Err.Clear
            PathToLibraries = ""
            Exit Property
        End If
        
        On Error Goto 0
        
        PathToLibraries = strValue
    End Property
    ' ---------------------------------------------------------------------------
    Public Property Let SimpleReEntrant(blnValue)
        If UCase(TypeName(blnValue)) = "BOOLEAN" Then
            blnSimpleReEntrant = blnValue
        Else
            Err.Raise 1204, "IncludeLibrary.SimpleReEntrant", _
                "Can't let SimpleReEntrant property: parameter [" & blnValue & "] is not boolean"
            Exit Property
        End If
    End Property
    ' ---------------------------------------------------------------------------
    Public Property Get SimpleReEntrant()
        SimpleReEntrant = blnSimpleReEntrant
    End Property
End Class
' ================================================================================

Класс IncludeLibrary реализует два свойства и один метод.

Свойство PathToLibraries: string, Read/Write; значение по умолчанию берётся из ключа реестра "HKEY_CURRENT_USER\Software\VBScript\PathToLibraries", если оно присутствует; там же сохраняется заданное значение свойства.

Свойство SimpleReEntrant: boolean, Read/Write; значение по умолчанию - False.

Метод LoadLibrary(strValue): метод по умолчанию; загружает текст указанной библиотеки.
strValue — string, путь к файлу библиотеки. Если не указан полный путь, сначала происходит поиск файла библиотеки в текущей папке (не в папке скрипта!), затем - с использованием значения свойства PathToLibraries.

Автор примеров - alexii.

Предложения в русском языке начинаются с большой буквы и заканчиваются точкой.
В названии ветки всегда должен быть указан язык программирования или среда исполнения скрипта, если это возможно.

3

Re: VBScript: имитация Include для целей повторного использования кода

Сымитировать Include также поможет формат WSF:

<job>
<script language='VBScript'>
  ' некоторый код (начало)
</script>
<script language='VBScript' src='external_file.inc'/>
<script language='VBScript'>
  ' некоторый код (конец)
</script>
</job>

И наконец, самым "правильным" методом повторного использования кода является создание WSC-серверов.

Предложения в русском языке начинаются с большой буквы и заканчиваются точкой.
В названии ветки всегда должен быть указан язык программирования или среда исполнения скрипта, если это возможно.