public unsafe int DebugLaunch(uint grfLaunch)
        {
            try
            {
                if (!this.m_project.CanLaunch)
                {
                    Utility.ShowMessageBox("The project must have either an output type of 'Console Application', or an output type of 'Class Library' and the start action set to a valid .NET MicroFramework application");
                    return(Utility.COM_HResults.E_FAIL);
                }

                //Consider Launching ourselves (at least for device), and then calling Attach.
                //This would get rid of the ugly dummy thread hack in CorDebugProcess.
                //However, we would need to jump through some other hoops, like resuming the process,
                //perhaps setting up the entry point breakpoint ourselves, ..?

                VsDebugTargetInfo2 vsDebugTargetInfo = new VsDebugTargetInfo2();
                DebugPort          port         = GetDebugPort();
                Process            processWin32 = null;
                bool fNoDebug = (__VSDBGLAUNCHFLAGS.DBGLAUNCH_NoDebug & (__VSDBGLAUNCHFLAGS)grfLaunch) != 0;
                int  hRes     = Utility.COM_HResults.S_OK;
                PlatformInfo.Emulator emulatorConfig = GetEmulatorConfig();

                if (port == null)
                {
                    throw new Exception("Cannot find port to deploy to");
                }

                string commandLine = GetCommandLineForLaunch(fNoDebug, emulatorConfig, IsTargetBigEndian());
                string exe         = port.IsLocalPort ? emulatorConfig.application : typeof(CorDebugProcess).Assembly.Location;

                if (!fNoDebug)
                {
                    commandLine = string.Format("{0} \"{1}{2}\"", commandLine, CorDebugProcess.c_DeployDeviceName, this.DeployDeviceName);
                }

                //use emulator args even though this may be a device launch.  This is needed to store
                //paths to assemblies.
                vsDebugTargetInfo.bstrArg           = commandLine;
                vsDebugTargetInfo.bstrCurDir        = (string)m_project.GetProperty(VSConstants.VSITEMID_ROOT, (int)__VSHPROPID.VSHPROPID_ProjectDir);
                vsDebugTargetInfo.bstrEnv           = null;
                vsDebugTargetInfo.bstrExe           = exe;
                vsDebugTargetInfo.bstrOptions       = null;
                vsDebugTargetInfo.bstrPortName      = DeployTransportName;
                vsDebugTargetInfo.bstrRemoteMachine = null;
                vsDebugTargetInfo.cbSize            = (uint)Marshal.SizeOf(vsDebugTargetInfo);
                vsDebugTargetInfo.dlo = (uint)DEBUG_LAUNCH_OPERATION.DLO_CreateProcess;
                vsDebugTargetInfo.dwDebugEngineCount    = 0;
                vsDebugTargetInfo.dwProcessId           = 0;
                vsDebugTargetInfo.dwReserved            = 0;
                vsDebugTargetInfo.fSendToOutputWindow   = 0;
                vsDebugTargetInfo.guidLaunchDebugEngine = CorDebug.s_guidDebugEngine;
                vsDebugTargetInfo.guidPortSupplier      = DebugPortSupplier.s_guidPortSupplier;
                vsDebugTargetInfo.guidProcessLanguage   = Guid.Empty;
                vsDebugTargetInfo.hStdError             = 0;
                vsDebugTargetInfo.hStdInput             = 0;
                vsDebugTargetInfo.hStdOutput            = 0;
                vsDebugTargetInfo.LaunchFlags           = grfLaunch;
                vsDebugTargetInfo.pDebugEngines         = IntPtr.Zero;
                vsDebugTargetInfo.pUnknown = null;

                if (fNoDebug)
                {
                    if (port.IsLocalPort)
                    {
                        processWin32 = new Process();

                        processWin32.StartInfo                  = new ProcessStartInfo();
                        processWin32.StartInfo.FileName         = vsDebugTargetInfo.bstrExe;
                        processWin32.StartInfo.Arguments        = vsDebugTargetInfo.bstrArg;
                        processWin32.StartInfo.WorkingDirectory = vsDebugTargetInfo.bstrCurDir;
                        processWin32.StartInfo.UseShellExecute  = false;
                        processWin32.Start();
                    }
                    else
                    {
                        RebootAndResumeExecution();
                    }
                }
                else
                {
                    byte * bpDebugTargetInfo = stackalloc byte[(int)vsDebugTargetInfo.cbSize];
                    IntPtr ipDebugTargetInfo = (IntPtr)bpDebugTargetInfo;
                    try
                    {
                        IVsDebugger2 iVsDebugger = ( IVsDebugger2 )ServiceProvider.GlobalProvider.GetService(typeof(IVsDebugger));
                        Marshal.StructureToPtr(vsDebugTargetInfo, ipDebugTargetInfo, false);
                        hRes = iVsDebugger.LaunchDebugTargets2(1, ipDebugTargetInfo);
                    }
                    finally
                    {
                        if (ipDebugTargetInfo != null)
                        {
                            Marshal.DestroyStructure(ipDebugTargetInfo, vsDebugTargetInfo.GetType());
                        }
                    }
                }

                return(hRes);
            }
            catch (Exception ex)
            {
                Utility.ShowMessageBox(String.Format("An exception occurred while attempting to launch the debugger: {0}", ex.Message));
                return(Utility.COM_HResults.E_FAIL);
            }
        }