c:\Taskkill /IM %ProgramName% /f - (%ProgramName% - real name of the executable) ?
I was wondering if there is some harbour function that does the same thing.
Sometime I need to start some external apps and sometimes, during testing these app, they can crash. As a consequence, various instances of called external apps can remain alive
and I have to close them manually from the task manager. With an automation, in my code, I can close these tasks if they exists at the beginning of my app so my app can continue normally.
Thanks
Zoran
function Main()
?"Excel Data import via Array"
lSuccess := .f.
IF ( oExcel := win_oleCreateObject( "Excel.Application" ) ) != NIL
BEGIN SEQUENCE with { |objErr| errStack( objErr ) }
oExcel:WorkBooks:Open( cXLS )
oAS := oExcel:ActiveSheet()
//using these methods: https://www.excelcampus.com/vba/find-last-row-column-cell/
nLastCol := oAS:Cells( 1, oAS:Columns:Count ):End( xlToLeft ):Column
nLastRow := oAS:Cells( oAS:Rows:Count, 1 ):End( xlUp ):Row
cRange := "A1:" + xlsNum2ColumnStr( nLastCol ) + hb_NtoS( nLastRow )
aCells := oAS:Range( cRange ):Value
RECOVER USING oError
END SEQUENCE
oExcel:Quit() //in case of error - nice cleanup
IF oError <> nil
?oError:cargo //or --> ErrorMessage( oError )
лSuccess := .f.
else
lSuccess := .t.
?"Data is in aCells"
ENDIF
endif
return nil
//---------------------
function xlsNum2ColumnStr( nColumn ) // "A" -> 1, "C" -> 3, "Z" -> 26, "AA" -> 27, "BA" -> 53
local cRet := ""
local nDiv
local nRemainder
local cRemainder
repeat
nDiv := Int( nColumn / 27 )
nRemainder := nColumn % 27
if nDiv <> 0
nRemainder++
endif
cRemainder := Chr( ASC( "A" ) + nRemainder - 1)
cRet := cRemainder + cRet
nColumn := nDiv
until nDiv == 0
return cRet
//---------------------
function errStack( oErr ) //error callstack goes to :cargo
local cProc
local nNum := 0, cErr := ""
while !empty( cProc := ProcName( ++nNum ) )
cErr += "Called from " + cProc + "(" + hb_NtoS( Procline( nNum ) ) + ") in " + ProcFile( nNum ) + hb_eol()
enddo
oErr:Cargo := cErr
return break( oErr )
Hi,there is a way to close instances of various non-harbour apps from the windows task manager through harbour code instead from a windows command line suchc:\Taskkill /IM %ProgramName% /f - (%ProgramName% - real name of the executable) ?
I was wondering if there is some harbour function that does the same thing.
/*
source : killprocess.prg
compile : hbmk2 killprocess.prg hbwin.hbc -okill
run : kill <progname.exe>
Pete D. 2017
*/
PROCEDURE Main( cExeName )
hb_default( @cExeName , "nonexistent.exe" )
? TerminateProcess( cExeName )
FUNCTION TerminateProcess( cExeName )
LOCAL cProcess, oProcessList, cQuery
LOCAL nResult := -1
LOCAL hResults := { 0 => "Success", 2 => "Access Denied", ;
3 => "Insufficient Privilege", 8 => "Unknown Failure", ;
9 => "Path Not Found", 21 => "Invalid Parameter" }
cQuery := 'Select * from Win32_Process where Name = "' + cExeName + '"'
oProcessList := win_oleCreateObject("WbemScripting.SWbemLocator"):ConnectServer( ".", "root\cimv2" ):ExecQuery( cQuery )
FOR EACH cProcess IN oProcessList
nResult := cProcess:Terminate()
IF nResult <> 0
EXIT
ENDIF
NEXT
RETURN hb_HGetDef( hResults, nResult, "Couldn't locate process " + cExeName )
Do you know how to get process PID of the launched EXE under Windows?
FOR EACH cProcess IN oProcessList
? cProcess:ProcessId // --> process ID numeric value
...Hi Pete.I mean getting PID of executed process via for example hb_ProcessRun() or something...
<cCommand>, [ @<cStdIn> ], [ @<cStdOut> ], [ @<cStdErr> ], [ <lDetach> ], [@PID]
) hProcess := hb_processOpen( <cCommand>, [ @<cStdIn> ], [ @<cStdOut> ], [ @<cStdErr> ], [ <lDetach> ], [@PID] )
IF QTime():currentTime():tostring("hh.mm.ss") >= dieTime:tostring("hh.mm.ss") .AND. oError <> nil
DO CASE
CASE ::docType = ".doc" ; ::oNewWordDoc:quit()
CASE ::docType = ".odt" ; ::oServiceManager:terminate()
ENDCASE
IF QtMsg( ,"There is some problem with the document. You can try again but first save all your Word or Openoffice documents and then pres yes.",,{ "Yes","No"} ) = 0
Pete, one more question.Where did you get the full syntax of hb_ProcessOpen()?
hProcess := hb_processOpen( <cCommand>, [ @<cStdIn> ], [ @<cStdOut> ], [ @<cStdErr> ], [ <lDetach> ], [@PID] )
nHandle := hb_vfOpen( <cFileSrc>, FO_READ + FO_SHARED )
if nHandle == nil
?"error opening file: " + <cFileSrc> + "; error: " + Str_( FERROR() ) + " " + DOSErr2Str( FERROR() ) )
endif
//if you need size - nFileSize := hb_vfSize( nHandle )
cContent := hb_vfREAD( nHandle, @cBuffer )
and write contents to new file.
if ::oNewWordDoc <> nil //if object is not created for some reason, whis would be NIL
::oNewWordDoc:quit()
endif
nStart := hb_milliseconds()
while hb_milliseconds() - nStart > 3000
enddo
dieTime:= QTime():currentTime():addMSecs( 3000 )
LOOP <---
ELSE
RETURN nil
ENDIF
ENDIF
LOOP <---
ENDDO