How can i do for launch a process from BMax.
I'm looking for commands like execFile or CreateProcess ?
I'm looking for commands like execFile or CreateProcess ?
Extern "Win32" Function WaitForSingleObject:Int(hHandle:Int, dwMilliseconds:Int) Function GetExitCodeProcess:Int(hProcess:Int, lpExitCode:Int) Function CreateProcessA:Int(lpApplicationName:Byte Ptr, lpCommandLine:Byte Ptr, lpProcessAttributes:Int, lpThreadAttributes:Int, bInheritHandles:Int, dwCreationFlags:Int, lpEnvironment:Int, lpCurrentDirectory:Byte Ptr, lpStartupInfo:ProcessStartUpInfo, lpProcessInformation:ProcessInformation) Function CloseHandle:Int(hProcess:Int) Function GetActiveWindow:Int() Function SetForegroundWindow(hWnd:Int) Function SetActiveWindow(hWnd:Int) Function OpenProcess:Int(dwDesiredAccess:Int, bInheritHandle:Int, dwProcessId:Int) Function keybd_event(bVk:Byte, bScan:Byte, dwFlags:Int, dwExtraInfo:Int) End Extern Local p:Process = New Process p.setExe("c:\windows\notepad.exe") p.setArgs("C:\Program Files\BlitzMax\doc\home.html") p.create() Repeat If p.isRunning()=0 Exit SendMessageA(p.myhwnd,WM_CLOSE,0,0) Print "Process is running..." Delay(1000) Forever Print "Process finished with return value " + p.getReturnValue() Type ProcessStartUpInfo Field cb:Int Field lpReserved:String Field lpDesktop:String Field lpTitle:String Field dwX:Int Field dwY:Int Field dwXSize:Int Field dwYSize:Int Field dwXCountChars:Int Field dwYCountChars:Int Field dwFillAttribute:Int Field dwFlags:Int Field wShowWindow:Int Field cbReserved2:Int Field lpReserved2:Int Field hStdInput:Int Field hStdOutput:Int Field hStdError:Int End Type Type ProcessInformation Field hProcess:Int Field hThread:Int Field dwProcessID:Int Field dwThreadID:Int End Type Type Process Field exe:String Field args:String Field proc:ProcessInformation Field returnValue:Int Field pHandle:Int Field myhWnd:Int Method New() myHwnd = GetActiveWindow() End Method Method setExe (appPath:String) exe = appPath End Method Method setArgs (argString:String) args = argString End Method Method getReturnValue:Int () Return returnValue End Method Method create() ' change to exe directory ChangeDir(ExtractDir(exe)) ' spawn process... Local cmd:String = "~q" + exe + "~q" + " " + "~q" + args + "~q" Print "Run process: " + cmd Local start:ProcessStartUpInfo = New ProcessStartUpInfo proc = New ProcessInformation CreateProcessA(Null, cmd.ToCString(), 0, 0, 1, 0, 0, Null, start, proc) pHandle = OpenProcess($100000, -1, proc.hProcess) returnValue = Null End Method Method isRunning:Int() Local v:Int = WaitForSingleObject(pHandle, 0) Select v Case 0 returnValue = GetExitCodeProcess(pHandle, v) CloseHandle(pHandle) Print "Process finished with return value: " + returnValue ' change back to this app dir. ChangeDir(LaunchDir$) ' Set focus back to this application. SetForegroundWindow(myHWnd) SetActiveWindow(myHWnd) ' Since were a full screen app Windows does not like ' makign you go back into full screen mode so we have ' to emulate the user pressing Alt + Enter :) ' Add a little delay Delay(100) ' send alt + enter to get back full screen window :) keybd_event(KEY_ALT, 0, 0, 0) keybd_event(KEY_RETURN, 0, 0, 0) ' we have to let go of the keys :) keybd_event(KEY_RETURN, 0, 2, 0) keybd_event(KEY_ALT, 0, 2, 0) ' app should now be back in focus and on the screen. Return 0 Case -1 ' We normally get this if the process failed to launch. Print "WaitForSingleObject failed." CloseHandle(pHandle) Return 0 Default ' Process is running. Return v End Select End Method End Type
EnumWindows((WNDENUMPROC)EmbedAppEnum, (LPARAM)AppProcessID);
Extern "Win32" Function WaitForSingleObject:Int(hHandle:Int, dwMilliseconds:Int) Function GetExitCodeProcess:Int(hProcess:Int, lpExitCode:Int) Function CreateProcessA:Int(lpApplicationName:Byte Ptr, lpCommandLine:Byte Ptr, lpProcessAttributes:Int, lpThreadAttributes:Int, bInheritHandles:Int, dwCreationFlags:Int, lpEnvironment:Int, lpCurrentDirectory:Byte Ptr, lpStartupInfo:ProcessStartUpInfo, lpProcessInformation:ProcessInformation) Function CloseHandle:Int(hProcess:Int) Function GetActiveWindow:Int() Function SetForegroundWindow(hWnd:Int) Function SetActiveWindow(hWnd:Int) Function OpenProcess:Int(dwDesiredAccess:Int, bInheritHandle:Int, dwProcessId:Int) Function keybd_event(bVk:Byte, bScan:Byte, dwFlags:Int, dwExtraInfo:Int) Function FindWindowA:Int(ff$z,f$z) Function ExitProcess(thing:Int) Function EnumWindows:Int(thing:Byte Ptr,f:Int) Function GetWindowThreadProcessId:Int(hwnd:Int,g:Byte Ptr) End Extern Local p:Process = New Process p.setExe("c:\windows\notepad.exe") p.setArgs("C:\Program Files\BlitzMax\doc\home.html") p.create() DebugLog "starting" Repeat Local window:TGadget Local button:TGadget window=CreateWindow("MaxGui Buttons",40,40,240,300,Null,WINDOW_TITLEBAR) button=CreateButton("Kill the Process",10,10,140,24,window,BUTTON_PUSH) While True WaitEvent Select EventID() Case EVENT_WINDOWCLOSE End Case EVENT_GADGETACTION If EventSource()=button If p If p.kill() p=Null Notify "Killed the process." Else Notify "Failed to kill the process." EndIf EndIf EndIf End Select Wend Forever Type ProcessStartUpInfo Field cb:Int Field lpReserved:String Field lpDesktop:String Field lpTitle:String Field dwX:Int Field dwY:Int Field dwXSize:Int Field dwYSize:Int Field dwXCountChars:Int Field dwYCountChars:Int Field dwFillAttribute:Int Field dwFlags:Int Field wShowWindow:Int Field cbReserved2:Int Field lpReserved2:Int Field hStdInput:Int Field hStdOutput:Int Field hStdError:Int End Type Type ProcessInformation Field hProcess:Int Field hThread:Int Field dwProcessID:Int Field dwThreadID:Int End Type Type Process Field exe:String Field args:String Field proc:ProcessInformation Field returnValue:Int Field pHandle:Int Field myhWnd:Int Field hprocess Function EnumWindowsProc:Int(hwnd:Int,lparam:Int) Local proc:Int GetWindowThreadProcessId(hwnd,Varptr proc) If proc=lparam SendMessageA hwnd,WM_CLOSE,0,0 Return True EndFunction Method Kill:Int(timeout=1000) If isRunning()=0 Return True EnumWindows(EnumWindowsProc,hProcess) Delay timeout If isRunning()=0 Return True Else Return False EndMethod Method New() myHwnd = GetActiveWindow() End Method Method setExe (appPath:String) exe = appPath End Method Method setArgs (argString:String) args = argString End Method Method getReturnValue:Int () Return returnValue End Method Method create() ' change to exe directory ChangeDir(ExtractDir(exe)) ' spawn process... Local cmd:String = "~q" + exe + "~q" + " " + "~q" + args + "~q" 'Print "Run process: " + cmd Local start:ProcessStartUpInfo = New ProcessStartUpInfo proc = New ProcessInformation CreateProcessA(Null, cmd.ToCString(), 0, 0, 1, 0, 0, Null, start, proc) pHandle = OpenProcess($100000, -1, proc.hProcess) returnValue = Null hprocess=proc.hprocess End Method Method isRunning:Int() Local v:Int = WaitForSingleObject(pHandle, 0) Select v Case 0 returnValue = GetExitCodeProcess(pHandle, v) CloseHandle(pHandle) 'Print "Process finished with return value: " + returnValue ' change back to this app dir. ChangeDir(LaunchDir$) ' Set focus back to this application. SetForegroundWindow(myHWnd) SetActiveWindow(myHWnd) ' Since were a full screen app Windows does not like ' makign you go back into full screen mode so we have ' to emulate the user pressing Alt + Enter :) ' Add a little delay Delay(100) ' send alt + enter to get back full screen window :) keybd_event(KEY_ALT, 0, 0, 0) keybd_event(KEY_RETURN, 0, 0, 0) ' we have to let go of the keys :) keybd_event(KEY_RETURN, 0, 2, 0) keybd_event(KEY_ALT, 0, 2, 0) ' app should now be back in focus and on the screen. Return 0 Case -1 ' We normally get this if the process failed to launch. 'Print "WaitForSingleObject failed." CloseHandle(pHandle) Return 0 Default ' Process is running. Return v End Select End Method End Type
Rem Windows Notepad PUB.FreeProcess Example EndRem Framework MaxGUI.Drivers Import BRL.EventQueue Import BRL.Timer Import PUB.FreeProcess SuperStrict Global wndMain:TGadget = CreateWindow("Test Window",100,100,400,300,Null,WINDOW_TITLEBAR|WINDOW_CLIENTCOORDS|WINDOW_STATUS) Global gadButton:TGadget = CreateButton("Start",10,10,100,25,wndMain,BUTTON_PUSH) Global pcsNotepad:TProcess CreateTimer(2) 'Create a timer that allows us to check status of process every 500ms Repeat Select WaitEvent() Case EVENT_WINDOWCLOSE;TProcess.TerminateAll();End 'If the program is closed, terminate all running processes. Case EVENT_GADGETACTION Select EventSource() Case gadButton;If GadgetText$(gadButton) = "Start" Then StartNotepad() Else CloseNotepad() EndSelect Case EVENT_TIMERTICK If pcsNotepad <> Null Then SetStatusText(wndMain,"Status of Notepad Process: " + pcsNotepad.Status()) Else SetStatusText(wndMain,"Object doesn't yet exist.") If pcsNotepad <> Null And pcsNotepad.Status() = 0 Then SetGadgetText(gadButton,"Start") 'If notepad was closed by user outside the program, update button text. EndSelect Forever Function StartNotepad() If pcsNotepad <> Null Then pcsNotepad.Terminate() 'Terminate process if it a) exists b) is running. pcsNotepad = CreateProcess("notepad.exe") 'Open the process notepad.exe and store handle in pcsNotepad SetGadgetText(gadButton,"Stop") 'Change button text. EndFunction Function CloseNotepad() If pcsNotepad <> Null And pcsNotepad.Status() Then pcsNotepad.Terminate() 'Terminate process if it a) exists b) is running. SetGadgetText(gadButton,"Start") 'Change button text. EndFunction