1

Is there a way to programmatically switch from the start menu to desktop. For example if you had a service thats runs once the user logs in and you wanted that service to switch to the desktop view once the user logs in? I can't seem to find a way around it. I tried virtual key press of the windows key but that didnt work?

ChrisF
  • 134,786
  • 31
  • 255
  • 325
  • 1
    "... wanted that service to switch to the desktop view once the user logs in" Are you asking how a service application can minimise all windows when a user logs in? – parrowdice Dec 06 '12 at 10:08
  • Well i was using that as an example. But if the start menu is shown and some event is triggered that calls let's say a function switch2desktop() from the user clicking on something, i'm wondering is there code that can be placed in the switch2desktop() function to switch to desktop. I can't find any – user1881918 Dec 06 '12 at 10:15
  • see the edit in my answer that replies to your comment above. – parrowdice Dec 06 '12 at 10:44
  • Restated "Is there a programmatic way to close Metro?" – Jerry Nixon Dec 06 '12 at 16:57

1 Answers1

1

I'm not really sure exactly what the problem you're facing is is. "programmatically switch from the start menu to desktop" can be interpreted a few different ways.

However, since you said "you wanted that service to switch to the desktop" "I tried virtual key press of the windows key", I assume you are trying to communicate with windows on the desktop from a service, which cannot be done. This is by design as a security feature. If you open task manager and do view -> select columns -> session ID, you will notice that the service runs in session 0, while 'desktop' applications run in the session of the logged on user. Applications cannot communicate via Windows messages between sessions.

There is a workaround, although more effort required than simply sending a virtual key press. The workaround is to have your service create a process in the user's session which then performs your tasks for you (your virtual key press method would work in this application, for example).

The API calls you will need to use to do this are:

CreateProcessAsUser

WTSGetActiveConsoleSessionId

WTSQueryUserToken

DuplicateTokenEx

EDIT

If you want to control the start menu, there is no easy method for that either. If you must do it, I suggest you use a tool called Spy++ (comes with visual studio - see Microsoft Visual Studio x.x\Common7\Tools, or can be downloaded). Use the Find Window feature to view the messages sent to the Windows Start button when you press it, and then you can see what messages you want to send to the button to control it in the way that you need to.

For example, you may see a WM_LBUTTONDOWN message sent to the start button. that toggles the start menu. You can then use FindWindow, perhaps with GetDesktopWindow to get a handle to the start button, and then send the messages you want to control it with SendMessage. You may also want to check if the start menu is shown by using the same procedure to get a handle to the start menu and using IsWindowVisible.

parrowdice
  • 1,902
  • 15
  • 24
  • I didn't know why the virtual keypress wasnt working. Is there a way to send virtual keypress in command line parameter of CreateProcessAsUser do you know? – user1881918 Dec 06 '12 at 11:05
  • [CreateProcessAsUser](http://msdn.microsoft.com/en-us/library/windows/desktop/ms682429%28v=vs.85%29.aspx) runs a specified .exe in the context of a user account. If you create an application that takes a command line parameter and uses that to send a virtual key press, then you can pass your application a command line parameter in the call to `CreateProcessAsUser`. – parrowdice Dec 06 '12 at 11:49
  • Could i create a function that has the virtual keypress commands. Call that function by assigning a thread to a CreateProcessAsUser process that doesnt launch any exe, then call CreateProcessAsUser agai to launch my original application? – user1881918 Dec 06 '12 at 11:57
  • Here's how I see it. You have a service running which wants to do 'something' with the start menu. The service should call `CreateProcessAsUser` which will launch an application which contains your 'function that has the virtual keypress commands' so it can be executed. I would avoid injecting threads - it seems needless in this instance, and will fail if mixing 32/64 bit. If you were thinking about only using one application instead of two, you can use your service in the call to `CreateProcessAsUser`, just give it a command line parameter that tells it to execute your keypress function. – parrowdice Dec 06 '12 at 12:28