Beispiel #1
0
        protected override void OnStartup(StartupEventArgs e)
        {
            base.OnStartup(e);

            //create the notifyicon (it's a resource declared in NotifyIconResources.xaml
            Globals.NotifyIcon           = (TaskbarIcon)FindResource("NotifyIcon");
            Globals.NotifyIcon.TrayPopup = new TextBlock
            {
                Text       = "No status available",
                Foreground = Brushes.LightSalmon,
                Background = Brushes.Black,
                FontSize   = 14,
            };

            if (SqlCe.GetAutoEnforceFlag())
            {
                Dispatcher.Invoke(() =>
                {
                    Globals.NotifyIcon.IconSource = new BitmapImage(new Uri("pack://application:,,,/Icons/red.ico"));
                });
            }

            _pipeServer = new PipeServer();
            _pipeServer.Listen("01DB94E3-90F1-43F4-8DDA-8AEAF6C08A8E");
            _pipeServer.PipeMessage += PipeServer_PipeMessage;
        }
Beispiel #2
0
        private void TaskbarIcon_TrayPopupOpen(object sender, RoutedEventArgs e)
        {
            var running = SqlCe.GetAutoEnforceFlag();

            Globals.NotifyIcon.TrayPopup = new TextBlock
            {
                Text       = running ? "Maintenance is currently running" : "Maintenance is currently not running",
                Foreground = running ? Brushes.LightGreen : Brushes.LightGray,
                Background = Brushes.Black,
                FontSize   = 14,
                Margin     = new Thickness(5, 5, 5, 40),
                Padding    = new Thickness(5),
            };
        }
Beispiel #3
0
        protected override void OnSessionChange(SessionChangeDescription changeDescription)
        {
            if (changeDescription.Reason == SessionChangeReason.SessionLogon || changeDescription.Reason == SessionChangeReason.SessionUnlock)
            {
                var enforcemets = SqlCe.GetPendingSchedules();

                if (enforcemets.Where(x => x.EnforcementTime < DateTime.Today.AddDays(2)).Any())
                {
                    Task.Run(() =>
                    {
                        System.Threading.Thread.Sleep(20000);
                        UnsafeNativeMethods.Run(_userApp, $"/ToastNotifyComingInstallation", false);
                    });
                }

                if (SqlCe.GetAutoEnforceFlag())
                {
                    UnsafeNativeMethods.Run(_userApp, $"/ToastServiceRunningNotification", false);
                }

                _rebootToastDelay = 0;

                var rs = SqlCe.GetRestartSchedule();

                if (rs != null)
                {
                    if (rs.IsExpress)
                    {
                        SqlCe.DeleteRestartSchedule();
                    }

                    RestartRequired();
                }
            }

            if (changeDescription.Reason == SessionChangeReason.SessionLogon)
            {
                UnsafeNativeMethods.Run(_trayApp, null, false);

                if (_settings.IpuApplication.ShowProgress && _ipuRunning)
                {
                    UnsafeNativeMethods.Run(_progressApp, string.Empty, false);
                }
            }
        }
Beispiel #4
0
        protected override void OnStop()
        {
            if (_serviceSettings.HardSuppressSCNotifications)
            {
                RestoreSCNotification();
            }

            _pipeClient.Send("Close", "01DB94E3-90F1-43F4-8DDA-8AEAF6C08A8E");

            if (SqlCe.GetAutoEnforceFlag())
            {
                var reqApps        = CcmUtils.RequiredApps.Where(x => !x.InstallState.Equals("Installed")).ToList();
                var pendingUpdates = CcmUtils.Updates.Where(x => x.EvaluationState == 1).ToList();

                if (reqApps.Count() == 0 && pendingUpdates.Count() == 0 && !RebootChecker.RebootRequired(new RestartChecks()
                {
                    PendingFileOperations = true
                }).Any)
                {
                    Globals.Log.Information("Resetting Auto Enforce Flag, nothing left to enforce.");
                    SqlCe.SetAutoEnforceFlag(false);
                    _pipeClient.Send("SetBlue", "01DB94E3-90F1-43F4-8DDA-8AEAF6C08A8E");
                    _iEnforcementInterval = 5;

                    if (UnsafeNativeMethods.IsUserLoggedOn())
                    {
                        UnsafeNativeMethods.Run(_userApp, $"/ToastServiceEndNotification", false);
                    }

                    if (_settings.LegalNotice.UseLegalNotice)
                    {
                        Reg.RemoveLegalNotice();
                    }
                }
            }

            Globals.Log.Information("Service is stopping");
        }
Beispiel #5
0
        private void CheckForApps()
        {
            try
            {
                if (SqlCe.GetAutoEnforceFlag())
                {
                    return;
                }

                var rApps = CcmUtils.RequiredApps;

                var allRequiredAppsApps = rApps.Where(x => !x.InstallState.Equals("Installed") && x.Deadline > DateTime.Now.AddMinutes(15)).ToList();

                if (allRequiredAppsApps.Count < 1)
                {
                    Globals.Log.Information($"Wmi didn't return any required applications at this time.");
                    return;
                }

                var appDeadline         = allRequiredAppsApps.OrderBy(x => x.Deadline).First().Deadline;
                var allSchedules        = SqlCe.GetAllSchedules();
                var showToast           = false;
                var featureUpdateExists = false;
                var dtNextServiceCycle  = CommonUtils.GetNextServiceCycleAsDateTime();

                foreach (var app in allRequiredAppsApps)
                {
                    if (allSchedules.Where(x => x.ObjectId.Trim().Equals(app.Id.Trim()) && x.Revision.Trim().Equals(app.Revision.Trim())).Any())
                    {
                        Globals.Log.Information($"Skipping toast for already scheduled application: '{app.Name}'");
                        continue;
                    }

                    if (dtNextServiceCycle < app.Deadline)
                    {
                        Globals.Log.Information($"Skipping toast for application covered by service cycle: '{app.Name}'");
                        continue;
                    }

                    if (app.EvaluationState == 12)
                    {
                        Globals.Log.Information($"Skipping toast for currently installing (possibly long-running) app '{app.Name}'");
                        continue;
                    }

                    if (app.IsIpuApplication)
                    {
                        featureUpdateExists = true;
                    }

                    showToast = true;
                }

                if (dtNextServiceCycle != null)
                {
                    if (dtNextServiceCycle <= appDeadline)
                    {
                        Globals.Log.Information($"Detected an upcoming service cycle, a Toast notification was suppressed.");
                        return;
                    }
                }

                if (showToast && UnsafeNativeMethods.IsUserLoggedOn() && !RegistryMethods.GetIpuIsRunning())
                {
                    if (!UnsafeNativeMethods.IsSessionLocked())
                    {
                        var arg = featureUpdateExists ? "/ToastIpu" : "/ToastApp";
                        UnsafeNativeMethods.Run(_userApp, $"{arg}", false);
                    }
                    else
                    {
                        Globals.Log.Information($"Detected a locked or non existing user session, a Toast notification was suppressed.");
                    }
                }
            }
            catch (Exception ex)
            {
                Globals.Log.Error(ex.Message);
            }
        }
Beispiel #6
0
        private void CheckForSups()
        {
            if (_supCheckBlocked || SqlCe.GetAutoEnforceFlag())
            {
                return;
            }

            try
            {
                var sups = CcmUtils.Updates;

                if (sups.Count() == 0)
                {
                    _lastFoundSups = null;
                    Globals.Log.Information("No updates available at this time");
                    return;
                }

                _lastFoundSups = _lastFoundSups ?? DateTime.Now;

                if (_lastFoundSups > DateTime.Now.AddMinutes(-5))
                {
                    return;
                }

                var jsonSups = JsonConvert.SerializeObject(sups);
                SqlCe.UpdateSupData("STD", jsonSups);

                Globals.Log.Information($"Found {sups.Count()} updates available for scheduling");

                var nextSchedule     = SqlCe.GetNextSupSchedule();
                var supdeadline      = sups.OrderBy(y => y.Deadline).First().Deadline;
                var nextServiceCycle = SqlCe.GetServiceSchedule();

                if (nextSchedule.Id != 0)
                {
                    Globals.Log.Information($"Next update enforcement time '{nextSchedule.EnforcementTime}' deadline for available updates = '{supdeadline}', 'toasting' user - reschedule necessary");

                    if (nextSchedule.EnforcementTime <= supdeadline)
                    {
                        Globals.Log.Information($"Next update enforcement time '{nextSchedule.EnforcementTime}' deadline for available updates = '{supdeadline}', skipping 'toast'");
                        return;
                    }
                    else
                    {
                        SqlCe.SetEnforcedFlag(nextSchedule.Id);
                    }
                }

                var dtNextServiceCycle = CommonUtils.GetNextServiceCycleAsDateTime();

                if (dtNextServiceCycle != null)
                {
                    if (dtNextServiceCycle <= supdeadline)
                    {
                        Globals.Log.Information($"Detected an upcoming service cycle, a Toast notification was suppressed.");
                        return;
                    }
                }

                if (UnsafeNativeMethods.IsUserLoggedOn() && !RegistryMethods.GetIpuIsRunning())
                {
                    if (!UnsafeNativeMethods.IsSessionLocked())
                    {
                        UnsafeNativeMethods.Run(_userApp, $"/ToastSup", false);
                    }
                    else
                    {
                        Globals.Log.Information($"Detected a locked or non existing user session, a Toast notification was suppressed.");
                    }
                }
            }
            catch (Exception ex)
            {
                Globals.Log.Error(ex.Message);
            }
        }
Beispiel #7
0
        private bool RestartRequired()
        {
            if (CcmUtils.IsUpdatesEnforcing() || CcmUtils.IsAppsEnforcing())
            {
                Globals.Log.Information("Detected ongoing installation, suppressing reboot checks.");
                return(false);
            }

            var checks = _settings.RestartChecks;

            var updatesStatus = _rebootServicingCheck && !SqlCe.GetUpdatesInstallStatusFlag();

            if (!updatesStatus)
            {
                checks.ComponentBasedServicing = updatesStatus;
                checks.PendingFileOperations   = updatesStatus;
                checks.WindowsUpdate           = updatesStatus;
            }

            var result = RebootChecker.RebootRequired(checks);
            var rs     = SqlCe.GetRestartSchedule();

            if (!result.Any)
            {
                SqlCe.DeleteRestartSchedule();
            }
            else if (rs != null)
            {
                if (rs.IsAcknowledged)
                {
                    return(false);
                }
            }

            if (result.ConfigMgrClient && (_allowFastReboot || !UnsafeNativeMethods.IsUserLoggedOn()))
            {
                SqlCe.DeleteRestartSchedule();

                SqlCe.SetRestartSchedule(new RestartSchedule
                {
                    DeadLine       = DateTime.Now.MinutePrecission().AddMinutes(5),
                    RestartTime    = DateTime.Now.MinutePrecission().AddMinutes(5),
                    IsAcknowledged = true,
                    IsExpress      = true,
                });

                return(result.Any);
            }

            if (result.Any && _rebootToastDelay-- <= 1)
            {
                if (rs == null)
                {
                    SqlCe.SetRestartSchedule(new RestartSchedule
                    {
                        DeadLine       = DateTime.Today.AddDays(_serviceSettings.RestartDeadlineAfterInstall.InDays).AddHours(_serviceSettings.RestartDeadlineAfterInstall.AtHour),
                        RestartTime    = DateTime.Today.AddDays(_serviceSettings.RestartDeadlineAfterInstall.InDays).AddHours(_serviceSettings.RestartDeadlineAfterInstall.AtHour),
                        IsAcknowledged = false,
                        IsExpress      = false,
                    });
                }

                if (SqlCe.GetAutoEnforceFlag())
                {
                    Globals.Log.Information($"Detected auto enforce flag 'true', skipping reboot toast.");
                }
                else if (!UnsafeNativeMethods.IsSessionLocked())
                {
                    UnsafeNativeMethods.Run(_userApp, $"/ToastReboot", false);
                }
                else
                {
                    Globals.Log.Information($"Detected a locked or non existing user session, a Toast notification was suppressed.");
                }

                _rebootToastDelay = _fiveMinuteIntervalsPerDay / _serviceSettings.NumberOfRestartToastsPerDay;
            }

            return(result.Any);
        }
Beispiel #8
0
        protected override void OnStart(string[] args)
        {
            Globals.Log.Information("Service is starting");
            WaitForCcmExec();
            WaitForCmClientOperational();
            SqlCe.MaintainDatabase();
            _pipeServer = new PipeServer();
            _pipeServer.Listen("3A2CD127-D069-4CD5-994D-C481F4760748");
            _pipeServer.PipeMessage += PipeServer_PipeMessage;

            _settings = SettingsUtils.Settings;

            if (_settings.IsDefault)
            {
                SettingsUtils.WriteSettingsToFile();
                Globals.Log.Warning("Failed to load settings from file, created new 'Settings.xml'. If this is the first start after installation, it's expected.");
            }

            _serviceSettings = _settings.ServiceConfig;

            if (SqlCe.GetAutoEnforceFlag())
            {
                Globals.Log.Information("Auto Enforce Flag is true, enforcing all.");

                _iEnforcementInterval = 1;
                CcmUtils.InstallAllAppsAndUpdates();

                if (_settings.LegalNotice.UseLegalNotice)
                {
                    Reg.SetLegalNotice(_settings.LegalNotice);
                }
            }

            SqlCe.SetUpdatesInstallStatusFlag(false);
            SaveAssignmentsToDB();

            _enforcementTimer.AutoReset = false;
            _enforcementTimer.Elapsed  += EnforcementTimer_Elapsed;
            _enforcementTimer.Interval  = AutoInterval();
            _enforcementTimer.Start();

            _ccmWmiEventListener = new CcmWmiEventListener();
            _ccmWmiEventListener.OnNewApplication += CcmWmiEventListener_OnNewApplication;
            _ccmWmiEventListener.OnNewUpdate      += CcmWmiEventListener_OnNewUpdate;

            FeedEnforcementsPump();
            EnforcePump();
            ConfirmPump();

            if (_serviceSettings.HardSuppressSCNotifications)
            {
                RenameSCNotification();
            }

            if (UnsafeNativeMethods.IsUserLoggedOn())
            {
                UnsafeNativeMethods.Run(_trayApp, null, false);
            }

            Globals.Log.Information("Service sucessfully started.");
        }
Beispiel #9
0
        private void EnforcementTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            _enforcementTimer.Stop();
            _enforcementTimer.Interval = AutoInterval();
            _enforcementTimer.Start();

            SaveAssignmentsToDB();

            if (SqlCe.GetAutoEnforceFlag())
            {
                Globals.Log.Information("Checking Service cycle status.");

                var reqApps        = CcmUtils.RequiredApps.Where(x => !x.InstallState.Equals("Installed") && x.EvaluationState == 3 && !x.IsIpuApplication).ToList();
                var pendingUpdates = CcmUtils.Updates.ToList();

                if (reqApps.Count() == 0 && pendingUpdates.Count() == 0 && !(CcmUtils.IsUpdatesEnforcing() || CcmUtils.IsAppsEnforcing()) && !RebootChecker.RebootRequired(new RestartChecks()
                {
                    PendingFileOperations = true
                }).Any)
                {
                    Globals.Log.Information("Service cycle - Resetting Auto Enforce Flag, nothing left to enforce and no reboot pending.");
                    SqlCe.SetAutoEnforceFlag(false);
                    _pipeClient.Send("SetBlue", "01DB94E3-90F1-43F4-8DDA-8AEAF6C08A8E");
                    _iEnforcementInterval = 5;

                    if (UnsafeNativeMethods.IsUserLoggedOn())
                    {
                        UnsafeNativeMethods.Run(_userApp, $"/ToastServiceEndNotification", false);
                    }

                    if (_settings.LegalNotice.UseLegalNotice)
                    {
                        Reg.RemoveLegalNotice();
                    }

                    return;
                }
                else if (CcmUtils.IsRebootPending().HardRebootPending&& !(CcmUtils.IsUpdatesEnforcing() || CcmUtils.IsAppsEnforcing()))
                {
                    Globals.Log.Information("Service cycle - Pending hard reboot detected - restarting computer.");

                    if (UnsafeNativeMethods.IsUserLoggedOn())
                    {
                        UnsafeNativeMethods.Run(_userApp, $"/ToastServiceRestartNotification", false);
                        RestartComputer();
                    }
                    else
                    {
                        RestartComputer(true);
                    }

                    return;
                }
                else if (!(CcmUtils.IsUpdatesEnforcing() || CcmUtils.IsAppsEnforcing()) && (reqApps.Count() != 0 || pendingUpdates.Count() != 0))
                {
                    Globals.Log.Information("Service cycle - Cycle running but required installations not enforcing - pushing enforcement.");
                    CcmUtils.InstallAllAppsAndUpdates();
                    return;
                }
                else if (reqApps.Count() == 0 && pendingUpdates.Count() == 0 && !(CcmUtils.IsUpdatesEnforcing() || CcmUtils.IsAppsEnforcing()) && RebootChecker.RebootRequired(new RestartChecks()
                {
                    PendingFileOperations = true
                }).Any)
                {
                    Globals.Log.Information("Service cycle - nothing left to enforce but a pending reboot (Any) was detected - restarting computer.");

                    if (UnsafeNativeMethods.IsUserLoggedOn())
                    {
                        UnsafeNativeMethods.Run(_userApp, $"/ToastServiceRestartNotification", false);
                        RestartComputer();
                    }
                    else
                    {
                        RestartComputer(true);
                    }

                    return;
                }

                Globals.Log.Information("Service cycle not yet finished.");

                return;
            }

            if (CcmUtils.IsUpdatesEnforcing())
            {
                return;
            }

            var rs = SqlCe.GetRestartSchedule();

            if (rs != null)
            {
                if (rs.RestartTime <= DateTime.Now)
                {
                    SqlCe.DeleteRestartSchedule();

                    if (UnsafeNativeMethods.IsUserLoggedOn())
                    {
                        UnsafeNativeMethods.Run(_userApp, $"/ShowRestartWindow", false);
                        Globals.Log.Information($"Launched Restart Window.");
                    }
                    else
                    {
                        RestartComputer(true);
                    }

                    return;
                }
            }

            RestartRequired();

            if (CcmUtils.IsRebootPending().HardRebootPending)
            {
                Globals.Log.Warning($"Detected pending hard reboot - postponing further enforcement(s)");
                return;
            }

            try
            {
                var serviceSchedule = CommonUtils.GetNextServiceCycleAsDateTime();

                if (serviceSchedule != null)
                {
                    if (serviceSchedule <= DateTime.Now)
                    {
                        SqlCe.SetAutoEnforceFlag(true);
                        _pipeClient.Send("SetRed", "01DB94E3-90F1-43F4-8DDA-8AEAF6C08A8E");
                        CcmUtils.InstallAllAppsAndUpdates();
                        _iEnforcementInterval = 1;
                        _enforcementTimer.Stop();
                        _enforcementTimer.Interval = AutoInterval();
                        _enforcementTimer.Start();

                        if (_settings.LegalNotice.UseLegalNotice)
                        {
                            Reg.SetLegalNotice(_settings.LegalNotice);
                        }

                        SqlCe.DeleteServiceSchedule();
                        SqlCe.UpdateSupData("STD", string.Empty);

                        if (UnsafeNativeMethods.IsUserLoggedOn())
                        {
                            UnsafeNativeMethods.Run(_userApp, $"/ToastServiceInitNotification", false);
                        }

                        Globals.Log.Information($"Found and triggered a Service Schedule (Install All)");
                        return;
                    }
                }
            }
            catch (Exception ex)
            {
                Globals.Log.Error(ex.Message);
            }

            try
            {
                var sch = SqlCe.GetDueSchedules();

                if (sch.Count() > 0)
                {
                    Globals.Log.Information($"Found {sch.Count()} objects due for enforcement.");
                    sch.ForEach(x => _objectsToEnforce.Add(x));
                }
                else
                {
                    Globals.Log.Information($"No scheduled enforcements found at this time");
                }
            }
            catch (Exception ex)
            {
                Globals.Log.Error(ex.Message);
            }

            try
            {
                if (CcmUtils.IsApplicationEvaluationRequired())
                {
                    CcmUtils.EvaluateAllPolicies();
                }
            }
            catch (Exception ex)
            {
                Globals.Log.Error(ex.Message);
            }
        }