Solved

C++ console app - window on top

Posted on 2011-03-23
18
612 Views
Last Modified: 2012-05-11
I have a C++ console app in VS2005 and from within the app, I make a call to run a standalone executable, and I really want this app to run in the background or minimized and not take focus away from my console app.  I have tried a bunch of different methods (See code below) to accomplish what I needed, but it seems to be a no-go.  The standalone executable seems to take focus away from my console app, or not starting minimized.  

Any help would be greatly appreciated.

Method 1:

system("C:\\StartEasySuite.bat");
Batch file contains: start /min c:\test\EasySuite.exe

Method 2:
WinExec("C:\\test\\EasySuite.exe",SW_FORCEMINIMIZE);

Method 3:

STARTUPINFO         siStartupInfo;
PROCESS_INFORMATION piProcessInfo;

memset(&siStartupInfo, 0, sizeof(siStartupInfo));
memset(&piProcessInfo, 0, sizeof(piProcessInfo));
siStartupInfo.cb = sizeof(siStartupInfo);
		
BOOL bSuccess;


bSuccess = CreateProcess(TEXT("C:\\Test\\EasySuite.exe"),    
                     0,						 
                     0,
                     0,
                     FALSE,
                     NORMAL_PRIORITY_CLASS | CREATE_NO_WINDOW ,
                     0,
                     0,                              
                     &siStartupInfo,
                     &piProcessInfo) ; 

Open in new window

0
Comment
Question by:arunykand
  • 9
  • 8
18 Comments
 
LVL 86

Expert Comment

by:jkr
ID: 35200498
You're on the right track - make that
siStartupInfo.cb           =   sizeof(STARTUPINFO);
	siStartupInfo.dwFlags      =   STARTF_USESHOWWINDOW;
	siStartupInfo.wShowWindow  =   SW_HIDE;

Open in new window


Or use this shrink-wrapped function that does that for you and waits until the called app finishes:
DWORD ExecuteAndWaitForCompletion   (   LPSTR   pszCmd, BOOL bShow)
{
	STARTUPINFO         si;
	PROCESS_INFORMATION pi;

	BOOL                bRes;

	DWORD               dwCode  =   0;

	MSG				   msg;

	ZeroMemory  (   &si,    sizeof  (   STARTUPINFO));

	si.cb           =   sizeof  (   STARTUPINFO);
	si.dwFlags      =   STARTF_USESHOWWINDOW;
	si.wShowWindow  =   bShow ? SW_SHOWNORMAL : SW_HIDE;

	bRes    =   CreateProcess   (   NULL,
								   pszCmd,
								   NULL,
								   NULL,
								   TRUE,
								   NORMAL_PRIORITY_CLASS,
								   NULL,
								   NULL,
								   &si,
								   &pi
							   );

	while   (   WAIT_OBJECT_0   !=  MsgWaitForMultipleObjects   (   1,
																   &pi.hProcess,
																   FALSE,
																   INFINITE,
																   QS_ALLINPUT
															   )
		   )
		   {
			   while   (   PeekMessage (   &msg,   NULL,   0,  0,  PM_REMOVE))
					   {
						   DispatchMessage     (   &msg);
					   }
		   }

	GetExitCodeProcess  (   pi.hProcess,    &dwCode);

	CloseHandle (   pi.hProcess);
	CloseHandle (   pi.hThread);

	return  (   dwCode);
}

Open in new window

0
 
LVL 86

Expert Comment

by:jkr
ID: 35200516
As a side note, 'SW_HIDE' is the key here. Oh, BTW, other alternatives would be
WinExec("C:\\test\\EasySuite.exe",SW_HIDE);

ShellExecute(NULL,"open","C:\\test\\EasySuite.exe",NULL,NULL,SW_HIDE);

Open in new window

0
 

Author Comment

by:arunykand
ID: 35201082
JKR....I'm still playing around with your suggestions..I cannot get any of them to work as expected, my window loses focus and the other software is shown, even when SW_HIDE is implemented.

FYI...my app is a full-screen console app (not GUI) that was created in c++ using 'CreateWindow', I didn't write this code, but in-herited.

g_hWnd = CreateWindow(WINDOW_CLASS_NAME, 0,
                         WS_VISIBLE |WS_POPUP | CS_DBLCLKS ,
                         CW_USEDEFAULT, CW_USEDEFAULT,
                         DEFAULT_VIDEO_WIDTH, DEFAULT_VIDEO_HEIGHT,
                         0, 0, g_hInstance, 0);

Open in new window

0
 
LVL 86

Expert Comment

by:jkr
ID: 35201108
That is more than weird. Can you double-check that with e.g. 'notepad.exe'?
0
 

Author Comment

by:arunykand
ID: 35201743
Hmm, I tried notepad, and works as intended.....

This software i'm trying to invoke from my app is called "EasySuite" from Targus.  It comes pre-loaded on their USB File Share cable http://http://www.staples.com/Targus-Data-SYNC-Cable/product_857875?cmArea=SC3:CG58:DP1426:CL164417  and it is supposed to 'Autorun' when inserted, but since auto-run was disabled on the PC due to security reasons, I thought I would invoke it, and have it minimized.  

Any ideas?
0
 
LVL 86

Expert Comment

by:jkr
ID: 35202929
Well, if an application choses not to obey the 'int nCmdShow' parameter passed in to 'WinMain()', there's hardly anything you can do other to complain that the program does not behave the way the Windows style guides require it. Another option would be (albeit the last resort) to start it on an invisible desktop...
0
 
LVL 86

Expert Comment

by:jkr
ID: 35202944
Ooops, another idea - try to set 'dwX' and/or 'dwY' in STARTUPINFO to positions outside your visible screen area and use 'STARTF_USEPOSITION' in 'dwFlags' - that could also work.
0
 

Author Comment

by:arunykand
ID: 35202966
Hmm...Ok i'm not sure how to proceed...My issue is, when this pc boots, it does an auto-login and starts up my software (full-screen, command window program), I've replaced the explorer shell with my software, so even if the user tries to exit, there will be no desktop, they just have to do a log-off or shutdown via ctrl-alt-del.  So to get back to my point, when my software is running in full screen mode, one of the options is to have this "EasySuite" software invoked, and run in the background, but as you can see, I haven't had much luck today!

0
 

Author Comment

by:arunykand
ID: 35202986
I just saw your comments about screen position, but I think the issue will be, I will still lose focus away from my app, but now I just won't be able to see the "EasySuite" software, still back to the same issue as before....
0
Top 6 Sources for Identifying Threat Actor TTPs

Understanding your enemy is essential. These six sources will help you identify the most popular threat actor tactics, techniques, and procedures (TTPs).

 
LVL 86

Expert Comment

by:jkr
ID: 35202989
>>I haven't had much luck today!

Don't say that, the 'invisible desktop' way will certainly work, but I'd certainly try the other way outlined in my last comment first ;o)
0
 

Author Comment

by:arunykand
ID: 35203000
Is it somehow possible to run the EasySuite software as a service....I'm out of ideas, just throwing it out there...
0
 
LVL 86

Accepted Solution

by:
jkr earned 500 total points
ID: 35203026
Well, then...
HWINSTA hWinStat = CreateWindowStation(_T("WinStatABC"), 0, 
      WINSTA_CREATEDESKTOP | WINSTA_ENUMDESKTOPS | WINSTA_ENUMERATE,
      NULL);

   HDESK hDesk = CreateDesktop(
         _T("WinStatABC\\DeskABC"), NULL, NULL, 0,
         DESKTOP_ENUMERATE | DESKTOP_CREATEWINDOW, NULL);

   siStartupInfo.cb           =   sizeof(STARTUPINFO);
   siStartupInfo.lpDesktop    =   _T("WinStatABC\\DeskABC");
   siStartupInfo.dwFlags      =   STARTF_USESHOWWINDOW;
   siStartupInfo.wShowWindow  =   SW_HIDE;

Open in new window

0
 

Author Comment

by:arunykand
ID: 35203198
So going back to the position comment you made, 0 0 is top left right?  What do I need to put in to take it out of my screen?  

Jkr, I appreciate the help
0
 
LVL 86

Expert Comment

by:jkr
ID: 35203225
Yes, that's right - yet I assume the 'focus' issue would remain. I'd try something ridiculpusly high for testing purposes, e.g. ix you have 1600x1200, try to set

siStartupInfo.dwX = 3200;
siStartupInfo.dwY = 0;
0
 

Author Comment

by:arunykand
ID: 35203249
I will give that a shot first thing in the morning.  Fyi....I went out and bought a different brand of usb databtransfer cable with built in software and unfortunately the software is the same used by targus
0
 
LVL 8

Expert Comment

by:lomo74
ID: 35207054
>> FYI...my app is a full-screen console app (not GUI) that was created in c++ using 'CreateWindow', I didn't write this code, but in-herited.
I'm a bit confused. CreateWindow is called for GUI apps, not for console apps.
Do you mean your app looks like a terminal? (just like putty or the like)

Besides this, what about this idea:

1) launch child process
2) wait the creation of the main window
3) once created, hide the main window
4) maybe get focus back calling SetForegroundWindow

have a look at example - I used notepad just to test.
be careful: after execution you'll have a wandering hidden notepad window... :-)

#include <windows.h>
#include <tchar.h>
#include <string.h>
#include <stdio.h>

BOOL CALLBACK MyEnumProc(HWND hWnd, LPARAM param)
{
	TCHAR buf[256];

	//is this the window we're looking for?
	if (GetClassName(hWnd, buf, 256) &&
		_tcsicmp(buf, TEXT("Notepad")) == 0)
	{
		//yes: store handle and stop searching
		*((HWND*)param) = hWnd;
		return FALSE;
	}
	else
		return TRUE; //go on searching
}

HWND WaitNotepadWindow()
{
	HWND ret = NULL;

	for (int i = 0; i < 100; i++)
	{
		//enum windows
		EnumWindows(MyEnumProc, (LPARAM)&ret);

		//found our main window?
		if (ret != NULL)
			break;

		//have a small rest, the retry
		Sleep(50);
	}

	return ret;
}

int main(int argc, char** argv)
{
	STARTUPINFO si;
	PROCESS_INFORMATION pi;

	ZeroMemory(&si, sizeof(si));
	ZeroMemory(&pi, sizeof(pi));

	si.cb = sizeof(si);
		
	BOOL bSuccess;

	if ((bSuccess = CreateProcess(TEXT("C:\\WINDOWS\\System32\\Notepad.exe"),
		0, 0, 0, FALSE, NORMAL_PRIORITY_CLASS, 0, 0, &si, &pi)) == TRUE)
	{
		//detach from process
		CloseHandle(pi.hProcess);
		CloseHandle(pi.hThread);
		
		HWND hWindow;

		//wait for main window to come up
		if ((hWindow = WaitNotepadWindow()) != NULL)
			ShowWindow(hWindow, SW_HIDE); //then hide it
		
		//if we were a GUI app, we could make this
		//call to get back focus
		//SetForegroundWindow(g_hWnd);
	}
}

Open in new window

0
 

Author Closing Comment

by:arunykand
ID: 35207636
JKR...got it working, you're the man!
0
 
LVL 86

Expert Comment

by:jkr
ID: 35208625
Thanks ;o)

BTW, don't forget to 'CloseWindowStation()' and 'CloseDesktop()' when you're done.
0

Featured Post

Free Trending Threat Insights Every Day

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

Join & Write a Comment

Ok I have been working on this for some time having learned and gained certification in XenDesktop 4 along came version 5 which was released last month. Since then I have been working to deploy XenDesktop 5 in a small environment with only 2 virt…
Step by step guide to Clean and Sort your windows registry! Introduction: Always remember: A Clean registry = Better performance = Save your invaluable time In this article we're going to clear our registry manually! Yes, manually! The e…
The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.

706 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

18 Experts available now in Live!

Get 1:1 Help Now