コード例 #1
0
 /// <summary>
 /// Loads installation-specific custom configuration information.
 /// </summary>
 public static T LoadInstallationCustomConfiguration <T>()
 {
     // Do not perform schema validation for non-development installations because the schema file won't be available on non-development machines. Do not
     // perform schema validation for development installations because we may create sample solutions and send them to tech support people for
     // troubleshooting, and these people may not put the solution in the proper location on disk. In this case we would not have access to the schema since
     // we use absolute paths in the XML files to refer to the schema files.
     return(XmlOps.DeserializeFromFile <T>(InstallationConfiguration.InstallationCustomConfigurationFilePath, false));
 }
コード例 #2
0
        /// <summary>
        /// Gets a new system list.
        /// </summary>
        public static void RefreshSystemList()
        {
            // Do not perform schema validation since we don't want to be forced into redeploying Program Runner after every schema change. We also don't have access
            // to the schema on non-development machines.
            var cacheFilePath = EwlStatics.CombinePaths(ConfigurationStatics.EwlFolderPath, "System List.xml");
            var cacheUsed     = false;

            try {
                ConfigurationLogic.ExecuteWithSystemManagerClient(
                    client => {
                    Task.Run(
                        async() => {
                        using (var response = await client.GetAsync("system-list", HttpCompletionOption.ResponseHeadersRead)) {
                            response.EnsureSuccessStatusCode();
                            using (var stream = await response.Content.ReadAsStreamAsync())
                                RsisSystemList = XmlOps.DeserializeFromStream <SystemList>(stream, false);
                        }
                    })
                    .Wait();
                });
            }
            catch (Exception e) {
                // Use the cached version of the system list if it is available.
                if (File.Exists(cacheFilePath))
                {
                    RsisSystemList = XmlOps.DeserializeFromFile <SystemList>(cacheFilePath, false);
                    cacheUsed      = true;
                }
                else
                {
                    throw new UserCorrectableException("Failed to download the system list and a cached version is not available.", e);
                }
            }

            StatusStatics.SetStatus(
                cacheUsed ? "Failed to download the system list; loaded a cached version from \"{0}\".".FormatWith(cacheFilePath) : "Downloaded the system list.");

            // Cache the system list so something is available in the future if the machine is offline.
            try {
                XmlOps.SerializeIntoFile(RsisSystemList, cacheFilePath);
            }
            catch (Exception e) {
                const string generalMessage = "Failed to cache the system list on disk.";
                if (e is UnauthorizedAccessException)
                {
                    throw new UserCorrectableException(generalMessage + " If the program is running as a non built in administrator, you may need to disable UAC.", e);
                }

                // An IOException probably means the file is locked. In this case we want to ignore the problem and move on.
                if (!(e is IOException))
                {
                    throw new UserCorrectableException(generalMessage, e);
                }
            }
        }
コード例 #3
0
        /// <summary>
        /// Gets a new system list from RSIS.
        /// </summary>
        public static void RefreshSystemList()
        {
            // When deserializing the system list below, do not perform schema validation since we don't want to be forced into redeploying Program Runner after every
            // schema change. We also don't have access to the schema on non-development machines.
            var cachedSystemListFilePath = EwlStatics.CombinePaths(ConfigurationStatics.RedStaplerFolderPath, "RSIS System List.xml");

            try {
                var serializedSystemList =
                    ConfigurationLogic.ExecuteProgramRunnerUnstreamedServiceMethod(
                        channel => channel.GetSystemList(ConfigurationLogic.AuthenticationKey),
                        "system list download");
                RsisSystemList = XmlOps.DeserializeFromString <SystemList>(serializedSystemList, false);

                // Cache the system list so something is available in the future if the machine is offline.
                try {
                    XmlOps.SerializeIntoFile(RsisSystemList, cachedSystemListFilePath);
                }
                catch (Exception e) {
                    const string generalMessage = "The RSIS system list cannot be cached on disk.";
                    if (e is UnauthorizedAccessException)
                    {
                        throw new UserCorrectableException(generalMessage + " If the program is running as a non built in administrator, you may need to disable UAC.", e);
                    }

                    // An IOException probably means the file is locked. In this case we want to ignore the problem and move on.
                    if (!(e is IOException))
                    {
                        throw new UserCorrectableException(generalMessage, e);
                    }
                }
            }
            catch (UserCorrectableException e) {
                if (e.InnerException == null || !(e.InnerException is EndpointNotFoundException))
                {
                    throw;
                }

                // Use the cached version of the system list if it is available.
                if (File.Exists(cachedSystemListFilePath))
                {
                    RsisSystemList = XmlOps.DeserializeFromFile <SystemList>(cachedSystemListFilePath, false);
                }
                else
                {
                    throw new UserCorrectableException("RSIS cannot be reached to download the system list and a cached version is not available.", e);
                }
            }
        }
コード例 #4
0
        internal static PackagingConfiguration GetPackagingConfiguration(DevelopmentInstallation installation)
        {
            var filePath = EwlStatics.CombinePaths(
                installation.ExistingInstallationLogic.RuntimeConfiguration.ConfigurationFolderPath,
                InstallationConfiguration.InstallationConfigurationFolderName,
                InstallationConfiguration.InstallationsFolderName,
                "Packaging" + FileExtensions.Xml);

            return(File.Exists(filePath)
                                       ? XmlOps.DeserializeFromFile <PackagingConfiguration>(filePath, false)
                                       : new PackagingConfiguration
            {
                SystemName = installation.ExistingInstallationLogic.RuntimeConfiguration.SystemName,
                SystemShortName = installation.ExistingInstallationLogic.RuntimeConfiguration.SystemShortName
            });
        }
コード例 #5
0
        /// <summary>
        /// Creates a new installation configuration.
        /// </summary>
        public InstallationConfiguration(bool machineIsStandbyServer, string installationPath, bool isDevelopmentInstallation)
        {
            this.installationPath = installationPath;

            // The EWL configuration folder is not inside any particular app's folder the way that Web.config and app.config are. This is for two reasons. First, EWL
            // configuration is system-wide (technically installation-wide) and not app-specific like Web.config and app.config. Second, it could be disastrous to
            // have EWL configuration files inside a web app's folder since then these files, which often contain database passwords and other sensitive information,
            // could potentially be served up to users.
            configurationFolderPath =
                StandardLibraryMethods.CombinePaths(
                    InstallationFileStatics.GetGeneralFilesFolderPath(installationPath, isDevelopmentInstallation),
                    ConfigurationFolderName);


            // Do not perform schema validation for non-development installations because the schema files may not be available. For development installations, also
            // do not perform schema validation since the schema files may not match this version of the library. This can happen, for example, when you are trying to
            // run a system using an unreleased version of the library that contains schema changes.

            // system general configuration
            var systemGeneralConfigurationFilePath = StandardLibraryMethods.CombinePaths(ConfigurationFolderPath, "General.xml");

            systemGeneralConfiguration = XmlOps.DeserializeFromFile <SystemGeneralConfiguration>(systemGeneralConfigurationFilePath, false);

            // system development configuration
            if (isDevelopmentInstallation)
            {
                systemDevelopmentConfiguration =
                    XmlOps.DeserializeFromFile <SystemDevelopment.SystemDevelopmentConfiguration>(
                        StandardLibraryMethods.CombinePaths(configurationFolderPath, SystemDevelopmentConfigurationFileName),
                        false);
            }

            var installationConfigurationFolderPath = isDevelopmentInstallation
                                                                          ? StandardLibraryMethods.CombinePaths(
                ConfigurationFolderPath,
                InstallationConfigurationFolderName,
                InstallationsFolderName,
                DevelopmentInstallationFolderName)
                                                                          : StandardLibraryMethods.CombinePaths(ConfigurationFolderPath, InstallationConfigurationFolderName);

            // installation standard configuration
            var installationStandardConfigurationFilePath = StandardLibraryMethods.CombinePaths(
                installationConfigurationFolderPath,
                InstallationStandardConfigurationFileName);

            installationStandardConfiguration = XmlOps.DeserializeFromFile <InstallationStandardConfiguration>(installationStandardConfigurationFilePath, false);


            var systemWebApplicationElements = systemGeneralConfiguration.WebApplications ?? new SystemGeneralConfigurationApplication[0];

            webApplications                       = from systemElement in systemWebApplicationElements
                                         let name = systemElement.Name
                                                    let supportsSecureConnections = systemElement.SupportsSecureConnections
                                                                                    select
                                                                                    isDevelopmentInstallation
                                                          ? new WebApplication(
                name,
                supportsSecureConnections,
                installationPath,
                SystemShortName,
                systemWebApplicationElements.Skip(1).Any(),
                systemDevelopmentConfiguration.webProjects.Single(i => i.name == name))
                                                          : InstallationType == InstallationType.Live
                                                                    ? new WebApplication(
                name,
                supportsSecureConnections,
                machineIsStandbyServer,
                LiveInstallationConfiguration.WebApplications.Single(i => i.Name == name))
                                                                    : new WebApplication(
                name,
                supportsSecureConnections,
                IntermediateInstallationConfiguration.WebApplications.Single(i => i.Name == name));

            webApplications = webApplications.ToArray();

            // installation custom configuration
            installationCustomConfigurationFilePath = StandardLibraryMethods.CombinePaths(installationConfigurationFolderPath, "Custom.xml");
        }
コード例 #6
0
        internal static void Init(Type systemLogicType, string appName, bool isClientSideProgram, ref string initializationLog)
        {
            RedStaplerFolderPath     = Environment.GetEnvironmentVariable("RedStaplerFolderPath") ?? @"C:\Red Stapler";
            MachineConfigXmlFilePath = StandardLibraryMethods.CombinePaths(RedStaplerFolderPath, "Machine Configuration.xml");

            initializationLog += Environment.NewLine + "About to load machine config";

            // Load machine configuration.
            if (File.Exists(MachineConfigXmlFilePath))
            {
                // Do not perform schema validation since the schema file won't be available on non-development machines.
                MachineConfiguration = XmlOps.DeserializeFromFile <MachineConfiguration>(MachineConfigXmlFilePath, false);
            }

            initializationLog += Environment.NewLine + "About to initialize stack trace";

            // Assume the first assembly up the call stack that is not this assembly is the application assembly.
            var stackFrames = new StackTrace().GetFrames();

            if (stackFrames == null)
            {
                throw new ApplicationException("No stack trace available.");
            }
            AppAssembly = stackFrames.Select(frame => frame.GetMethod().DeclaringType.Assembly).First(assembly => assembly != Assembly.GetExecutingAssembly());

            initializationLog += Environment.NewLine + "Stack trace initialized";

            // Determine the installation path and load configuration information.
            string installationPath;
            bool   isDevelopmentInstallation;

            if (NetTools.IsWebApp())
            {
                initializationLog += Environment.NewLine + "Is a web app";

                installationPath          = StandardLibraryMethods.CombinePaths(HttpRuntime.AppDomainAppPath, "..");
                isDevelopmentInstallation = !InstallationConfiguration.InstalledInstallationExists(installationPath);
            }
            else
            {
                initializationLog += Environment.NewLine + "Is not a web app";

                // Assume this is an installed installation. If this assumption turns out to be wrong, consider it a development installation.
                // We use the assembly folder path here so we're not relying on the working directory of the application.
                // Installed executables are one level below the installation folder.
                var assemblyFolderPath = Path.GetDirectoryName(AppAssembly.Location);
                installationPath          = StandardLibraryMethods.CombinePaths(assemblyFolderPath, "..");
                isDevelopmentInstallation = !InstallationConfiguration.InstalledInstallationExists(installationPath);
                if (isDevelopmentInstallation)
                {
                    installationPath = StandardLibraryMethods.CombinePaths(assemblyFolderPath, "..", "..", "..");                       // Visual Studio puts executables inside bin\Debug.
                }
            }
            initializationLog        += Environment.NewLine + "Successfully determined installation path";
            InstallationConfiguration = new InstallationConfiguration(MachineIsStandbyServer, installationPath, isDevelopmentInstallation);
            initializationLog        += Environment.NewLine + "Successfully loaded installation configuration";

            ConfigurationStatics.systemLogicType = systemLogicType;
            SystemGeneralProvider = GetSystemLibraryProvider("General") as SystemGeneralProvider;
            if (SystemGeneralProvider == null)
            {
                throw new ApplicationException("General provider not found in system");
            }

            AppName             = appName;
            IsClientSideProgram = isClientSideProgram;
        }
コード例 #7
0
        void Operation.Execute(Installation genericInstallation, OperationResult operationResult)
        {
            var installation = genericInstallation as DevelopmentInstallation;

            var logicPackagesFolderPath = EwlStatics.CombinePaths(installation.GeneralLogic.Path, "Logic Packages");

            IoMethods.DeleteFolder(logicPackagesFolderPath);

            // Set up the main (build) object in the build message.
            var build = new InstallationSupportUtility.RsisInterface.Messages.BuildMessage.Build();

            build.SystemName      = installation.ExistingInstallationLogic.RuntimeConfiguration.SystemName;
            build.SystemShortName = installation.ExistingInstallationLogic.RuntimeConfiguration.SystemShortName;
            build.MajorVersion    = installation.CurrentMajorVersion;
            build.BuildNumber     = installation.NextBuildNumber;
            build.LogicSize       = ConfigurationLogic.NDependIsPresent && !installation.DevelopmentInstallationLogic.SystemIsEwl
                                                  ? GetLogicSize.GetNDependLocCount(installation, false) as int?
                                                  : null;
            var serverSideLogicFolderPath = EwlStatics.CombinePaths(logicPackagesFolderPath, "Server Side Logic");

            packageWebApps(installation, serverSideLogicFolderPath);
            packageWindowsServices(installation, serverSideLogicFolderPath);
            packageServerSideConsoleApps(installation, serverSideLogicFolderPath);
            packageGeneralFiles(installation, serverSideLogicFolderPath, true);
            build.ServerSideLogicPackage             = ZipOps.ZipFolderAsByteArray(serverSideLogicFolderPath);
            operationResult.NumberOfBytesTransferred = build.ServerSideLogicPackage.LongLength;

            // Set up the client side application object in the build message, if necessary.
            if (installation.DevelopmentInstallationLogic.DevelopmentConfiguration.clientSideAppProject != null)
            {
                build.ClientSideApp              = new InstallationSupportUtility.RsisInterface.Messages.BuildMessage.Build.ClientSideAppType();
                build.ClientSideApp.Name         = installation.DevelopmentInstallationLogic.DevelopmentConfiguration.clientSideAppProject.name;
                build.ClientSideApp.AssemblyName = installation.DevelopmentInstallationLogic.DevelopmentConfiguration.clientSideAppProject.assemblyName;
                var clientSideAppFolder = EwlStatics.CombinePaths(logicPackagesFolderPath, "Client Side Application");
                packageClientSideApp(installation, clientSideAppFolder);
                packageGeneralFiles(installation, clientSideAppFolder, false);
                build.ClientSideApp.Package = ZipOps.ZipFolderAsByteArray(clientSideAppFolder);
                operationResult.NumberOfBytesTransferred += build.ClientSideApp.Package.LongLength;
            }

            // Set up the list of installation objects in the build message.
            build.Installations = new InstallationSupportUtility.RsisInterface.Messages.BuildMessage.Build.InstallationsType();
            foreach (var installationConfigurationFolderPath in
                     Directory.GetDirectories(
                         EwlStatics.CombinePaths(
                             installation.ExistingInstallationLogic.RuntimeConfiguration.ConfigurationFolderPath,
                             InstallationConfiguration.InstallationConfigurationFolderName,
                             InstallationConfiguration.InstallationsFolderName)))
            {
                if (Path.GetFileName(installationConfigurationFolderPath) != InstallationConfiguration.DevelopmentInstallationFolderName)
                {
                    var buildMessageInstallation = new InstallationSupportUtility.RsisInterface.Messages.BuildMessage.Installation();

                    // Do not perform schema validation since the schema file on disk may not match this version of the ISU.
                    var installationConfigurationFile =
                        XmlOps.DeserializeFromFile <InstallationStandardConfiguration>(
                            EwlStatics.CombinePaths(installationConfigurationFolderPath, InstallationConfiguration.InstallationStandardConfigurationFileName),
                            false);

                    buildMessageInstallation.Id                 = installationConfigurationFile.rsisInstallationId;
                    buildMessageInstallation.Name               = installationConfigurationFile.installedInstallation.name;
                    buildMessageInstallation.ShortName          = installationConfigurationFile.installedInstallation.shortName;
                    buildMessageInstallation.IsLiveInstallation =
                        installationConfigurationFile.installedInstallation.InstallationTypeConfiguration is LiveInstallationConfiguration;
                    buildMessageInstallation.ConfigurationPackage = ZipOps.ZipFolderAsByteArray(installationConfigurationFolderPath);
                    build.Installations.Add(buildMessageInstallation);
                    operationResult.NumberOfBytesTransferred += buildMessageInstallation.ConfigurationPackage.LongLength;
                }
            }

            if (installation.DevelopmentInstallationLogic.SystemIsEwl)
            {
                build.NuGetPackages = packageEwl(installation, logicPackagesFolderPath);
            }

            var recognizedInstallation = installation as RecognizedDevelopmentInstallation;

            if (recognizedInstallation == null)
            {
                return;
            }

            build.SystemId = recognizedInstallation.KnownSystemLogic.RsisSystem.Id;

            operationResult.TimeSpentWaitingForNetwork = EwlStatics.ExecuteTimedRegion(
                delegate {
                using (var memoryStream = new MemoryStream()) {
                    // Understand that by doing this, we are not really taking advantage of streaming, but at least it will be easier to do it the right way some day (probably by implementing our own BuildMessageStream)
                    XmlOps.SerializeIntoStream(build, memoryStream);
                    memoryStream.Position = 0;

                    ConfigurationLogic.ExecuteIsuServiceMethod(
                        channel => channel.UploadBuild(new BuildUploadMessage {
                        AuthenticationKey = ConfigurationLogic.AuthenticationKey, BuildDocument = memoryStream
                    }),
                        "build upload");
                }
            });
        }
コード例 #8
0
        internal static void Init(string assemblyFolderPath, Type globalInitializerType, string appName, bool isClientSideApp, ref string initializationLog)
        {
            EwlFolderPath = Environment.GetEnvironmentVariable("{0}FolderPath".FormatWith(EwlStatics.EwlInitialism.EnglishToPascal())) ??
                            @"C:\{0}".FormatWith(EwlStatics.EwlName);

            initializationLog += Environment.NewLine + "About to load machine config";

            // Load machine configuration.
            var machineConfigFilePath = EwlStatics.CombinePaths(EwlFolderPath, "Machine Configuration.xml");

            if (File.Exists(machineConfigFilePath))
            {
                // Do not perform schema validation since the schema file won't be available on non-development machines.
                try {
                    MachineConfiguration = XmlOps.DeserializeFromFile <MachineConfiguration>(machineConfigFilePath, false);
                }
                catch {
                    // The alt file allows us to smoothly transition all machines in the case of schema changes that break deserialization.
                    var altFilePath = EwlStatics.CombinePaths(EwlFolderPath, "Machine Configuration Alt.xml");
                    if (!File.Exists(altFilePath))
                    {
                        throw;
                    }
                    MachineConfiguration = XmlOps.DeserializeFromFile <MachineConfiguration>(altFilePath, false);
                }
            }

            initializationLog += Environment.NewLine + "About to initialize stack trace";

            // Assume the first assembly up the call stack that is not this assembly is the application assembly.
            var stackFrames = new StackTrace().GetFrames();

            if (stackFrames == null)
            {
                throw new ApplicationException("No stack trace available.");
            }
            AppAssembly = stackFrames.Select(frame => frame.GetMethod().DeclaringType.Assembly).First(assembly => assembly != Assembly.GetExecutingAssembly());

            initializationLog += Environment.NewLine + "Stack trace initialized";

            // Determine the installation path and load configuration information.
            string installationPath;
            bool   isDevelopmentInstallation;

            if (NetTools.IsWebApp())
            {
                initializationLog += Environment.NewLine + "Is a web app";

                installationPath          = EwlStatics.CombinePaths(HttpRuntime.AppDomainAppPath, "..");
                isDevelopmentInstallation = !InstallationConfiguration.InstalledInstallationExists(installationPath);
            }
            else
            {
                initializationLog += Environment.NewLine + "Is not a web app";

                // Assume this is an installed installation. If this assumption turns out to be wrong, consider it a development installation. Installed executables are
                // one level below the installation folder.
                installationPath          = EwlStatics.CombinePaths(assemblyFolderPath.Any() ? assemblyFolderPath : Path.GetDirectoryName(AppAssembly.Location), "..");
                isDevelopmentInstallation = !InstallationConfiguration.InstalledInstallationExists(installationPath);
                if (isDevelopmentInstallation)
                {
                    installationPath = EwlStatics.CombinePaths(installationPath, "..", "..");                       // Visual Studio puts executables inside bin\Debug.
                }
            }
            initializationLog        += Environment.NewLine + "Successfully determined installation path";
            InstallationConfiguration = new InstallationConfiguration(installationPath, isDevelopmentInstallation);
            initializationLog        += Environment.NewLine + "Successfully loaded installation configuration";

            ConfigurationStatics.globalInitializerType = globalInitializerType;
            SystemGeneralProvider = GetSystemLibraryProvider("General") as SystemGeneralProvider;
            if (SystemGeneralProvider == null)
            {
                throw new ApplicationException("General provider not found in system");
            }

            AppName         = appName;
            IsClientSideApp = isClientSideApp;
        }
コード例 #9
0
 /// <summary>
 /// Loads installation configuration information that is shared across installations.
 /// </summary>
 public static T LoadInstallationSharedConfiguration <T>()
 {
     return(XmlOps.DeserializeFromFile <T>(InstallationConfiguration.InstallationSharedConfigurationFilePath, false));
 }