Beispiel #1
0
        /// <summary>
        /// Installs the specified MSI.
        /// </summary>
        /// <param name="packagePath">The full path to the MSI package.</param>
        /// <param name="logFile">The full path of the log file.</param>
        /// <returns>An error code indicating the result of the operation.</returns>
        protected uint InstallMsi(string packagePath, string logFile)
        {
            // Make sure the package we're going to run is coming from the cache.
            if (!packagePath.StartsWith(Cache.PackageCacheRoot))
            {
                return(Error.INSTALL_PACKAGE_INVALID);
            }

            Elevate();

            if (IsElevated)
            {
                ConfigureInstall(logFile);
                return(WindowsInstaller.InstallProduct(packagePath, s_installProperties));
            }
            else if (IsClient)
            {
                InstallResponseMessage response = Dispatcher.SendMsiRequest(InstallRequestType.InstallMsi,
                                                                            logFile, packagePath);
                ExitOnFailure(response, "Failed to install MSI.");

                return(response.Error);
            }

            throw new InvalidOperationException($"Invalid configuration: elevated: {IsElevated}, client: {IsClient}");
        }
Beispiel #2
0
        /// <summary>
        /// Determines the state of the specified product.
        /// </summary>
        /// <param name="productCode">The product code of the MSI to detect.</param>
        /// <param name="installedVersion">If detected, contains the version of the installed MSI.</param>
        /// <returns>The detect state of the specified MSI.</returns>
        private DetectState Detect(string productCode, out string installedVersion)
        {
            uint error = WindowsInstaller.GetProductInfo(productCode, InstallProperty.VERSIONSTRING, out installedVersion);

            DetectState state = error == Error.SUCCESS ? DetectState.Present
                : (error == Error.UNKNOWN_PRODUCT) || (error == Error.UNKNOWN_PROPERTY) ? DetectState.Absent
                : DetectState.Unknown;

            ExitOnError(state == DetectState.Unknown, error, $"Failed to detect MSI package with ProductCode={productCode}.");
            Log?.LogMessage($"Detected package, ProductCode: {productCode}, version: {(string.IsNullOrWhiteSpace(installedVersion) ? "n/a" : $"{installedVersion}")}, state: {state}.");
Beispiel #3
0
        public void TestShortcut()
        {
            WindowsInstaller.CreateDesktopIcon("Project Dollhouse",
                                               Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles) + "\\Project Dollhouse\\" +
                                               m_PDEXECUTABLE,
                                               Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles) + "\\Project Dollhouse\\");

            Assert.IsTrue(File.Exists(Environment.GetFolderPath(Environment.SpecialFolder.Desktop) +
                                      "\\Project Dollhouse.lnk"));
        }
Beispiel #4
0
        /// <summary>
        /// Configures the installer UI and logging operations before starting an operation.
        /// </summary>
        /// <param name="logFile">The path of the log file.</param>
        protected void ConfigureInstall(string logFile)
        {
            uint error = Error.SUCCESS;

            // Turn off the MSI UI.
            _ = WindowsInstaller.SetInternalUI(InstallUILevel.None);

            // The log file must be created before calling MsiEnableLog and we should avoid having active handles
            // against it.
            FileStream logFileStream = File.Create(logFile);

            logFileStream.Close();
            error = WindowsInstaller.EnableLog(InstallLogMode.DEFAULT | InstallLogMode.VERBOSE, logFile, InstallLogAttributes.NONE);

            // We can report issues with the log file creation, but shouldn't fail the workload operation.
            LogError(error, $"Failed to configure log file: {logFile}");
        }
Beispiel #5
0
        /// <summary>
        /// Repairs the specified MSI package.
        /// </summary>
        /// <param name="productCode">The product code of the MSI to repair.</param>
        /// <param name="logFile">The full path of the log file.</param>
        /// <returns>An error code indicating the result of the operation.</returns>
        protected uint RepairMsi(string productCode, string logFile)
        {
            Elevate();

            if (IsElevated)
            {
                ConfigureInstall(logFile);
                return(WindowsInstaller.ReinstallProduct(productCode, DefaultReinstallMode));
            }
            else if (IsClient)
            {
                InstallResponseMessage response = Dispatcher.SendMsiRequest(InstallRequestType.RepairMsi,
                                                                            logFile, null, productCode);
                ExitOnFailure(response, "Failed to repair MSI.");

                return(response.Error);
            }

            throw new InvalidOperationException($"Invalid configuration: elevated: {IsElevated}, client: {IsClient}");
        }
Beispiel #6
0
        /// <summary>
        /// Uninstalls the MSI using its provided product code.
        /// </summary>
        /// <param name="productCode">The product code of the MSI to uninstall.</param>
        /// <param name="logFile">The full path of the log file.</param>
        /// <returns>An error code indicating the result of the operation.</returns>
        protected uint UninstallMsi(string productCode, string logFile)
        {
            Elevate();

            if (IsElevated)
            {
                ConfigureInstall(logFile);
                return(WindowsInstaller.ConfigureProduct(productCode, WindowsInstaller.INSTALLLEVEL_DEFAULT, InstallState.ABSENT,
                                                         s_uninstallProperties));
            }
            else if (IsClient)
            {
                InstallResponseMessage response = Dispatcher.SendMsiRequest(InstallRequestType.UninstallMsi,
                                                                            logFile, null, productCode);
                ExitOnFailure(response, "Failed to uninstall MSI.");

                return(response.Error);
            }

            throw new InvalidOperationException($"Invalid configuration: elevated: {IsElevated}, client: {IsClient}");
        }
Beispiel #7
0
        /// <summary>
        /// Determines the state of the specified product.
        /// </summary>
        /// <param name="productCode">The product code of the MSI to detect.</param>
        /// <param name="installedVersion">If detected, contains the version of the installed MSI.</param>
        /// <returns>The detect state of the specified MSI.</returns>
        private DetectState DetectPackage(string productCode, out Version installedVersion)
        {
            installedVersion = default;
            uint error = WindowsInstaller.GetProductInfo(productCode, InstallProperty.VERSIONSTRING, out string versionValue);

            DetectState state = error == Error.SUCCESS ? DetectState.Present
                : (error == Error.UNKNOWN_PRODUCT) || (error == Error.UNKNOWN_PROPERTY) ? DetectState.Absent
                : DetectState.Unknown;

            ExitOnError(state == DetectState.Unknown, error, $"DetectPackage: Failed to detect MSI package, ProductCode: {productCode}.");

            if (state == DetectState.Present)
            {
                if (!Version.TryParse(versionValue, out installedVersion))
                {
                    Log?.LogMessage($"DetectPackage: Failed to parse version: {versionValue}.");
                }
            }

            Log?.LogMessage($"DetectPackage: ProductCode: {productCode}, version: {installedVersion?.ToString() ?? "n/a"}, state: {state}.");

            return(state);
        }
Beispiel #8
0
        void InstallMsi(string path)
        {
            // Configure event handler for install messages
            UserInterfaceHandler ux = new UserInterfaceHandler(InstallLogMode.ACTIONDATA | InstallLogMode.ACTIONSTART | InstallLogMode.PROGRESS);

            ux.ActionData  += OnActionData;
            ux.ActionStart += OnActionStart;
            ux.Progress    += OnProgress;

            ProgressPhase = 0;

            Console.WriteLine();
            ActionTop      = Console.CursorTop;
            ProgressBarTop = ActionTop + 1;

            // Make sure we run quietly. Be careful, we won't be prompted to elevate.
            WindowsInstaller.SetInternalUI(InstallUILevel.None);

            uint error = WindowsInstaller.InstallProduct(path, "MSIFASTINSTALL=7 REBOOT=ReallySuppress");

            Console.CursorTop  = ProgressBarTop + 1;
            Console.CursorLeft = 0;

            Console.CursorTop = ActionTop;
            ClearLine();
            Console.CursorTop = ProgressBarTop;
            ClearLine();

            if ((error != Error.SUCCESS) && (error != Error.SUCCESS_REBOOT_INITIATED) && (error != Error.SUCCESS_REBOOT_REQUIRED))
            {
                throw new WindowsInstallerException((int)error);
            }
            else
            {
                Console.WriteLine("Done!");
            }
        }
Beispiel #9
0
        public void TestRegistry()
        {
            /*m_CrossThreadRunner.RunInSTA(
             *  delegate
             *  {
             *      MainWindow Window = new MainWindow();
             *
             *      if (!Window.CheckRegistry())
             *      {
             *          Window.CreateRegistry();
             *
             *          Assert.IsTrue(Window.CheckRegistry());
             *      }
             *  });*/

            if (!WindowsInstaller.CheckRegistry())
            {
                WindowsInstaller.CreateRegistry(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles) + "Maxis\\The Sims Online\\");

                Assert.IsTrue(WindowsInstaller.CheckRegistry());
            }

            Assert.Pass();
        }
Beispiel #10
0
        static void Main(string[] args)
        {
            var arguments = new HostArguments(args);

            if (arguments.Help)
            {
                arguments.PrintUsage();
                return;
            }

            assemblyScannerResults = AssemblyScanner.GetScannableAssemblies();

            var endpointTypeDeterminer    = new EndpointTypeDeterminer(assemblyScannerResults, () => ConfigurationManager.AppSettings["EndpointConfigurationType"]);
            var endpointConfigurationType = endpointTypeDeterminer.GetEndpointConfigurationTypeForHostedEndpoint(arguments);

            var endpointConfigurationFile = endpointConfigurationType.EndpointConfigurationFile;
            var endpointName    = endpointConfigurationType.EndpointName;
            var serviceName     = endpointConfigurationType.ServiceName;
            var endpointVersion = endpointConfigurationType.EndpointVersion;
            var displayName     = serviceName + "-" + endpointVersion;

            if (arguments.SideBySide)
            {
                serviceName += "-" + endpointVersion;
            }

            //Add the endpoint name so that the new appdomain can get it
            if (arguments.EndpointName == null && !String.IsNullOrEmpty(endpointName))
            {
                args = args.Concat(new[] { String.Format(@"/endpointName={0}", endpointName) }).ToArray();
            }

            //Add the ScannedAssemblies name so that the new appdomain can get it
            if (arguments.ScannedAssemblies.Count == 0)
            {
                args = assemblyScannerResults.Assemblies.Select(s => s.ToString()).Aggregate(args, (current, result) => current.Concat(new[] { String.Format(@"/scannedAssemblies={0}", result) }).ToArray());
            }

            //Add the endpointConfigurationType name so that the new appdomain can get it
            if (arguments.EndpointConfigurationType == null)
            {
                args = args.Concat(new[] { String.Format(@"/endpointConfigurationType={0}", endpointConfigurationType.AssemblyQualifiedName) }).ToArray();
            }

            if (arguments.Install)
            {
                WindowsInstaller.Install(args, endpointConfigurationFile);
            }

            IRunConfiguration cfg = RunnerConfigurator.New(x =>
            {
                x.ConfigureServiceInIsolation <WindowsHost>(endpointConfigurationType.AssemblyQualifiedName, c =>
                {
                    c.ConfigurationFile(endpointConfigurationFile);
                    c.WhenStarted(service => service.Start());
                    c.WhenStopped(service => service.Stop());
                    c.CommandLineArguments(args, () => SetHostServiceLocatorArgs);
                    c.CreateServiceLocator(() => new HostServiceLocator());
                });

                if (arguments.Username != null && arguments.Password != null)
                {
                    x.RunAs(arguments.Username, arguments.Password);
                }
                else
                {
                    x.RunAsLocalSystem();
                }

                if (arguments.StartManually)
                {
                    x.DoNotStartAutomatically();
                }

                x.SetDisplayName(arguments.DisplayName ?? displayName);
                x.SetServiceName(serviceName);
                x.SetDescription(arguments.Description ?? string.Format("NServiceBus Endpoint Host Service for {0}", displayName));

                var serviceCommandLine = new List <string>();

                if (!String.IsNullOrEmpty(arguments.EndpointConfigurationType))
                {
                    serviceCommandLine.Add(String.Format(@"/endpointConfigurationType:""{0}""", arguments.EndpointConfigurationType));
                }

                if (!String.IsNullOrEmpty(endpointName))
                {
                    serviceCommandLine.Add(String.Format(@"/endpointName:""{0}""", endpointName));
                }

                if (!String.IsNullOrEmpty(serviceName))
                {
                    serviceCommandLine.Add(String.Format(@"/serviceName:""{0}""", serviceName));
                }

                if (arguments.ScannedAssemblies.Count > 0)
                {
                    serviceCommandLine.AddRange(arguments.ScannedAssemblies.Select(assembly => String.Format(@"/scannedAssemblies:""{0}""", assembly)));
                }

                if (arguments.OtherArgs.Any())
                {
                    serviceCommandLine.AddRange(arguments.OtherArgs);
                }

                var commandLine = String.Join(" ", serviceCommandLine);
                x.SetServiceCommandLine(commandLine);

                if (arguments.DependsOn == null)
                {
                    x.DependencyOnMsmq();
                }
                else
                {
                    foreach (var dependency in arguments.DependsOn)
                    {
                        x.DependsOn(dependency);
                    }
                }
            });

            try
            {
                Runner.Host(cfg, args);
            }
            catch (StateMachineException exception)
            {
                var innerException = exception.InnerException;
                innerException.PreserveStackTrace();
                throw innerException;
            }
        }
Beispiel #11
0
        /// <summary>
        /// Verifies that the <see cref="MsiPayload"/> refers to a valid Windows Installer package (MSI).
        /// </summary>
        /// <param name="msiPayload">The payload to verify.</param>
        private void VerifyPackage(MsiPayload msiPayload)
        {
            uint error = WindowsInstaller.VerifyPackage(msiPayload.MsiPath);

            ExitOnError(error, $"Failed to verify package: {msiPayload.MsiPath}.");
        }
Beispiel #12
0
        /// <summary>
        /// Plans the specified MSI payload based on its state and the requested install action.
        /// </summary>
        /// <param name="msi">The MSI package to plan.</param>
        /// <param name="state">The detected state of the package.</param>
        /// <param name="requestedAction">The requested action to perform.</param>
        /// <returns>The action that will be performed.</returns>
        private InstallAction PlanPackage(MsiPayload msi, DetectState state, InstallAction requestedAction, Version installedVersion, out IEnumerable <string> relatedProductCodes)
        {
            InstallAction    plannedAction   = InstallAction.None;
            HashSet <string> relatedProducts = new();

            Log?.LogMessage($"PlanPackage: Begin, name: {msi.Name}, version: {msi.ProductVersion}, state: {state}, installed version: {installedVersion?.ToString() ?? "n/a"}, requested: {requestedAction}.");

            // Manifest packages should support major upgrades (both the ProductCode and ProductVersion should be different) while
            // workload packs should always be SxS (ProductCode and Upgrade should be different for each version).
            //
            // We cannot discount someone generating a minor update (ProductCode remains unchanged, but ProductVersion changes),
            // so we'll detect downgrades and minor updates. For more details, see https://docs.microsoft.com/en-us/windows/win32/msi/minor-upgrades.
            if (state == DetectState.Present)
            {
                if (msi.ProductVersion < installedVersion)
                {
                    Log?.LogMessage($"PlanPackage: Downgrade detected, installed version: {installedVersion}, requested version: {msi.ProductVersion}.");
                    plannedAction = InstallAction.Downgrade;
                    state         = DetectState.Superseded;
                }
                else if (msi.ProductVersion > installedVersion)
                {
                    Log?.LogMessage($"PlanPackage: Minor update detected, installed version: {installedVersion}, requested version: {msi.ProductVersion}.");
                    plannedAction = InstallAction.MinorUpdate;
                    state         = DetectState.Obsolete;
                }
                else
                {
                    // If the package is installed, then we can uninstall and repair it.
                    plannedAction = (requestedAction != InstallAction.Repair) && (requestedAction != InstallAction.Uninstall) ? InstallAction.None : requestedAction;
                }
            }
            else if (state == DetectState.Absent)
            {
                // If we're absent, convert repair to install or keep install.
                plannedAction = (requestedAction == InstallAction.Repair) ? InstallAction.Install
                    : (requestedAction == InstallAction.Install) ? InstallAction.Install
                    : InstallAction.None;
            }

            // At this point we know the MSI is absent so there are only three outcomes when executing the package:
            //   1. We'll just do a clean install if we don't find related products so we're either brand new or SxS.
            //   2. We'll perform a major upgrade.
            //   3. We'll trigger a downgrade and likely an error since most MSIs detect and block downgrades.
            //
            // We'll process the related product information to make a determination. This is similar to what the FindRelatedProducts
            // action does when an MSI is executed.
            foreach (RelatedProduct relatedProduct in msi.RelatedProducts)
            {
                foreach (string relatedProductCode in WindowsInstaller.FindRelatedProducts(relatedProduct.UpgradeCode))
                {
                    // Ignore potentially detecting ourselves.
                    if (string.Equals(relatedProductCode, msi.ProductCode, StringComparison.OrdinalIgnoreCase))
                    {
                        continue;
                    }

                    // Check whether the related product is installed and retrieve its version to determine
                    // how we're related.
                    uint error = WindowsInstaller.GetProductInfo(relatedProductCode, InstallProperty.VERSIONSTRING, out string relatedVersionValue);

                    // Continue searching if the related product is not installed.
                    if (error == Error.UNKNOWN_PRODUCT || error == Error.UNKNOWN_PROPERTY)
                    {
                        continue;
                    }

                    ExitOnError(error, $"PlanPackage: Failed to retrieve version for related product: ProductCode: {relatedProductCode}.");

                    // Parse the version, but don't try to catch any errors. If the version is invalid we want to fail
                    // because we can't compare invalid versions to see whether it's excluded by the VersionMin and VersionMax
                    // columns from the Upgrade table.
                    Version relatedVersion = Version.Parse(relatedVersionValue);

                    if (relatedProduct.ExcludesMinVersion(relatedVersion) || relatedProduct.ExcludesMaxVersion(relatedVersion))
                    {
                        continue;
                    }

                    // Check if the related product contains a matching language code (LCID). If we don't have any languages,
                    // all languages are detectable as related and we can ignore the msidbUpgradeAttributesLanguagesExclusive flag.
                    if (relatedProduct.Languages.Any())
                    {
                        string relatedLanguage = "0";
                        error = WindowsInstaller.GetProductInfo(relatedProductCode, InstallProperty.LANGUAGE, out relatedLanguage);

                        if (int.TryParse(relatedLanguage, out int lcid))
                        {
                            if (relatedProduct.ExcludesLanguage(lcid))
                            {
                                continue;
                            }
                        }
                        else
                        {
                            Log?.LogMessage($"PlanPackage: Failed to read Language property for related product, ProductCode: {relatedProductCode}. The related product will be skipped.");
                            continue;
                        }
                    }

                    relatedProducts.Add(relatedProductCode);
                    plannedAction = InstallAction.MajorUpgrade;

                    if (relatedProduct.Attributes.HasFlag(UpgradeAttributes.OnlyDetect) && (state == DetectState.Absent))
                    {
                        // If we're not installed, but detect-only related, it's very likely that
                        // that we'd trigger a downgrade launch condition. We can't know for sure, but
                        // generally that's the most common use for detect-only entries.
                        plannedAction = InstallAction.Downgrade;
                    }

                    Log?.LogMessage($"PlanPackage: Detected related product, ProductCode: {relatedProductCode}, version: {relatedVersion}, attributes: {relatedProduct.Attributes}, planned action: {plannedAction}.");
                }
            }

            Log?.LogMessage($"PlanPackage: Completed, name: {msi.Name}, version: {msi.ProductVersion}, state: {state}, installed version: {installedVersion?.ToString() ?? "n/a"}, requested: {requestedAction}, planned: {plannedAction}.");

            relatedProductCodes = relatedProducts.Select(p => p);
            return(plannedAction);
        }
Beispiel #13
0
        static void Main(string[] args)
        {
            Parser.Args commandLineArguments = Parser.ParseArgs(args);
            var         arguments            = new HostArguments(commandLineArguments);

            if (arguments.Help != null)
            {
                DisplayHelpContent();

                return;
            }

            var endpointConfigurationType = GetEndpointConfigurationType(arguments);

            if (endpointConfigurationType == null)
            {
                if (arguments.InstallInfrastructure == null)
                {
                    throw new InvalidOperationException("No endpoint configuration found in scanned assemblies. " +
                                                        "This usually happens when NServiceBus fails to load your assembly containing IConfigureThisEndpoint." +
                                                        " Try specifying the type explicitly in the NServiceBus.Host.exe.config using the appsetting key: EndpointConfigurationType, " +
                                                        "Scanned path: " + AppDomain.CurrentDomain.BaseDirectory);
                }

                Console.WriteLine("Running infrastructure installers and exiting (ignoring other command line parameters if exist).");
                InstallInfrastructure();
                return;
            }

            AssertThatEndpointConfigurationTypeHasDefaultConstructor(endpointConfigurationType);
            string endpointConfigurationFile = GetEndpointConfigurationFile(endpointConfigurationType);

            var endpointName    = GetEndpointName(endpointConfigurationType, arguments);
            var endpointVersion = GetEndpointVersion(endpointConfigurationType);

            var serviceName = endpointName;

            if (arguments.ServiceName != null)
            {
                serviceName = arguments.ServiceName.Value;
            }

            var displayName = serviceName + "-" + endpointVersion;

            if (arguments.SideBySide != null)
            {
                serviceName += "-" + endpointVersion;

                displayName += " (SideBySide)";
            }

            //add the endpoint name so that the new appdomain can get it
            args = args.Concat(new[] { endpointName }).ToArray();

            AppDomain.CurrentDomain.SetupInformation.AppDomainInitializerArguments = args;
            if ((commandLineArguments.Install) || (arguments.InstallInfrastructure != null))
            {
                WindowsInstaller.Install(args, endpointConfigurationType, endpointName, endpointConfigurationFile,
                                         commandLineArguments.Install, arguments.InstallInfrastructure != null);
            }


            IRunConfiguration cfg = RunnerConfigurator.New(x =>
            {
                x.ConfigureServiceInIsolation <WindowsHost>(endpointConfigurationType.AssemblyQualifiedName, c =>
                {
                    c.ConfigurationFile(endpointConfigurationFile);
                    c.CommandLineArguments(args, () => SetHostServiceLocatorArgs);
                    c.WhenStarted(service => service.Start());
                    c.WhenStopped(service => service.Stop());
                    c.CreateServiceLocator(() => new HostServiceLocator());
                });

                if (arguments.Username != null && arguments.Password != null)
                {
                    x.RunAs(arguments.Username.Value, arguments.Password.Value);
                }
                else
                {
                    x.RunAsLocalSystem();
                }

                if (arguments.StartManually != null)
                {
                    x.DoNotStartAutomatically();
                }

                x.SetDisplayName(arguments.DisplayName != null ? arguments.DisplayName.Value : displayName);
                x.SetServiceName(serviceName);
                x.SetDescription(arguments.Description != null ? arguments.Description.Value : "NServiceBus Message Endpoint Host Service for " + displayName);

                var serviceCommandLine = commandLineArguments.CustomArguments.AsCommandLine();
                serviceCommandLine    += " /serviceName:\"" + serviceName + "\"";
                serviceCommandLine    += " /endpointName:\"" + endpointName + "\"";

                x.SetServiceCommandLine(serviceCommandLine);

                if (arguments.DependsOn == null)
                {
                    x.DependencyOnMsmq();
                }
                else
                {
                    foreach (var dependency in arguments.DependsOn.Value.Split(','))
                    {
                        x.DependsOn(dependency);
                    }
                }
            });

            Runner.Host(cfg, args);
        }
        public void QueryProductStateReturnsAnError(string productCode, InstallState expectedState)
        {
            InstallState state = WindowsInstaller.QueryProduct(productCode);

            Assert.Equal(state, expectedState);
        }
        public void InstallProductReturnsAnError(string productCode, string property, uint expectedError)
        {
            uint error = WindowsInstaller.GetProductInfo(productCode, property, out string propertyValue);

            Assert.Equal(error, expectedError);
        }
Beispiel #16
0
        static void Main(string[] args)
        {
            Parser.Args commandLineArguments = Parser.ParseArgs(args);
            var         arguments            = new HostArguments(commandLineArguments);

            if (arguments.Help != null)
            {
                DisplayHelpContent();

                return;
            }

            var endpointConfigurationType = GetEndpointConfigurationType(arguments);

            AssertThatEndpointConfigurationTypeHasDefaultConstructor(endpointConfigurationType);

            string endpointConfigurationFile = GetEndpointConfigurationFile(endpointConfigurationType);


            var endpointName    = GetEndpointName(endpointConfigurationType);
            var endpointVersion = GetEndpointVersion(endpointConfigurationType);

            if (arguments.ServiceName != null)
            {
                endpointName = arguments.ServiceName.Value;
            }

            var serviceName = endpointName;

            var displayName = serviceName + "-" + endpointVersion;

            //add the endpoint name so that the new appdomain can get it
            args = args.Concat(new[] { endpointName }).ToArray();

            AppDomain.CurrentDomain.SetupInformation.AppDomainInitializerArguments = args;

            if (commandLineArguments.Install)
            {
                WindowsInstaller.Install(args, endpointConfigurationType, endpointName, endpointConfigurationFile);
            }

            IRunConfiguration cfg = RunnerConfigurator.New(x =>
            {
                x.ConfigureServiceInIsolation <WindowsHost>(endpointConfigurationType.AssemblyQualifiedName, c =>
                {
                    c.ConfigurationFile(endpointConfigurationFile);
                    c.CommandLineArguments(args, () => SetHostServiceLocatorArgs);
                    c.WhenStarted(service => service.Start());
                    c.WhenStopped(service => service.Stop());
                    c.CreateServiceLocator(() => new HostServiceLocator());
                });

                if (arguments.Username != null && arguments.Password != null)
                {
                    x.RunAs(arguments.Username.Value, arguments.Password.Value);
                }
                else
                {
                    x.RunAsLocalSystem();
                }

                if (arguments.StartManually != null)
                {
                    x.DoNotStartAutomatically();
                }

                x.SetDisplayName(arguments.DisplayName != null ? arguments.DisplayName.Value : displayName);
                x.SetServiceName(serviceName);
                x.SetDescription(arguments.Description != null ? arguments.Description.Value : "NServiceBus Message Endpoint Host Service for " + displayName);

                var serviceCommandLine = commandLineArguments.CustomArguments.AsCommandLine();
                serviceCommandLine    += " /serviceName:\"" + serviceName + "\"";

                x.SetServiceCommandLine(serviceCommandLine);

                if (arguments.DependsOn == null)
                {
                    x.DependencyOnMsmq();
                }
                else
                {
                    foreach (var dependency in arguments.DependsOn.Value.Split(','))
                    {
                        x.DependsOn(dependency);
                    }
                }
            });

            Runner.Host(cfg, args);
        }