Shell и другие способы

PavelT100

Well-Known Member
09.07.2007
103
0
#1
В хелпе по Shell написано:
In other environments, after Shell starts a program, LotusScript continues to execute the script without waiting to make sure the program has completed. You cannot be sure that a program started by Shell has finished running before the rest of your script is executed.

А как быть если мне надо запустить внешнюю программу, дождаться ее завершения и только после этого продолжать работу моего Lotus Script ?
 

morpheus

скриптописец
07.08.2006
3 915
1
34
Украина, Киев
#2
Для: PavelT100
Надо спрашивать у программы .
Если программа Ваша, зделайте так что бы она в файл кудато кидала информацию о завершении работы.
Если COM - то можно обьект опрашивать.

А вообще это делаеться с помощью Api -функций
Сначала CreateProcess
The CreateProcess function creates a new process and its primary thread. The new process executes the specified executable file.

Код:
BOOL CreateProcess(

LPCTSTR lpApplicationName,	// pointer to name of executable module 
LPTSTR lpCommandLine,	// pointer to command line string
LPSECURITY_ATTRIBUTES lpProcessAttributes,	// pointer to process security attributes 
LPSECURITY_ATTRIBUTES lpThreadAttributes,	// pointer to thread security attributes 
BOOL bInheritHandles,	// handle inheritance flag 
DWORD dwCreationFlags,	// creation flags 
LPVOID lpEnvironment,	// pointer to new environment block 
LPCTSTR lpCurrentDirectory,	// pointer to current directory name 
LPSTARTUPINFO lpStartupInfo,	// pointer to STARTUPINFO 
LPPROCESS_INFORMATION lpProcessInformation 	// pointer to PROCESS_INFORMATION 
);
а патом WaitForSingleObject
The WaitForSingleObject function returns when one of the following occurs:

· The specified object is in the signaled state.
· The time-out interval elapses.

Код:
DWORD WaitForSingleObject(

HANDLE hHandle,	// handle of object to wait for 
DWORD dwMilliseconds 	// time-out interval in milliseconds 
);
А Вот пример на Delphi
 

PavelT100

Well-Known Member
09.07.2007
103
0
#3
Вот по мотивам вызова CreateProcess из VBA попытался написать следующий код на Lotus Script.
Но запуск калькулятора не получается, в функции RunAndWait переменная ret после вызова CreateProcess становится равна нулю, при этом и GetLastError тоже возвращает 0.
Как CreateProcess запустить на Lotus Script ?
Код:
Const INFINITE = &HFFFF
'StartupInfo constants
Public Const STARTF_FORCEOFFFEEDBACK = &H80
Public Const STARTF_FORCEONFEEDBACK = &H40
Public Const STARTF_RUNFULLSCREEN = &H20
Public Const STARTF_USECOUNTCHARS = &H8
Public Const STARTF_USEFILLATTRIBUTE = &H10
Public Const STARTF_USEPOSITION = &H4
Public Const STARTF_USESHOWWINDOW = &H1
Public Const STARTF_USESIZE = &H2
Public Const STARTF_USESTDHANDLES = &H100
'ShowWindow constants
Public Const SW_HIDE = 0
Public Const SW_SHOWNORMAL = 1
Public Const SW_SHOWMINIMIZED = 2
Public Const SW_MAXIMIZE = 3
Public Const SW_SHOWMAXIMIZED = 3
Public Const SW_SHOWNOACTIVATE = 4
Public Const SW_SHOW = 5
Public Const SW_MINIMIZE = 6
Public Const SW_SHOWMINNOACTIVE = 7
Public Const SW_SHOWNA = 8
Public Const SW_RESTORE = 9
Public Const SW_SHOWDEFAULT = 10

Public Type PROCESS_INFORMATION
hProcess As Long
hThread As Long
dwProcessId As Long
dwThreadId As Long
End Type

Public Type STARTUPINFO
cb As Long
lpReserved As String
lpDesktop As String
lpTitle As String
dwX As Long
dwY As Long
dwXSize As Long
dwYSize As Long
dwXCountChars As Long
dwYCountChars As Long
dwFillAttribute As Long
dwFlags As Long
wShowWindow As Integer
cbReserved2 As Integer
lpReserved2 As Long
hStdInput As Long
hStdOutput As Long
hStdError As Long
End Type
Declare Function CreateProcess Lib "kernel32" Alias "CreateProcessA" (Byval lpApplicationName As String, Byval lpCommandLine As String, lpProcessAttributes As Any, lpThreadAttributes As Any, Byval bInheritHandles As Long, Byval dwCreationFlags As Long, lpEnvironment As Any, Byval lpCurrentDriectory As String, lpStartupInfo As STARTUPINFO, lpProcessInformation As PROCESS_INFORMATION) As Long
Declare Function CloseHandle Lib "kernel32" (Byval hObject As Long) As Long
Declare Function WaitForSingleObject Lib "kernel32" (Byval hHandle As Long, Byval dwMilliseconds As Long) As Long
Declare Function GetLastError Lib "kernel32" () As Long


Function RunAndWait(ComLine As String, DefaultDir As String) As Boolean
Dim si As STARTUPINFO
Dim pii As PROCESS_INFORMATION
si.cb = 72
si.wShowWindow = 1
si.dwFlags = STARTF_USESHOWWINDOW
Dim ret As Long
ret = CreateProcess(0, ComLine, Byval 0&, Byval 0&, False, 0, Byval 0&, DefaultDir, si, pii)
If ret Then
WaitForSingleObject pii.hProcess, INFINITE
CloseHandle pii.hProcess
RunAndWait = True
Exit Function
Else
Dim err1 As Long		
err1 = GetLastError()
Msgbox "LastError = " & err1
End If
RunAndWait = False
End Function

....

If RunAndWait("calc.exe", "c:\windows") Then
Msgbox "Run OK!"
End If
 

PavelT100

Well-Known Member
09.07.2007
103
0
#5
Чет не понял.. а Вы откуда его запускали?
Запускал я его из агента, я просто поставил в коде многоточие, думал это не очень важно.

Код:
Sub Initialize	
Dim CountError As Integer
CountError = 0
If RunAndWait("calc.exe", "c:\windows") Then
Msgbox "Run OK!"
End If
end sub
 

PavelT100

Well-Known Member
09.07.2007
103
0
#9
Вот нашёл на мелкософте, пробуйте
А фактически у меня тот же самый код, есть нюансы по инициализации si, но практически они ни на что не повлияли. Ничего не изменилось. Что характерно - этот код на VBA например в Excel у меня работает, а в Lotus нет.
 
R

root

Гость
#10
Для: PavelT100
дождаться ее завершения и только после этого продолжать
Код:
	Set WShell = CreateObject("WScript.Shell") 
ReturnCode = WShell.Run("%windir%\notepad.exe", 1, True)
Msgbox "123"
 

PavelT100

Well-Known Member
09.07.2007
103
0
#12
дождаться ее завершения и только после этого продолжать
Код:
	Set WShell = CreateObject("WScript.Shell") 
...
Ура, спасибо за решение, задача решена, все работает. Но неудовлетворенность от процесса программирования под Lotus накапливается:
1. почему не удается нормально работать с CreateProcess ?
2. http://codeby.net/forum/threads/19277s0.html?gopid=88234& - тоже в результате всех мучений решение найдено обходное(это мягко говоря).
 

Medevic

Что это ? :)
Lotus team
10.12.2004
3 346
2
36
Россия, Калуга
#14
Для: PavelT100
<!--QuoteBegin-PavelT100+4:12:2007, 12:05 -->
<span class="vbquote">(PavelT100 @ 4:12:2007, 12:05 )</span><!--QuoteEBegin-->Ура, спасибо за решение, задача решена, все работает. Но неудовлетворенность от процесса программирования под Lotus накапливается:
[snapback]88236" rel="nofollow" target="_blank[/snapback]​
[/quote]
Видимо, не те задачи решаешь. :ph34r:
 

morpheus

скриптописец
07.08.2006
3 915
1
34
Украина, Киев
#17
Для: Constantin A Chervonenko
дык то что запускаеться на винде , н будет запускаться на других осях, в любом случае переделывать приёдеться
 

PavelT100

Well-Known Member
09.07.2007
103
0
#18
Ну, так он и есть родной - для Виндовз!
А как быть в пингвине, маке и пр.?
Для: Constantin A Chervonenko
дык то что запускаеться на винде , н будет запускаться на других осях, в любом случае переделывать приёдеться
Разговор не об этом. У меня Lotus работает под Windows.

Код:
Declare Function GetTempDir Lib "kernel32" Alias "GetTempPathA" (Byval n As Integer, Byval s As String) As Integer
Функция GetTempPathA - прекрасно вызывается и работает, функция CreateProcess из той же библиотеки нет.
 

PavelT100

Well-Known Member
09.07.2007
103
0
#20
Для: PavelT100
имхо неправильные входящие параметры, может чтото не так с классами
Я вот и стал искать помощи на форуме из-за того что не могу понять где я ошибаюсь, с параметрами ли, с классами ли. Код я привел. Но вообщем я доволен, спасибо за помощь root.