Example #1
0
        /// <exception cref="ParseException">Token '{0}' not expected in object declaration</exception>
        private XDictionary <string, IValue> ParseMetadataObject(ObjectNode context, XDictionary <string, IValue> result = null)
        {
            if (TokenType.CloseBrace == NextAfter(WhiteSpaceCommentsOrSemicolons))
            {
                return(result);
            }

            Rewind();

            var selector = ParseSelector(ColonOrEqual);

            // should be at the terminator still!
            switch (Type)
            {
            case TokenType.Equal:
                result = result ?? new XDictionary <string, IValue>();
                result.Add(selector.Name, ParseRValue(context, SemicolonCommaOrCloseBrace, null));
                return(ParseMetadataObject(context, result));

            case TokenType.Colon:
                result = result ?? new XDictionary <string, IValue>();
                result.Add(selector.Name, ParseRValue(context, SemicolonCommaOrCloseBrace, null));
                return(ParseMetadataObject(context, result));
            }
            throw Fail(ErrorCode.TokenNotExpected, "Token '{0}' not expected in metadata kvpair declaration");
        }
        public static IDictionary<string, string> GetSubjectNameParts(this X509Certificate2 cert) {
            var result = new XDictionary<string, string>();

            foreach (var bits in cert.SubjectName.Name.SplitToList(',').Select(each => each.Split('='))) {
                var newKey = bits[0].Trim(' ');
                result.Add(result.ContainsKey(newKey) ? newKey + result.Keys.Where(key => key.StartsWith(newKey)).Count() : newKey, bits[1]);
            }

            return result;
        }
Example #3
0
 internal ProcessStartInfo(System.Diagnostics.ProcessStartInfo psi)
 {
     _processStartInfo = psi;
     _environmentVariables = new XDictionary<string, string>();
     foreach (var i in psi.EnvironmentVariables.Keys) {
         _environmentVariables.Add(i.ToString(), psi.EnvironmentVariables[(string)i]);
     }
     _processStartInfo.RedirectStandardError = true;
     _processStartInfo.RedirectStandardOutput = true;
     SyncEnvironment();
 }
Example #4
0
 internal ProcessStartInfo(System.Diagnostics.ProcessStartInfo psi)
 {
     _processStartInfo     = psi;
     _environmentVariables = new XDictionary <string, string>();
     foreach (var i in psi.EnvironmentVariables.Keys)
     {
         _environmentVariables.Add(i.ToString(), psi.EnvironmentVariables[(string)i]);
     }
     _processStartInfo.RedirectStandardError  = true;
     _processStartInfo.RedirectStandardOutput = true;
     SyncEnvironment();
 }
Example #5
0
        public static IDictionary <string, string> GetSubjectNameParts(this X509Certificate2 cert)
        {
            var result = new XDictionary <string, string>();

            foreach (var bits in cert.SubjectName.Name.SplitToList(',').Select(each => each.Split('=')))
            {
                var newKey = bits[0].Trim(' ');
                result.Add(result.ContainsKey(newKey) ? newKey + result.Keys.Where(key => key.StartsWith(newKey)).Count() : newKey, bits[1]);
            }

            return(result);
        }
Example #6
0
        public static IDictionary<string, string> GetPublisherInformation(string filename) {
            var result = new XDictionary<string, string>();
            try {
                var cert = new X509Certificate2(filename);
                var fields = cert.Subject.Split(new[] {
                    ','
                }, StringSplitOptions.RemoveEmptyEntries);
                // var result = fields.Select(f => f.Split('=')).Where(s => s.Length > 1).ToDictionary(s => s[0], s => s[1]);

                result.Add("PublisherName", fields[0].Split('=')[1]);
            } catch (Exception) {
            }

            return result;
        }
Example #7
0
        public static IDictionary <string, string> GetPublisherInformation(string filename)
        {
            var result = new XDictionary <string, string>();

            try {
                var cert   = new X509Certificate2(filename);
                var fields = cert.Subject.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
                // var result = fields.Select(f => f.Split('=')).Where(s => s.Length > 1).ToDictionary(s => s[0], s => s[1]);

                result.Add("PublisherName", fields[0].Split('=')[1]);
            } catch (Exception) {
            }

            return(result);
        }
Example #8
0
        public static void AddChildren(this XDictionary <string, string> propertyDictionary, IEnumerable <XElement> children)
        {
            foreach (var child in children)
            {
                var val = child.Value;
                var key = child.LocalName();

                if (propertyDictionary.ContainsKey(key))
                {
                    var cur = propertyDictionary[key];
                    val = val.Replace("%({0})".format(key), cur);
                }
                val = Event <CustomReplacement> .Raise(val);

                propertyDictionary.Add(key, val);
            }
        }
Example #9
0
        public static XDictionary <TKey, TElement> ToXDictionary <TSource, TKey, TElement>(this IEnumerable <TSource> source, Func <TSource, TKey> keySelector, Func <TSource, TElement> elementSelector, IEqualityComparer <TKey> comparer)
        {
            if (source == null)
            {
                throw new CoAppException("ToXDictionary (source) value null.");
            }
            if (keySelector == null)
            {
                throw new CoAppException("ToXDictionary (keySelector) value null.");
            }
            if (elementSelector == null)
            {
                throw new CoAppException("ToXDictionary (elementSelector) value null.");
            }

            var d = new XDictionary <TKey, TElement>(comparer);

            foreach (var element in source)
            {
                d.Add(keySelector(element), elementSelector(element));
            }
            return(d);
        }
Example #10
0
        private int Startup(IEnumerable<string> args)
        {
            var options = args.Where(each => each.StartsWith("--")).Switches();
            var parameters = args.Parameters();

            foreach (var arg in options.Keys) {
                var argumentParameters = options[arg];

                switch (arg) {
                        /* global switches */
                    case "load-config":
                        // all ready done, but don't get too picky.
                        break;

                    case "nologo":
                        this.Assembly().SetLogo(string.Empty);
                        break;

                    case "help":
                        return Help();

                    case "certificate-path":
                        var cert = argumentParameters.Last();
                        _signingCertPath = _signingCertPath.IndexOf(":") > 1 ? cert : Path.GetFullPath(argumentParameters.Last());
                        break;

                    case "password":
                        _signingCertPassword = argumentParameters.Last();
                        break;

                    case "remember":
                        _remember = true;
                        break;

                    case "auto":
                        break;

                    case "sign":
                        _sign = true;
                        break;

                    case "just-sign":
                        _sign = true;
                        _justsign = true;
                        break;

                    case "strong-name":
                        _strongname = true;
                        break;

                    case "verbose":
                        _verbose = true;
                        break;

                    case "company":
                        _company = argumentParameters.Last();
                        break;

                    case "description":
                        _description = argumentParameters.Last();
                        break;

                    case "internal-name":
                        _internalName = argumentParameters.Last();
                        break;

                    case "copyright":
                        _copyright = argumentParameters.Last();
                        break;

                    case "original-filename":
                        _originalFilename = argumentParameters.Last();
                        break;

                    case "product-name":
                        _productName = argumentParameters.Last();
                        break;

                    case "verify":
                        _verify = true;
                        break;

                    case "reference-assembly":
                        foreach (var asmRef in argumentParameters) {
                            if (string.IsNullOrEmpty(asmRef)) {
                                return Fail("Missing assembly information for --assembly-reference.");
                            }

                            var parts = asmRef.Split(", ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
                            var assemblyref = new AssemblyReference {Name = parts[0]};

                            foreach (var part in parts.Skip(1)) {
                                var kp = part.Split("= ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
                                if (kp.Length != 2) {
                                    return Fail("Invalid option '{0}' in assembly reference '{1}'.", part, asmRef);
                                }

                                switch (kp[0].ToLower()) {
                                    case "version":
                                    case "ver":
                                        assemblyref.Version = kp[1];
                                        if (assemblyref.Version == 0L) {
                                            return Fail("Invalid Version '{0}' in assembly reference '{1}'.", kp[1], asmRef);
                                        }
                                        break;

                                    case "publickeytoken":
                                    case "pkt":
                                    case "token":
                                        if (kp[1].Length != 16) {
                                            return Fail("Invalid publicKeyToken '{0}' in assembly reference '{1}'.", kp[1], asmRef);
                                        }
                                        assemblyref.PublicKeyToken = kp[1];
                                        break;

                                    case "processorarchitecture":
                                    case "architecture":
                                    case "arch":
                                        assemblyref.Architecture = kp[1];
                                        if (assemblyref.Architecture == Architecture.Auto || assemblyref.Architecture == Architecture.Unknown) {
                                            return Fail("Invalid processorArchitecture '{0}' in assembly reference '{1}'.", kp[1], asmRef);
                                        }
                                        break;
                                }
                            }
                            if (assemblyref.Version == 0 || assemblyref.Architecture == Architecture.Unknown || string.IsNullOrEmpty(assemblyref.PublicKeyToken)) {
                                return Fail("Invalid assembly reference '{0}' ", asmRef);
                            }
                            assemblyReferences.Add(assemblyref);
                        }
                        break;

                    case "product-version":
                        _productVersion = argumentParameters.Last();
                        if (_productVersion == 0L) {
                            return Fail("--product-version must be in the form ##.##.##.##");
                        }

                        break;

                    case "file-version":
                        _fileVersion = argumentParameters.Last();
                        if (_fileVersion == 0L) {
                            return Fail("--file-version must be in the form ##.##.##.##");
                        }
                        break;

                    case "execution-level":
                        switch (argumentParameters.Last()) {
                            case "administrator":
                            case "admin":
                            case "requires-admin":
                            case "requiresadmin":
                            case "requiresadministrator":
                            case "requires-administrator":
                                _executionLevel = ExecutionLevel.requireAdministrator;
                                break;
                            case "invoker":
                            case "asinvoker":
                            case "as-invoker":
                                _executionLevel = ExecutionLevel.asInvoker;
                                break;
                            case "highest-available":
                            case "highest":
                            case "highestavailable":
                                _executionLevel = ExecutionLevel.highestAvailable;
                                break;
                        }
                        break;

                    case "dpi-aware":
                        if (argumentParameters.Last().IsTrue()) {
                            _dpiAware = true;
                        }
                        if (argumentParameters.Last().IsFalse()) {
                            _dpiAware = false;
                        }
                        break;
                    default:
                        return Fail("Unknown parameter [--{0}]", arg);
                }
            }

            Logo();

            if (_verify) {
                // return Verify(parameters);
            }

            if (string.IsNullOrEmpty(_signingCertPath)) {
                _certificate = CertificateReference.Default;
                if (_certificate == null) {
                    return Fail("No default certificate stored in the registry");
                }
            } else if (string.IsNullOrEmpty(_signingCertPassword)) {
                _certificate = new CertificateReference(_signingCertPath);
            } else {
                _certificate = new CertificateReference(_signingCertPath, _signingCertPassword);
            }

            using (new ConsoleColors(ConsoleColor.White, ConsoleColor.Black)) {
                Verbose("Loaded certificate with private key {0}", _certificate.Location);
            }

            if (_remember) {
                Verbose("Storing certificate details in the registry.");
                _certificate.RememberPassword();
                CertificateReference.Default = _certificate;
            }

            if (parameters.Count() < 1) {
                return Fail("Missing files to sign/name. \r\n\r\n    Use --help for command line help.");
            }

            var tasks = new List<Task>();

            if (_company != null && _company.Equals("auto", StringComparison.CurrentCultureIgnoreCase)) {
                _company = _certificate.CommonName;
            }
            var failures = 0;
            try {
                var allFiles = parameters.FindFilesSmarter().ToArray();
                var origMD5 = new XDictionary<string, string>();

                var loading = allFiles.Select(each =>
                    Binary.Load(each,
                        BinaryLoadOptions.PEInfo |
                            BinaryLoadOptions.VersionInfo |
                                BinaryLoadOptions.Managed |
                                    BinaryLoadOptions.Resources |
                                        BinaryLoadOptions.Manifest |
                                            BinaryLoadOptions.UnsignedManagedDependencies |
                                                BinaryLoadOptions.MD5).ContinueWith(antecedent => {
                                                    lock (allFiles) {
                                                        if (antecedent.IsFaulted) {
                                                            Console.WriteLine("Failed to load file '{0}'", each);
                                                            var e = antecedent.Exception.Flatten().InnerExceptions.First();
                                                            Console.WriteLine("{0}--{1}", e.Message, e.StackTrace);
                                                            return;
                                                        }

                                                        try {
                                                            var binary = antecedent.Result;
                                                            origMD5.Add(each, binary.MD5);

                                                            if (binary.IsPEFile && !_justsign) {
                                                                // do PE file stuff
                                                                if (_sign) {
                                                                    binary.SigningCertificate = _certificate;
                                                                }

                                                                if (binary.IsManaged && _strongname) {
                                                                    binary.StrongNameKeyCertificate = _certificate;
                                                                }

                                                                if (!assemblyReferences.IsNullOrEmpty()) {
                                                                    foreach (var asmRef in assemblyReferences) {
                                                                        binary.Manifest.Value.AddDependency(asmRef.Name, asmRef.Version, asmRef.Architecture, asmRef.PublicKeyToken);
                                                                    }
                                                                }

                                                                if (_company != null) {
                                                                    binary.CompanyName = _company;
                                                                }
                                                                if (_description != null) {
                                                                    binary.FileDescription = _description;
                                                                }
                                                                if (_internalName != null) {
                                                                    binary.InternalName = _internalName;
                                                                }
                                                                if (_copyright != null) {
                                                                    binary.LegalCopyright = _copyright;
                                                                }
                                                                if (_originalFilename != null) {
                                                                    binary.OriginalFilename = _originalFilename;
                                                                }
                                                                if (_productName != null) {
                                                                    binary.ProductName = _productName;
                                                                }
                                                                if (_productVersion != 0) {
                                                                    binary.ProductVersion = _productVersion;
                                                                }
                                                                if (_fileVersion != 0) {
                                                                    binary.FileVersion = _fileVersion;
                                                                }
                                                                if (_dpiAware != null) {
                                                                    binary.Manifest.Value.DpiAware = _dpiAware == true;
                                                                }
                                                                if (_executionLevel != ExecutionLevel.none) {
                                                                    binary.Manifest.Value.RequestedExecutionLevel = _executionLevel;
                                                                }
                                                            } else {
                                                                // do stuff for non-pe files
                                                                // we can try to apply a signature, and that's about it.
                                                                if (_sign) {
                                                                    binary.SigningCertificate = _certificate;
                                                                }
                                                            }
                                                            binary.Save().Wait();
                                                        } catch (Exception e) {
                                                            while (e.GetType() == typeof (AggregateException)) {
                                                                e = (e as AggregateException).Flatten().InnerExceptions[0];
                                                            }
                                                            failures += Fail("{0}--{1}", e.Message, e.StackTrace);
                                                        }
                                                    }
                                                }, TaskContinuationOptions.AttachedToParent)).ToArray();

                // Thread.Sleep(1000);
                // wait for loading.
                return Task.Factory.ContinueWhenAll(loading, tsks => {
                    Console.WriteLine("Done {0} files", tsks.Length);

                    (from each in Binary.Files
                        select new {
                            Filename = Path.GetFileName(each.Filename),
                            Original_MD5 = origMD5[each.Filename],
                            New_MD5 = each.MD5,
                            //  Status = each.Message,
                        }).ToTable().ConsoleOut();

                    if (failures > 0) {
                        Console.WriteLine("*** Bad News. Failed. *** ");
                    }

                    if (Binary.IsAnythingStillLoading) {
                        Console.WriteLine("\r\n==== Uh, stuff is still in the loading state?! ====\r\n");
                    }

                    return failures;
                }).Result;
            } catch (Exception e) {
                Console.WriteLine("{0}--{1}", e.Message, e.StackTrace);
                return Fail("not good.");
            }
        }
        /// <summary>
        ///   The (non-static) startup method
        /// </summary>
        /// <param name = "args">
        ///   The command line arguments.
        /// </param>
        /// <returns>
        ///   Process return code.
        /// </returns>
        protected override int Main(IEnumerable<string> args)
        {
            // force temporary folder to be where we want it to be.
            CurrentTask.Events += new DownloadProgress((remoteLocation, location, progress) => {
                "Downloading {0}".format(remoteLocation.UrlDecode()).PrintProgressBar(progress);
            });

            CurrentTask.Events += new DownloadCompleted((remoteLocation, locallocation) => {
                Console.WriteLine();
            });

            PackageManager.AddSessionFeed(Environment.CurrentDirectory).Wait();

            var macrovals = new XDictionary<string, string>();

            try {
                // default:
                var options = args.Where(each => each.StartsWith("--")).Switches();
                var parameters = args.Where(each => !each.StartsWith("--")).Parameters();

                foreach (var arg in options.Keys) {
                    var argumentParameters = options[arg];
                    var last = argumentParameters.LastOrDefault();
                    var lastAsBool = string.IsNullOrEmpty(last) || last.IsTrue();

                    switch (arg) {
                            /* options  */

                            /* global switches */
                        case "verbose":
                            _verbose = lastAsBool;
                            Logger.Messages = true;
                            Logger.Warnings = true;
                            Logger.Errors = true;
                            break;

                        case "load-config":
                            // all ready done, but don't get too picky.
                            break;

                        case "nologo":
                            this.Assembly().SetLogo(string.Empty);
                            break;

                        case "show-tools":
                            Tools.ShowTools = lastAsBool;
                            break;

                        case "certificate-path":
                            _signingCertPath = Path.GetFullPath(last);
                            break;

                        case "password":
                            _signingCertPassword = last;
                            break;

                        case "remember":
                            _remember = lastAsBool;
                            break;

                        case "override":
                            Override = true;
                            break;

                        case "help":
                            return Help();

                        case "no-toolkit-dependency":
                            break;

                        default:
                            macrovals.Add(arg, last);
                            break;
                    }
                }

                // set up the stuff to catch our errors and warnings

                CurrentTask.Events += new Error(HandleErrors);
                CurrentTask.Events += new Warning(HandleWarnings);
                CurrentTask.Events += new Verbose(Verbose);
                CurrentTask.Events += new Message(HandleMessage);

                // find all the command line tools that we're gonna need.
                Tools.LocateCommandlineTools();

                if (!parameters.Any()) {
                    throw new ConsoleException("Missing .autopkg script.");
                    // throw new ConsoleException(Resources.NoConfigFileLoaded);
                }

                Logo();

                var allFiles = parameters.FindFilesSmarter().ToArray();
                foreach (var file in allFiles) {
                    FilesystemExtensions.ResetTempFolder();
                    using (var popd = new PushDirectory(Path.GetDirectoryName(file.GetFullPath()))) {
                        Binary.UnloadAndResetAll();

                        PackageManager.AddSessionFeed(Path.GetDirectoryName(file.GetFullPath())).Wait();

                        PackageSource = new PackageSource(file, macrovals );

                        var template = PropertySheet.Parse(Resources.template_autopkg,null);

                        PackageSource.ImportedSheets.Add("template", template);

                        FindCertificate();

                        SigningCertPath = _signingCertPath;
                        SigningCertPassword = _signingCertPassword;
                        Remember = _remember;

                        // ------- Create data model for package
                        CreatePackageModel();

                        // ------ Generate package MSI from model
                        CreatePackageFile();
                    }
                }

            } catch (PackageException) {
                return Fail("Autopackage encountered errors.\r\n");
            } catch (ConsoleException failure) {
                return Fail("{0}\r\n\r\n    {1}", failure.Message, Resources.ForCommandLineHelp);
            } catch (Exception failure) {
                if( failure.InnerException != null ) {
                    Fail("Exception Caught: {0}\r\n{1}\r\n\r\n    {2}", failure.InnerException.Message, failure.InnerException.StackTrace, Resources.ForCommandLineHelp);
                }

                return Fail("Exception Caught: {0}\r\n{1}\r\n\r\n    {2}", failure.Message, failure.StackTrace, Resources.ForCommandLineHelp);
            }
            return 0;
        }
        protected override int Main(IEnumerable<string> args)
        {
            var hosts = new string[] { "*" };
            var ports = new int[] { 80 };
            var commitMessage = "trigger";
            var packageUpload = "upload";

            string localfeedLocation = null;
            string packageStoragePath = null;
            string packagePrefixUrl = null;
            string canonicalFeedUrl = null;

            string tweetCommits = Settings["#tweet-commits"].StringValue;
            string tweetPackages = Settings["#tweet-packages"].StringValue;
            string azureAccount = Settings["#azure-account"].StringValue;

            string azureKey = null;

            var options = args.Where(each => each.StartsWith("--")).Switches();
            var parameters = args.Where(each => !each.StartsWith("--")).Parameters();
            var aliases = new XDictionary<string, string>();

            foreach (var arg in options.Keys) {
                var argumentParameters = options[arg];
                var last = argumentParameters.LastOrDefault();
                var lastAsBool = string.IsNullOrEmpty(last) || last.IsTrue();

                switch (arg) {
                        /* options  */
                    case "verbose":
                        _verbose = lastAsBool;
                        Logger.Errors = true;
                        Logger.Messages = true;
                        Logger.Warnings = true;
                        break;

                        /* global switches */
                    case "load-config":
                        // all ready done, but don't get too picky.
                        break;

                    case "nologo":
                        this.Assembly().SetLogo(string.Empty);
                        break;

                    case "help":
                        return Help();

                    case "feed-path":
                        localfeedLocation = last;
                        break;

                    case "feed-url":
                        canonicalFeedUrl = last;
                        break;

                    case "package-path":
                        packageStoragePath = last;
                        break;

                    case "package-prefix":
                        packagePrefixUrl = last;
                        break;

                    case "host":
                        hosts = argumentParameters.ToArray();
                        break;

                    case "port":
                        ports = argumentParameters.Select(each => each.ToInt32()).ToArray();
                        break;

                    case "package-upload":
                        packageUpload = last;
                        break;

                    case "commit-message":
                        commitMessage = last;
                        break;

                    case "tweet-commits":
                        Settings["#tweet-commits"].StringValue = tweetCommits = last;
                        break;

                    case "tweet-packages":
                        Settings["#tweet-commits"].StringValue = tweetPackages = last;
                        break;

                    case "azure-name":
                        Settings["#azure-account"].StringValue = azureAccount = last;
                        break;

                    case "azure-key":
                        azureKey = last;
                        break;
                }
                if( arg.StartsWith("alias-")) {
                    aliases.Add(arg.Substring(6), last);
                }
            }

            Tweeter.Init(Settings, options);
            Bitly.Init(Settings, options);
            CloudFileSystem cfs = null;

            if( !string.IsNullOrEmpty(azureAccount)) {
                cfs = new CloudFileSystem(Settings, azureAccount, azureKey);
            }

            try {
                var listener = new Listener();

                // get startup information.

                foreach( var host in hosts ) {
                    listener.AddHost(host);
                }

                foreach( var port in ports ) {
                    listener.AddPort(port);
                }

                listener.AddHandler(commitMessage, new CommitMessageHandler(tweetCommits, aliases));

                if( string.IsNullOrEmpty(packageStoragePath) || string.IsNullOrEmpty(localfeedLocation) || string.IsNullOrEmpty(packagePrefixUrl)  ) {
                    Console.WriteLine("[Package Uploader Disabled] specify must specify --package-path, --feed-path and  --package-prefix");
                }else {
                    listener.AddHandler(packageUpload, new UploadedFileHandler(localfeedLocation, canonicalFeedUrl, packageStoragePath, packagePrefixUrl, tweetPackages, cfs));
                }
                listener.Start();

                Console.WriteLine("Press ctrl-c to stop the listener.");

                while (true) {
                    // one day, Ill put a check to restart the server in here.
                    Thread.Sleep(60 * 1000);

                }

                // listener.Stop();
            } catch(Exception e) {
                Listener.HandleException(e);
                CancellationTokenSource.Cancel();
            }

            return 0;
        }
Example #13
0
        /// <summary>
        /// Mains the specified args.
        /// </summary>
        /// <param name="args">The args.</param>
        /// <returns></returns>
        /// <remarks></remarks>
        private int main(IEnumerable<string> args)
        {
            var options = args.Switches();
            var parameters = args.Parameters();

            Console.CancelKeyPress += (x, y) => {
                Console.WriteLine("Stopping ...");

            };

            foreach (string arg in options.Keys) {
                IEnumerable<string> argumentParameters = options[arg];

                switch (arg) {
                    case "nologo":
                        this.Assembly().SetLogo("");
                        break;

                    case "send":
                        send= true;
                        break;

                    case "rescan-tools":
                        ProgramFinder.IgnoreCache = true;
                        break;

                    case "output":
                        outputfilename = argumentParameters.Last().GetFullPath();
                        break;

                    case "default":
                        var drive = argumentParameters.Last();
                        var driveletter = string.IsNullOrEmpty(drive) ? 'c' : drive[0];
                        parameters = new[] {@"{0}:\program files*", @"{0}:\cyg*", @"{0}:\ming*", @"{0}:\msys*",@"{0}:\*ddk*"}.Select(d => d.format(driveletter)).Aggregate(parameters, (current, path) => current.UnionSingleItem(path));

                        break;

                    case "help":
                        return Help();
                }
            }
            // make sure that we're in the parent directory of the .buildinfo file.
            // Environment.CurrentDirectory = Path.GetDirectoryName(Path.GetDirectoryName(buildinfo));

            Logo();

            if (parameters.Count() < 1) {
                return Fail("Missing directory to scan. \r\n\r\n    Use --help for command line help.");
            }

            var dirList = new List<string>();
            foreach( var d in parameters) {
                var i = d.LastIndexOf("\\");

                if (i > -1) {
                    dirList.AddRange(Directory.EnumerateDirectories(d.Substring(0, i + 1), d.Substring(i + 1)));
                } else {
                    dirList.AddRange(Directory.EnumerateDirectories(Environment.CurrentDirectory,d));
                }

            }

            Console.WriteLine("Folders that will be searched");
            foreach (var dir in dirList) {
                Console.WriteLine("   {0}", dir.GetFullPath());
            }
            Console.WriteLine("---------------------------------------------------------\r\n");

            var EXEs = Enumerable.Empty<string>();
            // EXEs = dirList.Aggregate(EXEs, (current, dir) => current.Union(Directory.EnumerateFiles(dir.GetFullPath(), "*.exe", SearchOption.AllDirectories)));
            EXEs = dirList.Aggregate(EXEs, (current, dir) => current.Union(dir.GetFullPath().DirectoryEnumerateFilesSmarter("*.exe", SearchOption.AllDirectories) ));
            // "".DirectoryEnumerateFilesSmarter("*.exe", SearchOption.AllDirectories)

            var matchPatterns = new[] {
                "*cl*.exe",
                "*cc*.exe",
                "*++*.exe",
                "*cpp*.exe",
                "*plusplus*.exe",

                "*windres*.exe",
                "*rc*.exe",

                "*mc*.exe",

                "*idl*.exe",

                "*link*.exe",
                "*ld*.exe",
                "*lib*.exe",

                "*asm*.exe",

                "*ml*.exe",

                "*mt*.exe",

                "*make*.exe",
            };

            var filterPatterns = new[] {
                "*plink*",
                "**\\calibre**",
                "**\\git**",
                "**\\bazaar**",
                "**\\jetbrains**",
                "**sql**",
                "**\\mirc**",
                "**pantaray**",
                "**Windows Installer XML**",
                "**internet explorer**",
                "**live**",
                "**office**",
                "**help**",
                "**home server**",
                "**media**",
            };

            var candidates = from exe in EXEs where
                matchPatterns.HasWildcardMatch(exe) &&
                !filterPatterns.HasWildcardMatch(exe) &&
                new FileInfo(exe).Length > 4096
                             select exe;

            dynamic xmldoc = new DynamicNode("Tools");

            foreach (var exe in candidates) {
                try {
                    var Node = InterrogateBinary(exe);
                    xmldoc.Node.Add(Node);

                    Console.WriteLine("   {0}", exe);
                } catch (Exception e)
                {
                    Console.WriteLine("{0} ===== {1}",exe, e.Message);
                    // Console.WriteLine(e.Message);
                    // Console.WriteLine(e.StackTrace);
                }
            }

            if (!string.IsNullOrEmpty(outputfilename)) {
                File.WriteAllText(outputfilename, xmldoc.Node.ToString());
            } else if (send) {
                // send it

                Console.WriteLine("Uploading...");

                var d = new XDictionary<string, string>();

                d.Add("data", xmldoc.Node.ToString());

                "http://static.withinwindows.com/sqm/upload.php".Post(d);
                Console.WriteLine("Done");
            }
            else {
                Console.WriteLine(xmldoc.Node.ToString());
            }

            return 0;
        }