Пример #1
0
        private static void ProcessOptions(Options opts)
        {
            TL.LogMessage("ProcessOptions", string.Format("Local server path: {0}", opts.LocalServerPath));
            TL.LogMessage("ProcessOptions", string.Format("Remote server path: {0}", opts.RemoteServerPath));
            TL.LogMessage("ProcessOptions", string.Format("API URI: {0}", opts.SetApiUriAcl));
            TL.LogMessage("ProcessOptions", string.Format("Manafgement URI: {0}", opts.SetManagementUriAcl));
            TL.BlankLine();

            // Set firewall rules depending on which command line parameter was supplied
            if (opts.LocalServerPath != NOT_PRESENT_FLAG)
            {
                SetFireWallRules(opts.LocalServerPath, LOCAL_SERVER_RULE_NAME_BASE);
            }
            if (opts.RemoteServerPath != NOT_PRESENT_FLAG)
            {
                SetFireWallRules(opts.RemoteServerPath, REMOTE_SERVER_RULE_NAME_BASE);
            }

            // Set http.sys ACLs as needed
            if (opts.SetApiUriAcl != NOT_PRESENT_FLAG)
            {
                SetAcl(opts.SetApiUriAcl);
            }
            if (opts.SetManagementUriAcl != NOT_PRESENT_FLAG)
            {
                SetAcl(opts.SetManagementUriAcl);
            }
        }
Пример #2
0
        static void Main(string[] args)
        {
            AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);

            try
            {
                TL         = new TraceLogger("", "SetFireWallRules");
                TL.Enabled = true;

                Version version = Assembly.GetEntryAssembly().GetName().Version;
                TL.LogMessage("SetFireWallRules", string.Format("Version {0}, Run on {1}", version.ToString(), DateTime.Now.ToString("dddd d MMMM yyyy HH:mm:ss")));
                TL.BlankLine();

                // Add the event handler for handling non-UI thread exceptions to the event.

                CommandLine.Parser.Default.ParseArguments <Options>(args)
                .WithParsed <Options>(opts => ProcessOptions(opts))
                .WithNotParsed <Options>((errs) => HandleParseError(errs));

                TL.Enabled = false;
                TL         = null;
            }
            catch (Exception ex)
            {
                TraceLogger TL = new TraceLogger("SetFireWallRulesMainException")
                {
                    Enabled = true
                };
                TL.LogMessageCrLf("Main", "Unhandled exception: " + ex.ToString());
                TL.Enabled = false;
                TL.Dispose();
                TL = null;
            }
        }
Пример #3
0
        private static void ProcessOptions(Options opts)
        {
            TL.LogMessage("ProcessOptions", $"Local server path: {opts.LocalServerPath}");
            TL.LogMessage("ProcessOptions", $"API URI: {opts.SetApiUriAcl}");
            TL.LogMessage("ProcessOptions", $"Remote server management URI: {opts.SetRemoteServerManagementUriAcl}");
            TL.LogMessage("ProcessOptions", $"Alpaca device management URI: {opts.SetAlpacaManagementUriAcl}");
            TL.LogMessage("ProcessOptions", $"Alpaca device HTML setup URI: {opts.SetAlpacaSetupUriAcl}");
            TL.LogMessage("ProcessOptions", $"HTTP.SYS port: {opts.HttpDotSysPort}");
            TL.LogMessage("ProcessOptions", $"HTTP.SYS supplied user name: {opts.UserName}");

            // Get the supplied user name but substitute the current user name if none was supplied
            string userName = $"\"{opts.UserName}\"";

            if (userName == NOT_PRESENT_FLAG)
            {
                userName = $"{Environment.UserDomainName}\\{Environment.UserName}";
            }
            TL.LogMessage("ProcessOptions", $"HTTP.SYS user name that will be used: {userName}");
            TL.BlankLine();

            // Set firewall rules as needed
            if (opts.LocalServerPath != NOT_PRESENT_FLAG)
            {
                SetLocalServerFireWallOutboundRule(opts.LocalServerPath);
            }
            if (opts.HttpDotSysPort != NOT_PRESENT_FLAG)
            {
                SetHttpSysFireWallInboundRule(opts.HttpDotSysPort);
            }


            // Set http.sys ACLs as needed
            if (opts.SetApiUriAcl != NOT_PRESENT_FLAG)
            {
                SetAcl(opts.SetApiUriAcl, userName);
            }
            if (opts.SetRemoteServerManagementUriAcl != NOT_PRESENT_FLAG)
            {
                SetAcl(opts.SetRemoteServerManagementUriAcl, userName);
            }
            if (opts.SetAlpacaManagementUriAcl != NOT_PRESENT_FLAG)
            {
                SetAcl(opts.SetAlpacaManagementUriAcl, userName);
            }
            if (opts.SetAlpacaSetupUriAcl != NOT_PRESENT_FLAG)
            {
                SetAcl(opts.SetAlpacaSetupUriAcl, userName);
            }
        }
Пример #4
0
        private static string DownloadFile(string Function, string DataFile, WebClient Client, TraceLogger TL)
        {
            string    tempFileName;
            Stopwatch timeOutTimer;

            tempFileName = Path.GetTempFileName();
            timeOutTimer = new Stopwatch();

            TL.LogMessage(Function, string.Format("About to download {0} from {1} as {2}", DataFile, Client.BaseAddress, tempFileName));

            Client.DownloadFileAsync(new Uri(DataFile, UriKind.Relative), tempFileName);

            int printCount = 0;

            //DateTime timeOut = DateTime.Now.AddSeconds(DownloadTimeout);
            DownloadComplete = false;
            downloadError    = null;
            timeOutTimer.Start();
            do
            {
                if (printCount == 9)
                {
                    TL.LogMessage(Function, string.Format("Waiting for download to complete...{0} / {1} seconds", timeOutTimer.Elapsed.TotalSeconds.ToString("0"), parameters.DownloadTaskTimeOut));
                    printCount = 0;
                }
                else
                {
                    printCount += 1;
                }
                Thread.Sleep(100);
            } while (!DownloadComplete & (timeOutTimer.Elapsed.TotalSeconds < parameters.DownloadTaskTimeOut));

            if (DownloadComplete)
            {
                if (downloadError == null) // No error occurred
                {
                    TL.LogMessage(Function, "Response headers");
                    WebHeaderCollection responseHeaders = Client.ResponseHeaders;
                    if (!(responseHeaders is null))
                    {
                        foreach (string header in responseHeaders.AllKeys)
                        {
                            TL.LogMessage(Function, string.Format("Response header {0} = {1}", header, responseHeaders[header]));
                        }
                    }
                    FileInfo info = new FileInfo(tempFileName);
                    TL.LogMessage(Function, string.Format("Successfully downloaded {0} from {1} as {2}. Size: {3}", DataFile, Client.BaseAddress, tempFileName, info.Length));
                }
                else // An error occurred
                {
                    // Just throw the error, which will be reported in the calling routine
                    throw downloadError;
                }
            }
            else
            {
                TL.LogMessage(Function, string.Format("Download cancelled because of {0} second timeout", DownloadTimeout));
                try
                {
                    Client.CancelAsync();
                }
                catch (Exception ex)
                {
                    TL.LogMessageCrLf("DownloadFile", "Exception cancelling download: " + ex.ToString());
                }

                throw new TimeoutException(string.Format("Timed out downloading {0} from {1} as {2}", DataFile, Client.BaseAddress, tempFileName));
            }
            TL.BlankLine();

            return(tempFileName);
        }
Пример #5
0
        private static readonly double UNKNOWN_LEAP_SECONDS = double.MinValue;   // Value for dates which have not yet been determined

        static void Main(string[] args)
        {
            try
            {
                // In December 2020, ascom-standards.org minimum SSL protocol version is TLS1.2
                // Normally, this application will use the OS default SSL protocol, but Windows 7 default protocol is earlier that TLS1.2 and connection cannot be established to ascom-standards.org from this OS.
                // The following command ensures that TLS1.2 will be tried in addition to the OS default protocol.
                ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.SystemDefault;

                // Get some basic details for this run
                string   runBy    = WindowsIdentity.GetCurrent().Name; // Get the name of the user executing this program
                bool     isSystem = WindowsIdentity.GetCurrent().IsSystem;
                DateTime now      = DateTime.Now;

                ReturnCode = 0; // Initialise return code to success

                // Get access to the ASCOM Profile store and retrieve the trace logger configuration
                RegistryAccess profile       = new RegistryAccess();
                string         traceFileName = "";
                string         traceBasePath = "";
                if (isSystem) // If we are running as user SYSTEM, create our own trace file name so that all scheduled job trace files end up in the same directory
                {
                    // Get the configured trace file directory and make sure that it exists
                    traceBasePath = profile.GetProfile(GlobalItems.ASTROMETRY_SUBKEY,
                                                       GlobalItems.DOWNLOAD_TASK_TRACE_PATH_VALUE_NAME,
                                                       string.Format(GlobalItems.DOWNLOAD_TASK_TRACE_DEFAULT_PATH_FORMAT, Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments))
                                                       ).TrimEnd('\\');
                    Directory.CreateDirectory(traceBasePath);
                    // Now make the full trace file name from the path above and the file name format template
                    traceFileName = string.Format(GlobalItems.DOWNLOAD_TASK_TRACE_FILE_NAME_FORMAT, traceBasePath, now.Year, now.Month, now.Day, now.Hour.ToString("00"), now.Minute.ToString("00"), now.Second.ToString("00"));
                }

                // Get the trace state from the Profile
                string DownloadTaskTraceEnabledString = profile.GetProfile(GlobalItems.ASTROMETRY_SUBKEY, GlobalItems.DOWNLOAD_TASK_TRACE_ENABLED_VALUE_NAME, GlobalItems.DOWNLOAD_TASK_TRACE_ENABLED_DEFAULT.ToString());
                if (!Boolean.TryParse(DownloadTaskTraceEnabledString, out bool DownloadTaskTraceEnabledValue)) //' String parsed OK so no further action
                {                                                                                              //'Returned string doesn't represent a boolean so use the default
                    DownloadTaskTraceEnabledValue = GlobalItems.DOWNLOAD_TASK_TRACE_ENABLED_DEFAULT;
                }

                // Create the trace logger with either the supplied fully qualified name if running as SYSTEM or an automatic file name if running as a normal user
                TL                 = new TraceLogger(traceFileName, GlobalItems.DOWNLOAD_TASK_TRACE_LOG_FILETYPE);
                TL.Enabled         = DownloadTaskTraceEnabledValue; // Set the trace state
                TL.IdentifierWidth = GlobalItems.DOWNLOAD_TASK_TRACE_LOGGER_IDENTIFIER_FIELD_WIDTH;

                invariantCulture = new CultureInfo("");
                invariantCulture.Calendar.TwoDigitYearMax = 2117;                          // Specify that two digit years will be converted to the range 2018-2117 - Likely to outlast ASCOM Platform and me!
                monthAbbrev       = invariantCulture.DateTimeFormat.AbbreviatedMonthNames; // Get the 12 three letter abbreviated month names of the year
                invariantTextInfo = invariantCulture.TextInfo;

                TL.LogMessage("EarthRotationUpdate", string.Format("InstalledUICulture: {0}, CurrentUICulture: {1}, CurrentCulture: {2}", CultureInfo.InstalledUICulture.Name, CultureInfo.CurrentUICulture, CultureInfo.CurrentCulture));

                parameters = new EarthRotationParameters(TL);                                                       // Get configuration from the Profile store
                string runDate = now.ToString(GlobalItems.DOWNLOAD_TASK_TIME_FORMAT, CultureInfo.CurrentUICulture); // Get today's date and time in a locally readable format
                hostURIString = parameters.DownloadTaskDataSource;                                                  // Initialise the data source URI

                if (args.Length > 0)
                {
                    foreach (string arg in args)
                    {
                        TL.LogMessage("EarthRotationUpdate", string.Format("Received parameter: {0}", arg));
                    }
                }

                // If we have been provided with an "Initialise" parameter then stop here after having set up all the default profile values by creating the EarthRotationParameters object
                if (args.Length == 1)
                {
                    if (args[0].Trim(' ', '-', '\\', '/').Equals("INITIALISE", StringComparison.OrdinalIgnoreCase)) // Test for the presence of and act on the initialise argument ignoring everything else
                    {
                        TL.LogMessage("EarthRotationUpdate", string.Format("Earth rotation parameter initialisation run on {0} by {1}, IsSystem: {2}", runDate, runBy, isSystem));
                        LogEvent(string.Format("Earth rotation parameter initialisation run on {0} by {1}, IsSystem: {2}", runDate, runBy, isSystem), EventLogEntryType.Information);

                        TL.LogMessage("EarthRotationUpdate", string.Format("Calling ManageScheduledTask"));
                        parameters.ManageScheduledTask();
                        TL.LogMessage("EarthRotationUpdate", string.Format("Completed ManageScheduledTask"));

                        Environment.Exit(0);
                    }
                }

                // If we have been provided with a "DataSource" override parameter then apply the new URI otherwise read it from the Profile
                if (args.Length == 2)
                {
                    if (args[0].Trim(' ', '-', '\\', '/').Equals("DATASOURCE", StringComparison.OrdinalIgnoreCase)) // Test for the presence of and act on the data source argument ignoring everything else
                    {
                        TL.LogMessage("EarthRotationUpdate", string.Format("Data source override parameter provided: {0}", args[1]));
                        string overrideDataSource = args[1].Trim(' ', '"');
                        bool   UriValid           = false; // Set the valid flag false, then set to true if the download source starts with a supported URI prefix
                        if (overrideDataSource.StartsWith(GlobalItems.URI_PREFIX_HTTP, StringComparison.OrdinalIgnoreCase))
                        {
                            UriValid = true;
                        }
                        if (overrideDataSource.StartsWith(GlobalItems.URI_PREFIX_HTTPS, StringComparison.OrdinalIgnoreCase))
                        {
                            UriValid = true;
                        }
                        if (overrideDataSource.StartsWith(GlobalItems.URI_PREFIX_FTP, StringComparison.OrdinalIgnoreCase))
                        {
                            UriValid = true;
                        }

                        if (UriValid)
                        {
                            hostURIString = overrideDataSource;
                            TL.LogMessage("EarthRotationUpdate", string.Format("Data source override parameter is valid and will be used: {0}", hostURIString));
                        }
                        else
                        {
                            TL.LogMessage("EarthRotationUpdate", string.Format("Data source override parameter {0} is not valid and the Profile data source will be used instead: {1}", overrideDataSource, hostURIString));
                        }
                    }
                }

                // Ensure that the host URI string, wherever it has come from, ends with a single backslash otherwise the URI will be incorrect when the file name is formed
                hostURIString = hostURIString.TrimEnd(' ', '-', '\\', '/') + "/";

                LogEvent(string.Format("Run on {0} by {1}, IsSystem: {2}", runDate, runBy, isSystem), EventLogEntryType.Information);
                TL.LogMessage("EarthRotationUpdate", string.Format("Run on {0} by {1}, IsSystem: {2}", runDate, runBy, isSystem));
                TL.BlankLine();
                LogEvent(string.Format("Log file: {0}, Trace state: {1}, Log file path: {2}", TL.LogFileName, parameters.DownloadTaskTraceEnabled, TL.LogFilePath), EventLogEntryType.Information);
                TL.LogMessage("EarthRotationUpdate", string.Format("Log file: {0}, Trace state: {1}, Log file path: {2}", TL.LogFileName, parameters.DownloadTaskTraceEnabled, TL.LogFilePath));
                TL.LogMessage("EarthRotationUpdate", string.Format("Earth rotation data last updated: {0}", parameters.EarthRotationDataLastUpdatedString));
                TL.LogMessage("EarthRotationUpdate", string.Format("Data source: {0}", hostURIString));

                DownloadTimeout = parameters.DownloadTaskTimeOut;

                WebClient client = new WebClient();

                client.DownloadProgressChanged += Client_DownloadProgressChanged;
                client.DownloadFileCompleted   += Client_DownloadFileCompleted;

                Uri hostURI = new Uri(hostURIString);

                if (WebRequest.DefaultWebProxy.GetProxy(hostURI) == hostURI)
                {
                    TL.LogMessage("EarthRotationUpdate", "No proxy server detected, going directly to Internet"); // No proxy is in use so go straight out
                }
                else // Proxy is in use so set it and apply credentials
                {
                    TL.LogMessage("EarthRotationUpdate", "Setting default proxy");
                    client.Proxy = WebRequest.DefaultWebProxy;
                    TL.LogMessage("EarthRotationUpdate", "Setting default credentials");
                    client.Proxy.Credentials = CredentialCache.DefaultCredentials;
                    TL.LogMessage("EarthRotationUpdate", "Using proxy server: " + WebRequest.DefaultWebProxy.GetProxy(hostURI).ToString());
                }

                client.Headers.Add("user-agent", GlobalItems.DOWNLOAD_TASK_USER_AGENT);
                client.Headers.Add("Accept", "text/plain");
                client.Encoding    = Encoding.ASCII;
                client.BaseAddress = hostURIString;
                NetworkCredential credentials = new NetworkCredential("anonymous", "guest"); // Apply some standard credentials for FTP sites
                client.Credentials = credentials;
                TL.BlankLine();

                // Get the latest delta UT1 values
                try
                {
                    string   dUT1fileName = DownloadFile("DeltaUT1", GlobalItems.DELTAUT1_FILE, client, TL); // Download the latest delta UT1 values and receive the filename holding the data
                    FileInfo info         = new FileInfo(dUT1fileName);                                      // Find out if we have any data
                    if (info.Length > 0)                                                                     // We actually received some data so process it
                    {
                        // List the data position parameters that will be used to extract the delta UT1 data from the file
                        TL.LogMessage("DeltaUT1", string.Format("Expected file format for the {0} file", GlobalItems.DELTAUT1_FILE));
                        TL.LogMessage("DeltaUT1", string.Format("Year string start position: {0}, Year string length: {1}", GlobalItems.DELTAUT1_YEAR_START, GlobalItems.DELTAUT1_YEAR_LENGTH));
                        TL.LogMessage("DeltaUT1", string.Format("Month string start position: {0}, Month string length: {1}", GlobalItems.DELTAUT1_MONTH_START, GlobalItems.DELTAUT1_MONTH_LENGTH));
                        TL.LogMessage("DeltaUT1", string.Format("Day string start position: {0}, Day string length: {1}", GlobalItems.DELTAUT1_DAY_START, GlobalItems.DELTAUT1_DAY_LENGTH));
                        TL.LogMessage("DeltaUT1", string.Format("Julian date start position: {0}, Julian date string length: {1}", GlobalItems.DELTAUT1_JULIAN_DATE_START, GlobalItems.DELTAUT1_JULIAN_DATE_LENGTH));
                        TL.LogMessage("DeltaUT1", string.Format("Delta UT1 start position: {0}, Delta UT1 string length: {1}", GlobalItems.DELTAUT1_START, GlobalItems.DELTAUT1_LENGTH));
                        TL.BlankLine();

                        profile.DeleteKey(GlobalItems.AUTOMATIC_UPDATE_DELTAUT1_SUBKEY_NAME); // Clear out old delta UT1 values
                        profile.CreateKey(GlobalItems.AUTOMATIC_UPDATE_DELTAUT1_SUBKEY_NAME);

                        // Process the data file
                        using (var filestream = new FileStream(dUT1fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
                        {
                            using (var file = new StreamReader(filestream, Encoding.ASCII, true, 4096))
                            {
                                string   lineOfText;
                                DateTime date;

                                while ((lineOfText = file.ReadLine()) != null) // Get lines of text one at a time and parse them
                                {
                                    try
                                    {
                                        // Extract string values for data items
                                        string yearString       = lineOfText.Substring(GlobalItems.DELTAUT1_YEAR_START, GlobalItems.DELTAUT1_YEAR_LENGTH);
                                        string monthString      = lineOfText.Substring(GlobalItems.DELTAUT1_MONTH_START, GlobalItems.DELTAUT1_MONTH_LENGTH);
                                        string dayString        = lineOfText.Substring(GlobalItems.DELTAUT1_DAY_START, GlobalItems.DELTAUT1_DAY_LENGTH);
                                        string julianDateString = lineOfText.Substring(GlobalItems.DELTAUT1_JULIAN_DATE_START, GlobalItems.DELTAUT1_JULIAN_DATE_LENGTH);
                                        string dUT1String       = lineOfText.Substring(GlobalItems.DELTAUT1_START, GlobalItems.DELTAUT1_LENGTH);

                                        // Validate that the data items are parse-able
                                        bool yearOK       = int.TryParse(yearString, NumberStyles.Integer, CultureInfo.InvariantCulture, out int year);
                                        bool monthOK      = int.TryParse(monthString, NumberStyles.Integer, CultureInfo.InvariantCulture, out int month);
                                        bool dayOK        = int.TryParse(dayString, NumberStyles.Integer, CultureInfo.InvariantCulture, out int day);
                                        bool julianDateOK = double.TryParse(julianDateString, NumberStyles.Float, CultureInfo.InvariantCulture, out double julianDate);
                                        bool dut1OK       = double.TryParse(dUT1String, NumberStyles.Float, CultureInfo.InvariantCulture, out double dUT1);

                                        if (yearOK & monthOK & dayOK & julianDateOK & dut1OK)       // We have good values for all data items so save these to the Profile
                                        {
                                            year = invariantCulture.Calendar.ToFourDigitYear(year); // Convert the two digit year to a four digit year
                                            date = new DateTime(year, month, day);

                                            // Only save the item if it is from a few days back or is a future prediction
                                            if (date.Date >= DateTime.Now.Date.Subtract(new TimeSpan(GlobalItems.DOWNLOAD_TASK_NUMBER_OF_BACK_DAYS_OF_DELTAUT1_DATA_TO_LOAD, 0, 0, 0)))
                                            {
                                                string deltaUT1ValueName = string.Format(GlobalItems.DELTAUT1_VALUE_NAME_FORMAT,
                                                                                         date.Year.ToString(GlobalItems.DELTAUT1_VALUE_NAME_YEAR_FORMAT),
                                                                                         date.Month.ToString(GlobalItems.DELTAUT1_VALUE_NAME_MONTH_FORMAT),
                                                                                         date.Day.ToString(GlobalItems.DELTAUT1_VALUE_NAME_DAY_FORMAT));
                                                TL.LogMessage("DeltaUT1", string.Format("Setting {0}, JD = {1} - DUT1 = {2} with key: {3}", date.ToLongDateString(), julianDate, dUT1, deltaUT1ValueName));
                                                profile.WriteProfile(GlobalItems.AUTOMATIC_UPDATE_DELTAUT1_SUBKEY_NAME, deltaUT1ValueName, dUT1.ToString("0.000", CultureInfo.InvariantCulture));
                                            }
                                        }
                                        else
                                        {
                                            TL.LogMessage("DeltaUT1", string.Format("Unable to parse Delta UT1 values from the line below - Year: {0}, Month: {1}, Day: {2}, Julian Day: {3},Delta UT1: {4}",
                                                                                    yearString, monthString, dayString, julianDateString, dUT1String));
                                            TL.LogMessage("DeltaUT1", string.Format("Corrupt line: {0}", lineOfText));
                                        }
                                    }
                                    catch (Exception ex)
                                    {
                                        TL.LogMessageCrLf("DeltaUT1", string.Format("Unexpected exception: {0}, parsing line: ", ex.Message, lineOfText));
                                        TL.LogMessageCrLf("DeltaUT1", ex.ToString());
                                    }
                                }
                            }
                        }
                    }
                    else
                    {
                        TL.LogMessage("DeltaUT1", string.Format("Downloaded file size was zero so nothing to process!"));
                    }
                    File.Delete(dUT1fileName);
                    TL.BlankLine();
                }
                catch (WebException ex) // An issue occurred with receiving the leap second file over the network
                {
                    TL.LogMessageCrLf("DeltaUT1", string.Format("Error: {0} - delta UT1 data not updated", ex.Message));
                    ReturnCode = 1;
                }
                catch (Exception ex)
                {
                    TL.LogMessageCrLf("DeltaUT1", ex.ToString());
                    ReturnCode = 2;
                }

                // Get the latest leap second values
                try
                {
                    string   leapSecondsfileName = DownloadFile("LeapSeconds", GlobalItems.LEAP_SECONDS_FILE, client, TL); // Download the latest leap second values and receive the filename holding the data
                    FileInfo info = new FileInfo(leapSecondsfileName);                                                     // Find out if we have any data
                    if (info.Length > 0)                                                                                   // We actually received some data so process it
                    {
                        // List the data position parameters that will be used to extract the delta UT1 data from the file
                        TL.LogMessage("LeapSeconds", string.Format("Expected file format for the {0} file", GlobalItems.DELTAUT1_FILE));
                        TL.LogMessage("LeapSeconds", string.Format("Year string start position: {0}, Year string length: {1}", GlobalItems.LEAP_SECONDS_YEAR_START, GlobalItems.LEAP_SECONDS_YEAR_LENGTH));
                        TL.LogMessage("LeapSeconds", string.Format("Month string start position: {0}, Month string length: {1}", GlobalItems.LEAP_SECONDS_MONTH_START, GlobalItems.LEAP_SECONDS_MONTH_LENGTH));
                        TL.LogMessage("LeapSeconds", string.Format("Day string start position: {0}, Day string length: {1}", GlobalItems.LEAP_SECONDS_DAY_START, GlobalItems.LEAP_SECONDS_DAY_LENGTH));
                        TL.LogMessage("LeapSeconds", string.Format("Julian date start position: {0}, Julian date string length: {1}", GlobalItems.LEAP_SECONDS_JULIAN_DATE_START, GlobalItems.LEAP_SECONDS_JULIAN_DATE_LENGTH));
                        TL.LogMessage("LeapSeconds", string.Format("Leap seconds start position: {0}, Leap seconds string length: {1}", GlobalItems.LEAP_SECONDS_LEAPSECONDS_START, GlobalItems.LEAP_SECONDS_LEAPSECONDS_LENGTH));
                        TL.BlankLine();

                        profile.DeleteKey(GlobalItems.AUTOMATIC_UPDATE_LEAP_SECOND_HISTORY_SUBKEY_NAME);;  // Clear out old leap second values
                        profile.CreateKey(GlobalItems.AUTOMATIC_UPDATE_LEAP_SECOND_HISTORY_SUBKEY_NAME);

                        // Process the data file
                        using (var filestream = new FileStream(leapSecondsfileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
                        {
                            double   currentLeapSeconds  = UNKNOWN_LEAP_SECONDS;
                            double   nextLeapSeconds     = 0.0;
                            DateTime leapSecondDate      = UNKNOWN_DATE;
                            DateTime nextleapSecondsDate = UNKNOWN_DATE;

                            using (var file = new StreamReader(filestream, Encoding.ASCII, true, 4096))
                            {
                                string   lineOfText;
                                DateTime latestLeapSecondDate = UNKNOWN_DATE;
                                while ((lineOfText = file.ReadLine()) != null) // Get lines of text one at a time and parse them
                                {
                                    try
                                    {
                                        // Read values from the file as strings based on their position within the file
                                        string yearString        = lineOfText.Substring(GlobalItems.LEAP_SECONDS_YEAR_START, GlobalItems.LEAP_SECONDS_YEAR_LENGTH);
                                        string monthString       = lineOfText.Substring(GlobalItems.LEAP_SECONDS_MONTH_START, GlobalItems.LEAP_SECONDS_MONTH_LENGTH);
                                        string dayString         = lineOfText.Substring(GlobalItems.LEAP_SECONDS_DAY_START, GlobalItems.LEAP_SECONDS_DAY_LENGTH);
                                        string julianDateString  = lineOfText.Substring(GlobalItems.LEAP_SECONDS_JULIAN_DATE_START, GlobalItems.LEAP_SECONDS_JULIAN_DATE_LENGTH);
                                        string leapSecondsString = lineOfText.Substring(GlobalItems.LEAP_SECONDS_LEAPSECONDS_START, GlobalItems.LEAP_SECONDS_LEAPSECONDS_LENGTH);

                                        // Validate that the data items are parse-able
                                        bool yearOK        = int.TryParse(yearString, NumberStyles.Integer, CultureInfo.InvariantCulture, out int year);
                                        bool dayOK         = int.TryParse(dayString, NumberStyles.Integer, CultureInfo.InvariantCulture, out int day);
                                        bool julianDateOK  = double.TryParse(julianDateString, NumberStyles.Float, CultureInfo.InvariantCulture, out double julianDate);
                                        bool leapSecondsOK = double.TryParse(leapSecondsString, NumberStyles.Float, CultureInfo.InvariantCulture, out double leapSeconds);

                                        // Get the month number by trimming the month string, converting to lower case then title case then looking up the index in the abbreviated months array
                                        int month = Array.IndexOf(monthAbbrev, invariantTextInfo.ToTitleCase(monthString.Trim(' ').ToLower(CultureInfo.InvariantCulture))) + 1; // If IndexOf fails, it returns -1 so the resultant month number will be zero and this is checked below

                                        if (yearOK & (month > 0) & dayOK & julianDateOK & leapSecondsOK)                                                                        // We have good values for all data items so save these to the Profile
                                        {
                                            double modifiedJulianDate = julianDate - GlobalItems.MODIFIED_JULIAN_DAY_OFFSET;
                                            leapSecondDate = new DateTime(year, month, day);

                                            // Write all leap second values and Julian dates that they become effective to the leap second history subkey
                                            profile.WriteProfile(GlobalItems.AUTOMATIC_UPDATE_LEAP_SECOND_HISTORY_SUBKEY_NAME, julianDate.ToString(CultureInfo.InvariantCulture), leapSeconds.ToString(CultureInfo.InvariantCulture));

                                            if ((leapSecondDate.Date >= latestLeapSecondDate) & (leapSecondDate.Date <= DateTime.UtcNow.Date.Subtract(new TimeSpan(GlobalItems.TEST_HISTORIC_DAYS_OFFSET, 0, 0, 0))))
                                            {
                                                currentLeapSeconds = leapSeconds;
                                            }
                                            if ((leapSecondDate.Date > DateTime.UtcNow.Date.Subtract(new TimeSpan(GlobalItems.TEST_HISTORIC_DAYS_OFFSET, 0, 0, 0))) & (nextleapSecondsDate == UNKNOWN_DATE)) // Record the next leap seconds value in the file
                                            {
                                                nextLeapSeconds     = leapSeconds;
                                                nextleapSecondsDate = leapSecondDate;
                                            }

                                            TL.LogMessage("LeapSeconds", string.Format("Leap second takes effect on: {0}, Modified JD = {1} - Current Leap Seconds = {2}, Latest Leap Seconds: {3}, Next Leap Seconds: {4} on {5}", leapSecondDate.ToLongDateString(), modifiedJulianDate, leapSeconds, currentLeapSeconds, nextLeapSeconds, nextleapSecondsDate.ToLongDateString()));
                                        }
                                        else
                                        {
                                            TL.LogMessage("LeapSeconds", string.Format("Unable to parse leap second values from the line below - Year: {0}, Month: {1}, Day: {2}, Julian Day: {3},Leap seconds: {4}",
                                                                                       yearString, monthString, dayString, julianDateString, leapSecondsString));
                                            TL.LogMessage("LeapSeconds", string.Format("Corrupt line: {0}", lineOfText));
                                        }
                                    }
                                    catch (Exception ex)
                                    {
                                        TL.LogMessageCrLf("LeapSeconds", ex.ToString());
                                    }
                                }
                            }
                            TL.BlankLine();

                            if (currentLeapSeconds == UNKNOWN_LEAP_SECONDS) // No valid leap seconds were found so indicate that this
                            {
                                profile.WriteProfile(GlobalItems.ASTROMETRY_SUBKEY, GlobalItems.AUTOMATIC_LEAP_SECONDS_VALUENAME, GlobalItems.AUTOMATIC_LEAP_SECONDS_NOT_AVAILABLE_DEFAULT);
                            }
                            else  // Persist the current leap second value to the Profile
                            {
                                parameters.AutomaticLeapSecondsString = currentLeapSeconds.ToString(CultureInfo.InvariantCulture);
                                // Also include a value that is in the SOFA library defaults but is not in the USNO files. It pre-dates the start of UTC but I am assuming that IAU is correct on this occasion
                                profile.WriteProfile(GlobalItems.AUTOMATIC_UPDATE_LEAP_SECOND_HISTORY_SUBKEY_NAME, double.Parse("2436934.5", CultureInfo.InvariantCulture).ToString(CultureInfo.InvariantCulture), double.Parse("1.4178180", CultureInfo.InvariantCulture).ToString(CultureInfo.InvariantCulture));
                            }

                            // Persist the next leap second value and its implementation date if these have been announced
                            if (nextleapSecondsDate == UNKNOWN_DATE) // No announcement has been made
                            {
                                parameters.NextLeapSecondsString     = GlobalItems.DOWNLOAD_TASK_NEXT_LEAP_SECONDS_NOT_PUBLISHED_MESSAGE;
                                parameters.NextLeapSecondsDateString = GlobalItems.DOWNLOAD_TASK_NEXT_LEAP_SECONDS_NOT_PUBLISHED_MESSAGE;
                            }
                            else // A future leap second has been announced
                            {
                                parameters.NextLeapSecondsString     = nextLeapSeconds.ToString(CultureInfo.InvariantCulture);
                                parameters.NextLeapSecondsDateString = nextleapSecondsDate.ToString(GlobalItems.DOWNLOAD_TASK_TIME_FORMAT, CultureInfo.InvariantCulture);
                            }
                            TL.BlankLine();
                            TL.LogMessage("LeapSeconds", string.Format("Current Leap Seconds = {0}, Next Leap Seconds: {1} on {2}", currentLeapSeconds, nextLeapSeconds, nextleapSecondsDate.ToLongDateString()));
                        }
                    }
                    else
                    {
                        TL.LogMessage("LeapSeconds", string.Format("Downloaded file size was zero so nothing to process!"));
                    }

                    parameters.EarthRotationDataLastUpdatedString = runDate; // Save a new last run time to the Profile

                    TL.BlankLine();
                    TL.LogMessage("LeapSeconds", string.Format("Task completed."));

                    File.Delete(leapSecondsfileName);
                    parameters.Dispose();
                    parameters = null;
                }
                catch (WebException ex) // An issue occurred with receiving the leap second file over the network
                {
                    TL.LogMessageCrLf("LeapSeconds", string.Format("Error: {0} - leap second data not updated.", ex.Message));
                    ReturnCode = 3;
                }
                catch (Exception ex)
                {
                    TL.LogMessageCrLf("LeapSeconds", ex.ToString());
                    ReturnCode = 4;
                }

                TL.Enabled = false;
                TL.Dispose();
                TL = null;
            }
            catch (Exception ex)
            {
                try { TL.LogMessageCrLf("EarthRotationUpdate", ex.ToString()); } catch { }

                EventLogCode.LogEvent("EarthRotationUpdate",
                                      string.Format("EarthRotationUpdate - Unexpected exception: {0}", ex.Message),
                                      EventLogEntryType.Error,
                                      GlobalConstants.EventLogErrors.EarthRotationUpdate,
                                      ex.ToString());
                ReturnCode = 5;
            }
            Environment.Exit(ReturnCode);
        }
Пример #6
0
        /// <summary>
        /// Trawls through the Platform source code base picking out all GUIDs explicitly defined. These are then written out as the
        /// GUIDList class in the RemoveASCOM program so that it can remove these from the user's PC. This dynamic approach is used so that this
        /// application is maintenance free as new GUIDs are added in future.
        ///
        /// This program is run by the build process before RemoveASCOM is compiled so that GUIDList is up to date.
        /// </summary>
        /// <param name="args">Accepts one parameter, the full path to the base of the Exported Platform source code.</param>
        /// <remarks> If the command line parameter is omitted the program will default to values appropriate to the development environment as oposed to the build environment.</remarks>
        static void Main(string[] args)
        {
            // Settings for use in the development environment, these are overriden by a command line argument in the build environment
            string developmentSearchPath          = @"..\..\..\..";
            string outputPath                     = @"\Remove ASCOM\Remove ASCOM\";
            string devlopmentPath                 = developmentSearchPath + outputPath;
            string outputClassFileName            = @"DynamicLists.vb";
            string outputTextFileName             = @"GUIDList.txt";
            string platformInstallerTextFileName  = @"\Releases\ASCOM 6\Platform\Installer Project\Ascom Platform 6.mia.txt";
            string developerInstallerTextFileName = @"\Releases\ASCOM 6\Developer\Installer Project\ASCOM Platform 6 Developer.mia.txt";

            // Construct the development environment values
            string sourceSearchPath                   = developmentSearchPath;
            string outputClassFullFileName            = devlopmentPath + outputClassFileName;
            string outputTextFullFileName             = devlopmentPath + outputTextFileName;
            string platformInstallerTextFileFullName  = developmentSearchPath + platformInstallerTextFileName;
            string developerInstallerTextFileFullName = developmentSearchPath + developerInstallerTextFileName;

            // Storage for the GUIDs found and a suppression list of GUIDs that should be left undisturbed
            SortedList <string, string> guidList = new SortedList <string, string>();
            List <string> guidSuppressionList    = new List <string>();

            // Storage for the lists of files installed by the Platform
            SortedSet <string> platformFileList  = new SortedSet <string>();
            SortedSet <string> developerFileList = new SortedSet <string>();

            using (TraceLogger TL = new TraceLogger("", "MakeDynamicLists"))
            {
                TL.Enabled = true;

                //
                // Create the list of GUIDs created by the Platform
                //
                try
                {
                    // Override the source and output paths if a command line search path is provided
                    if (args.Length > 0)
                    {
                        sourceSearchPath                   = args[0];
                        outputClassFullFileName            = args[0] + outputPath + outputClassFileName;
                        outputTextFullFileName             = args[0] + outputPath + outputTextFileName;
                        platformInstallerTextFileFullName  = args[0] + platformInstallerTextFileName;
                        developerInstallerTextFileFullName = args[0] + developerInstallerTextFileName;
                    }

                    TL.LogMessage("Main", "Search path: " + Path.GetFullPath(sourceSearchPath));
                    TL.LogMessage("Main", "Output class file: " + Path.GetFullPath(outputClassFullFileName));
                    TL.LogMessage("Main", "Output text file: " + Path.GetFullPath(outputTextFullFileName));

                    // Add required items to the suppression list so that they are not deleted by RemoveASCOM when it runs
                    guidSuppressionList.Add("00000001-0000-0000-C000-000000000046");
                    guidSuppressionList.Add("00000002-0000-0000-C000-000000000046");

                    // Set up a regular expression for a GUID format e.g.:   Guid("0EF59E5C-2715-4E91-8A5E-38FE388B4F00")
                    // Regular expression groups within the matched GUID:    <-G1-><--------------G2------------------>
                    // Group 2 picks out the GUID value inside the double quote characters. This is used as m.Groups[2] below
                    Regex regexGuid = new Regex(@"(Guid\(\"")([0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12})""", RegexOptions.IgnoreCase);

                    // Get a list of all the files with a .cs CSharp extension
                    List <string> files = new List <string>(Directory.GetFiles(sourceSearchPath, "*.cs*", SearchOption.AllDirectories));
                    TL.LogMessage("Main", "Number of C# files found: " + files.Count);

                    // Add the list of files with a .vb extension
                    files.AddRange(new List <string>(Directory.GetFiles(sourceSearchPath, "*.vb*", SearchOption.AllDirectories)));
                    TL.LogMessage("Main", "Total files found: " + files.Count);

                    // Process the list of files opening each file in turn and searching every line with the GUID regular expression
                    // Save every match except for those on the suppression list
                    foreach (string file in files)
                    {
                        if (!file.Contains(Path.GetFileName(outputClassFullFileName)))        // Process all files except our output file!
                        {
                            List <string> lines = new List <string>(File.ReadAllLines(file)); // Get all lines into a list
                            foreach (string line in lines)                                    // Iterate over the list of lines
                            {
                                Match m = regexGuid.Match(line);                              // Use the regular expression to search for a match
                                if (m.Success)                                                // We have found a GUID
                                {
                                    try
                                    {
                                        // Check whether this a GUID to suppress
                                        if (!guidSuppressionList.Contains(m.Groups[2].ToString()))        // Not suppressed
                                        {
                                            guidList.Add(m.Groups[2].ToString(), Path.GetFullPath(file)); // Add the GUID to the found GUIDs list
                                            TL.LogMessage("Main", "Match: " + m.Groups[2] + " in: " + file);
                                        }
                                        else // This GUID should be left alone so don't add it to the list
                                        {
                                            TL.LogMessage("Main", "Suppressing: " + m.Groups[2] + " in: " + file);
                                        }
                                    }
                                    catch (ArgumentException) // The GUID has already been added so ignore it as a duplicate
                                    {
                                        TL.LogMessage("Main", "Duplicate: " + m.Groups[2] + " in: " + file);
                                    }
                                }
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    TL.LogMessageCrLf("Main", "Exception creating GUID list: " + ex.ToString());
                }
                TL.BlankLine();

                // Create lists of "Install Files" lines in the Platform and Developer installer scripts
                platformFileList  = FindInstalledFiles(platformInstallerTextFileFullName, TL);  // Lines from the Platform installer
                developerFileList = FindInstalledFiles(developerInstallerTextFileFullName, TL); // Lines from the Developer installer.
                TL.BlankLine();

                //
                // Create the class file that will be used by the RemoveASCOM program
                //
                try
                {
                    // Create the streamwriter to make the updated GUIDList class file and the readable txt file
                    StreamWriter outputTextFile  = new StreamWriter(outputTextFullFileName);
                    StreamWriter outputClassFile = new StreamWriter(outputClassFullFileName);

                    // Add the first lines of the GUID text list
                    outputTextFile.WriteLine(@"This is a list of the GUIDs that will be removed by RemoveASCOM");
                    outputTextFile.WriteLine(" ");

                    // Add the first lines of the DynamicLists class
                    outputClassFile.WriteLine(@"' ***** WARNING ***** WARNING ***** WARNING *****");
                    outputClassFile.WriteLine(" ");
                    outputClassFile.WriteLine(@"' This class is dynamically generated by the MakeDynamicLists Program.");
                    outputClassFile.WriteLine(@"' Do not alter this class, alter the MakeDynamicLists program instead and your changes will appear when the next build is made.");
                    outputClassFile.WriteLine(" ");
                    outputClassFile.WriteLine("Imports System.Collections.Generic");
                    outputClassFile.WriteLine("Imports System.IO");
                    outputClassFile.WriteLine(" ");
                    outputClassFile.WriteLine("Class DynamicLists");
                    outputClassFile.WriteLine("");

                    // Add the first lines of the GUIDs member
                    outputClassFile.WriteLine("    Shared Function GUIDs(TL as TraceLogger) As SortedList(Of String, String)");
                    outputClassFile.WriteLine("        Dim guidList As SortedList(Of String, String)");
                    outputClassFile.WriteLine("        guidList = New SortedList(Of String, String)");

                    // Add the GUIDs in the list
                    foreach (KeyValuePair <string, string> guid in guidList)
                    {
                        TL.LogMessage("Main", "Adding to class: " + guid.Key + " in: " + guid.Value);
                        outputClassFile.WriteLine("        Try : guidList.Add(\"" + guid.Key + "\", \"" + guid.Value + "\") :TL.LogMessage(\"GUIDs\",\"Added GUID: \" + \"" + guid.Key + "\") : Catch ex As ArgumentException : TL.LogMessage(\"GUIDs\",\"Duplicate GUID: \" + \"" + guid.Key + "\"):End Try");
                        outputTextFile.WriteLine(guid.Key + " defined in: " + guid.Value);
                    }

                    // Add the closing lines of the GUIDs member
                    outputClassFile.WriteLine("        Return guidList");
                    outputClassFile.WriteLine("    End Function");
                    outputClassFile.WriteLine("");

                    // Add the first lines of the PlatformFiles member
                    outputClassFile.WriteLine("    Shared Function PlatformFiles(TL as TraceLogger) As SortedSet(Of String)");
                    outputClassFile.WriteLine("        Dim fileList As SortedSet(Of String)");
                    outputClassFile.WriteLine("        fileList = New SortedSet(Of String)");

                    // Add the files in the list
                    foreach (string file in platformFileList)
                    {
                        TL.LogMessage("Main", "Adding to class: " + file);
                        outputClassFile.WriteLine("        Try : fileList.Add(\"" + file + "\") :TL.LogMessage(\"PlatformFiles\",\"Added file: " + file + "\") : Catch ex As Exception : TL.LogMessage(\"PlatformFiles\",\"Exception: \" + ex.ToString()):End Try");
                    }

                    // Add the closing lines of the PlatformFiles member
                    outputClassFile.WriteLine("        Return fileList");
                    outputClassFile.WriteLine("    End Function");
                    outputClassFile.WriteLine("");


                    // Add the first lines of the DeveloperFiles member
                    outputClassFile.WriteLine("    Shared Function DeveloperFiles(TL as TraceLogger) As SortedSet(Of String)");
                    outputClassFile.WriteLine("        Dim fileList As SortedSet(Of String)");
                    outputClassFile.WriteLine("        fileList = New SortedSet(Of String)");

                    // Add the files in the list
                    foreach (string file in developerFileList)
                    {
                        TL.LogMessage("Main", "Adding to class: " + file);
                        outputClassFile.WriteLine("        Try : fileList.Add(\"" + file + "\") :TL.LogMessage(\"DeveloperFiles\",\"Added file: " + file + "\") : Catch ex As Exception : TL.LogMessage(\"PlatformFiles\",\"Exception: \" + ex.ToString()):End Try");
                    }

                    // Add the closing lines of the DeveloperFiles member
                    outputClassFile.WriteLine("        Return fileList");
                    outputClassFile.WriteLine("    End Function");
                    outputClassFile.WriteLine("");

                    // Add the closing lines of the DynamicLists class
                    outputClassFile.WriteLine("End Class");

                    // Close the files
                    outputTextFile.Flush();
                    outputTextFile.Close();
                    outputClassFile.Flush();
                    outputClassFile.Close();
                }
                catch (Exception ex)
                {
                    TL.LogMessageCrLf("Main", "Exception writing class file: " + ex.ToString());
                }
            }
        }
Пример #7
0
        /// <summary>
        /// Create a new Alpaca client executable using the supplied parameters
        /// </summary>
        /// <param name="DeviceType">The ASCOM device type to create</param>
        /// <param name="DeviceNumber">The number of this device type to create</param>
        /// <param name="OutputDirectory">The directory in which to place the compiled assembly</param>
        /// <remarks>
        /// This subroutine creates compiler source line definitions (not source code as such) and stores them in memory
        /// When complete, the compiler is called and the resultant assembly is stored in the specified output directory.
        /// The code created has no function as such it is just a shell with all of the heavy lifting undertaken by an inherited base class that is supplied pre-compiled
        /// The resultant assembly for Camera device 1 has this form:
        ///
        /// using System;
        /// using System.Runtime.InteropServices;
        /// namespace ASCOM.DynamicRemoteClients
        /// {
        ///     [Guid("70495DF9-C01E-4987-AE49-E12967202C7F")]             <====> The GUID is dynamically created on the user's machine so that it is unique for every driver
        ///     [ProgId(DRIVER_PROGID)]
        ///     [ServedClassName(DRIVER_DISPLAY_NAME)]
        ///     [ClassInterface(ClassInterfaceType.None)]
        ///     public class Camera : CameraBaseClass                      <====> Created from supplied parameters - all executable code is in the base class
        ///     {
        ///         private const string DRIVER_NUMBER = "1";              <====> Created from supplied parameters
        ///         private const string DEVICE_TYPE = "Camera";           <====> Created from supplied parameters
        ///         private const string DRIVER_DISPLAY_NAME = SharedConstants.DRIVER_DISPLAY_NAME + " " + DRIVER_NUMBER;
        ///         private const string DRIVER_PROGID = SharedConstants.DRIVER_PROGID_BASE + DRIVER_NUMBER + "." + DEVICE_TYPE;
        ///         public Camera() : base(DRIVER_NUMBER, DRIVER_DISPLAY_NAME, DRIVER_PROGID)
        ///         {
        ///         }
        ///     }
        /// }
        /// </remarks>
        internal static void CreateAlpacaClient(string DeviceType, int DeviceNumber, string ProgId, string DisplayName, string localServerPath)
        {
            TL.LogMessage("CreateAlpacaClient", $"Creating new ProgID: for {DeviceType} device {DeviceNumber} with ProgID: {ProgId} and display name: {DisplayName}");

            try
            {
                // Generate the container unit
                CodeCompileUnit program = new CodeCompileUnit();

                // Generate the namespace
                CodeNamespace ns = new CodeNamespace("ASCOM.DynamicRemoteClients");

                // Add required imports
                ns.Imports.Add(new CodeNamespaceImport("System"));
                ns.Imports.Add(new CodeNamespaceImport("System.Runtime.InteropServices"));

                // Declare the device class
                CodeTypeDeclaration deviceClass = new CodeTypeDeclaration()
                {
                    Name    = DeviceType,
                    IsClass = true
                };

                // Add the class base type
                deviceClass.BaseTypes.Add(new CodeTypeReference {
                    BaseType = DeviceType + BASE_CLASS_POSTFIX
                });
                TL.LogMessage("CreateAlpacaClient", "Created base type");

                // Create custom attributes to decorate the class
                CodeAttributeDeclaration           guidAttribute            = new CodeAttributeDeclaration("Guid", new CodeAttributeArgument(new CodePrimitiveExpression(Guid.NewGuid().ToString())));
                CodeAttributeDeclaration           progIdAttribute          = new CodeAttributeDeclaration("ProgId", new CodeAttributeArgument(new CodeArgumentReferenceExpression("DRIVER_PROGID")));
                CodeAttributeDeclaration           servedClassNameAttribute = new CodeAttributeDeclaration("ServedClassName", new CodeAttributeArgument(new CodeArgumentReferenceExpression("DRIVER_DISPLAY_NAME")));
                CodeAttributeDeclaration           classInterfaceAttribute  = new CodeAttributeDeclaration("ClassInterface", new CodeAttributeArgument(new CodeArgumentReferenceExpression("ClassInterfaceType.None")));
                CodeAttributeDeclarationCollection customAttributes         = new CodeAttributeDeclarationCollection()
                {
                    guidAttribute, progIdAttribute, servedClassNameAttribute, classInterfaceAttribute
                };
                TL.LogMessage("CreateAlpacaClient", "Created custom attributes");

                // Add the custom attributes to the class
                deviceClass.CustomAttributes = customAttributes;

                // Create some class level private constants
                CodeMemberField driverNumberConst = new CodeMemberField(typeof(string), "DRIVER_NUMBER");
                driverNumberConst.Attributes     = MemberAttributes.Private | MemberAttributes.Const;
                driverNumberConst.InitExpression = new CodePrimitiveExpression(DeviceNumber.ToString());

                CodeMemberField deviceTypeConst = new CodeMemberField(typeof(string), "DEVICE_TYPE");
                deviceTypeConst.Attributes     = MemberAttributes.Private | MemberAttributes.Const;
                deviceTypeConst.InitExpression = new CodePrimitiveExpression(DeviceType);

                CodeMemberField driverDisplayNameConst = new CodeMemberField(typeof(string), "DRIVER_DISPLAY_NAME");
                driverDisplayNameConst.Attributes     = (MemberAttributes.Private | MemberAttributes.Const);
                driverDisplayNameConst.InitExpression = new CodePrimitiveExpression(DisplayName);

                CodeMemberField driverProgIDConst = new CodeMemberField(typeof(string), "DRIVER_PROGID");
                driverProgIDConst.Attributes     = MemberAttributes.Private | MemberAttributes.Const;
                driverProgIDConst.InitExpression = new CodePrimitiveExpression(ProgId);

                // Add the constants to the class
                deviceClass.Members.AddRange(new CodeMemberField[] { driverNumberConst, deviceTypeConst, driverDisplayNameConst, driverProgIDConst });
                TL.LogMessage("CreateAlpacaClient", "Added constants to class");

                // Declare the class constructor
                CodeConstructor constructor = new CodeConstructor();
                constructor.Attributes = MemberAttributes.Public | MemberAttributes.Final;

                // Add a call to the base class with required parameters
                constructor.BaseConstructorArgs.Add(new CodeArgumentReferenceExpression("DRIVER_NUMBER"));
                constructor.BaseConstructorArgs.Add(new CodeArgumentReferenceExpression("DRIVER_DISPLAY_NAME"));
                constructor.BaseConstructorArgs.Add(new CodeArgumentReferenceExpression("DRIVER_PROGID"));
                deviceClass.Members.Add(constructor);
                TL.LogMessage("CreateAlpacaClient", "Added base constructor");

                // Add the class to the namespace
                ns.Types.Add(deviceClass);
                TL.LogMessage("CreateAlpacaClient", "Added class to name space");

                // Add the namespace to the program, which is now complete
                program.Namespaces.Add(ns);
                TL.LogMessage("CreateAlpacaClient", "Added name space to program");

                // Construct the path to the output DLL
                String dllName = $"{localServerPath.TrimEnd('\\')}\\{SharedConstants.DRIVER_PROGID_BASE}{DeviceNumber}.{DeviceType}.dll";
                TL.LogMessage("CreateAlpacaClient", string.Format("Output file name: {0}", dllName));

                // Create relevant compiler options to shape the compilation
                CompilerParameters cp = new CompilerParameters()
                {
                    GenerateExecutable      = false,   // Specify output of a DLL
                    OutputAssembly          = dllName, // Specify the assembly file name to generate
                    GenerateInMemory        = false,   // Save the assembly as a physical file.
                    TreatWarningsAsErrors   = false,   // Don't treat warnings as errors.
                    IncludeDebugInformation = true     // Include debug information
                };
                TL.LogMessage("CreateAlpacaClient", "Created compiler parameters");

                // Add required assembly references to make sure the compilation succeeds
                cp.ReferencedAssemblies.Add(@"ASCOM.Attributes.dll");                    // Must be present in the current directory because the compiler doesn't use the GAC
                cp.ReferencedAssemblies.Add(@"ASCOM.DeviceInterfaces.dll");              // Must be present in the current directory because the compiler doesn't use the GAC
                cp.ReferencedAssemblies.Add(@"ASCOM.Newtonsoft.Json.dll");               // Must be present in the current directory because the compiler doesn't use the GAC
                cp.ReferencedAssemblies.Add(@"RestSharp.dll");                           // Must be present in the current directory
                cp.ReferencedAssemblies.Add(@"ASCOM.AlpacaClientDeviceBaseClasses.dll"); // Must be present in the current directory
                cp.ReferencedAssemblies.Add(SharedConstants.ALPACA_CLIENT_LOCAL_SERVER); // Must be present in the current directory

                Assembly executingAssembly = Assembly.GetExecutingAssembly();
                cp.ReferencedAssemblies.Add(executingAssembly.Location);

                foreach (AssemblyName assemblyName in executingAssembly.GetReferencedAssemblies())
                {
                    cp.ReferencedAssemblies.Add(Assembly.Load(assemblyName).Location);
                }

                TL.LogMessage("CreateAlpacaClient", "Added assembly references");

                // Create formatting options for the generated code that will be logged into the trace logger
                CodeGeneratorOptions codeGeneratorOptions = new CodeGeneratorOptions()
                {
                    BracingStyle             = "C",
                    IndentString             = "    ",
                    VerbatimOrder            = true,
                    BlankLinesBetweenMembers = false
                };

                // Get a code provider so that we can compile the program
                CodeDomProvider provider = CodeDomProvider.CreateProvider("CSharp");
                TL.LogMessage("CreateAlpacaClient", "Created CSharp provider");

                // Write the generated code to the trace logger
                using (MemoryStream outputStream = new MemoryStream())
                {
                    using (StreamWriter writer = new StreamWriter(outputStream))
                    {
                        provider.GenerateCodeFromNamespace(ns, writer, codeGeneratorOptions);
                    }

                    MemoryStream actualStream = new MemoryStream(outputStream.ToArray());
                    using (StreamReader reader = new StreamReader(actualStream))
                    {
                        do
                        {
                            TL.LogMessage("GeneratedCode", reader.ReadLine());
                        } while (!reader.EndOfStream);
                    }
                }
                provider.Dispose();

                // Compile the source contained in the "program" variable
                CompilerResults cr = provider.CompileAssemblyFromDom(cp, program);
                TL.LogMessage("CreateAlpacaClient", string.Format("Compiled assembly - {0} errors", cr.Errors.Count));

                // Report success or errors
                if (cr.Errors.Count > 0)
                {
                    // Display compilation errors.
                    foreach (CompilerError ce in cr.Errors)
                    {
                        TL.LogMessage("CreateAlpacaClient", string.Format("Compiler error: {0}", ce.ToString()));
                    }
                }
                else
                {
                    // Display a successful compilation message.
                    TL.LogMessage("CreateAlpacaClient", "Assembly compiled OK!");
                }

                TL.BlankLine();
            }
            catch (Exception ex)
            {
                TL.LogMessageCrLf("CreateAlpacaClient", ex.ToString());
            }
        }
Пример #8
0
        /// <summary>
        /// Calls a method on an object dynamically.
        ///
        /// parameterTypes must match the parameters and in the same order.
        /// </summary>
        /// <param name="memberCode">1-GetProperty, 2-SetProperty, 3-Method</param>
        /// <param name="memberName">The member name to call as a string</param>
        /// <param name="parameterTypes">Array of paramerter types in order</param>
        /// <param name="parms">Array of parameters in order</param>
        /// <exception cref="PropertyNotImplementedException"></exception>
        /// <exception cref="MethodNotImplementedException"></exception>
        /// <returns>object</returns>
        internal object CallMember(int memberCode, string memberName, Type[] parameterTypes, params object[] parms)
        {
            TL.BlankLine();
            switch (memberCode)
            {
            case 1:                          // Property Read
                PropertyInfo propertyGetInfo = GetObjType.GetProperty(memberName);
                if (propertyGetInfo != null) // We have a .NET object
                {
                    TL.LogMessage(memberName + " Get", "GET " + memberName + " - .NET");
                    try
                    {
                        //run the .net object
                        object result = propertyGetInfo.GetValue(GetLateBoundObject, null);
                        TL.LogMessage(memberName + " Get", "  " + result.ToString());
                        return(result);
                    }
                    catch (TargetInvocationException e)
                    {
                        GetTargetInvocationExceptionHandler(memberName, e);
                    }
                    catch (Exception e)
                    {
                        TL.LogMessageCrLf("Exception", e.ToString());
                        throw;
                    }
                }

                //check the type to see if it's a COM object
                if (IsComObject)     // We have a COM object
                {
                    TL.LogMessage(memberName + " Get", "GET " + memberName + " - COM");

                    try
                    {
                        //run the COM object property
                        object result = GetObjType.InvokeMember(memberName,
                                                                BindingFlags.Default | BindingFlags.GetProperty,
                                                                null,
                                                                GetLateBoundObject,
                                                                new object[] { },
                                                                CultureInfo.InvariantCulture);
                        TL.LogMessage(memberName + " Get", "  " + result.ToString());
                        return(result);
                    }
                    catch (COMException e)
                    {
                        TL.LogMessageCrLf("COMException", e.ToString());
                        if (e.ErrorCode == int.Parse("80020006", NumberStyles.HexNumber, CultureInfo.InvariantCulture))
                        {
                            TL.LogMessageCrLf(memberName + " Get", "  Throwing PropertyNotImplementedException: " + _strProgId + " " + memberName);
                            throw new PropertyNotImplementedException(_strProgId + " " + memberName, false, e);
                        }
                        TL.LogMessageCrLf(memberName + " Get", "Re-throwing exception");
                        throw;
                    }
                    catch (TargetInvocationException e)
                    {
                        TL.LogMessageCrLf("TargetInvocationException", e.ToString());
                        if (e.InnerException is COMException)
                        {
                            string message   = e.InnerException.Message;
                            int    errorcode = ((COMException)e.InnerException).ErrorCode;
                            // Telescope simulator in V1 mode throws not implemented exceptions rather than some kind of missing member exception, so test for this!
                            if (errorcode == int.Parse("80040400", NumberStyles.HexNumber, CultureInfo.InvariantCulture))
                            {
                                TL.LogMessageCrLf(memberName + " Get", "  Translating COM not implemented exception to PropertyNotImplementedException: " + _strProgId + " " + memberName);
                                throw new PropertyNotImplementedException(_strProgId + " " + memberName, false, e);
                            }
                            else     // Throw a new COM exception that looks like the original exception, containing the original inner COM exception for reference
                            {
                                TL.LogMessageCrLf(memberName + " Get", "COM Exception so throwing inner exception: '" + message + "' '0x" + String.Format("{0:x8}", errorcode) + "'");
                                throw new DriverAccessCOMException(message, errorcode, e);
                            }
                        }

                        GetTargetInvocationExceptionHandler(memberName, e);
                    }

                    catch (Exception e)
                    {
                        TL.LogMessageCrLf("Exception", e.ToString());
                        throw;
                    }
                }

                //evertyhing failed so throw an exception
                TL.LogMessage(memberName + " Get", "  The object is neither a .NET object nor a COM object!");
                throw new PropertyNotImplementedException(_strProgId + " " + memberName, false);

            case 2:                          // Property Write
                PropertyInfo propertySetInfo = GetObjType.GetProperty(memberName);
                if (propertySetInfo != null) // We have a .NET object
                {
                    TL.LogMessage(memberName + " Set", "SET " + memberName + " - .NET");
                    try
                    {
                        TL.LogMessage(memberName + " Set", "  " + parms[0].ToString());
                        propertySetInfo.SetValue(GetLateBoundObject, parms[0], null);
                        return(null);
                    }
                    catch (TargetInvocationException e)
                    {
                        SetTargetInvocationExceptionHandler(memberName, e);
                    }
                    catch (Exception e)
                    {
                        TL.LogMessageCrLf("Exception", e.ToString());
                        throw;
                    }
                }

                //check the type to see if it's a COM object
                if (IsComObject)
                {
                    TL.LogMessage(memberName + " Set", "SET " + memberName + " - COM");

                    try
                    {
                        TL.LogMessage(memberName + " Set", "  " + parms[0].ToString());
                        //run the COM object property
                        GetObjType.InvokeMember(memberName,
                                                BindingFlags.Default | BindingFlags.SetProperty,
                                                null,
                                                GetLateBoundObject,
                                                parms,
                                                CultureInfo.InvariantCulture);
                        return(null);
                    }
                    catch (COMException e)
                    {
                        TL.LogMessageCrLf("COMException", e.ToString());
                        if (e.ErrorCode == int.Parse("80020006", NumberStyles.HexNumber, CultureInfo.InvariantCulture))
                        {
                            TL.LogMessageCrLf(memberName + " Set", "  Throwing PropertyNotImplementedException: " + _strProgId + " " + memberName);
                            throw new PropertyNotImplementedException(_strProgId + " " + memberName, true, e);
                        }
                        TL.LogMessageCrLf(memberName + " Set", "  Re-throwing exception");
                        throw;
                    }
                    catch (TargetInvocationException e)
                    {
                        TL.LogMessageCrLf("TargetInvocationException", e.ToString());

                        if (e.InnerException is COMException)
                        {
                            string message   = e.InnerException.Message;
                            int    errorcode = ((COMException)e.InnerException).ErrorCode;
                            // Telescope simulator in V1 mode throws not implemented exceptions rather than some kind of missing member exception, so test for this!
                            if (errorcode == int.Parse("80040400", NumberStyles.HexNumber, CultureInfo.InvariantCulture))
                            {
                                TL.LogMessageCrLf(memberName + " Set", "  Translating COM not implemented exception to PropertyNotImplementedException: " + _strProgId + " " + memberName);
                                throw new PropertyNotImplementedException(_strProgId + " " + memberName, true, e);
                            }
                            else     // Throw a new COM exception that looks like the original exception, containing the original inner COM exception for reference
                            {
                                TL.LogMessageCrLf(memberName + " Set", "COM Exception so throwing inner exception: '" + message + "' '0x" + String.Format("{0:x8}", errorcode) + "'");
                                throw new DriverAccessCOMException(message, errorcode, e);
                            }
                        }

                        SetTargetInvocationExceptionHandler(memberName, e);
                    }
                    catch (Exception e)
                    {
                        TL.LogMessageCrLf("Exception", e.ToString());
                        throw;
                    }
                }

                //evertyhing failed so throw an exception
                TL.LogMessage("PropertySet", "  The object is neither a .NET object nor a COM object!");
                throw new PropertyNotImplementedException(_strProgId + " " + memberName, true);

            case 3:     // Method
                TL.LogMessage(memberName, "Start");

                /*foreach (Type t in parameterTypes)
                 * {
                 *  TL.LogMessage(memberName, "  Parameter: " + t.FullName);
                 * }*/

                var methodInfo = GetObjType.GetMethod(memberName);
                //, parameterTypes); //Peter: Had to take parameterTypes out to get CanMoveAxis to work with .NET drivers
                if (methodInfo != null)
                {
                    //TL.LogMessage(memberName, "  Got MethodInfo");

                    //ParameterInfo[] pars = methodInfo.GetParameters();

                    /*foreach (ParameterInfo p in pars)
                     * {
                     *  TL.LogMessage(memberName, "    Parameter: " + p.ParameterType);
                     * } */

                    try
                    {
                        foreach (object parm in parms)
                        {
                            TL.LogMessage(memberName, "  Parameter: " + parm.ToString());
                        }
                        TL.LogMessage(memberName, "  Calling " + memberName);
                        object result = methodInfo.Invoke(GetLateBoundObject, parms);

                        if (result == null)
                        {
                            TL.LogMessage(memberName, "  Successfully called method, no return value");
                        }
                        else
                        {
                            TL.LogMessage(memberName, "  " + result.ToString());
                        }

                        return(result);
                    }
                    catch (TargetInvocationException e)
                    {
                        MethodTargetInvocationExceptionHandler(memberName, e);
                    }

                    // Unexpected exception so throw it all to the client
                    catch (Exception e)
                    {
                        TL.LogMessageCrLf("Exception", e.ToString());
                        throw;
                    }
                }

                //check the type to see if it's a COM object
                if (IsComObject)
                {
                    try
                    {
                        //run the COM object method
                        foreach (object parm in parms)
                        {
                            TL.LogMessage(memberName, "  Parameter: " + parm.ToString());
                        }
                        TL.LogMessage(memberName, "  Calling " + memberName + " - it is a COM object");
                        object result = GetObjType.InvokeMember(memberName,
                                                                BindingFlags.Default | BindingFlags.InvokeMethod,
                                                                null,
                                                                GetLateBoundObject,
                                                                parms,
                                                                CultureInfo.InvariantCulture);

                        if (result == null)
                        {
                            TL.LogMessage(memberName, "  Successfully called method, no return value");
                        }
                        else
                        {
                            TL.LogMessage(memberName, "  " + result.ToString());
                        }

                        return(result);
                    }
                    catch (COMException e)
                    {
                        TL.LogMessageCrLf("COMException", e.ToString());
                        if (e.ErrorCode == int.Parse("80020006", NumberStyles.HexNumber, CultureInfo.InvariantCulture))
                        {
                            TL.LogMessageCrLf(memberName, "  Throwing MethodNotImplementedException: " + _strProgId + " " + memberName);
                            throw new MethodNotImplementedException(_strProgId + " " + memberName);
                        }
                        TL.LogMessageCrLf(memberName, "Re-throwing exception");
                        throw;
                    }
                    catch (TargetInvocationException e)
                    {
                        TL.LogMessageCrLf("TargetInvocationException", e.ToString());
                        if (e.InnerException is COMException)
                        {
                            string message   = e.InnerException.Message;
                            int    errorcode = ((COMException)e.InnerException).ErrorCode;
                            // Telescope simulator in V1 mode throws not implemented exceptions rather than some kind of missing member exception, so test for this!
                            if (errorcode == int.Parse("80040400", NumberStyles.HexNumber, CultureInfo.InvariantCulture))
                            {
                                TL.LogMessageCrLf(memberName, "  Translating COM not implemented exception to MethodNotImplementedException: " + _strProgId + " " + memberName);
                                throw new MethodNotImplementedException(_strProgId + " " + memberName, e);
                            }
                            else     // Throw a new COM exception that looks like the original exception, containing the original inner COM exception for reference
                            {
                                TL.LogMessageCrLf(memberName, "  COM Exception so throwing inner exception: '" + message + "' '0x" + String.Format("{0:x8}", errorcode) + "'");
                                throw new DriverAccessCOMException(message, errorcode, e);
                            }
                        }

                        MethodTargetInvocationExceptionHandler(memberName, e);
                    }
                    catch (Exception e)
                    {
                        TL.LogMessageCrLf("Exception", e.ToString());
                        throw;
                    }
                }

                TL.LogMessage(memberName, "  is neither a .NET object nor a COM object!");
                throw new MethodNotImplementedException(_strProgId + " " + memberName);

            default:
                return(null);
            }
        }
Пример #9
0
        /// <summary>
        /// Reads the current device configuration from the Profile and saves this for use elsewhere
        /// </summary>
        private void ReadConfiguration()
        {
            ArrayList deviceTypes = profile.RegisteredDeviceTypes;

            Regex regex = new Regex(REGEX_FORMAT_STRING, RegexOptions.Compiled | RegexOptions.IgnoreCase);

            deviceTypeSummary.Clear();
            remoteDrivers.Clear();

            // List all the up-down controls present
            foreach (Control ctrl in this.Controls)
            {
                if (ctrl.GetType() == typeof(NumericUpDown))
                {
                    TL.LogMessage("ReadConfiguration", string.Format("Found NumericUpDown control {0}", ctrl.Name));
                    ctrl.BackColor = SystemColors.Window;
                }
            }

            // Extract a list of the remote client drivers from the list of devices in the Profile
            foreach (string deviceType in deviceTypes)
            {
                ArrayList devices = profile.RegisteredDevices(deviceType);
                foreach (KeyValuePair device in devices)
                {
                    Match match = regex.Match(device.Key);
                    if (match.Success)
                    {
                        DriverRegistration foundDriver = new DriverRegistration();
                        foundDriver.ProgId     = match.Groups["0"].Value;
                        foundDriver.Number     = int.Parse(match.Groups[DEVICE_NUMBER].Value, CultureInfo.InvariantCulture);
                        foundDriver.DeviceType = match.Groups[DEVICE_TYPE].Value;
                        remoteDrivers.Add(foundDriver);
                        TL.LogMessage("ReadConfiguration", string.Format("{0} - {1} - {2}", foundDriver.ProgId, foundDriver.Number, foundDriver.DeviceType));
                    }
                }

                TL.BlankLine();
            }

            // List the remote client drivers and create summary counts of client drivers of each device type
            foreach (string deviceType in deviceTypes)
            {
                List <DriverRegistration> result = (from s in remoteDrivers where s.DeviceType.Equals(deviceType, StringComparison.InvariantCultureIgnoreCase) select s).ToList();
                foreach (DriverRegistration driver in result)
                {
                    TL.LogMessage("ReadConfiguration", string.Format("{0} driver: {1} - {2} - {3}", deviceType, driver.ProgId, driver.Number, driver.DeviceType));
                }

                deviceTypeSummary.Add(deviceType, result.Count);
            }

            // List the summary information
            foreach (string deviceType in deviceTypes)
            {
                TL.LogMessage("ReadConfiguration", string.Format("There are {0} {1} remote drivers", deviceTypeSummary[deviceType], deviceType));
            }

            // Set the numeric up-down controls to the current number of drivers of each type
            NumCamera.Value              = deviceTypeSummary["Camera"];
            NumDome.Value                = deviceTypeSummary["Dome"];
            NumFilterWheel.Value         = deviceTypeSummary["FilterWheel"];
            NumFocuser.Value             = deviceTypeSummary["Focuser"];
            NumObservingConditions.Value = deviceTypeSummary["ObservingConditions"];
            NumRotator.Value             = deviceTypeSummary["Rotator"];
            NumSafetyMonitor.Value       = deviceTypeSummary["SafetyMonitor"];
            NumSwitch.Value              = deviceTypeSummary["Switch"];
            NumTelescope.Value           = deviceTypeSummary["Telescope"];
        }
Пример #10
0
        static int Main(string[] args)
        {
            if (args[0].ToUpperInvariant() == "/SETPROFILEACL") // Set and check the Profile registry ACL
            {
                try
                {
                    TL         = new TraceLogger("", "SetProfileACL"); // Create a trace logger so we can log what happens
                    TL.Enabled = true;

                    // Create the Profile key if required and set its access rights
                    LogMessage("SetRegistryACL", "Creating RegistryAccess object");
                    using (regAccess = new RegistryAccess(TL))
                    {
                        LogMessage("SetRegistryACL", "Setting Profile registry ACL");
                        regAccess.SetRegistryACL();
                    }

                    TL.BlankLine();

                    // Check whether the Profile key has the required access rights
                    using (RegistryKey hklm32 = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32))
                    {
                        if (!UserhasFullProfileAccessRights(hklm32, REGISTRY_ROOT_KEY_NAME))
                        {
                            returnCode = 99;
                        }
                    }
                }
                catch (Exception ex)
                {
                    LogError("SetProfileACL", ex.ToString());
                    returnCode = 1;
                }
            }
            else // Remove previous platforms, if present
            {
                try
                {
                    TL         = new TraceLogger("", "UninstallASCOM"); // Create a trace logger so we can log what happens
                    TL.Enabled = true;

                    LogMessage("Uninstall", "Creating RegistryAccess object");
                    regAccess = new RegistryAccess(TL); //Create a RegistryAccess object that will use the UninstallASCOM trace logger to ensure all messages appear in one log file

                    // This has been removed because it destroys the ability to remove 5.5 after use and does NOT restore all the
                    // Platform 5 files resulting in an unexpected automatic repair. Its left here just in case, Please DO NOT RE-ENABLE THIS FEATURE unless have a way round the resulting issues
                    // CreateRestorePoint();

                    LogMessage("Uninstall", "Removing previous versions of ASCOM....");

                    //Initial setup
                    bool is64BitProcess         = (IntPtr.Size == 8);
                    bool is64BitOperatingSystem = is64BitProcess || InternalCheckIsWow64();
                    LogMessage("Uninstall", "OS is 64bit: " + is64BitOperatingSystem.ToString() + ", Process is 64bit: " + is64BitProcess.ToString());

                    string platform4164KeyValue = null;
                    string platform564aKeyValue = null;
                    string platform564bKeyValue = null;
                    string platform564KeyValue  = null;
                    string platform5564KeyValue = null;

                    bool found = false;

                    if (is64BitOperatingSystem)                                       // Is a 64bit OS
                    {
                        platform4164KeyValue = Read(UNINSTALL_STRING, PLATFORM_4164); // Read the 4.1 uninstall string
                        platform5564KeyValue = Read(UNINSTALL_STRING, PLATFORM_5564); // Read the 5.5 uninstall string
                        platform564aKeyValue = Read(UNINSTALL_STRING, PLATFORM_564a); // Read the 5.0A uninstall string
                        platform564bKeyValue = Read(UNINSTALL_STRING, PLATFORM_564b); // Read the 5.0B uninstall string

                        if (platform564bKeyValue != null)                             // We have a 5.0B value so go with this
                        {
                            platform564KeyValue = platform564bKeyValue;
                            LogMessage("Uninstall", "Found 64bit Platform 5.0B");
                        }
                        else if (platform564aKeyValue != null) // No 5.0B value so go  with 5.0A if it is present
                        {
                            platform564KeyValue = platform564aKeyValue;
                            LogMessage("Uninstall", "Found 64bit Platform 5.0A");
                            //Now have to fix a missing registry key that fouls up the uninstaller - this was fixed in 5B but prevents 5A from uninstalling on 64bit systems
                            RegistryKey RKey = Registry.ClassesRoot.CreateSubKey(@"AppID\{DF2EB077-4D59-4231-9CB4-C61AD4ECB874}");
                            RKey.SetValue("", "Fixed registry key value");
                            RKey.Close();
                            RKey = null;
                            LogMessage("Uninstall", @"Successfully set AppID\{DF2EB077-4D59-4231-9CB4-C61AD4ECB874}");
                        }

                        StringBuilder Path = new StringBuilder(260);
                        int           rc   = SHGetSpecialFolderPath(IntPtr.Zero, Path, CSIDL_PROGRAM_FILES_COMMONX86, 0);
                        ascomDirectory = Path.ToString() + @"\ASCOM";
                        LogMessage("Uninstall", "64bit Common Files Path: " + ascomDirectory);
                    }
                    else //32 bit OS
                    {
                        ascomDirectory = Environment.GetFolderPath(Environment.SpecialFolder.CommonProgramFiles) + @"\ASCOM";
                        LogMessage("Uninstall", "32bit Common Files Path: " + ascomDirectory);
                    }

                    string platform4132KeyValue = Read(UNINSTALL_STRING, PLATFORM_4132);
                    string platform5532KeyValue = Read(UNINSTALL_STRING, PLATFORM_5532);
                    string platform532aKeyValue = Read(UNINSTALL_STRING, PLATFORM_532a);
                    string platform532bKeyValue = Read(UNINSTALL_STRING, PLATFORM_532b);
                    string platform532KeyValue  = null;

                    if (platform532bKeyValue != null) // We have a 5.0B value so go with this
                    {
                        platform532KeyValue = platform532bKeyValue;
                        LogMessage("Uninstall", "Found 32bit Platform 5,0B");
                    }
                    else if (platform532aKeyValue != null) // No 5.0B value so go  with 5.0A if it is present
                    {
                        platform532KeyValue = platform532aKeyValue;
                        LogMessage("Uninstall", "Found 32bit Platform 5,0A");
                    }

                    // Backup the profile based on the latest platform installed
                    if ((platform5564KeyValue != null) | (platform5532KeyValue != null))
                    {
                        regAccess.BackupProfile("5.5");
                    }
                    else if ((platform564KeyValue != null) | (platform532KeyValue != null))
                    {
                        regAccess.BackupProfile("5");
                    }
                    else
                    {
                        regAccess.BackupProfile("");
                    }

                    //remove 5.5
                    if (platform5564KeyValue != null)
                    {
                        LogMessage("Uninstall", "64 Removing ASCOM 5.5... " + platform5564KeyValue);
                        found = true;
                        RunProcess(platform5564KeyValue, " /VERYSILENT /NORESTART /LOG");
                        RemoveAssembly("policy.1.0.ASCOM.DriverAccess"); // Remove left over policy file
                    }
                    else
                    {
                        if (platform5532KeyValue != null)
                        {
                            LogMessage("Uninstall", "32 Removing ASCOM 5.5... " + platform5532KeyValue);
                            found = true;
                            RunProcess(platform5532KeyValue, " /VERYSILENT /NORESTART /LOG");
                            RemoveAssembly("policy.1.0.ASCOM.DriverAccess"); // Remove left over policy file
                        }
                    }

                    //remove 5.0
                    if (platform564KeyValue != null)
                    {
                        FixHelper("Helper.dll", 5, 0);// Original helpers should be in place at this point, check and fix if not to prevent Platform 5 uninstaller from failing
                        FixHelper("Helper2.dll", 4, 0);
                        LogMessage("Uninstall", "64 Removing ASCOM 5... " + platform564KeyValue);
                        found = true;
                        RunProcess("MsiExec.exe", SplitKey(platform564KeyValue));
                    }
                    else
                    {
                        if (platform532KeyValue != null)
                        {
                            FixHelper("Helper.dll", 5, 0);
                            FixHelper("Helper2.dll", 4, 0);
                            LogMessage("Uninstall", "32 Removing ASCOM 5... " + platform532KeyValue);
                            found = true;
                            RunProcess("MsiExec.exe", SplitKey(platform532KeyValue));
                        }
                    }

                    //Remove 4.1
                    //remove 5.0
                    if (platform4164KeyValue != null)
                    {
                        LogMessage("Uninstall", "64 Removing ASCOM 4.1... " + platform4164KeyValue);
                        found = true;

                        string[] vals = platform4164KeyValue.Split(new string[] { " " }, System.StringSplitOptions.RemoveEmptyEntries);
                        LogMessage("Uninstall", @"Found uninstall values: """ + vals[0] + @""", """ + vals[1] + @"""");

                        RunProcess(vals[0], @"/S /Z " + vals[1]);
                        CleanUp4();
                    }
                    else
                    {
                        if (platform4132KeyValue != null)
                        {
                            LogMessage("Uninstall", "32 Removing ASCOM 4.1... " + platform4132KeyValue);
                            found = true;

                            string[] vals = platform4132KeyValue.Split(new string[] { " " }, System.StringSplitOptions.RemoveEmptyEntries);
                            LogMessage("Uninstall", @"Found uninstall values: """ + vals[0] + @""", """ + vals[1] + @"""");

                            RunProcess(vals[0], @"/S /Z " + vals[1]);
                            CleanUp4();
                        }
                    }

                    if (found == true)
                    {
                        CleanUp55();
                        CleanUp5();
                    }
                    else
                    {
                        LogMessage("Uninstall", "No previous platforms found");
                    }

                    LogMessage("Uninstall", "Setting Profile registry ACL");
                    regAccess.SetRegistryACL();

                    // Restore the relevant profile based on the latest platform installed
                    if ((platform5564KeyValue != null) | (platform5532KeyValue != null))
                    {
                        LogMessage("Uninstall", "Restoring Platform 5.5 Profile");
                        regAccess.RestoreProfile("5.5");
                    }
                    else if ((platform564KeyValue != null) | (platform532KeyValue != null))
                    {
                        LogMessage("Uninstall", "Restoring Platform 5 Profile");
                        regAccess.RestoreProfile("5");
                    }

                    LogMessage("Uninstall", "Disposing of registry access object");
                    regAccess.Dispose();
                    regAccess = null;
                    LogMessage("Uninstall", "Completed uninstall process");
                }
                catch (Exception ex)
                {
                    LogError("Uninstall", ex.ToString());
                    returnCode = 1;
                }
            }

            TL.Enabled = false; // Clean up trace logger

            TL.Dispose();

            return(returnCode);
        }
Пример #11
0
        static private bool UserhasFullProfileAccessRights(RegistryKey key, string subKey)
        {
            RegistryKey sKey;
            bool        foundFullAccess = false;
            string      builtInUsers;

            try
            {
                builtInUsers = GetBuiltInUsers().ToUpperInvariant();
                TL.LogMessage("RegistryRights", (subKey == "") ? key.Name.ToString() : key.Name.ToString() + @"\" + subKey);

                if (subKey == "")
                {
                    sKey = key;
                }
                else
                {
                    sKey = key.OpenSubKey(subKey);
                }

                RegistrySecurity sec = sKey.GetAccessControl();                                           // System.Security.AccessControl.AccessControlSections.All)

                foreach (RegistryAccessRule RegRule in sec.GetAccessRules(true, true, typeof(NTAccount))) // Iterate over the rule set and list them
                {
                    try
                    {
                        TL.LogMessage("RegistryRights", RegRule.AccessControlType.ToString() + " " + RegRule.IdentityReference.ToString() + " " + RegRule.RegistryRights.ToString() + " / " + (RegRule.IsInherited ? "Inherited" : "NotInherited") + " / " + RegRule.InheritanceFlags.ToString() + " / " + RegRule.PropagationFlags.ToString());
                    }
                    catch (Exception ex1)
                    {
                        TL.LogMessageCrLf("RegistryRights", "Issue formatting registry rights: " + ex1.ToString());
                    }

                    if ((RegRule.IdentityReference.ToString().ToUpperInvariant() == builtInUsers) & (RegRule.RegistryRights == global::System.Security.AccessControl.RegistryRights.FullControl))
                    {
                        foundFullAccess = true;
                    }
                }

                if (foundFullAccess)
                {
                    TL.BlankLine();
                    TL.LogMessage("RegistryRights", "OK - SubKey " + subKey + @" does have full registry access rights for BUILTIN\Users");
                }
                else
                {
                    LogError("RegistryRights", "Subkey " + subKey + @" does not have full access rights for BUILTIN\Users!");
                }
            }
            catch (NullReferenceException)
            {
                TL.LogMessageCrLf("RegistryRights", "The subkey: " + key.Name + @"\" + subKey + " does not exist.");
            }
            catch (Exception ex)
            {
                TL.LogMessageCrLf("RegistryRights", "Issue reading registry rights: " + ex.ToString());
            }

            TL.BlankLine();

            return(foundFullAccess);
        }