How to close a shelled process in VB6 - shell

I shell out an application from my VB6 app. I would then like to close it. How can I pull this off?

Here is Karl Peterson's VB6 method for closing applications. As you request, this asks nicely - sending WM_CLOSE rather than using TerminateProcess. Note that it sends the message to all of the top-level windows belonging to the process, there could be more than one.
I haven't tried this, but in my experience Karl Peterson's code always rates five stars out of a possible five!
EDIT: Please note this is an edited version of the original answer, and now links to the latest version of Karl's code. If anyone has questions about this, Karl is still active on the VB6 newsgroup but I don't think he hangs out on Stack Overflow.

Check this out:
End an Application that was Started by the Shell Function

Related

Behind the scenes of "Windows is searching for a solution ..."?

So when a program dies rather ungracefully, modern versions of Windows put up a dialog that reads:
Windows is searching for a solution to the problem
It clocks for a little while, then doesn't find anything. Well, I've never had it tell me it's found a solution.
The question is, what exactly is going on when this dialog is being shown? What are possible things it can show as "solutions"? Is there a way my application can tap into it?
Obviously, if I know enough about what could go wrong, I should handle it in the app, so I'm left wondering what this actually does.
Anyone know?
Windows Error Reporting is capturing a stack trace of the failed program and sending it off to Microsoft. The data it collects is stuffed into an enormous database for vendors to research; if this is your program, you can sign up here. If the vendor submits a patch, Windows will notify you.
You can tap into it, either by customizing the info, triggering reports for (soon to be) fatal errors, and much more.

How to find which dynamic objects taking excessively long time to finish?

M 8.0.1, windows 7.
A debugging question.
Sometimes when I start M and open my notebook (which has dynamics enabled in it before I closed it) I get this message
The problem is, no matter if I click on wait, or disable dynamics, the message keeps coming back.
I have to terminate the process itself (i.e. Mathematica) from windows task manager to get out of this.
Clearly I seem to have a bug somewhere in dynamics in my code.
My question is: Is there a way for M to tell me which dynamic objects is causing this problem? And any idea why telling it to disable dynamics updating is not helping here (as I keep getting the message).
thanks
You may have some luck by evaluating:
SetOptions[$FrontEnd, PrintKernelDynamicTraffic -> True]
This will cause the Mathematica FrontEnd to print messages to the system console (on Mac, I don't know where it goes on Windows) whenever it sends Dynamic evaluations to the kernel. If you can find the last Dynamic evaluation to print out when the message appears, that should be the one which is taking a long time to evaluate.
You'll probably want to disable this when you're done debugging so it doesn't fill your system log with millions of debug messages.
You may find DebugTrace, written by David Bailey, useful. It is a debugger which may also be used to debug dynamic constructions. In this documentation there is an example on how to debug such programs. Basically you set a breakpoint in your code, run it, and after it's done you are presented with detailed information on what happened when.
In general I highly recommend giving it a try, not only for the dynamic functionality.

Uninterruptible Windows Process

We're starting a new custom project right now from a client and one of the requirements is the process cannot be terminated unless the system is shutting down, restarting, or logging-off.
This application monitors the USB interface. We will be using WMI to query the device periodically.
The client want's to run the application on Windows XP Operating System and doesn't like installing .NET. So we targeted Visual Basic 6 as our language.
My main concern is this application cannot be terminated. Our Project Adviser talks about Anti-virus and yes, some of the anti virus cannot be terminated. I was thinking how to do the same in Visual Basic 6. I know there will be API involved on the project but where should I go? so API is ok with me.
I saw some articles that converts the EXE to a SERVICE, create Windows Service in Visual Basic 6, etc.
So please .. share your thoughts.
If you want to be evil, you can call the (officially) undocumented RtlSetProcessIsCritical NTDLL function. This will immediately BSOD the machine if your process is terminated.
You cannot create a process that cannot be terminated without some sort of kernel-mode hooking, which involves writing a driver. You might want to look into Rootkits: subverting the Windows kernel if you're interested in that. However, even with kernel-mode hooking there are still numerous ways to terminate processes. The alternative is to use user-mode hooking, easily bypassed but enough for very simple projects.
The solution you want to use will depend on how far you want to go with the termination protection. And even if you do succeed in preventing process termination, there may be ways of preventing your application from working properly - e.g. killing the WMI service.
I think you want to look at writing an NT Service.
More info here: http://www.montgomerysoftware.com/CreatinganNTServiceinVisualBasic6/tabid/161/language/en-US/Default.aspxlink text
It's really frustrating coding in VB6 right now specially I dumped my head in C# for 2 years though I coded in VB6 for 5 years..
Moving back is a pain as if I am starting a new programming language.
To be honest, you are trying to do something in VB6 that it really isn't that great at.
When you say 'cannot be terminated' - what do you mean by that? There are several levels there:
a) App shows a window but the user cannot close it with the X button, or it does not show one
b) App shows no windows or maybe sits in task tray
c) App shows no windows and cannot be shut down from the Applications tab of task manager
d) App cannot be shut down from the process list of task manager
(a) and (b) are probably easiest to do in straight VB. (c) is still possible, but getting uglier. (d) gets you into hack territory and would almost certainly be frownd upon if you did manage it.
If you really need to stop users closing then you can probably hack it to a greater or lesser degree, but the real answer is as the others have said - a system service (this is exactly the srt of thing they were intended for). However that is one thing that VB6 isn't good at so the best solution to your problem is c#.

Win32 API For Shutting Down Another Process Elegantly?

I'm looking for a way to shutdown a windows app from another. Is there a way to do this?
Ideally I'd like something that basically mimics an ALT-F4, or pressing the 'X' in the top right corner or some such.
Alternatively, is there an application out there that does this already? tskill is a bit too harsh for what I have in mind.
EDIT: I did a little digging and found a MSDN Article with the Microsoft recommended approach.
Since this is a windows app you can send the WM_CLOSE message to the main window however keep in mind that if the application overrides handling of the WM_CLOSE message you may get unexpected results. Also keep in mind that use of win32 functions like TerminateProcess and ExitProcess can also have unpleasant side-effects (see the remarks sections on msdn) including global data in dll's getting compromised as well as deadlocks.
If you are responsible for having coded the target application I would recommend adding some form of built in termination mechanism that can be triggered externally (e.g. magic packet on the loopback address or pipes) that way you can be sure your application has cleaned up after itself appropriately.
According to your description this sounds like a windowed app. In that case you can send it a WM_CLOSE message to mimic the behavior when pressing the "X" button.
Another alternative is to use TerminateProcess, but this is probably what tskill does as well.
More powerful command to close app is:
PostMessage (myhnd,WM_ENDSESSION,TRUE,ENDSESSION_LOGOFF);
I'll first refer you to my answer to another question; although it was about Delphi and services, the answer is neither Delphi- nor service-specific. In short, there is no generic way to gracefully stop a program. The accepted answer for that question demonstrates posting a wm_Close message to a program's window.

Windows Systems Programming: Can a keystroke be sent to an open application that is not the currently active one?

I'm a bit rusty on my Windows system programming...
Is it possible for a program to send a keystroke (I'm guessing by SendMessage() api call) to another application, if the (open) target application does not currently have the focus? If it is possible, does it then make the target application become the active application, or does it still remain in the background?
Thanks in advance for any info you may be able to provide!
No, It will not change the focus, unless subsequent calls do setfocus. It will remain the same window order
PostMessage(hwndOther, WM_KEYDOWN, VK_ENTER, 0);
This works for me, but only under Windows XP.
But On Vista and Windows 7 I've too got problem. Propably with UIPI.
I am trying to send a message to process from a DLL injected to this process.
How to fix it?
From memory: Yes, No.
You are looking for WM_KEYDOWN:
PostMessage(hwndOther, WM_KEYDOWN, VK_ENTER, 0);
For a directed send of keystrokes, SendInput is the native method of choice, though it is subject to UIPI (integrity level) checks on Vista/2008/W7. You can't send keystrokes to an app that has an IL > yours.
A more general solution for capturing and redirecting input is a global keyboard hook (See the help for SetWindowsHookEx). But this is fairly hairy stuff - you have to cope with how you send the keystrokes on, you affect every process in the system because your code is effectively inserted in the input stream, it involves writing a native DLL... you have to know exactly what you're doing.
We use a global keyboard hook in our system (I wrote it), but we're a special case - a single function emergency call handling system. I wouldn't advise a global hook as a solution in general purpose Windows computing.
You don't need SendInput() or hooks
The answer with PostMessage is wrong.
You must attach remotely your thread. See on Win32 api Group where it's a very classic question (C code, right MS method)
Yes you can send keystrokes, no it won't bring the other window to the top.
One way is to use the SendInput API function - here's an example of how to use it in VB6 (ulp!).
Probably easier to use GUI Automation which is supported directly from .NET Framework 3.0 - for instance read this.

Resources