0

I am very new to c++ and am trying to create an application that will switch desktops. I have so far been able to switch desktops successfully and attempt to launch an application on that desktop. I unfortunately keep running into an access violation when the application launches on my newly created desktop. My question is: What could be causing this access violation? From what I have read it is an issue where the program is attempting to access memory that it should not. The error is:

"The application was unable to start correctly (0xC0000005). Click OK to close the application"

Also, can anyone please make a suggestion as to how I could possibly improve this code? It would help me to learn a bit from experienced programmers. Thank you in advance!

EDIT: I am running Windows 7 x64 using Visual Studio Express 2010

Here is the code:

#include <Windows.h>

//Globals
HDESK hLastDesktop;

struct tDesktop {
    HDESK Desktop1;
    HDESK Desktop2;
    HDESK Desktop3;
    HDESK Desktop4;
};

HDESK FindCurrentDesktop()
{
    return GetThreadDesktop(GetCurrentThreadId());
}

int ChangeDesktop(HDESK hDesktopName)
{
    //Save the handle to this desktop
    hLastDesktop = FindCurrentDesktop();
    //Set the main thread to this desktop
    SetThreadDesktop(hDesktopName);
    //Switch
    SwitchDesktop(hDesktopName);

    return 0;
}

PROCESS_INFORMATION CreateProcessDesktop(LPWSTR lpProcessPath, LPWSTR lpDesktop)
{
    PROCESS_INFORMATION processInfo;
    STARTUPINFO startupInfo;
    startupInfo.cb = sizeof(startupInfo);
    startupInfo.lpDesktop = lpDesktop;

    CreateProcess(lpProcessPath,
                0, 
                0, 
                0,
                FALSE,
                0, 
                0,
                0,
                &startupInfo,
                &processInfo
            );

    return processInfo;
}

int _tmain(int argc, _TCHAR* argv[])
{
    //Create an instance to use the struct
    tDesktop myDesktop;

    //Assign data for home desktop
    myDesktop.Desktop1 = FindCurrentDesktop();
    printf("Home desktop: %d\n", myDesktop.Desktop1);

    myDesktop.Desktop2 = CreateDesktop(L"Desktop2", NULL, NULL, 0, GENERIC_ALL, NULL);
    printf("Desktop 2 opened: %d\n", myDesktop.Desktop2);

    printf("Changing to desktop 2: %d\n", myDesktop.Desktop2);
    ChangeDesktop(myDesktop.Desktop2);

    //Set up process to start in Desktop2 (for PID, etc later)
    PROCESS_INFORMATION pi;
    pi = CreateProcessDesktop(L"C:\\Windows\\explorer.exe", L"Desktop2");
    Sleep(5000);

    TerminateProcess(pi.hProcess, 0);

    ChangeDesktop(hLastDesktop);

    return 0;
}
  • run it in debuggger. and find your where its crashing – Neel Basu Jun 09 '13 at 16:26
  • I am very new to using c++ and programming in general. Usually, I can do more when I can see the window for my Visual Studio application. However, since my program switches desktops, I am unable to see the windows or interact with them on the previous desktop (where my debugger is). – user2468637 Jun 09 '13 at 16:29
  • You should be checking function calls for failure. Each article on each function describes what it does when it fails. – chris Jun 09 '13 at 16:34
  • The odd thing is that the function calls are not failing. I omitted my debug info for clarity in this post, I should have mentioned that. I am receiving a valid handle to the process in the new desktop, it just gets as access violation and closes. – user2468637 Jun 09 '13 at 16:48
  • I found the answer but cannot post the answer to my own question so soon since I am so new to StackOverflow. I will post a complete solution once I can answer it. All I had to do was change bInheritHandles to TRUE in the CreateProcess function and it worked like a charm. – user2468637 Jun 09 '13 at 16:53

1 Answers1

0

So here is the answer:

I had mentioned in a comment that I called CreateProcess with bInheritHandles as FALSE and that was the issue, that was incorrect. It had to do with SetThreadDesktop. CreateProcess was succeeding, it was just not populating on the correct desktop.

I had to look at the SetThreadDesktop function a little better. It was not failing, but the way that I was calling it was incorrect. You should always call it after switching desktops, then get the current desktop handle to pass as the parameter. Here is the corrected section of code:

int ChangeDesktop(HDESK hDesktopName)
{

    hLastDesktop = FindCurrentDesktop();  
    SwitchDesktop(hDesktopName);
    SetThreadDesktop(FindCurrentDesktop());

    return 0;
}