/*
		* @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;
		}
示例#2
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);
        }