示例#1
0
        /*
         * @see Flash.Tools.Debugger.SessionManager#launch(java.lang.String, Flash.Tools.Debugger.AIRLaunchInfo, boolean, Flash.Tools.Debugger.IProgress)
         */
        public override Session launch(String uri, AIRLaunchInfo airLaunchInfo, bool forDebugging, IProgress waitReporter)
        {
            bool       modify       = (getPreference(SessionManager.PREF_URI_MODIFICATION) != 0);
            LaunchInfo launchInfo   = new LaunchInfo(this, uri);
            bool       nativeLaunch = launchInfo.WebBrowserNativeLaunch() || launchInfo.PlayerNativeLaunch();

            // one of these is assigned to launchAction
            const int NO_ACTION       = 0; // no special action
            const int SHOULD_LISTEN   = 1; // create a ProcessListener
            const int WAIT_FOR_LAUNCH = 2; // block until process completes

            int launchAction;              // either NO_ACTION, SHOULD_LISTEN, or WAIT_FOR_LAUNCH

            uri = uri.Trim();

            // bool isMacOSX = false;
            bool isWindows = false;

            // if isMacOSX and isWindows are both false, then it's *NIX
            if (Environment.OSVersion.Platform == PlatformID.MacOSX)
            {
                // isMacOSX = true;
            }
            else if (Environment.OSVersion.Platform != PlatformID.Unix)
            {
                isWindows = true;
            }

            if (airLaunchInfo == null)
            {
                // first let's see if it's an HTTP URL or not
                if (launchInfo.HttpOrAbout)
                {
                    if (modify && forDebugging && !uri.StartsWith("about:"))
                    //$NON-NLS-1$
                    {
                        // escape spaces if we have any
                        uri = URLHelper.escapeSpace(uri);

                        // be sure that ?debug=true is included in query string
                        URLHelper urlHelper = new URLHelper(uri);
                        System.Collections.IDictionary parameters = urlHelper.getParameterMap();
                        parameters["debug"] = "true";                         //$NON-NLS-1$ //$NON-NLS-2$
                        urlHelper.setParameterMap(parameters);

                        uri = urlHelper.URL;
                    }
                }
                else
                {
                    // ok, its not an http: type request therefore we should be able to see
                    // it on the file system, right?  If not then it's probably not valid
                    FileInfo f = null;
                    if (uri.StartsWith("file:"))                     //$NON-NLS-1$
                    {
                        f = new FileInfo(new Uri(uri).LocalPath);
                    }
                    else
                    {
                        f = new FileInfo(uri);
                    }

                    if (f != null && f.Exists)
                    {
                        uri = f.FullName;
                    }
                    else
                    {
                        throw new FileNotFoundException(uri);
                    }
                }

                if (nativeLaunch)
                {
                    // We used to have
                    //
                    //		launchAction = SHOULD_LISTEN;
                    //
                    // However, it turns out that when you launch Firefox, if there
                    // is another instance of Firefox already running, then the
                    // new instance just passes a message to the old one and then
                    // immediately exits.  So, it doesn't work to abort when our
                    // child process dies.
                    launchAction = NO_ACTION;
                }
                else
                {
                    launchAction = NO_ACTION;
                }

                /*
                 * Various ways to launch this stupid thing.  If we have the exe
                 * values for the player, then we can launch it directly, monitor
                 * it and kill it when we die; otherwise we launch it through
                 * a command shell (cmd.exe, open, or bash) and our Process object
                 * dies right away since it spawned another process to run the
                 * Player within.
                 */
#if false
                if (isMacOSX)
                {
                    if (launchInfo.WebBrowserNativeLaunch)
                    {
                        FileInfo httpExe = m_debuggerCallbacks.getHttpExe();
                        m_launchCommand = new String[] { "/usr/bin/open", "-a", httpExe.ToString(), uri };                      //$NON-NLS-1$ //$NON-NLS-2$
                    }
                    else if (launchInfo.PlayerNativeLaunch)
                    {
                        FileInfo playerExe = m_debuggerCallbacks.getPlayerExe();
                        m_launchCommand = new String[] { "/usr/bin/open", "-a", playerExe.ToString(), uri };                      //$NON-NLS-1$ //$NON-NLS-2$
                    }
                    else
                    {
                        m_launchCommand = new String[] { "/usr/bin/open", uri };                      //$NON-NLS-1$
                    }
                }
                else
#endif
                {
                    if (launchInfo.WebBrowserNativeLaunch())
                    {
                        FileInfo httpExe = m_debuggerCallbacks.getHttpExe();
                        m_launchCommand = new String[] { httpExe.ToString(), uri };
                    }
                    else if (launchInfo.PlayerNativeLaunch())
                    {
                        FileInfo playerExe = m_debuggerCallbacks.getPlayerExe();
                        m_launchCommand = new String[] { playerExe.ToString(), uri };
                    }
                    else
                    {
                        if (isWindows)
                        {
                            // We must quote all ampersands in the URL; if we don't, then
                            // cmd.exe will interpret the ampersand as a command separator.
                            uri = uri.Replace("&", "\"&\"");                              //$NON-NLS-1$ //$NON-NLS-2$

                            m_launchCommand = new String[] { "cmd", "/c", "start", uri }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
                        }
                        else
                        {
                            String exeName;
                            if (launchInfo.WebPage)
                            {
                                exeName = m_debuggerCallbacks.HttpExeName;
                            }
                            else
                            {
                                exeName = m_debuggerCallbacks.PlayerExeName;
                            }
                            throw new FileNotFoundException(exeName);
                        }
                    }
                }
            }
            // else, AIR
            else
            {
                if (forDebugging)
                {
                    launchAction = SHOULD_LISTEN;
                }
                // wait inside accept() until ADL exits
                else
                {
                    launchAction = NO_ACTION;                     // just launch it
                }
                LinkedList <String> cmdList = new LinkedList <String>();

                cmdList.AddLast(airLaunchInfo.airDebugLauncher.FullName);

                if (airLaunchInfo.airRuntimeDir != null && airLaunchInfo.airRuntimeDir.Length > 0)
                {
                    cmdList.AddLast("-runtime"); //$NON-NLS-1$
                    cmdList.AddLast(airLaunchInfo.airRuntimeDir.FullName);
                }

                if (airLaunchInfo.airSecurityPolicy != null && airLaunchInfo.airSecurityPolicy.Length > 0)
                {
                    cmdList.AddLast("-security-policy"); //$NON-NLS-1$
                    cmdList.AddLast(airLaunchInfo.airSecurityPolicy.FullName);
                }

                if (airLaunchInfo.airPublisherID != null && airLaunchInfo.airPublisherID.Length > 0)
                {
                    cmdList.AddLast("-pubid"); //$NON-NLS-1$
                    cmdList.AddLast(airLaunchInfo.airPublisherID);
                }

                // If it's a "file:" URL, then pass the actual filename; otherwise, use the URL
                // ok, its not an http: type request therefore we should be able to see
                // it on the file system, right?  If not then it's probably not valid
                FileInfo f = null;
                if (uri.StartsWith("file:"))
                //$NON-NLS-1$
                {
                    f = new FileInfo(new Uri(uri).LocalPath);
                    cmdList.AddLast(f.FullName);
                }
                else
                {
                    cmdList.AddLast(uri);
                }

                if (airLaunchInfo.applicationContentRootDir != null)
                {
                    cmdList.AddLast(airLaunchInfo.applicationContentRootDir.FullName);
                }

                if (airLaunchInfo.applicationArguments != null && airLaunchInfo.applicationArguments.Length > 0)
                {
                    cmdList.AddLast("--"); //$NON-NLS-1$

                    foreach (String arg in splitArgs(airLaunchInfo.applicationArguments))
                    {
                        cmdList.AddLast(arg);
                    }
                }

                m_launchCommand = new String[cmdList.Count];
                int index = 0;

                foreach (String arg in cmdList)
                {
                    m_launchCommand[index++] = arg;
                }
            }

            ProcessListener pl      = null;
            PlayerSession   session = null;
            try
            {
                // create the process and attach a thread to watch it during our accept phase
                System.Diagnostics.Process proc = m_debuggerCallbacks.launchDebugTarget(m_launchCommand);

                m_processMessages = new StringWriter();
                new StreamListener(proc.StandardOutput, m_processMessages).Start();
                new StreamListener(proc.StandardError, m_processMessages).Start();
#if false
                try
                {
                    Stream stm = proc.StandardOutput.BaseStream;
                    if (stm != null)
                    {
                        stm.Close();
                    }
                }
                catch (IOException)
                {
                    /* not serious; ignore */
                }
#endif
                switch (launchAction)
                {
                case NO_ACTION:
                    break;

                case SHOULD_LISTEN:
                {
                    // allows us to hear when the process dies
                    pl = new ProcessListener(this, proc);
                    pl.Start();
                    break;
                }

                case WAIT_FOR_LAUNCH:
                {
                    // block until the process completes
                    bool done = false;
                    while (!done)
                    {
                        try
                        {
                            proc.WaitForExit();
                            Int32 generatedAux = proc.ExitCode;
                            done = true;
                        }
                        catch (System.Threading.ThreadInterruptedException)
                        {
                            /* do nothing */
                        }
                    }
                    if (proc.ExitCode != 0)
                    {
                        throw new IOException(m_processMessages.ToString());
                    }
                    break;
                }
                }

                if (forDebugging)
                {
                    /* now wait for a connection */
                    session = (PlayerSession)accept(waitReporter, airLaunchInfo != null);
                    session.LaunchProcess = proc;
                    session.LaunchUrl     = uri;
                    session.AIRLaunchInfo = airLaunchInfo;
                }
            }
            finally
            {
                if (pl != null)
                {
                    pl.Finish();
                }
            }
            return(session);
        }