Thread: CreateProcess going away indefinitely

  1. #1
    Registered User
    Join Date
    Dec 2003
    Posts
    5

    CreateProcess going away indefinitely

    Here's my cry for help:

    Within a DLL I am calling CreateProcess to run an exe which brings up a window which requires user interaction. My problem is that the first time this call is made the window will not appear until the user clicks on something else on the Desktop - the taskbar, another window, the start menu, etc. - only then will the window we're waiting on appear. The second time this is run the window comes up on its own.

    Another odditiy: If the .exe is run on its own without being called from within the DLL it comes up immediately, with no delay whether it is the first time running or the hundredth.

    Does anyone have a suggestion for fixing this behavior so that I can make the exe call from the DLL, having it run as if it were NOT being called from the DLL? I am working in various versions of Windows (98/ME/XP).

    Thanks in advance!!

  2. #2
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    Post the code which calls CreateProcess().

    gg

  3. #3
    Registered User
    Join Date
    Dec 2003
    Posts
    5

    Post Here's the code that calls CreateProcess:

    First LaunchScanner is called, then WaitForImage. If anything like a MessageBox call is stuck in after the CreateProcess, the scanner program comes up immediately - is there something else that I can call which will have the same effect, without displaying something like a MessageBox on the screen?

    Code:
    CString CFilterModuleDllApp::GetScannerProgram() {
    	CHAR windowsDirectory[MAX_LOADSTRING];
    	CHAR orexAppPath[MAX_LOADSTRING];
    	CHAR executable[MAX_LOADSTRING];
    
    	GetWindowsDirectory(windowsDirectory, MAX_LOADSTRING);
    	LoadString(m_hInstance, OREX_SCANPATH, orexAppPath, MAX_LOADSTRING);
    	strcpy(executable, windowsDirectory);
    	strcat(executable, "\\");
    	strcat(executable, orexAppPath);
    	return CString(executable);
    }
    
    int CFilterModuleDllApp::LaunchScanner() {
    	PROCESS_INFORMATION	scan_procinfo;
    	STARTUPINFO			scan_startup;
    
    	scan_startup.cb = sizeof(STARTUPINFO);
    	scan_startup.lpReserved = NULL;
    	scan_startup.lpDesktop = NULL;
    	scan_startup.lpTitle = NULL;
    	scan_startup.dwFlags = 0;
    	scan_startup.cbReserved2 = 0;
    	scan_startup.lpReserved2 = 0;
    
    	if (!CreateProcess(GetScannerProgram(), NULL, NULL, NULL, TRUE, REALTIME_PRIORITY_CLASS,
    		               NULL, NULL, &scan_startup, &scan_procinfo)) {
    		return -500;
    	}
    	return 0;
    }
    
    int CFilterModuleDllApp::WaitForImage(int *width, int *height, int *xPixelSize, int *yPixelSize) {
    	CHAR interfacename[MAX_LOADSTRING];
    	CHAR tempbuf[MAX_LOADSTRING];
    	CHAR compbuf[MAX_LOADSTRING];
    	CString pixelSizeLookup;
    	CString pixelSizeTranslation;
    	LoadString(m_hInstance, OREX_INI, interfacename, MAX_LOADSTRING);
    	LoadString(m_hInstance, OREX_CLOSE, tempbuf, MAX_LOADSTRING);
    	LoadString(m_hInstance, OREX_CLOSE, compbuf, MAX_LOADSTRING);
    	for(;!strcmp(tempbuf,compbuf);) {
    		if (GetPrivateProfileString("SCANNER STATUS", "Scanner Status", "",
    			                        tempbuf, MAX_LOADSTRING, interfacename) == 0) {
    			return -20;
    		}
    	}
    
    	LoadString(m_hInstance, OREX_OPEN, tempbuf, MAX_LOADSTRING);
    	LoadString(m_hInstance, OREX_OPEN, compbuf, MAX_LOADSTRING);
    	for(;!strcmp(tempbuf,compbuf);) {
    		if (GetPrivateProfileString("SCANNER STATUS", "Scanner Status", "",
    			                        tempbuf, MAX_LOADSTRING, interfacename) == 0) {
    			return -20;
    		}
    	}
    
    	LoadString(m_hInstance, OREX_CLOSE, compbuf, MAX_LOADSTRING);
    	if (!strcmp(compbuf,tempbuf)) {
    		return 0;
    	}
    
    	if (GetPrivateProfileString("SCANNER STATUS", "Image Width", "",
    		                        tempbuf, MAX_LOADSTRING, interfacename) == 0) {
    		return -21;
    	}
    	*width = atoi(tempbuf);
    
    	if (GetPrivateProfileString("SCANNER STATUS", "Image Height", "",
    		                        tempbuf, MAX_LOADSTRING, interfacename) == 0) {
    		return -22;
    	}
    	*height = atoi(tempbuf);
    
    	// look up the pixel size for the width, height
    	pixelSizeLookup.Format("%d,%d", *width, *height);
    	pixelSizeTranslation = GetProfileString("PixelSize", pixelSizeLookup);
    	
    	// extract the x and y pixel sizes from the results
    	int pos = pixelSizeTranslation.Find(",");
    	*xPixelSize = atoi(pixelSizeTranslation.Mid(0, pos));
    	*yPixelSize = atoi(pixelSizeTranslation.Mid(pos + 1));
    
    	return 1;
    }

  4. #4
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    Try this - I'll look at the rest later if this doesn't fix it.
    Code:
    PROCESS_INFORMATION scan_procinfo = {0};
    STARTUPINFO         scan_startup = {0};
    gg

  5. #5
    Registered User
    Join Date
    Dec 2003
    Posts
    5

    No joy

    I wish I could report that your suggestion fixed the problem, but it didn't seem to change anything. Thanks, though!

  6. #6
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    Try these suggestions individually:
    - use NORMAL_PRIORITY_CLASS to rule that out as being the cause (for whatever reason)
    - use GetScannerProgram() as the second parameter and make the first NULL (this is what I normally do).
    - don't inherit handles - set 5th parameter to FALSE

    If those don't work, try this:
    Code:
    STARTUPINFO si = {0};
    si.cb = sizeof(STARTUPINFO);
    si.dwFlags = STARTF_USESHOWWINDOW;
    si.wShowWindow = SW_SHOWNORMAL;
    Also, you have a handle leak.
    You are responsible for closing the handles in the PROCESS_INFORMATION strcuture:
    Code:
    CloseHandle(scan_procinfo.hProcess);
    CloseHandle(scan_procinfo.hThread);
    gg

  7. #7
    Registered User
    Join Date
    Dec 2003
    Posts
    5
    Well, LaunchScanner has the suggested changes in it - I tried all of the suggestions above, still no change in behavior. Is there no call that I can make that will yield to the O/S in a manner similar to MessageBox, but without the visuals?

    Code:
    int CFilterModuleDllApp::LaunchScanner() {
    	PROCESS_INFORMATION scan_procinfo = {0};
    	STARTUPINFO         scan_startup = {0};
    	CHAR		*executable;
    	CString		strexec;
    
    	scan_startup.cb = sizeof(STARTUPINFO);
    	scan_startup.lpReserved = NULL;
    	scan_startup.lpDesktop = NULL;
    	scan_startup.lpTitle = NULL;
    	scan_startup.dwFlags = 0;
    	scan_startup.cbReserved2 = 0;
    	scan_startup.lpReserved2 = 0;
    	strexec = GetScannerProgram();
    	int length = strexec.GetLength();
    	executable = strexec.GetBuffer(length);
    	STARTUPINFO si = {0};
    	si.cb = sizeof(STARTUPINFO);
    	si.dwFlags = STARTF_USESHOWWINDOW;
    	si.wShowWindow = SW_SHOWNORMAL;
    
    
    	if (!CreateProcess(NULL, executable, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS,
    		               NULL, NULL, &si, &scan_procinfo)) {
    		CloseHandle(scan_procinfo.hProcess);
    		CloseHandle(scan_procinfo.hThread);
    		return -500;
    	}
    
    	CloseHandle(scan_procinfo.hProcess);
    	CloseHandle(scan_procinfo.hThread);
    	return 0;
    }

  8. #8
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    Do you have the code for that application? If so, how does it create and show its main window?

    Do you get the same behavior when calling CreateProcess() from an exe instead of a DLL?

    What OS are you testing on? Same behavior on multiple OS's?

    You don't have to close handles if CreateProcess() fails.

    gg

  9. #9
    Yes, my avatar is stolen anonytmouse's Avatar
    Join Date
    Dec 2002
    Posts
    2,544
    I think I may have experienced the same problem a while back.

    When the parent program spawned the child process with CreateProcess it did not come to the foreground. Instead it stayed in the background until clicked on.

    It seems that Windows does not bring the new process to the foreground if the parent process does not pump its message loop or exit within a given time period.

    Wierdly enough, this rule does not seem to apply if the parent process was launched from the console, even though it is not a console program.

    The solution would seem to be to do what the call to MessageBox is doing. That is to pump the message loop straight after you spawn the process.

    Here is the stock standard DoEvents implementation:
    Code:
    void DoEvents(void) {
    
    	MSG Msg; 
    
    	while ( PeekMessage(&Msg,NULL,0,0,PM_REMOVE) ) {
    		TranslateMessage(&Msg); 
    		DispatchMessage(&Msg);
    	}
    }
    As a side note, you probably want to put a short Sleep() call in those loops.

  10. #10
    Registered User
    Join Date
    Dec 2003
    Posts
    5

    Cool Hooray! Happy New Year!

    That did the trick - thank you!!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. CreateProcess with arguments
    By Niara in forum Windows Programming
    Replies: 14
    Last Post: 09-08-2007, 05:41 AM
  2. CreateProcess with Resource of executable, not the Filename
    By Ktulu in forum Windows Programming
    Replies: 4
    Last Post: 11-04-2006, 01:07 AM
  3. question on CreateProcess() redirection
    By ac251404 in forum Windows Programming
    Replies: 13
    Last Post: 07-18-2006, 11:06 AM
  4. CreateProcess
    By Unregistered in forum Windows Programming
    Replies: 3
    Last Post: 05-12-2002, 06:45 AM
  5. CreateProcess()
    By Newfie in forum C++ Programming
    Replies: 2
    Last Post: 05-07-2002, 07:31 AM