Страница 1 из 1

Запуск *.bat файла не через RUN()

Добавлено: 17 Ноябрь 2010, 13:14
ThePPK
Здравствуйте,

столкнулся со следующей проблемой: нужно запускать bat-ник, но у RUN() почему-то нет параметра, позволяющего сделать это в фоне. В результате появляется черное окно, которое пользователи норовят закрыть.
Желательно получать код результата выполнения bat-ника. А
Обязательно останавливать выполнение основной программы до окончания исполнения bat-ника.

Покопавшись на форуме, я обнаружил упоминание CreateProcess, но как именно его использовать?

Re: Запуск *.bat файла не через RUN()

Добавлено: 17 Ноябрь 2010, 14:21
Admin
ThePPK писал(а):Здравствуйте,

столкнулся со следующей проблемой: нужно запускать bat-ник, но у RUN() почему-то нет параметра, позволяющего сделать это в фоне. В результате появляется черное окно, которое пользователи норовят закрыть.
Желательно получать код результата выполнения bat-ника. А
Обязательно останавливать выполнение основной программы до окончания исполнения bat-ника.

Покопавшись на форуме, я обнаружил упоминание CreateProcess, но как именно его использовать?
Использую ABAPIEX.TPL

Код: Выделить всё

#TEMPLATE(APIExecute,'Windows API execute calls'),family('ABC')
#! ----------------------------------------------------------------------
#!  Template file:  ABAPIEX.TPL     
#!  Original date:  05. October, 1997
#!  Author:         Arnor Baldvinsson, Denmark.  
#!  E-mail:         arnorbld@post3.tele.dk
#!  
#!  Note:           This template demonstrates use of API calls for
#!                  both 16 and 32 bit api calls.  It consists of one
#!                  global extension template that prototypes some of
#!                  the common api calls for executing programs etc.
#!                  It also includes a code template to call the
#!                  ShellExecute api function.
#!                  This template must be considered as being under
#!                  construction and other developers use it at their
#!                  own risk.
#!                  
#!                  You may modify this template, but you may not use 
#!                  it or distribute it or any parts of it in any kind
#!                  of commercial templates for your benefit.
#! ----------------------------------------------------------------------
#!
#EXTENSION(ABAPIExecGlo,'Global Win API Exec calls'),APPLICATION
#SHEET
#TAB('Execution functions')
#DISPLAY('')
#DISPLAY('Please select the functions to include')
#DISPLAY('')
#BOXED('Functions')
  #PROMPT('WinExec',CHECK),%ABAPIWinExec,AT(10,65)
  #PROMPT('ShellExec',CHECK),%ABAPIShellExec,AT(10)
  #PROMPT('GetModuleUsage',CHECK),%ABAPIGetModuleUsage,AT(10)
  #PROMPT('ModuleFileName',CHECK),%ABAPIModuleFileName,AT(10)
  #PROMPT('GetModuleFileName',CHECK),%ABAPIGetModuleFileName,AT(10)
  #PROMPT('GetModuleHandle',CHECK),%ABAPIGetModuleHandle,AT(10)
  #PROMPT('GetWindowsDirectory',CHECK),%ABAPIGetWindowsDirectory,AT(10)
  #PROMPT('GetSystemDirectory',CHECK),%ABAPIGetSystemDirectory,AT(10)
  #PROMPT('FindExecutable',CHECK),%ABAPIFindExecutable,AT(10)
#ENDBOXED
#ENDTAB
#TAB('Options')
#DISPLAY('')
#DISPLAY('Please select the options for the api functions')
#DISPLAY('')
#BOXED('Options')
  #PROMPT('Include winequ.clw equates file',CHECK),%ABAPIIncludeEquates,AT(10,65)
  #PROMPT('Include Show equates',CHECK),%ABAPIIncludeShowEquates,AT(10)
  #PROMPT('Include Shellexec error messages',CHECK),%ABAPIShellExecErr,DEFAULT(%TRUE),AT(10)
#ENDBOXED
#ENDTAB
#ENDSHEET
#AT(%AfterGlobalIncludes)
  #IF(%ABAPIIncludeEquates)
   INCLUDE('winequ.clw')
  #ENDIF  
#ENDAT
#AT(%GlobalMap)
 #IF(%Target32)
 Module('Win32.lib')
 #ELSE
 Module('Win16.lib')
 #ENDIF
 #IF(%ABAPIWinExec)
   WinExec(*LPCSTR,UNSIGNED),UNSIGNED,PASCAL,RAW
 #ENDIF
 #IF(%ABAPIGetModuleUsage)
   GetModuleUsage(HINSTANCE),SIGNED,PASCAL
 #ENDIF
 
 OMIT('***',_WIDTH32_)
 #IF(%ABAPIShellExec)
   ShellExecute(HWND,*LPCSTR,*LPCSTR,*LPCSTR,*LPCSTR,SIGNED),HINSTANCE,PASCAL,RAW
 #ENDIF
 #IF(%ABAPIModuleFileName)
   ModuleFileName(*MODULEENTRY,*LPCSTR),HMODULE,PASCAL,RAW
 #ENDIF  
 #IF(%ABAPIGetModuleFileName)
   GetModuleFileName(HINSTANCE, *LPSTR, SIGNED),SIGNED,PASCAL,RAW
 #ENDIF
 #IF(%ABAPIGetModuleHandle)
   GetModuleHandle(*LPCSTR),HMODULE,PASCAL,RAW
 #ENDIF
 #IF(%ABAPIGetWindowsDirectory)
   GetWindowsDirectory(*LPSTR, WORD),WORD,PASCAL,RAW
 #ENDIF
 #IF(%ABAPIGetSystemDirectory)
   GetSystemDirectory(*LPSTR, WORD),WORD,PASCAL,RAW
 #ENDIF
 #IF(%ABAPIFindExecutable)
   FindExecutable(*LPCSTR,*LPCSTR,*LPSTR),HINSTANCE,PASCAL,RAW
 #ENDIF  
 ***
 COMPILE('***',_WIDTH32_)
 #IF(%ABAPIShellExec)
   ShellExecute(HWND,*LPCSTR,*LPCSTR,*LPCSTR,*LPCSTR,SIGNED),HINSTANCE,PASCAL,RAW,NAME('ShellExecuteA')
 #ENDIF
 #IF(%ABAPIModuleFileName)
   ModuleFileName(*MODULEENTRY,*LPCSTR),HMODULE,PASCAL,RAW,NAME('ModuleFileNameA')
 #ENDIF  
 #IF(%ABAPIGetModuleFileName)  
   GetModuleFileName(HINSTANCE,*LPSTR,DWORD),DWORD,PASCAL,RAW,NAME('GetModuleFileNameA')
 #ENDIF  
 #IF(%ABAPIGetModuleHandle)
   GetModuleHandle(*LPCSTR),HMODULE,PASCAL,RAW,NAME('GetModuleHandleA')
 #ENDIF  
 #IF(%ABAPIGetWindowsDirectory)   
   GetWindowsDirectory(*LPSTR,UNSIGNED),UNSIGNED,PASCAL,RAW,NAME('GetWindowsDirectoryA')
 #ENDIF  
 #IF(%ABAPIGetSystemDirectory)
   GetSystemDirectory(*LPSTR,UNSIGNED),UNSIGNED,PASCAL,RAW,NAME('GetSystemDirectoryA')
 #ENDIF  
 #IF(%ABAPIFindExecutable)
   FindExecutable(*LPCSTR,*LPCSTR,*LPSTR),HINSTANCE,PASCAL,RAW,NAME('FindExecutableA')
 #ENDIF  
 ***
 END !Module
#ENDAT
#AT(%BeforeFileDeclarations)
#IF(%ABAPIIncludeShowEquates)
sw_Hide            EQUATE(0)
sw_ShowNormal      EQUATE(1)
sw_ShowMinimized   EQUATE(2)
sw_ShowMaximized   EQUATE(3)
sw_ShowNoActivate  EQUATE(4)
sw_Show            EQUATE(5)
sw_Minimize        EQUATE(6)
sw_ShowMinNoActive EQUATE(7)
sw_ShowNA          EQUATE(8)
sw_Restore         EQUATE(9)
#ENDIF
#ENDAT
#!------------------------------------------ Code template: ShellExecute
#CODE(ABShellExecute,'ShellExecute code'),REQ(ABAPIExecGlo)
#BOXED
#PROMPT('Action',DROP('open|print|explore')),%ABAShellExecOp
#PROMPT('File variable',FIELD),%ABAShellExecFile,REQ
#PROMPT('Parameters',FIELD),%ABAShellExecParam
#PROMPT('Show',DROP('Normal|Maximized|Minimized|Hide')),%ABAShellExecShow
#DISPLAY('')
#DISPLAY('Open action:'),AT(10,70)
#DISPLAY('Opens the file in the associated program'),AT(70,70)
#DISPLAY('Print action:'),AT(10,82)
#DISPLAY('Sends the file to the printer'),AT(70,82)
#DISPLAY('Explore action:'),AT(10,94)
#DISPLAY('Opens Explorer in the path specified'),AT(70,94)
#DISPLAY('NOTE!'),AT(10,108)
#DISPLAY('With the Explore action, you must provide a PATH'),AT(70,108)
#DISPLAY('NOT a filename.'),AT(70,116)
#DISPLAY('Parameters are optional parameters to be passed to a'),AT(70,124)
#DISPLAY('program, if the  File variable  contains the name of an'),AT(70,132)
#DISPLAY('.EXE file, NOT a document file.   Using the parameter'),AT(70,140)
#DISPLAY('you can use ShellExecute to open files that don''t have'),AT(70,148)
#DISPLAY('any associated programs.  Then you pass the program'),AT(70,156)
#DISPLAY('name in the File Variable, and the file name to open'),AT(70,164)
#DISPLAY('as a parameter.'),AT(70,172)
#ENDBOXED
#ATSTART
  #DECLARE(%ABSEInstance)
  #SET(%ABSEInstance,%ActiveTemplateInstance)
#ENDAT
#LOCALDATA
LOC:AB:SE:Handle      USHORT
LOC:AB:SE:Op          CSTRING(20)
LOC:AB:SE:File        CSTRING(256)
LOC:AB:SE:Path        CSTRING(256)
LOC:AB:SE:Param       CSTRING(256)
LOC:AB:SE:Show        SHORT
LOC:AB:SE:RetHandle   USHORT
#ENDLOCALDATA
DO ABSE%ABSEInstance::ShellExecute
#AT(%ProcedureRoutines)

ABSE%ABSEInstance::ShellExecute   ROUTINE

  LOC:AB:SE:Handle = %Window{PROP:Handle}
  LOC:AB:SE:Op     = '%ABAShellExecOp'
  LOC:AB:SE:File   = CLIP(%ABAShellExecFile)
  LOC:AB:SE:Path   = PATH()
#IF(%ABAShellExecParam)
  LOC:AB:SE:Param  = %ABAShellExecParam
#ELSE
  LOC:AB:SE:Param  = ''
#END
 #CASE(%ABAShellExecShow)
 #OF('Normal')
  LOC:AB:SE:Show   = sw_ShowNormal
 #OF('Maximized')
  LOC:AB:SE:Show   = sw_ShowMaximized
 #OF('Minimized')
  LOC:AB:SE:Show   = sw_ShowMinimized
 #OF('Hide')
  LOC:AB:SE:Show   = sw_Hide
 #ENDCASE
  LOC:AB:SE:RetHandle = ShellExecute(LOC:AB:SE:Handle, |
                                     LOC:AB:SE:Op, |
                                     LOC:AB:SE:File, |
                                     LOC:AB:SE:Param, |
                                     LOC:AB:SE:Path, |
                                     LOC:AB:SE:Show)
 #IF(%ABAPIShellExecErr)
  IF LOC:AB:SE:RetHandle =< 32
    CASE LOC:AB:SE:RetHandle
    OF 0
      Message('Out of memory or file is corrupt running program','ERROR',ICON:HAND)
    OF 2
      Message('File not found','ERROR',ICON:HAND)
    OF 3
      Message('Path noth found','ERROR',ICON:HAND)
    OF 5
      Message('Sharing violation','ERROR',ICON:HAND)
    OF 6
      Message('Data segment error','ERROR',ICON:HAND)
    OF 8
      Message('Not enough memory to run program','ERROR',ICON:HAND)
    OF 10
      Message('Incorrect windows version','ERROR',ICON:HAND)
    OF 11
      Message('Invalid program file.  Non windows or corrupt .exe file','ERROR',ICON:HAND)
    OF 12
      Message('Not a windows program','ERROR',ICON:HAND)
    OF 13
      Message('MS-DOS 4.0 program','ERROR',ICON:HAND)
    OF 14
      Message('Unknown program type','ERROR',ICON:HAND)
    OF 15
      Message('Can not run a real mode program','ERROR',ICON:HAND)
    OF 16
      Message('This program is already running and can only have one instance running','ERROR',ICON:HAND)
    OF 19
      Message('This is a compressed program file','ERROR',ICON:HAND)
    OF 20
      Message('One or more run time libraries are missing or corrupt','ERROR',ICON:HAND)
    OF 21
      Message('This program requires 32bit extension for Windows','ERROR',ICON:HAND)
    OF 31
      Message('No program associated with this file','ERROR',ICON:HAND)
    END
  END
!---------------------------------------------------------------------------  
 #END
#ENDAT   

Re: Запуск *.bat файла не через RUN()

Добавлено: 17 Ноябрь 2010, 17:43
ThePPK
Спасибо большое за наводку! :-)
А нет ли у Вас какого-нибудь примера запуска приложения с контролем кода результата (с использованием этого шаблона)?

Re: Запуск *.bat файла не через RUN()

Добавлено: 18 Ноябрь 2010, 3:25
Admin
ThePPK писал(а):А нет ли у Вас какого-нибудь примера запуска приложения с контролем кода результата (с использованием этого шаблона)?
Вот Андрей Попов когда то писал этот пример.
Тут есть запуск процесса, по моему в фоне.
Я немного дописал для получения ERRORLEVEL.
Куча мутного кода но вырезать что то можно.
Общая технология примерно такая:

Код: Выделить всё

IF CreateProcess(...)
  !error on start process
ELSE
  CloseHandle(...) ! for thread
  WaitForSingleObject(...)
  IF GetExitCodeProcess(...)
    !successfully retrieved exit code
  END
  CloseHandle(...) ! for process
END
P.S. Где то тут могут за IF следовать NOT, не очень написал точно.
P.P.S. Когда предлагал ABAPIEX.TPL, не заметил что нужно получить ERRORLEVEL.

Re: Запуск *.bat файла не через RUN()

Добавлено: 18 Ноябрь 2010, 9:41
ThePPK
Большое Вам спасибо, уважаемый Admin! Буду разбираться :-)

Re: Запуск *.bat файла не через RUN()

Добавлено: 20 Ноябрь 2010, 2:05
WadimZapara

Re: Запуск *.bat файла не через RUN()

Добавлено: 20 Ноябрь 2010, 10:57
ThePPK
Огромное спасибо, похоже по третьей ссылке именно то, что нужно!