Здесь нет готового решения. Но вы можете написать код VBScript в mimi c, что делает EA, когда запускает скрипт, т.е.
- получить код скрипта из таблицы t_script
- получить все iclude (! IN C script_group.script_name)
- заменить строки! IN C включенным текстом сценария
- поместить сценарий во временный файл .VBS и запустить его
Кроме того, вам необходимо обеспечить замену всех функций, легко доступных в EA при запуске скрипта, по крайней мере
- создать экземпляр объекта Repository как глобальную переменную
- replace all all операторы Session.Output для получения вывода на консоль (в качестве альтернативы вы можете реализовать и создать свой собственный класс Session)
Поскольку EA является 32-разрядным приложением, вам необходимо вызвать 32-разрядную версию обработчика сценариев (cscript.exe) для запуска сценария, взаимодействующего с EA API, обычно по адресу C: \ Windows \ SysWOW64 \ cscript.exe
Все перечисленные выше задачи скомпилированы в следующую папку код сценария wing:
option explicit
'(c) Martin Jecny 2020
'WScript.Echo "Scripting Engine: " & ScriptEngine & " ver. " & ScriptEngineMajorVersion & "." & ScriptEngineMinorVersion & "." & ScriptEngineBuildVersion
'WScript.Echo "Creating Repository object"
dim Repository 'as EA.Repository 'defined as global, as it is default in EA environment
set Repository=CreateObject("EA.Repository")
dim ses 'as EA.Session
WScript.Echo "Start: " & Now
runIt(WScript.Arguments) 'complete script name, -v|--verbose
WScript.Echo "End: " & Now
'cleanup
on error resume next
Repository.exit
set Repository=Nothing
on error goto 0
sub runIt(argList)
dim result 'as Variant
if argList.Count <1 then
WScript.Echo "Usage: runEaScript <scriptGroup>.<scriptName> [-v|--verbose] [-c|--copysource]"
result=cleanup(Nothing)
WScript.Quit(0)
end if
'parse arguments
dim scriptFullName 'as String
scriptFullName=argList(0)
dim arg
dim verbose 'as Boolean
verbose=false
dim copysource 'as Bollean
copysource=false
for each arg in argList
select case arg
case "-v", "--verbose"
WScript.Echo "Verbose mode on"
verbose=true
case "-c", "--copysource"
copysource=true
if verbose then
WScript.Echo "Copy of the produced code will be stored to current directory"
end if
end select
next
if verbose then WScript.Echo "Requested script to run: '" & scriptFullName & "'"
if verbose then WScript.Echo "Opening cloud Repository ..."
Repository.OpenFile ("mycloudrepository --- ;Connect=Cloud=protocol:http,address:cloudhost,port:80;Data Source=modelname;DSN=modelname;LazyLoad=1;")
if verbose then WScript.Echo "Retrieving main script code ..."
dim sql 'as String
dim mainScriptCode 'as String
mainScriptCode=getScriptCode(scriptFullName)
if Len(mainScriptCode)<1 then
WScript.Echo "500002" & ": " & "Main script code retrieval failed."
result=cleanup(Nothing)
WScript.Quit(3)
end if
if verbose then WScript.Echo "Resolving !INCludes ..."
dim startPos 'as Integer 'position of !INC in the code
dim endOfPreviousLinePos 'as Integer 'position before start of the !INC line
dim startToInc 'as String ' string between start of line and !INC directive
dim endLinePos 'as Integer 'end position of !INC line
dim endIncPos 'as Integer 'end of included script name within the line
startPos=1 'start position of !INC in script code
endLinePos=0
endIncPos=0
dim includeList 'as Scripting.Dictionary 'list of already included scripts
set includeList=CreateObject("Scripting.Dictionary")
includeList.RemoveAll
dim includeString 'as String '!INC <script> string
dim toBeReplaced 'as String 'usualy full line with !INC string
do while startPos<>0
'detect !INC
startPos = InStr(1,mainScriptCode,"!INC ")
'detection and removal of !INC within commented line
if startPos > 0 then
endLinePos=InStr(startPos,mainScriptCode,chr(10))
endOfPreviousLinePos=InStrRev(mainScriptCode, chr(10),startPos)
if endOfPreviousLinePos <> (startPos-1) then
startToInc=mid(mainScriptCode,endOfPreviousLinePos,startPos-endOfPreviousLinePos)
if InStr(startToInc,"'")>0 then
if verbose then WScript.Echo "Skipping commented reference " & startToInc & toBeReplaced
toBeReplaced=mid(mainScriptCode,startPos,endLinePos-startPos)
mainScriptCode=Replace(mainScriptCode,toBeReplaced,"",1,1)
startPos=InStr(1,mainScriptCode,"!INC ")
end if
end if
end if
'including the code if not already included
if startPos > 0 then
endLinePos=InStr(startPos,mainScriptCode,chr(10))
includeString=trim(mid(mainScriptCode,startPos+5,endLinePos-(startPos+5))) 'ommit !INC string
toBeReplaced=mid(mainScriptCode,startPos,endLinePos-startPos)
'remove comment from reference line
endIncPos=InStr(1,includeString,"'") 'comment?
if endIncPos>0 then 'strip comment after reference
includeString=left(includeString,endIncPos-1)
end if
includeString=trim(includeString)
Err.Clear 'probably not necessary, just for sure
on error resume next
includeList.Add includeString,includeString 'Dictionary object has natively unique index
if Err.Number >0 then 'already exists
if verbose then WScript.Echo includeString & " already included, removing the reference."
mainScriptCode=Replace(mainScriptCode,toBeReplaced,"",1,1)
else 'new one found
if verbose then WScript.Echo "Including '" & includeString & "'"
mainScriptCode=Replace(mainScriptCode,toBeReplaced,getScriptCode(includeString),1,1)
end if
on error goto 0
end if
loop
'adapt code for running in pure VBS environment
if verbose then WScript.Echo "Adapting the code ..."
mainScriptCode=adaptToPureVbsCode(mainScriptCode)
'make file with the code to run
dim tempFileName 'as String
dim fso 'as Scripting.FileSystemObject
dim tempFolder 'as Folder
set fso=CreateObject("Scripting.FileSystemObject")
set tempFolder=fso.GetSpecialFolder(2) 'get temp diectory
tempFileName=fso.GetSpecialFolder(2).Path & "\" & fso.getTempName
dim mainScriptFile 'as File
set mainScriptFile=fso.createTextFile(tempFileName)
result=mainScriptFile.Write(mainScriptCode) '@TODO error handling
result=mainScriptFile.Close
if verbose then WScript.Echo "Written to file: " & tempFileName
if copysource then
dim scriptdir 'as Folder
scriptdir = fso.GetParentFolderName(WScript.ScriptFullName)
result=fso.CopyFile (tempFileName, scriptdir & scripFullName& ".vbs",true) 'overwrite allowed
end if
executeGlobal fso.openTextFile( tempFileName).readAll() 'run the complete script from temporary file
if verbose then Wscript.Echo "000000" & ": " & "Successful exit"
WScript.Quit(0)
end sub
function getScriptCode(scriptFullName)
if Len(scriptFullName)<1 then
WScript.Echo "500001" & ": " & "No script name provided"
getScriptCode=""
exit function
end if
if InStr(scriptFullName,".")<2 then
WScript.Echo "500004" & ": " & "No group - provide full script name in the form <Group>.<Script>"
getScriptCode=""
exit function
end if
dim dotPos 'as Integer
dotPos=InStr(scriptFullName,".")
dim scriptGroupName 'as String
dim ScriptName 'as String
scriptGroupName=Left(scriptFullName,dotPos-1)
scriptName=Mid(scriptFullName,dotPos+1)
if Len(scriptName)<1 then
WScript.Echo "500005" & ": " & "No script name - provide full script name in the form <Group>.<Script>"
getScriptCode=""
end if
dim sql
sql="select s.script from t_script s, t_script g where s.scriptauthor=g.scriptname"
sql = sql & " and g.script like '" & scriptGroupName & "'"
sql = sql & " and s.notes like '%Script Name=""" & scriptName & """%'"
dim scriptCode 'as String
getScriptCode=getSqlSingleValue(sql)
end function
'* adapts the code to run in pure VBS outside of EA
'* @param String 'original EA VBS code
'* @return String 'code with replacements
function adaptToPureVbsCode(code) '@TODO: replacement for Session.Input and Session.Prompt
dim regEx 'as RegExp
set regEx=New RegExp
regEx.IgnoreCase=true
regEx.Global=true
regEx.Pattern=chr(10)
'beautification of the code, mainly for debug purposes
code=regEx.Replace(code,chr(13) & chr(10))
'redirect outuput commands
regEx.Pattern="session.output" 'replace output command
code=regEx.Replace(code,"WScript.Echo")
'comment out manipulation with script output window
regEx.Pattern="Repository.EnsureOutputVisible \""Script\"""
code=regEx.Replace(code,"'"& "Repository.EnsureOutputVisible ""Script""")
regEx.Pattern="Repository.ClearOutput \""Script\"""
code=regEx.Replace(code,"'Repository.ClearOutput ""Script""")
adaptToPureVbsCode=code
end function
'* returns single (or first) value from single column; SQL query must comply to this; returns empty string if not found
'* @param sql as String SQL query
'* @return String
public function getSqlSingleValue(sql) 'as String
dim xmlDoc 'as MSXML2.DomDocument60 '1.2.0
set xmlDoc=CreateObject("Msxml2.DOMDocument.6.0") '1.2.0
dim node 'as MSXML2.IXMLDomNode
xmlDoc.loadXML(Repository.SQLQuery(sql)) '@TODO fails with field names like COUNT(*) on "("; needs escaping
set node= xmlDoc.selectSingleNode("//Row[1]/child::node()")
if node is nothing then
getSqlSingleValue=""
exit function
end if
if len(node.text)>0 then
getSqlSingleValue=node.text
else
getSqlSingleValue=""
end if
end function
'*@ Cleanup of the environment
'*@param FileSystemObject fso
'*@return void
function cleanup(fso)
on error resume next
Repository.CloseFile
Repository.Exit
set Repository=nothing
result=fso.DeleteFile(tempFileName)
set fso=nothing
on error goto 0
end function
использование сценария
"C: \ Windows \ SysWOW64 \ cscript.exe" "C: \ Users \ пользователь \ Documents \ jobs \ runEaScript .vbs "" Моя группа сценариев. Имя моего сценария "--verbose / nolo go
Следует отметить, что текстовые операции VBScript не являются чрезвычайно быстрыми, и подготовка сценария может занять некоторое время. Если вам нужно очень часто запускать скрипт, внедрите некоторое кэширование полученного файла VBS.