SHFileOperation needs a valid window handle in which it performs all window messages.
I would like to use SHFileOperation independently from the current calling process, so I can close the process right after SHFileOperation has been called (and returned?!) which means I would like to "pass" it to another process or window.
I have tried the GetDesktopWindow handle in order to "pass" it to the explorer.
So my question is, how is it possible to call SHFileOperation, close the process right after the call and it's still doing the job?
So my question is, how is it possible to call SHFileOperation, close the process right after the call and it's still doing the job?
It is not possible. If you kill the process then SHFileOperation will be stopped before completion. The only way to achieve this is to hand of the task of calling SHFileOperation to a different process.
Of course, you could just as well let your process remain alive until SHFileOperation returns. You can close any other visible UI from your process, and wait until SHFileOperation completes. Then exit the process.
Related
The process is not getting terminated after closing its handle in CloseHandle().
Well I have a process created by CreateProcess() api. Even after closing Its handle it is still running.
From the msdn, they say that CloseHandle() closes the handle and doesn't terminate process. Have to call terminate thread for that. Then why CloseHandle()?
But when I checked CloseHandle()'s return value, it succeeded. If so I want know what is actually done in this CloseHandle() and why it returns successfully. And I want to know what all operation can be done on the process using its handle. I felt misleading, as CloseHandle() succeeds but the process still runs on!
Would also be great what actually contains in the handle of a process and is there any differences with other type of handles? (file,I/O etc)
Why does closing the handle not terminate the process? Have to call TerminateProcess for that.
Closing the handle does not terminate the process because it would be absurd. Processes generally run independently of each other. If closing the process handle terminated the corresponding process, this wouldn't be the case since when a program exits, all open handles it holds are closed. Which would for example mean that if Explorer crashed, every program you started would be instantly terminated. That would be a desaster, and thus closing the process handle does, by design, not terminate the program.
Terminating a process is almost always a very bad idea. The same goes for terminating a thread. Never do that if you can avoid it. If you want a thread/process to exit, send it a message and wait until it has exited (on its own behalf). This guarantees that data is properly saved and in a consistent state, no resources are leaked, and that no serious conflicts can occur (such as a thread being terminated while it holds a lock).
Terminating threads is often troublesome, and sometimes catastrophic. The same goes for terminating processes. It is only "allowable" to terminate a process or a thread when it is caught in an infinite loop and non-responsive.
Then why do you have to close the handle anyway, and why are you getting one at all if you must close it?
You can do certain things with a handle, among these are for example ReadProcessMemory, WriteProcessMemory, CancelIoEx, running a debugger, use PSAPI, and a few others. Also you can wait on the handle, it will be signalled when the process exits. That is a very simple way of inter-process synchronization.
On the other hand, the operating system cannot release resources as long as you hold the handle open and thus have a "legitimate right" to access these. How can you for example wait for a process, if the process (or at least its structures) does not exist at all any more?
This (and the fact that the handle itself is a resource) is why you should close the handle as soon as possible if you don't need it. Holding it indefinitely requires the OS to keep resources around that are not needed but cannot be freed.
Closing the handle tells the operating system that you don't need it any more, so whenever the OS wants to release all resources associated with the process, it can do so.
What is contained in the process handle?
Like all handles, the process handle is merely an opaque integer that doesn't contain anything. It is an index in a kernel-owned table, technically a void*, but that is only an implementation detail. The actual kernel structure that it refers to is not something you can directly access, not in an easy way anyway.
A handle is a reference to some kernel-managed, reference-counted object. Normally, closing the last handle to an object will result in the destruction of such an object.
But: processes and threads are not killed when closing the last handle, you can think that they "start living on their own" after being started. Without this exception, you couldn't have a process outlive its parent, since each process' handles is closed automatically at process termination (and having a thread outlive its parent would require needless complications).
Anyway, all of this is documented: if you read the documentation of CloseHandle you would have found:
Closing a thread handle does not terminate the associated thread or
remove the thread object. Closing a process handle does not terminate
the associated process or remove the process object. To remove a
thread object, you must terminate the thread, then close all handles
to the thread. For more information, see Terminating a Thread. To
remove a process object, you must terminate the process, then close
all handles to the process. For more information, see Terminating a
Process.
What you described is behavior by design. A process runs on its own, it might have zero or more handles opened, which let their holders control the process in certain ways. Once you hold a handle, you are responsible for closing it.
Termination of the process is a different thing, and you basically are not expected to terminate externally: you never know where exactly you stop the process. You are expected to somehow signal that you want the process termination, so that the process could figure it out and terminate its activity internally, and gracefully.
I'm trying to create a Child Process with Redirected Input and Output (as described here - http://msdn.microsoft.com/en-us/library/ms682499(VS.85).aspx).
For the people that don't want to bother reading the source code on that page, the author is using anonymous pipes to redirect the child's input and output. The parent process writes to the child process's input and reads from the child process's output.
In that code however, the program is closing the pipes after reading and writing (in WriteToPipe and ReadFromPipe), so actually the program just reads a file, dumps it on the child process input stream and then reads the child process response.
Now, what I'm looking for is a code where we will not close the pipes, but we will continuously post requests and read the child process response (in contrast to making just 1 request).
I've tried several modifications to the source code given on the link posted above, but no matter what I try, the program always hangs when calling ReadFile() in the ReadFromPipe() function (it probably waits for the child to quit - but as I said I like to get the child response, and then send other requests to it).
Any ideas on how I can get over this?
Update:
Can anyone at least tell me whether using the .NET Process class with RedirectStandardInput and RedirectStandardOutput is a good option?
Had exactly the same problem, and solved it by using PeekNamedPipe (which according to MSDN is also fine for anonymous read pipes) to check for available data before each call to ReadFile. That removed the blocking issues I was getting, and allowed my GetExitCodeProcess() to see that the process had exited and cleanup the pipes.
Yes - the .Net Process class redirects the standard input / output of the child process with anonymous pipes in a very similar way to the linked sample if you use RedirectStandardInput and RedirectStandardOutput, so this is probably a fairly good option.
As for why ReadFile is hanging - it sounds like this function is waiting for the child process to either send some data back, or to close the pipe. If you want to continuously post requests to the child process then you need to either:
Know exactly when it is appropriate to read so that you are not left waiting / blocked for the child process (so for example you only read immediately after a request has been sent). This strategy is very risky as there is always a chance that the child process doesn't behave as expected and you are left waiting on the child process indefinitely.
Have a dedicated thread for reading - if you have a dedicated thread for reading then it doesn't matter that the thread may wait indefinitely for the child process as your other threads are still able to send requests and operate as normal. This method is more complex than the first option, however when done properly is far more robust. The only other drawback to this approach is that it requires you have an additional read thread for each child process, meaning that it doesn't scale very well if you need to communicate with a large number of child processes.
Use asynchronous IO - It is possible to call the ReadFile function in a way such that it always immediately returns, however notifies you when a read has completed (I'm a little fuzzy on the exact details on how this works as I'm more used to C#). This is know as Asynchronous IO and is the most versatile of these 3 methods as it allows you to communicate with many child processes without needing a dedicated thread for each one. The tradeoff however is that it is also the most complex to do correctly (at least in my opinion).
I wish to launch a separate thread for handling window messages (via a blocking GetMessage loop), but still create the windows in the initial thread, afterward.
Within the separate thread, as soon as it launches, I am calling PeekMessage with PM_NOREMOVE to ensure a message queue exists (is this necessary?), followed by..
AttachThreadInput(initial thread id,GetCurrentThreadId(),true)
..before finally entering the message loop
I am not yet using a mutex or cs to ensure this is happening in time, but am merely using a Sleep statement in my initial thread for the sake of simplicity.
Regardless, window messages do not appear to be intercepted by the separate thread.
I am a little unsure as to whether I am doing this correctly, and would appreciate any possible guidance. Both threads are in the same process
Thank you all
That's not what AttachThreadInput does. Even after you attach your input queue to another thread, Windows still have thread affinity. Messages in the queue for a given window can only be removed from the queue by that window's thread.
What AttachTheadInput does is to make two threads share an input queue. This allows them to query information about the input state and know that the other thread will get the same answer for the same query. For instance, one thread could call GetAsyncKeyState and know that the answer reflected the key state for the other thread.
It allows two or more threads to have the same relationship to the input queue and each other as processes had in Windows 3x. This is the reason that this API exists; so that complex multiprocess applications could be ported from Win 3x to Win95/WinNT.
It seems the best way to instigate window creation from the main thread, while having messages for them handled in a separate, looping thread is to use a custom message, that can be sent to the separate thread - Thus allowing it to create the window, but still allowing that action to be invoked from the initial thread:
1) Allocate a custom message, and create a structure to hold the window initialisation parameters:
message_create_window = WM_USER + 0;
class Message_create_window{
Message_create_window(...);
};
2) Instead of calling CreateWindow(Ex), use something similiar to the following, passing in the relavant window creation parameters:
PostThreadMessage(
thread.id,
message_create_window,
new Message_create_window(...),
0
);
3) Handle the custom message in the message pump of your ui handling thread, extract the creation parameters, & free afterwards:
MSG msg;
GetMessage(&msg,0,0,0);
...
switch(msg->message){
...
case message_create_window:{
Message_create_window *data=msg->wParam;
CreateWindowEx(data->...);
delete data;
}break;
...
This does, however, have the following side-effects:
The window will be created asynchronously. If it is required that the initial thread block until the window is created (or, indeed, that the window's existence can ever be asserted) then a thread synchronisation tool must be used (such as an event)
Care should be taken when interacting with the window (it is a multithreaded application, after all)
If there are any major holes in this answer, or this seems like a terrible approach, please correct me.
(This is still my question, & I am trying to find the best way to accomplish this)
I note an applications handle when I use the shell function to open it.
I then use that handle to close the application later.
However the user can also close that other application himself.
Can that handle then be reused by windows so that when I use that handle I close a different process.
If it is possible is it likely?
No, you don't have to worry about it. The handle returned by, say, OpenProcess, ShellExecuteEx() or CreateProcess keeps the process object alive. That's how it is possible to call GetExitCodeProcess() to retrieve the exit code after the process is terminated.
The object doesn't get released until the last handle on it is closed. Opposite of earlier advice given in this thread, it is very important that you call CloseHandle() or you'll have a leak.
You can wait on a process handle to figure out when it is exited.
WaitForSingleObject(hProcess, INFINITE);
Once this returns, you know the process has exited and you don't need to close it.
What is the best way to run an external program from excel. It might run for several minutes. What's the best-practice about how to to this. Ideally,
A model dialog box that let's the user know that the process is executing.
If the executable fails, the user should receive a notification.
A timeout should be enforced.
A cancel button should be on the dialog box.
But any best-practices are welcome. I'm interested in solutions with calling either a .dll or an .exe. Preferably something that works with Excel '03 or earlier, but I'd love to hear a reason to move to a later version as well.
You should check out these two Microsoft KB articles
How to launch a Win32 Application from Visual Basic
and
How To Use a 32-Bit Application to Determine When a Shelled Process Ends
They both quickly give you the framework to launch a process and then check on its completion. Each of the KB articles have some additional references that may be relevant.
The latter knowledgebase article assumes that you want to wait for an infinite amount of time for your shell process to end.
You can modify the ret& = WaitForSingleObject(proc.hProcess, INFINITE) function call to return after some finite amount of time in milliseconds--replace INFINITE with a positive value representing milliseconds and wrap the whole thing in a Do While loop. The return value tells you if the process completed or the timer ran out. The return value will be zero if the process ended.
If the return value is non-zero then the process is still running, but control is given back to your application. During this time while you have positive control of your application, you can determine whether to update some sort of UI status, check on cancellation, etc. Or you can loop around again and wait some more.
There are even additional options if the program you are shelling to is something that you wrote. You could hook into one of its windows and have the program post messages that you can attach to and use as status feedback. This is probably best left for a separate item if you need to consider it.
You can use the process structure to get a return value from the called process. Your process does need to return a value for this to be useful.
My general approach to this kind of need is to:
give the user a non-modal status dialog at the start of the process with a cancel button, which when clicked will set a flag to be checked later. Providing the user with any status is most likely impossible, so giving them an elapsed time or one of those animated GIFs might be helpful in managing expectations.
Start the process
Wait for the process to complete, allowing cancellation check every 500ms
If the process is complete close the dialog and continue along.
If the process is not complete, see if the user hit cancel and if so send a close message to the process' window. This may not work and terminating the process might be required--careful if you do this. Your best bet may be to abandon the process if it won't close properly. You can also check for a timeout at this point and try to take the same path as if the user hit cancel.
Hope this helps,
Bill.