Ejemplo n.º 1
0
        // Parses the command line and sets public fields/properties including IsHelpWanted and ErrorMessage.
        // If canDisplayMsg is true, a message box will be displayed if an error is found or the -help switch is found.
        // Otherwise, the caller should display any error found and/or call ShowHelp().
        // Returns true if no error was found, false if the ErrorMessage property was set.
        public static bool ParseCommandLine(bool canDisplayMsg)
        {
            using (Log.InfoCall())
            {
                string[] args = ArgParserTX.GetArgs(keepQuotes: false);

                foreach (string arg in args)
                {
                    Log.Debug("Got argument: ", arg);

                    // Arguments that start with - or / are switches.
                    // Others are "non-switches".

                    char switchFlag = arg[0];

                    if (switchFlag == '-' || switchFlag == '/')
                    {
                        // It's a switch.
                        // In general switches can have optional values, like "-switch:value".  ParseSwitch() sets switchPart
                        // and valuePart.  If the syntax is incorrect, ParseSwitch() returns false and sets
                        // msg to an error message.

                        string switchPart;
                        string valuePart;
                        string msg;

                        if (ArgParserTX.ParseSwitch(arg, out switchPart, out valuePart, out msg))
                        {
                            switch (switchPart.ToLower())
                            {
                            case "?":
                            case "h":
                            case "help":
                                IsHelpWanted = true;
                                break;

                            case "s":
                            case "server":
                                if (valuePart.NullOrWhiteSpace())
                                {
                                    SetError("The '{0}{1}' switch requires a value (i.e. the server name).".Fmt(switchFlag, switchPart));
                                }
                                else if (ServerName == null)
                                {
                                    if (System.Deployment.Application.ApplicationDeployment.IsNetworkDeployed)
                                    {
                                        ServerName = ArgParserTX.PercentDecode(valuePart);
                                    }
                                    else
                                    {
                                        ServerName = valuePart;
                                    }
                                }
                                else
                                {
                                    SetError("Two or more server names have been specified: '{0}' and '{1}'.".Fmt(ServerName, valuePart));
                                }
                                break;

                            case "ff":
                            case "filefilter":
                                if (valuePart.NullOrWhiteSpace())
                                {
                                    SetError("The '{0}{1}' switch requires a value (i.e. a file name filter).".Fmt(switchFlag, switchPart));
                                }
                                else if (FileFilter == null)
                                {
                                    if (System.Deployment.Application.ApplicationDeployment.IsNetworkDeployed)
                                    {
                                        FileFilter = ArgParserTX.PercentDecode(valuePart);
                                    }
                                    else
                                    {
                                        FileFilter = valuePart;
                                    }
                                }
                                else
                                {
                                    SetError("Two or more file filters have been specified: '{0}' and '{1}'.".Fmt(FileFilter, valuePart));
                                }
                                break;

                            default:
                                SetError("Unrecognized switch: {0}{1}".Fmt(switchFlag, switchPart));
                                break;
                            } // switch (switchPart)
                        }     // Valid switch format
                        else
                        {
                            // Some fundamental error in the format of a "-switch:value" pair
                            // such as the presence of "-switch:" with no value.

                            SetError(msg);
                        }
                    } // Found switch arg
                    else
                    {
                        // It's a non-switch.  This program allows a single non-switch to specify the file to view.

                        if (FilePath == null)
                        {
                            FilePath = arg;
                        }
                        else
                        {
                            SetError("More than one <FilePath> argument was specfied.  Are quotes needed?\n\n  First: {0}\n  Second: {1}".Fmt(FilePath, arg));
                        }
                    }
                } // foreach arg

                if (FilePath != null)
                {
                    if (FilePath.EndsWith(".application", StringComparison.OrdinalIgnoreCase))
                    {
                        // Assume this means we were launched via our own TracerX-Viewer.application file, when means don't actually have a file arg.
                        FilePath = null;
                    }
                    else
                    {
                        // If this app is installed as a ClickOnce app and the user double-clicks a
                        // file, the FilePath argument will be a URI such as
                        // "file:///c:\logs\may%20have%20blanks.tx1". That is, any blanks will be
                        // percent-encoded. We can construct a Uri object from the string and get the
                        // Url.LocalPath property.

                        Uri    uri;
                        string localPath = FilePath;

                        if (Uri.TryCreate(FilePath, UriKind.Absolute, out uri))
                        {
                            localPath = uri.LocalPath;
                        }

                        // Constructing a FileInfo is the best way I know
                        // to check if the file path syntax is valid.

                        try
                        {
                            FileInfo test = new FileInfo(localPath);
                            FilePath = localPath;
                        }
                        catch (Exception ex)
                        {
                            // Use the original argument in the error message.

                            SetError("Invalid file path syntax:\n\n  {0}".Fmt(FilePath));
                        }
                    }
                }

                if (IsHelpWanted || ErrorMessage != null)
                {
                    // Clear any args that were found so they are not acted on.

                    ServerName = null;
                    FilePath   = null;

                    if (canDisplayMsg)
                    {
                        ShowHelp(ErrorMessage);
                    }
                }
                else
                {
                    Log.Info("AppArgs.FilePath = ", FilePath);
                    Log.Info("AppArgs.ServerName = ", ServerName);
                }

                return(ErrorMessage == null);
            } // using Log
        }
Ejemplo n.º 2
0
        // Parses the command line and sets public fields/properties including IsHelpWanted and ErrorMessage.
        // If canDisplayMsg is true, a message box will be displayed if an error is found or the -help switch is found.
        // Otherwise, the caller should display any error found and/or call ShowHelp().
        // Returns true if no error was found, false if the ErrorMessage property was set.
        public static bool ParseCommandLine(bool canDisplayMsg)
        {
            using (Log.InfoCall())
            {
                string[] args = ArgParserTX.GetArgs(keepQuotes: false);

                foreach (string arg in args)
                {
                    Log.Debug("Got argument: ", arg);

                    // Arguments that start with - or / are switches.
                    // Others are "non-switches".

                    char switchFlag = arg[0];

                    if (switchFlag == '-' || switchFlag == '/')
                    {
                        // It's a switch.
                        // In general switches can have optional values, like "-switch:value".  ParseSwitch() sets switchPart
                        // and valuePart.  If the syntax is incorrect, ParseSwitch() returns false and sets
                        // msg to an error message.

                        string switchPart;
                        string valuePart;
                        string msg;

                        if (ArgParserTX.ParseSwitch(arg, out switchPart, out valuePart, out msg))
                        {
                            switch (switchPart.ToLower())
                            {
                            case "?":
                            case "h":
                            case "help":
                                IsHelpWanted = true;
                                break;

                            case "s":
                            case "server":
                                if (valuePart.NullOrWhiteSpace())
                                {
                                    SetError("The '{0}{1}' switch requires a value (i.e. the server name).".Fmt(switchFlag, switchPart));
                                }
                                else if (ServerName == null)
                                {
                                    if (System.Deployment.Application.ApplicationDeployment.IsNetworkDeployed)
                                    {
                                        ServerName = ArgParserTX.PercentDecode(valuePart);
                                    }
                                    else
                                    {
                                        ServerName = valuePart;
                                    }
                                }
                                else
                                {
                                    SetError("Two or more server names have been specified: '{0}' and '{1}'.".Fmt(ServerName, valuePart));
                                }
                                break;

                            case "ff":
                            case "filefilter":
                                if (valuePart.NullOrWhiteSpace())
                                {
                                    SetError("The '{0}{1}' switch requires a value (i.e. a file name filter).".Fmt(switchFlag, switchPart));
                                }
                                else if (FileFilter == null)
                                {
                                    if (System.Deployment.Application.ApplicationDeployment.IsNetworkDeployed)
                                    {
                                        FileFilter = ArgParserTX.PercentDecode(valuePart);
                                    }
                                    else
                                    {
                                        FileFilter = valuePart;
                                    }
                                }
                                else
                                {
                                    SetError("Two or more file filters have been specified: '{0}' and '{1}'.".Fmt(FileFilter, valuePart));
                                }
                                break;

                            default:
                                SetError("Unrecognized switch: {0}{1}".Fmt(switchFlag, switchPart));
                                break;
                            } // switch (switchPart)
                        }     // Valid switch format
                        else
                        {
                            // Some fundamental error in the format of a "-switch:value" pair
                            // such as the presence of "-switch:" with no value.

                            SetError(msg);
                        }
                    } // Found switch arg
                    else
                    {
                        // It's a non-switch.  This program allows a single non-switch to specify the file to view.

                        if (FilePath == null)
                        {
                            FilePath = arg;
                        }
                        else
                        {
                            SetError("More than one <FilePath> argument was specfied.  Are quotes needed?\n\n  First: {0}\n  Second: {1}".Fmt(FilePath, arg));
                        }
                    }
                } // foreach arg

                if (FilePath != null)
                {
                    if (FilePath.EndsWith(".application", StringComparison.OrdinalIgnoreCase))
                    {
                        // Assume this means we were launched via our own TracerX-Viewer.application file, which means we don't actually have a file arg.
                        FilePath = null;
                    }
                    else
                    {
                        // If this app is installed as a ClickOnce app and the user double-clicks a
                        // file, the FilePath argument will be a URI such as
                        // "file:///c:\logs\may%20have%20spaces.tx1"
                        // or
                        // "file://server/share/has%20space%20and%20%25.tx1".
                        // That is, it will be percent-encoded.  However, we want a regular
                        // file path that is NOT percent-encoded.
                        // We can construct a Uri object from the string and get the
                        // Url.LocalPath property to do that.  If FilePath is not a valid URI
                        // we may need to percent-decode it ourselves but we must not
                        // percent-decode it twice because the original file name may contain the % char.

                        Uri    uri;
                        string localPath = null;

                        if (FilePath.StartsWith("file://", StringComparison.InvariantCultureIgnoreCase) && Uri.TryCreate(FilePath, UriKind.Absolute, out uri))
                        {
                            localPath = uri.LocalPath;
                            Log.Debug("Converted URI '", FilePath, "' to\n", localPath);
                        }
                        else if (System.Deployment.Application.ApplicationDeployment.IsNetworkDeployed)
                        {
                            // This is a ClickOnce app.  It was probably invoked via the command line or Process.Start() using the .appref-ms file.
                            // In that scenario we require the file path to be percent-encoded (also the switch arguments).
                            localPath = ArgParserTX.PercentDecode(FilePath);
                            Log.Debug("PercentDecode(\"", FilePath, "\") returned\n", localPath);
                        }
                        else
                        {
                            // Since this is not a ClickOnce app, regular command line syntax applies.  The FilePath
                            // need not be percent-encoded, though the user should have enclosed it in quotes, that are
                            // gone now, if it contains blanks.
                            localPath = FilePath;
                            Log.Debug("Using FilePath as is: ", FilePath);
                        }

                        // Constructing a FileInfo is the best way I know
                        // to check if the file path syntax is valid.

                        try
                        {
                            FileInfo test = new FileInfo(localPath);

                            // If no exception we have a valid path (syntax).
                            FilePath = localPath;
                        }
                        catch (Exception ex)
                        {
                            // Use the original argument in the error message.

                            SetError("Invalid file path syntax:\n\n  {0}".Fmt(FilePath));
                        }
                    }
                }

                if (IsHelpWanted || ErrorMessage != null)
                {
                    // Clear any args that were found so they are not acted on.

                    ServerName = null;
                    FilePath   = null;

                    if (canDisplayMsg)
                    {
                        ShowHelp(ErrorMessage);
                    }
                }
                else
                {
                    Log.Info("AppArgs.FilePath = ", FilePath);
                    Log.Info("AppArgs.ServerName = ", ServerName);
                }

                return(ErrorMessage == null);
            } // using Log
        }