Run a process as a synchronous operation from a Win32 application - visual-c++

I have an existing utility application, let's call it util.exe. It's a command-line tool which takes inputs from the command line, and creates a file on disk, let's say an image file
I want to use this within another application, by running util.exe. However it needs to be synchronous so the file is known to exist when processing continues.
e.g (psudeo)
bool CreateImageFile(params)
{
//ret is util.exe program exit code
int ret = runprocess("util.exe",params);
return ret==0;
}
Is there a single Win32 API call that will run the process and wait until it ends? I looked at CreateProcess but it returns as soon as it tries to start, I looked at ShellExecute but that seems a bit ugly even it were synchronous.

There's no single api, but this is actually a more interesting general question for Win32 apps. You can use CreateProcess or ShellExecuteEx and WaitForSingleObject on the process handle. GetExitCodeProcess at that point will give you the program's exit code. See here for simple sample code.
However this blocks your main thread completely, and can give you serious deadlock problems under some Win32 messaging scenarios. Let's say the spawned exe does a broadcast sendmessage. It can't proceed until all windows have processed the message - but you can't proceed because you're blocked waiting for it. Deadlock. Since you're using purely command line programs this issue probably doesn't apply to you though. Do you care if a command line program hangs for a while?
The best general solution for normal apps is probably to split a process launch-and-wait off onto a thread and post a message back to your main window when the thread runs to completion. When you receive the message, you know it is safe to continue, and there are no deadlock issues.

Process handle is a waitable object, AFAIK. This is exactly what you need.
However, I'd recommend against doing anything like that. Starting process on windows may be slow and it will block your UI. Consider a PeekMessage loop with 50ms wait timeouts to do it from a windows application.

Related

Creating a new "internal" process?

I'm writing a DLL (in Visual C++) and I recently decided that I need to move stuff that currently happens in threads into their own process. This is because I want to support multiple instances of the DLL being loaded and running. However, they all need to access the same group of resources (i/o buffers to a COM port) that needs to be autonomously monitored as long as there is at least one instance of the DLL running.
It seems I need to use CreateProcess(), but I'm unclear on how I should use the lpApplicationName argument. In the examples I've seen, the name of an existing program gets passed, but that isn't what I imagine I need to do. I expected to be able to start a process by specifying a function, much like with CreateThread(). The process doesn't need to be compiled and output as its own executable, does it? It definitely shouldn't be used by anything other than my DLL. Thanks.
EDIT: Okay, so if all CreateProcess() can do is start a pre-existing program, how can I get this to work? If the following happens:
Process loads the DLL
DLL starts port monitoring threads
Second process loads the DLL
Second DLL establishes some IPC to access the same data as the first DLL
First DLL is about to exit, and terminates the monitoring threads
Second DLL starts its own monitoring threads and continues
Doing 5 and 6 seems (especially with my implementation) like a clunky way of doing things, rather than just have behavior that I never have to terminate and restart.
EDIT: The more I think about this, the more I like the idea of making a separate executable, but if anyone think of a more "elegant" method, I'd still like to know.
You can't do that. On *nix you could fork can then call whatever function you want, but CreateProcess doesn't work that way. The only thing CreateProcess can do is launch a new process with execution starting at the entry point of an on-disk executable.

QWebFrame::evaluateJavaScript(scriptSource) leads to "SyntaxError: Parse error" when not executed in main Thread

When I run QWebFrame::evaluateJavaScript(scriptSource) from main thread everything seems to work just fine. But when I try to run it from a different thread I get a SyntaxError: Parse error. Even when I'm trying to run trivial code like 1+1;.
Can somebody explain why this occurs and whether this is the expected behavior?
Is there a possibility to use the QWebKit in another thread then the main thread?
P.S.: I am running Qt4.8
I don't know much about QWebFrame or QT, but following should hold true.
In simplest terms, its GUI application and all the actions have to be done in main thread. If you have multiple threads, you will have to find a way to channel the call to main gui loop thread or main thread in your case.
One of the main reason is thread local storage that application could be using internally. If you execute the function from another thread local storage may not be set.
For GTK calls, most (all?) of the webkit calls have to be channelled through gtk idle hook so that it will get executed in proper thread. There should be something equivalent in QT.

Why the window of my vb6 application stalls when calling a function written in C?

I'm using 3.9.7 cURL library to download files from the internet, so I created a dynamic bibioteca of viculo. dll written in C using VC + + 6.0 the problem is that when either I call my function from within my vb6 application window locks and unlocks only after you have downloaded the file how do I solve this problem?
The problem is that when you call the function from your DLL, it "blocks" your app's execution until it gets finished. Basically, execution goes from the piece of code that makes the function call, to the code inside of the function call, and then only comes back to the next line after the function call after the code inside of the function has finished running. In fact, that's how all function calls work. You can see this for yourself by single-stepping through your code in the VB 6 development environment.
You don't normally notice this because the code inside of a function being called doesn't take very long to execute before control is returned to the caller. But in this case, since the function you're calling from the DLL is doing a lot of processing, it takes a while to execute, so it "blocks" the execution of your application's code for quite a while.
This is a good general explanation for the reason why your application window appears to be frozen. A bit more technically, it's because the message pump that is responsible for processing user interaction with on-screen elements is not running (it's part of your code that has been temporarily suspended until the function that you called finishes processing). This is a bit more difficult for a VB programmer to appreciate, since none of this nitty-gritty stuff is exposed in the world of VB. It's all happening behind the scenes, just like it is in a C program, but you don't normally have to deal with any of it. Occasionally, though, the abstraction leaks, and the nitty-gritty rears its ugly head. This is one of those cases.
The correct solution to this general problem, as others have hinted at, is to run lengthy operations on a background thread. This leaves your main thread (right now, the only one you have, the one your application is running on) free to continue processing user input, while the other thread can process the data and return that processed data to the main thread when it is finished. Of course, computers can't actually do more than one thing at a time, but the magic of the operating system rapidly switching between one task and another means that you can simulate this. The mechanism for doing so involves threads.
The catch comes in the fact that the VB 6 environment does not have any type of support for creating multiple threads. You only get one thread, and that's the main thread that your application runs on. If you freeze execution of that one, even temporarily, your application freezes—as you've already found out.
However, if you're already writing a C++ DLL, there's no reason you can't create multiple threads in a VB 6 app. You just have to handle everything yourself as if you were using another lower-level language like C++. Run the C++ code on a background thread, and only return its results to the main thread when it is completely finished. In the mean time, your main thread is free.
This is still quite a bit of work, though, especially if you're inexperienced when it comes to Win32 programming and the issues surrounding multiple threads. It might be easier to find a different library that supports asynchronous function calls out-of-the-box. Antagony suggests using VB's AsyncRead method. That is probably a good option; as Karl Peterson says in the linked article, it keeps everything in pure VB 6 code, which can be a real time saver as well as a boon to future maintenance programmers. The only problem is that you'll still have to process the data somehow once you obtain it. And if that's slow, you're right back where you started from…
Check out this article, which demonstrates how to asynchronously transfer large files using a little-known method in user controls.

What signal should I expect when my program exits normally?

I have a shared object that I have written which I link to an Linux executable (say a game for example). Now when the program finishes (game over!), what kind of signal handler should I have in my shared object that I created in order to perform some cleanup activities?
Please remember that I DO NOT have control over the Linux executable, it is a game that I simply download from the Internet and run it by linking it to my shared object. When the game finishes, I want to be able to catch that event and do some cleanup activities.
Have I made my question clear? Any ideas?
Thanks,
Krishna
if you run the game as a child process, you'll get SIGCHLD (17) when the other process ends.
If the main application uses the standard C library, then you can make use of the atexit(3) function to register a function to be called when the application exits.
There are a number of cases where the function will not be called though (abnormal termination through signals, a call to _exit(2), etc), so check the man page to see if all your use cases are covered.
In general, you can't do this from within the process. (Software can't have dying wishes.)
However, you could run the existing game process inside a wrapper script or something that runs another program after the game finishes:
#!/bin/sh
run_game
perform_cleanup_activity

UpdateAllViews() from within a worker thread?

I have a worker thread in a class that is owned by a ChildView. (I intend to move this to the Doc eventually.) When the worker thread completes a task I want all the views to be updated. How can I make a call to tell the Doc to issue an UpdateAllViews()? Or is there a better approach?
Thank you.
Added by OP: I am looking for a simple solution. The App is running on a single user, single CPU computer and does not need network (or Internet) access. There is nothing to cause a deadlock.
I think I would like to have the worker thread post (or send) a message to cause the views to update.
Everything I read about threading seems way more complicated than what I need - and, yes, I understand that all those precautions are necessary for applications that are running in multiprocessor, multiuser, client-server systems, etc. But none of those apply in my situation.
I am just stuck at getting the right combination of getting the window handle, posting the message and responding to the message in the right functions and classes to compile and function at all.
UpdateAllViews is not thread-safe, so you need to marshal the call to the main thread.
I suggest you to signal a manual-reset event to mark your thread's completion and check the event's status in a WM_TIMER handler.
suggested reading:
First Aid for the Thread-Impaired:
Using Multiple Threads with MFC
More First Aid for the Thread
Impaired: Cool Ways to Take Advantage
of Multithreading

Resources