/// <summary> /// Validate the given driver ProgID /// </summary> /// <param name="driverDirectory"></param> /// <param name="deviceType"></param> /// <param name="progId"></param> private void ValidateDriver(string driverDirectory, string deviceType, string progId) { Type typeFromProgId = Type.GetTypeFromProgID(progId); if (typeFromProgId != null) // This ProgID is registered { TL.LogMessage("ReadConfiguration", $"ProgID {progId} is registered. Type name: {typeFromProgId?.Name}"); string driverExecutable = $"{driverDirectory}{progId}.dll"; TL.LogMessage("ReadConfiguration", $"Searching for driver: {driverExecutable}"); // Test whether the driver DLL executable is missing if (!File.Exists(driverExecutable)) // Driver DLL does not exist so flag as corrupted and suggest deletion { // Only add this driver to the list if it is not already in the list if (dynamicDrivers.Where(x => x.ProgId.ToLowerInvariant() == progId.ToLowerInvariant()).Count() == 0) // There are no drivers with this ProgID already in the list { // Create a new list entry DynamicDriverRegistration foundDriver = new DynamicDriverRegistration(); foundDriver.ProgId = progId; foundDriver.DeviceType = deviceType; foundDriver.Name = progId; foundDriver.InstallState = InstallationState.MissingDriver; foundDriver.Description = $"{foundDriver.ProgId} - Driver is COM registered but driver executable does not exist - Deletion recommended"; dynamicDrivers.Add(foundDriver); dynamicDriversCheckedListBox.Items.Add(foundDriver); TL.LogMessage("ReadConfiguration", $"Adding driver to deletion list: {progId}"); } else // A driver with this ProgID is already in the list so no need to add it again, which would just create a duplicate entry { TL.LogMessage("ReadConfiguration", $"{progId} - A driver with this ProgID already exists - no action taken"); // No action } } else // Driver is COM registered and its driver DLL exists { // Test whether the device is ASCOM registered if (!profile.IsRegistered(progId)) // The driver is not registered in the ASCOM Profile { // Create a new list entry DynamicDriverRegistration foundDriver = new DynamicDriverRegistration(); foundDriver.ProgId = progId; foundDriver.DeviceType = deviceType; foundDriver.Name = progId; foundDriver.InstallState = InstallationState.BadProfile; foundDriver.Description = $"{foundDriver.ProgId} - Driver is COM registered but not ASCOM registered - Deletion recommended"; dynamicDrivers.Add(foundDriver); dynamicDriversCheckedListBox.Items.Add(foundDriver); TL.LogMessage("ReadConfiguration", $"Adding driver to deletion list: {progId}"); } else // The driver is registered in the ASCOM Profile { // No action required TL.LogMessage("ReadConfiguration", $"{progId} - Driver DLL exists and is registered for COM and ASCOM so this driver will have been already listed - no action taken"); } } } else // This progID is not registered { // No action required TL.LogMessage("ReadConfiguration", $"{progId} - ProgID is not COM registered - no action taken"); } }
/// <summary> /// Creates a list of Alpaca dynamic drivers and their configuration information /// </summary> private void FindInstalledDrivers() { Regex dynamicDriverProgidParseRegex = new Regex(DYNAMIC_DRIVER_PROGID_PARSE_REGEX_STRING, RegexOptions.Compiled | RegexOptions.IgnoreCase); Regex remoteDriverProgidParseRegex = new Regex(REMOTE_DRIVER_PROGID_PARSE_REGEX_STRING, RegexOptions.Compiled | RegexOptions.IgnoreCase); string dynamicDriverDirectory = Environment.GetFolderPath(Environment.SpecialFolder.CommonProgramFilesX86) + SharedConstants.ALPACA_CLIENT_LOCAL_SERVER_PATH; string remoteDriverDirectory = Environment.GetFolderPath(Environment.SpecialFolder.CommonProgramFilesX86) + ASCOM_REMOTE_CLIENT_LOCAL_SERVER_PATH; // Initialise dynamicDrivers.Clear(); dynamicDriversCheckedListBox.Items.Clear(); if ((ChkIncludeAlpacaDynamicDrivers.Checked == false) & (ChkIncludeAscomRemoteDrivers.Checked == false)) { MessageBox.Show("Neither Alpaca Dynamic nor ASCOM Remote drivers have been selected for display", "Driver Selection", MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } // Extract a list of the remote client drivers from the list of devices in the Profile ArrayList deviceTypes = profile.RegisteredDeviceTypes; foreach (string deviceType in deviceTypes) { ArrayList devices = profile.RegisteredDevices(deviceType); foreach (KeyValuePair device in devices) { // Process any Alpaca Dynamic Drivers that are found if (ChkIncludeAlpacaDynamicDrivers.Checked) // We do need to include ASCOM Remote drivers { Match dynamicDriverMatch = dynamicDriverProgidParseRegex.Match(device.Key); // Parse the ProgID to extract the dynamic device number and device type if (dynamicDriverMatch.Success) { // Create a new data class to hold information about this dynamic driver DynamicDriverRegistration foundDriver = new DynamicDriverRegistration(); try { // Populate information from the dynamic driver's ProgID foundDriver.ProgId = dynamicDriverMatch.Groups["0"].Value; foundDriver.Number = int.Parse(dynamicDriverMatch.Groups[DEVICE_NUMBER].Value, CultureInfo.InvariantCulture); foundDriver.DeviceType = deviceType; // populate configuration information from the dynamic driver's Profile and profile.DeviceType = foundDriver.DeviceType; foundDriver.IPAdrress = profile.GetValue(foundDriver.ProgId, SharedConstants.IPADDRESS_PROFILENAME); foundDriver.PortNumber = Convert.ToInt32(profile.GetValue(foundDriver.ProgId, SharedConstants.PORTNUMBER_PROFILENAME)); foundDriver.RemoteDeviceNumber = Convert.ToInt32(profile.GetValue(foundDriver.ProgId, SharedConstants.REMOTE_DEVICE_NUMBER_PROFILENAME)); foundDriver.UniqueID = profile.GetValue(foundDriver.ProgId, SharedConstants.UNIQUEID_PROFILENAME); foundDriver.Name = device.Value; foundDriver.Description = $"{foundDriver.Name} ({foundDriver.ProgId}) - {foundDriver.IPAdrress}:{foundDriver.PortNumber}/api/v1/{foundDriver.DeviceType}/{foundDriver.RemoteDeviceNumber} - {foundDriver.UniqueID}"; // Test whether the driver is correctly registered and installed and flag accordingly string compatibilityMessage = VersionCode.DriverCompatibilityMessage(foundDriver.ProgId, VersionCode.Bitness.Bits32, TL); if (compatibilityMessage == "") // Driver is correctly registered { string driverExecutable = $"{dynamicDriverDirectory}{foundDriver.ProgId}.dll"; TL.LogMessage("ReadConfiguration", $"Searching for driver: {driverExecutable}"); // Confirm that the driver DLL executable exists if (File.Exists(driverExecutable)) // DLL exists so flag OK { foundDriver.InstallState = InstallationState.Ok; } else // Driver DLL does not exist so flag as corrupted and suggest deletion { foundDriver.InstallState = InstallationState.MissingDriver; foundDriver.Description = $"{foundDriver.ProgId} - Driver is ASCOM registered does not exist - Deletion recommended"; } } else // A driver installation issue was found so flag as corrupted and recommend deletion { foundDriver.InstallState = InstallationState.NotCompatible; foundDriver.Description = $"{foundDriver.ProgId} - {compatibilityMessage} - Deletion recommended"; } TL.LogMessage("ReadConfiguration", $"{foundDriver.ProgId} - {compatibilityMessage} - Installed OK: {foundDriver.InstallState}"); } catch (Exception ex) { foundDriver.InstallState = InstallationState.BadProfile; foundDriver.Description = $"{foundDriver.ProgId} - ASCOM Profile is invalid - Deletion recommended"; TL.LogMessageCrLf("ReadConfiguration", ex.ToString()); } finally { // Add the data class to the dynamic devices collection and to the form's checked list box dynamicDrivers.Add(foundDriver); dynamicDriversCheckedListBox.Items.Add(foundDriver); TL.LogMessage("ReadConfiguration", $"{foundDriver.ProgId} - {foundDriver.Number} - {foundDriver.DeviceType} - Installed OK: {foundDriver.InstallState}"); } } } // Process any ASCOM Remote drivers that are found if this is enabled if (ChkIncludeAscomRemoteDrivers.Checked) // We do need to include ASCOM Remote drivers { Match remoteDrivermatch = remoteDriverProgidParseRegex.Match(device.Key); // Parse the ProgID to extract the remote device number and device type if (remoteDrivermatch.Success) { // Create a new data class to hold information about this dynamic driver DynamicDriverRegistration foundDriver = new DynamicDriverRegistration(); try { // Populate information from the dynamic driver's ProgID foundDriver.ProgId = remoteDrivermatch.Groups["0"].Value; foundDriver.Number = int.Parse(remoteDrivermatch.Groups[DEVICE_NUMBER].Value, CultureInfo.InvariantCulture); foundDriver.DeviceType = deviceType; // populate configuration information from the dynamic driver's Profile and profile.DeviceType = foundDriver.DeviceType; foundDriver.IPAdrress = profile.GetValue(foundDriver.ProgId, SharedConstants.IPADDRESS_PROFILENAME); foundDriver.PortNumber = Convert.ToInt32(profile.GetValue(foundDriver.ProgId, SharedConstants.PORTNUMBER_PROFILENAME)); foundDriver.RemoteDeviceNumber = Convert.ToInt32(profile.GetValue(foundDriver.ProgId, SharedConstants.REMOTE_DEVICE_NUMBER_PROFILENAME)); foundDriver.UniqueID = profile.GetValue(foundDriver.ProgId, SharedConstants.UNIQUEID_PROFILENAME); foundDriver.Name = device.Value; foundDriver.Description = $"{foundDriver.Name} ({foundDriver.ProgId}) - {foundDriver.IPAdrress}:{foundDriver.PortNumber}/api/v1/{foundDriver.DeviceType}/{foundDriver.RemoteDeviceNumber} - {foundDriver.UniqueID}"; // Test whether the driver is correctly registered and installed and flag accordingly string compatibilityMessage = VersionCode.DriverCompatibilityMessage(foundDriver.ProgId, VersionCode.Bitness.Bits32, TL); if (compatibilityMessage == "") // Driver is correctly registered { string driverExecutable = $"{remoteDriverDirectory}{foundDriver.ProgId}.dll"; TL.LogMessage("ReadConfiguration", $"Searching for driver: {driverExecutable}"); // Confirm that the driver DLL executable exists if (File.Exists(driverExecutable)) // DLL exists so flag OK { foundDriver.InstallState = InstallationState.Ok; } else // Driver DLL does not exist so flag as corrupted and suggest deletion { foundDriver.InstallState = InstallationState.MissingDriver; foundDriver.Description = $"{foundDriver.ProgId} - Driver is ASCOM registered does not exist - Deletion recommended"; } } else // A driver installation issue was found so flag as corrupted and recommend deletion { foundDriver.InstallState = InstallationState.NotCompatible; foundDriver.Description = $"{foundDriver.ProgId} - {compatibilityMessage} - Deletion recommended"; } TL.LogMessage("ReadConfiguration", $"{foundDriver.ProgId} - {compatibilityMessage} - Installed OK: {foundDriver.InstallState}"); } catch (Exception ex) { foundDriver.InstallState = InstallationState.BadProfile; foundDriver.Description = $"{foundDriver.ProgId} - ASCOM Profile is invalid - Deletion recommended"; TL.LogMessageCrLf("ReadConfiguration", ex.ToString()); } finally { // Add the data class to the dynamic devices collection and to the form's checked list box dynamicDrivers.Add(foundDriver); dynamicDriversCheckedListBox.Items.Add(foundDriver); TL.LogMessage("ReadConfiguration", $"{foundDriver.ProgId} - {foundDriver.Number} - {foundDriver.DeviceType} - Installed OK: {foundDriver.InstallState}"); } } } } // Test the first N COM registrations of the form ASCOM.AlpacaDynamic{X}.{DeviceType} and ASCOM.Remote{X}.{DeviceType} to check whether they are registered for COM and whether their DLL executables exist. // If not flag as corrupt for (int i = 1; i <= NUMBER_OF_DYNAMIC_DRIVER_NUMBERS_TO_TEST; i++) { // Validate Alpaca dynamic drivers if (ChkIncludeAlpacaDynamicDrivers.Checked) { string dynamicDriverProgId = $"{SharedConstants.DRIVER_PROGID_BASE}{i}.{deviceType}"; ValidateDriver(dynamicDriverDirectory, deviceType, dynamicDriverProgId); } // Validate ASCOM Remote drivers if (ChkIncludeAscomRemoteDrivers.Checked) { string remoteDriverProgId = $"{ASCOM_REMOTE_PROGID_BASE}{i}.{deviceType}"; ValidateDriver(remoteDriverDirectory, deviceType, remoteDriverProgId); } } } }