Running your apps on a hidden desktop

Here’s a technique to run a GUI application in a hidden manner. It’s not a big deal really and is not meant for espionage or any such activity; rather it’s just an useful trick to know if you want to run a desktop game when you are at work and you don’t want your boss to see it. Basically we create a second desktop, switch to it, and run our apps on it.

bool RunAppInDesktop(
    const char* szDesktop, //A name for the new desktop
    const char* szAppPath, //Fully qualified path to your app
    bool bPrompt = false   //Set true to get a mock messagebox
);

If the bPrompt parameter is false, the new app is spawned on the new desktop and we switch back to the current desktop quickly; if you set it to true, the mock messagebox pops up and remains on screen preventing the new desktop from closing. Play your games or watch you videos or whatever and when your boss comes near you, close the messagebox to go back to the default desktop. When he/she leaves, switch back again and your apps will be still running there just as you had left them – like obedient little puppies 🙂

When you are done, close all the apps and then dismiss the messagebox; the second desktop will now be closed and destroyed.

Here is the full code listing :-

bool RunAppInDesktop(const char* szDesktop,
  const char* szAppPath, bool bPrompt = false);

//... your code goes here

bool RunAppInDesktop(const char* szDesktop,
           const char* szAppPath,
           bool bPrompt /*= false*/)
{
  bool ret = true;
  HDESK horig = GetThreadDesktop(GetCurrentThreadId());
  HDESK hdesk = CreateDesktop(szDesktop,NULL,NULL,
    0,GENERIC_ALL,NULL);
  if(hdesk)
  {
    if(SetThreadDesktop(hdesk))
    {
      SwitchDesktop(hdesk);
      PROCESS_INFORMATION ProcessInfo;
      STARTUPINFO StartupInfo;
      ZeroMemory(&StartupInfo, sizeof(StartupInfo));
      StartupInfo.cb = sizeof StartupInfo ;
      char tmp[1024];
      strcpy(tmp,szDesktop);
      StartupInfo.lpDesktop = tmp;
      if(CreateProcess(szAppPath, NULL,
        NULL,NULL,FALSE,0,NULL,
        NULL,&StartupInfo,&ProcessInfo))
      {
        CloseHandle(ProcessInfo.hThread);
        CloseHandle(ProcessInfo.hProcess);
      }
      else
        ret = false;
      if(bPrompt)
        MessageBox(NULL,"Close all your apps now",
          "Prompt",MB_OK);
      else
        Sleep(300);
      SwitchDesktop(horig);
      SetThreadDesktop(horig);
    }
    else
      ret = false;
  }
  else
    ret = false;
  CloseDesktop(hdesk);
  return ret;
}

12 thoughts on “Running your apps on a hidden desktop

  1. Nish …. a screen shot with the “hidden” desktop and also one with the mock messagebox so that we could see the code in action. That would be great!

  2. Come on, char tmp[1024];

    Why do you have to assume it is 1024. Isn’t there enough Windows Security threats already by this kind of assumption?

  3. I am trying to create the desktop using this listing, but I found SetThreadDesktop function isn’t succeeding. So what could be the reason? Also please tell me first, which kind of application I need to create from wizard in order to run this code. Win32 or MFC or else?

  4. I need help about the code so that I can Get all the IP addresses of the Subnet
    weather it is Client server network or Peer to Peer Network
    suggest me the name and listing of APIs.
    Thanks
    Atul Jindal

  5. Sorry, I have the same question lik Gaurang . I have tried two ways in win32 console and MFC dialog based respectively, but there always something wrong with it. In win32 console , there are some errors like below,

    in32_Mock.obj : error LNK2001: unresolved external symbol __imp__CloseDesktop@4
    win32_Mock.obj : error LNK2001: unresolved external symbol __imp__MessageBoxA@16
    win32_Mock.obj : error LNK2001: unresolved external symbol __imp__SwitchDesktop@4
    win32_Mock.obj : error LNK2001: unresolved external symbol __imp__SetThreadDesktop@4
    win32_Mock.obj : error LNK2001: unresolved external symbol __imp__CreateDesktopA@24
    win32_Mock.obj : error LNK2001: unresolved external symbol __imp__GetThreadDesktop@4
    Debug/win32_Mock.exe : fatal error LNK1120: 6 unresolved externals
    Error executing link.exe.

    win32_Mock.exe – 7 error(s), 0 warning(s)

    And in MFC dialog based, SetThreadDesktop function always return false. Please help me, Thank you indeed!

  6. I simply couldn’t depart your website before suggesting that I extremely enjoyed the usual info a person supply for your guests? Is going to be back steadily in order to check out new posts.

Leave a comment