Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 3052
  • Last Modified:

Using CreateProcess() to call a C++ program and communicating back and forth with it from MFC GUI interface.

Hi all,
I have a Win32 (MFC) application that serves as an interface to time-consuming scientific computation. Currently I have the main interface thread start the scientific computation in a separate worker-thread (using AfxBeginThread()). I also pass a pointer to a relatively large parameter structure/object to the scientific worker-thread function. The structure contains a number of control parameters and input/output file names. One of the parameters is a Boolean variable, which gives main thread power to terminate the worker-thread function in the middle of its computation, if necessary. The worker thread also communicates back with the main thread (using windows messages) to update the Progress Bar, status, etc.
My employer now wants me to separate the main interface thread and the time-intensive worker thread into separate processes. The idea is to give users the ability to look at and modify the scientific code, but not the interface code. That’s where I am at right now. I realize I can use CreateProcess() and ShellExecuteEx()/ShellExecute() functions to start the scientific worker-process from the main interface-process. The user would have to enter (in the main interface-process) the path name to the executable they obtained after recompiling the scientific worker-program. I can also probably stuff all of the parameters: about 15 numbers and 20 long input/output file names into the parameter character string. However, how do I terminate such process in mid-run at will from the main interface? Also, how can the scientific worker-process communicate with the main interface-process to update its status information, progress bar, etc.? Would 2-way communication be possible with such setup? If not, could anyone suggest an alternative setup?  
I would appreciate any help/advice/code you could offer me.
Thank you in advance.
0
abuly80
Asked:
abuly80
  • 3
  • 2
1 Solution
 
jkrCommented:
>>However, how do I terminate such process in mid-run at will from the main
>>interface?

As for this part of your question, see http://support.microsoft.com/default.aspx?scid=http://support.microsoft.com:80/support/kb/articles/Q178/8/93.ASP&NoWebContent=1 ("HOWTO: Terminate an Application "Cleanly" in Win32")

>>Also, how can the scientific worker-process communicate with the main
>>interface-process to update its status information, progress bar, etc.?

There's the bad news: If that process is not providing any notifications about the progress (most likely to be documented in the manufacturer's manual), you are out of luck.
0
 
abuly80Author Commented:
I am sorry if I was not clear enough. The process I will need to terminate is a windowless program, which I currently use as a worker-thread in my application. The article you referred me to states: "In a perfect world, your process could ask another process, through some form of inter-process communication, to shut down. However, if you do not have source-level control of the application that you wish to shut down, then you may not have this option." My question is: how do I design "some form of inter-process communication" mechanism to make this possible, because I do have "source-level control" over the application I need to shut down.

The same goes for the second point you made. In fact, I can legislate the worker-process to provide all the notifications of progress I require.

I just do not know how to make a leap from thread-based to process-based multitasking. For example, I used to start the worker thread with code similar to below:
typedef struct
{

HWND hCommunicationWnd;
BOOL bContinue;
} params_t;

params_t params;
params.bContinue = TRUE;
params.hCommunicationWnd = this.m_hWnd;
AfxBeginThread(ScientificCalculation,&params);

To terminate such worker thread I would program it to terminate on params.bContinue being FALSE. To inform the main thread of the worker-thread’s progress, I would program the worker thread to send update messages to hCommunicationWnd.

Now, when I go from using different threads within the same process to using different processes/programs, how do I cleanly terminate the worker-process from the main interface process? Also, how do I send messages from one process to another? Can I pass the window handle or a pointer to a boolean continue-or-stop variable from one process to another?

Hope this clears things up a bit. Thanks again.
0
 
MikProgCommented:
Windows API brings you many abylities for interporcess communication and data exchange.
First: Events.
  CreateEvent
  SetEvent
  ResetEvent
 This one intend to notify about 'events'. Process that want to notify another process sets event to signaled state and process to be notifyed reads event and reset it to nonsignaled state.
Second: Shared memory.
This implemented throught Memory Mapped Files. Thise files may have underlying phisical file but may have not. It is standart mechanism for interprocess data exchange
Follows text from Win32 API help files

The first process calls the CreateFileMapping function to create a file-mapping object and give it the name MyFileMappingObject. By using the PAGE_READWRITE flag, the processes will have read/write permission to the memory through any file views that are created.

HANDLE hMapFile;
 
hMapFile = CreateFileMapping(hFile,    // Current file handle.
    NULL,                              // Default security.
    PAGE_READWRITE,                    // Read/write permission.
    0,                                 // Max. object size.
    0,                                 // Size of hFile.
    "MyFileMappingObject");            // Name of mapping object.
 
if (hMapFile == NULL) {
    ErrorHandler("Could not create file-mapping object.");

}
 

The process then uses the file-mapping object handle returned by CreateFileMapping in the call to MapViewOfFile to create a view of the file in the process's address space. The MapViewOfFile function returns a pointer to the file view.

LPVOID lpMapAddress;
lpMapAddress = MapViewOfFile(hMapFile, // Handle to mapping object.  
    FILE_MAP_ALL_ACCESS,               // Read/write permission
    0,                                 // Max. object size.
    0,                                 // Size of hFile.
    0);                                // Map entire file.
 
if (lpMapAddress == NULL) {
    ErrorHandler("Could not map view of file.");
}
 

The second process calls the OpenFileMapping function with the name MyFileMappingObject to use the same file-mapping object as the first process. Like the first process, the second process uses the MapViewOfFile function to obtain a pointer to the file view.

HANDLE hMapFile;
LPVOID lpMapAddress;
 
hMapFile = OpenFileMapping(FILE_MAP_ALL_ACCESS, // Read/write permission.
    FALSE,                             // Do not inherit the name
    "MyFileMappingObject");            // of the mapping object.
 
if (hMapFile == NULL) {
    ErrorHandler("Could not open file-mapping object.");
}
 
lpMapAddress = MapViewOfFile(hMapFile, // Handle to mapping object.
    FILE_MAP_ALL_ACCESS,               // Read/write permission.

    0,                                 // Max. object size.
    0,                                 // Size of hFile.
    0);                                // Map entire file.
 
if (lpMapAddress == NULL) {
    ErrorHandler("Could not map view of file.");
}
 
After creating file mappings tasks do its work eventually change data pointed by lpMapAddress and rise Event to signaled state.

You frontend process periodically perform Event state check in loop. If Event rised than it need to read changed data from File Mapping and update visuals. You can use WaitForSingleObject, WaitForMultipleObject functions to detect Event state.
0
Free Backup Tool for VMware and Hyper-V

Restore full virtual machine or individual guest files from 19 common file systems directly from the backup file. Schedule VM backups with PowerShell scripts. Set desired time, lean back and let the script to notify you via email upon completion.  

 
abuly80Author Commented:
MikProg:

First of all, thank you for your detailed comment. However, I am still not clear on a number of things. I think I understand how the events work. They can only pass signals from one process to another, but not data. For data passing, you suggest that I use some sort of file reading/writing mechanism. That’s where I am still a bit confused.
 
1) How is mapped-file reading and writing performed? Is it done via regular ReadFile()/WriteFile() functions? In that case, the front-end process has the file handle (“hFile”), but the back-end process does not. How would back-end process read and write data? In other words, how do processes change data pointed to by “lpMapAddress” and read data from “lpMapAddress”?

2) What is the difference between using these File Mapping Functions and regular (maybe hidden) binary file reading/writing? The name of the shared binary file could be passed from the front-end to back-end process via the parameter list of CreateProcess(), could it not? The same event mechanism could then be used to signal reading and writing.

3) You referred to the File Mapping Functions mechanism as a “Shared memory” mechanism. Is there a way for the front-end process to pass pointer(s)/window handle(s) to the back-end process using some sort of shared memory block structure without using disk?

Thanks again.
0
 
abuly80Author Commented:
I think I have figured out all other things I was not clear on with respect to the File Mapping Functions. Thanks!
0
 
MikProgCommented:
Sorry about silence. It was a looong weekend. ;)
0

Featured Post

Free learning courses: Active Directory Deep Dive

Get a firm grasp on your IT environment when you learn Active Directory best practices with Veeam! Watch all, or choose any amount, of this three-part webinar series to improve your skills. From the basics to virtualization and backup, we got you covered.

  • 3
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now