dkl
Full Member
Posts: 234
|
Post by dkl on Jan 8, 2021 1:32:07 GMT -5
Can I close an external programme from within LB?
I know I can open one e.g.
run "notepad.exe D:\FileName.txt"
but I would also like to close it. I have tried using 'Kill' with no success.
Thanks
|
|
|
Post by Rod on Jan 8, 2021 4:33:33 GMT -5
nomainwin run "notepad.exe" timer 5000,[done] wait [done] timer 0 run "taskkill /im notepad.exe" end
|
|
dkl
Full Member
Posts: 234
|
Post by dkl on Jan 8, 2021 18:30:59 GMT -5
Many Thanks - I didn't realise I could use 'taskkill' as I didm't see it in the list of cmd.
I would like to be able to close specifically named programmes though e.g.
run "taskkill /im notepad.exe D:\foldername\testlist.txt"
but this doesn't work.
I tried running an AutoHotKey file to do it, but I think I have my syntax wrong
I suppose I could just run a simple BAT file to do it, but is there another way?
|
|
|
Post by Brandon Parker on Jan 8, 2021 19:20:05 GMT -5
Try this code out and see if it works for your purposes...
Print SendMessage(FindWindow("testlist - Notepad"), _WM_CLOSE, _NULL, _NULL) End
'_________________________________________________________________________________________________________________________________________________________ '_________________________________________________________________________________________________________________________________________________________
Function FindWindow(lpWindowName$) lpWindowName$ = lpWindowName$ + chr$(0) CallDLL #user32, "FindWindowA", _NULL As ulong, _ lpWindowName$ As ptr, _ FindWindow As ulong End Function
'_________________________________________________________________________________________________________________________________________________________ '_________________________________________________________________________________________________________________________________________________________
Function SendMessage(hWnd, Msg, wParam, lParam) CallDLL #user32, "SendMessageA" , hWnd As ulong, _ Msg As long, _ wParam As long, _ lParam As long, _ SendMessage As long End Function
{:0)
Brandon Parker
|
|
|
Post by Chris Iverson on Jan 8, 2021 19:21:01 GMT -5
RUN doesn't return anything, so there's no way to know the identifier of a process started with RUN.
Without having some sort of identifier, your best chances are shotgunning it(using taskkill to kill all notepad instances, for example), or something like using FindWindow to find the program's window by title or class name, and sending that window a WM_CLOSE message. (That still runs into the issue of the application deciding NOT to close in response, such as popping up a "do you want to save" notification.)
If you absolutely need to be able to control subprocesses that get created, you should run them using the CreateProcess() API, and use the handles returned to terminate them when needed.
Please note that if you call TerminateProcess() on a process, it is terminated ASAP, if not immediately. It gets no notification, and no chance to do any cleanup. If it's in the middle of writing a file, too bad, it's gone.
open "testproccreate.txt" for output as #f print #f, "data" close #f
hProcess = RunCmd("notepad.exe testproccreate.txt")
print "Press enter to end the program." input a
a = TerminateProcess(hProcess, 0)
a = CloseHandle(hProcess)
Function RunCmd(cmd$) StartupInfoSize = 65 startupInfo$ = chr$(StartupInfoSize)
for x = 1 to (StartupInfoSize - 1) startupInfo$ = startupInfo$ + chr$(0) next x
struct procInfo, hProcess as ulong, hThread as ulong,_ procID as long, threadID as long
CallDLL #kernel32, "CreateProcessA",_ 0 as long, cmd$ as ptr, 0 as long, 0 as long,_ 0 as long, 0 as long, 0 as long, 0 as long,_ startupInfo$ as ptr, procInfo as struct, ret as long
RunCmd = procInfo.hProcess.struct a = CloseHandle(procInfo.hThread.struct)
End Function
Function CloseHandle(hndl) CallDLL #kernel32, "CloseHandle",_ hndl as ulong,_ CloseHandle as long End Function
Function TerminateProcess(hProc, exitCode) CallDLL #kernel32, "TerminateProcess",_ hProc as ulong,_ exitCode as long,_ TerminateProcess as long End Function
EDIT: Hah, I get ninja'd by Brandon with one of the same methods I suggested!
|
|
|
Post by Brandon Parker on Jan 8, 2021 19:25:30 GMT -5
Haaaaaa...
That was awesome! I posted it, went back to the main page, and got a "participated" alert.
{:0)
Brandon Parker
|
|
dkl
Full Member
Posts: 234
|
Post by dkl on Jan 8, 2021 22:19:07 GMT -5
Many Thanks Gentlemen. I'll try out that code and see how it works for me. I have to admit Functions and API calls terrify me. I really don't understand them and have never got one to work yet!! I've got the book by Alyce that explains it all, but it's still water off a duck's to me!!! back!!
|
|
|
Post by Brandon Parker on Jan 9, 2021 9:25:24 GMT -5
Just keep investigating them; one day they will click.
{:0)
Brandon Parker
|
|
dkl
Full Member
Posts: 234
|
Post by dkl on Jan 9, 2021 20:31:59 GMT -5
I'm sorry Brandon, I really didn't understand how I was supposed to use your code!! Chris - I did get you programme running for me and just had to delete the first 3 statements and add my own filename to hprocess = etc...... I presume if I want to be able to close 2 different files (at different times) then I have to add an additional Funtion RunCmd(cmd$) and rename it? OR... I was thinking using it as it is and putting the 2 files into an Array$ and putting the Array$ into hprocess = ..... e.g. if flag = 1 then FN1$ = "testfile.txt" if flag = 2 then FN1$ = "finaltest.txt" hProcess = RunCmd("notepad.exe FN1$") Keeping in mind both files will already be created and I don't need the first 3 lines of you prog Yes....NO....?? Haven't had time to try it yet - 1970's programming I'm afraid!!
|
|
|
Post by Brandon Parker on Jan 9, 2021 22:41:36 GMT -5
All you need to do is replace "testlist - Notepad" with the title of your window that you want to close. The string I used would close a Notepad file named "testlist" that is open. If you wanted to close the "testfile.txt" file that was opened with Notepad then you would replace the string with "testfile - Notepad" ... Does that make sense? {:0) Brandon Parker
|
|
dkl
Full Member
Posts: 234
|
Post by dkl on Jan 10, 2021 3:33:45 GMT -5
Ah.......Now I see! I was expecting the prog to do something.....which it did once I opened the correct file! Thank you for your patience!
|
|
|
Post by Chris Iverson on Jan 11, 2021 12:50:46 GMT -5
I presume if I want to be able to close 2 different files (at different times) then I have to add an additional Funtion RunCmd(cmd$) and rename it? OR... I was thinking using it as it is and putting the 2 files into an Array$ and putting the Array$ into hprocess = ..... e.g. if flag = 1 then FN1$ = "testfile.txt" if flag = 2 then FN1$ = "finaltest.txt" hProcess = RunCmd("notepad.exe FN1$") Keeping in mind both files will already be created and I don't need the first 3 lines of you prog Yes....NO....?? You've actually almost got it with that example. To cover different things: No. You can use the same function to handle multiple external programs, you just need to save the return values separately(if they're going to be concurrent). This will work, if you only intend to open one program at a time, and close it before using it for another program. If you intend to be able to open multiple programs at once, then you need to save each process handle into a separate variable. Otherwise, you can't control the programs anymore. As an example, if you do this: print "Open first program..." hProcess = RunCmd("notepad.exe testfile.txt")
print "Open second program..." hProcess = RunCmd("notepad.exe finaltest.txt") You'll note that hProcess gets overwritten when opening the second program, so you can no longer use it to close the first! 'Close second process a = TerminateProcess(hProcess, 0) a = CloseHandle(hProcess)
'Uhh.... now what? hProcess = ??? Therefore, if you're running multiple programs at the same time, you need to use separate variables to keep track of them. print "Open first program..." hProcessTestFile = RunCmd("notepad.exe testfile.txt")
print "Open second program..." hProcessFinalTest = RunCmd("notepad.exe finaltest.txt") There, now we have both, and we can close both! a = TerminateProcess(hProcessTestFile, 0) a = CloseHandle(hProcessTestFile)
a = TerminateProcess(hProcessFinalTest, 0) a = CloseHandle(hProcessFinalTest)
|
|
dkl
Full Member
Posts: 234
|
Post by dkl on Jan 30, 2021 6:12:58 GMT -5
I thought I had posted a 'Thank you' for all the above hard work, but I didn't My Apologies
Anyhow, it was most helpful and I got it all working. Your help was much appreciated
|
|
|
Post by honkytonk on Feb 1, 2021 9:09:21 GMT -5
Tape: "taskkill /F /IM name of exe" in the bloc note Save: "To close.txt" Rename: "To close.bat" Put the file: "To close.bat" with the: ".bas" code in a folder. And include in the code ".bas": run "To close.bat"
|
|
Tasp
Full Member
Posts: 215
|
Post by Tasp on Feb 1, 2021 12:42:15 GMT -5
Be careful with Taskkill as it doesn't always run correctly on various machines. I think you need to be running LB as Administrator to get it to work.
|
|