Getting rid of the evil delay caused by ShellExecute - c++

This is something that's been bothering me a while and there just has to be a solution to this. Every time I call ShellExecute to open an external file (be it a document, executable or a URL) this causes a very long lockup in my program before ShellExecute spawns the new process and returns. Does anyone know how to solve or work around this?
EDIT: And as the tags might indicate, this is on Win32 using C++.

I don't know what is causing it, but Mark Russinovich (of sysinternal's fame) has a really great blog where he explains how to debug these kinds of things. A good one to look at for you would be The Case of the Delayed Windows Vista File Open Dialogs, where he debugged a similar issue using only process explorer (it turned out to be a problem accessing the domain). You can of course do similar things using a regular windows debugger.
You problem is probably not the same as his, but using these techniques may help you get closer to the source of the problem. I suggest invoking the CreateProcess call and then capturing a few stack traces and seeing where it appears to be hung.
The Case of the Process Startup Delays might be even more relevant for you.

Are you multithreaded?
I've seen issues with opening files with ShellExecute. Not executables, but files associated an application - usually MS Office. Applications that used DDE to open their files did some of broadcast of a message to all threads in all (well, I don't know if it was all...) programs. Since I wasn't pumping messages in worker threads in my application I'd hang the shell (and the opening of the file) for some time. It eventually timed out waiting for me to process the message and the application would launch and open the file.
I recall using PeekMessage in a loop to just remove messages in the queue for that worker thread. I always assumed there was a way to avoid this in another way, maybe create the thread differently as to never be the target of messages?
Update
It must have not just been any thread that was doing this but one servicing a window. Raymond (link 1) knows all (link 2). I bet either CoInitialize (single threaded apartment) or something in MFC created a hidden window for the thread.

Related

Continuously (asynchronously) poll and update label in C++ GUI application

I have an application that opens another process and modifies its memory. What I'd like to have as a part of the GUI is a label that updates (perhaps every second or so) to let the user know if they're attached to the other process.
When the application is found running, I'm creating a handle to it, obtaining the base address of it, and then the rest of the work is done through button clicks and hotkeys. Anyway, for each time the application is found running, I want it to do all the things I have it do to obtain the handle, etc., etc.
This way, the other application can be closed and reopened without my app also needing to be closed/reopened accordingly.
Thus far, my research has led me to CreateThread() and std::async (as well as std::launch::async and std::launch::deferred). The issue I'm having is I can't seem to find examples of infinitely-running asynchronous code (in its own thread, perhaps). I'm having a difficult time wrapping my head around how to make this happen, as everything I've tried still keeps execution from continuing as if I'd just written a while loop in main() or something.
Anything exemplifying the type of functionality I'm looking to achieve would be immensely appreciated! Thanks for your time and help, everyone.

How to find where the program is waiting

I am working on a big code base. It is heavily multithreaded.
After running the linux based application for a few hours, in the end, right before reporting, the application silences. It doesn't die, it doesn't crash, it just waits there. Joins, mutexes, condition variables ... any of these can be the culprit.
If it had crashed, I would at least have a chance to find the source using debugger. But this way, I have no clue how to use what tool to find the bug. I can't even post a code sample for you. The only thing that can possibly help is to tap MANY places with cout to get a visual where the application is.
Have you been in such a situation? What do you recommend?
If you're running under Linux then just use gdb to run the program. When the application 'silences', interrupt it with CTRL+C, then type backtrace to see the call stack. With this you will find out the function where your application was blocked.
Incase of linux, gdb will be great help. Another tool that can be of great help is strace (This can also be used where there are problems with program for with source is not readily available because strace does not need recompilation to trace them.)
strace shall intercept/record system calls that are called by a process and also the signals that are received by a process. It will be able to show the order of events and all the return/resumption paths of calls. This can take you almost closer to the area of problem.
iotop, LTTng and Ftrace are few of other tools that be helpful to you in this scenario.

Closing an application properly: an Alternative to TerminateProcess

I'm facing an issue with TerminateProcess() function.
The application I'm currently writing a JobScheduler app that schedules and launches job at a specific time.
For this purpose, I'm using CreateProcess() to execute my JobLauncher.
The JobLauncher process then launches a console program (using createprocess ) which effectively executes the job executable, waits for its termination and monitors the duration, user and kernel times elapsed etc.
In order to kill the job from the JobScheduler I firstly started using TerminateProcess() but it does not allow me to close the executable itself properly. I mean i found no way to hook any termination event.
Until I find a better way than a brutal TerminateProcess(), I wrote an intermediate solution using the GenerateConsoleCtrlEvent() in the calling program.
In the job application that launches the target job executable, I installed a handler using SetConsoleCtrlHandler().
And in the handler, I can terminate the process of the job and notifies my thirdparties properly.
This is the better solution I found for now.
Is there a better way to programmaticaly and properly close a process ?
Do you this solution is completly absurd ?
I'm not a "system-level" specialist developer though...
Z.
This well know Windows console problem and you can find some solutions here.
We used on internal console utility which has name "Kamikaze". It worked as described here and for me it's a best solution cause there is no problem with porting between Windows versions and Windows architectures (x86, x64).

Uncloseable Application

I was sitting around bored and thought of this idea. Is it possible to change the WM_DESTROY code so that it will do something else instead of closing the application. But, I don't think this will work, but does that keep it from closing when you try to close the application from the task manager in windows. Also, is there a way to remove my application from the task manager so they wouldn't be able to do that in the first place? So, is this possible or do you have a better way? I have googled this and have tried this, but I want to ask the experienced here to answer this question.
BTW, I am not making a virus.
Windows Task Manager will use TerminateProcess to "close" a process - which is a good thing if your program has accidentally or on purpose got a broken VM_DESTROY handler.
There are supposedly ways to mess about with the process list that hides a process. But I don't actually know how that is done othat than very fundamentally (the process list is a linked list, and you can "unlink" a process from the list, and it "disappears"). Obviously doing so would be the type of thing that virus, trojan's, spyware, etc does, and I don't see any reason why you would want to do that in a legitimate application.
Edit: And hiding the application just means it doesn't appear in the list of processes in task manager. If you KNOW that the task exists (and you could for example "guess" based on system activity or some such), it can still be killed using it's process ID by some application that has enough privileges to terminate the process.
you shoud read win32 api demo. when mainwindow receives WM_DESTROY message, call postquitmessage([exitcode]) to end message loop。

Monitoring open programs with Win32

I've searched the web, and various forums, but I can't find one thing, how to continually monitor open programs and then close another program (not the one being monitored) if something happens to the program being monitored.
For example, say that there is an already open Notepad window, and then the user or some other program opens a Windows Explorer window. I want to know how to close the Notepad window without interacting with the Windows Explorer window (other than realizing that it is indeed open), as well as closing the Notepad window if the user closes the Windows Explorer window.
Thanks in advance! :D
On windows, you can use PSAPI (The Process Status API) to know when processes are started and terminate. The EnumProcesses function can give you this information.
A more reliable method to determine that a process terminated (since process ids can be reused) is to wait on its process handle (you will need the SYNCHRONIZE access right) which you can obtain using OpenProcess and the process' id obtained from EnumProcesses.
To terminate a process, there is always TerminateProcess. To call TerminateProcess, you will need a handle to the process with the PROCESS_TERMINATE access right. All of this assumes that you have the privileges needed to perform these actions on the process to be terminated.
One thing to be aware of is that processes and programs - or at least what the user regards as a program - are not necessarily the same thing.
If you use the PSAPI to get a list of all the processes running, you'll see a lot of background process that don't correspond to open windows at all. There's also cases where a single process can have multiple top-level windows open. So while you have simple cases like notepad where once notepad.exe process corresponds to one Notepad window, you also have cases like:
Word, where one word process handles all the word documents currently open (one process, many windows)
Explorer, where a single exploere.exe process handles all the open explorer windows, and also things like control panel windows and the task bar.
Chrome (and other browsers), where each tab gets its own process (many processes, one window!)
Using TerminateProcess is perhaps not the best way to close an app: it's not directly equivalent to clicking the close button. It forcibly terminates the entire process there and then, without giving it any chance to clean up. If you do this on Word, when it restarts, it will go into 'recovery mode', and act as though it hadn't shut down cleanly the last time. It's best left as a last resort if a process has stopped responding. Also, if you TerminateProcess on a process like Word or Explorer, you'll end up closing all windows owned by that process, not just one specific one.
Given all of this, if you want to essentially write some sort of program manager, you might be better off taking a window-centric approach rather than a process centric one. Instead of monitoring running processes, monitor top-level application windows.
There are several ways to listen for changes to windows; SetWinEventHook with EVENT_CREATE/DESTROY is one way to listen for HWNDs being created or destroyed (you'll need to do filtering here, since it will tell you about all HWNDs - and more! - but you only care about top-level ones, and only app ones at that). SetWindowsHookEx may have other options that could work here (WH_CBT). You can also use EnumWindows to list the windows currently present (again, you'll need to filter out owned dialogs and tooltips, currently invisible HWNDs, etc).
Given a HWND, you can get process information if needed by using GetWindowThreadProcessId.
To close a window, sending WM_SYSCOMMAND/SC_CLOSE is the best thing to try first: this is closer to clicking the close button, and it gives the app a chance to clean up. Note that some apps will display a "are you sure you wish to close?" dialog if you haven't saved recently - again, it's consistent with clicking the close button with the mouse.
The most well-known way of doing this on Windows is to use the Process Status API. You can use this API to enumerate processes However, this API is annoying in that it doesn't guarantee you get the full list or processes.
A better way to enumerate processes is using the Tool Help Library, which includes a way to take a complete snapshot of all processes in the system at any given time.
You need the Microsoft PSAPI (Processes API), for example to see the open processes you can use the openProcess function.