Пример #1
0
        private static bool ProgramRecording(int bufferMinutes)
        {
            var       expireTime      = DateTime.Now + TimeSpan.FromHours(MaximumRecordingWaitHours);
            const int intervalMinutes = 1;
            var       intervalCheck   = 0;

            do
            {
                var active = WmcStore.DetermineRecordingsInProgress() || WmcRegistries.NextScheduledRecording() - TimeSpan.FromMinutes(bufferMinutes) < DateTime.Now;
                if (!active && intervalCheck > 0)
                {
                    Thread.Sleep(30000);
                    active = WmcStore.DetermineRecordingsInProgress() || WmcRegistries.NextScheduledRecording() - TimeSpan.FromMinutes(bufferMinutes) < DateTime.Now;
                }

                if (!active || expireTime < DateTime.Now)
                {
                    WmcStore.Close();
                    return(active);
                }

                Helper.SendPipeMessage($"Importing|Waiting for recordings to end...|Will check again at {DateTime.Now + TimeSpan.FromMinutes(intervalMinutes):HH:mm:ss}");
                if (intervalCheck++ % (60 / intervalMinutes) == 0)
                {
                    Logger.WriteInformation($"There is a recording in progress or the next scheduled recording is within {bufferMinutes} minutes. Delaying garbage collection and/or import.");
                }
                Thread.Sleep(intervalMinutes * 60000);
            } while (true);
        }
Пример #2
0
        private static int Main(string[] args)
        {
            // setup catch to fatal program crash
            AppDomain.CurrentDomain.UnhandledException += MyUnhandledException;
            Application.ThreadException += MyThreadException;

            // filter out mcupdate calls that may be redirected
            var arguments = string.Join(" ", args);

            switch (arguments)
            {
            case "-u -nogc":     // opening WMC
            case "-uf -nogc":
                Logger.WriteVerbose($"**** Intercepted \"mcupdate.exe {arguments}\" call. Ignored. ****");
                Logger.Close();
                return(0);

            case "-u -manual -nogc -p 0":     // guide update
            case "-manual -nogc -p 0":
                var startTime = DateTime.Now;
                var startInfo = new ProcessStartInfo()
                {
                    FileName        = "schtasks.exe",
                    Arguments       = "/run /tn \"epg123_update\"",
                    UseShellExecute = false,
                    CreateNoWindow  = true,
                };

                // begin update
                var proc = Process.Start(startInfo);
                proc?.WaitForExit();

                Logger.WriteInformation("**** Attempted to kick off the epg123_update task on demand. ****");
                Logger.Close();

                // monitor the task status until it is complete
                var ts = new epgTaskScheduler();
                while (true)
                {
                    // looks like WMC may have a 30000 ms timeout for the update action
                    // no reason to continue with the mcupdate run if it is going to be ignored
                    if (DateTime.Now - startTime > TimeSpan.FromMinutes(5.0))
                    {
                        return(0);
                    }

                    ts.QueryTask(true);
                    if (ts.StatusString.ToLower().Contains("running"))
                    {
                        Thread.Sleep(100);
                    }
                    else
                    {
                        break;
                    }
                }

                // kick off mcupdate so it can fail but signal WMC that update is complete
                startInfo = new ProcessStartInfo()
                {
                    FileName  = Environment.ExpandEnvironmentVariables(@"%SystemRoot%\ehome\mcupdate.exe"),
                    Arguments = arguments
                };
                proc = Process.Start(startInfo);
                proc?.WaitForExit();
                return(0);
            }

            // evaluate arguments
            bool nologo, import, force, showGui, advanced, nogc, verbose, noverify;
            var  match = nologo = import = force = showGui = advanced = nogc = verbose = noverify = false;

            if (File.Exists($"{Helper.Epg123ProgramDataFolder}\\nogc.txt"))
            {
                File.Delete($"{Helper.Epg123ProgramDataFolder}\\nogc.txt");
                nogc = true;
            }
            if (args.Length > 0)
            {
                for (var i = 0; i < args.Length; ++i)
                {
                    switch (args[i].ToLower())
                    {
                    case "-match":
                        match = true;
                        break;

                    case "-nologo":
                        nologo = true;
                        break;

                    case "-i":
                        if (i + 1 < args.Length)
                        {
                            filename = args[++i].Replace("EPG:", "http:");
                            if (filename.StartsWith("http"))
                            {
                                statusLogo.MxfFile = Helper.Epg123MxfPath;
                                import             = true;
                                break;
                            }

                            if (!File.Exists(filename))
                            {
                                var err = $"File \"{filename}\" does not exist.";
                                Logger.WriteError(err);
                                return(-1);
                            }
                            filename = new FileInfo(filename).FullName.ToLower();

                            var testNewFile = filename.Replace("\\epg123.mxf", "\\output\\epg123.mxf");
                            if (File.Exists(testNewFile))
                            {
                                Logger.WriteWarning($"It appears the MXF file to import is incorrect. Changing the import file from \"{filename}\" to \"{testNewFile}\". Delete and re-create your Scheduled Task.");
                                filename = testNewFile;
                            }
                            statusLogo.MxfFile = filename;
                        }
                        else
                        {
                            Logger.WriteError("Missing input filename and path.");
                            return(-1);
                        }
                        import = true;
                        break;

                    case "-f":
                        force = true;
                        break;

                    case "-p":
                        showProgress = true;
                        break;

                    case "-x":
                        advanced = true;
                        showGui  = true;
                        break;

                    case "-nogc":
                        nogc = true;
                        break;

                    case "-verbose":
                        verbose = true;
                        break;

                    case "-noverify":
                        noverify = true;
                        break;

                    default:
                        Logger.WriteVerbose($"**** Invalid arguments for epg123Client.exe; \"{arguments}\" ****");
                        Logger.Close();
                        return(-1);
                    }
                }
            }
            else
            {
                showGui = true;
            }

            // create a mutex and keep alive until program exits
            using (var mutex = !showGui && showProgress ? new Mutex(false, $"Global\\{AppGuid}") : Helper.GetProgramMutex($"Global\\{AppGuid}", !showGui))
            {
                // check for an instance already running
                if (mutex == null)
                {
                    return(-1);
                }

                Logger.WriteMessage("===============================================================================");
                Logger.WriteMessage($" {(showGui ? "Activating the epg123 client GUI." : "Beginning epg123 client execution.")} version {Helper.Epg123Version}");
                Logger.WriteMessage("===============================================================================");
                Logger.WriteMessage($"*** {Helper.GetOsDescription()} ***");
                Logger.WriteMessage($"*** {Helper.GetWmcDescription()} ***");

                // show gui if needed
                if (showGui)
                {
                    var client = new clientForm(advanced);
                    client.ShowDialog();
                    GC.Collect();

                    if (client.RestartClientForm)
                    {
                        // start a new process
                        _ = Process.Start(new ProcessStartInfo
                        {
                            FileName         = Helper.Epg123ClientExePath,
                            WorkingDirectory = Helper.ExecutablePath,
                            UseShellExecute  = true,
                            Verb             = client.RestartAsAdmin ? "runas" : null
                        });
                    }
                    client.Dispose();
                }
                else
                {
                    // prevent machine from entering sleep mode
                    var prevThreadState = NativeMethods.SetThreadExecutionState(
                        (uint)ExecutionFlags.ES_CONTINUOUS |
                        (uint)ExecutionFlags.ES_SYSTEM_REQUIRED |
                        (uint)ExecutionFlags.ES_AWAYMODE_REQUIRED);

                    Logger.WriteVerbose($"Import: {import} , Match: {match} , NoLogo: {nologo} , Force: {force} , ShowProgress: {showProgress} , NoGC: {force || nogc} , NoVerify: {noverify} , Verbose: {verbose}");
                    var startTime = DateTime.UtcNow;

                    if (import)
                    {
                        // check if garbage cleanup is needed
                        if (!nogc && !force && WmcRegistries.IsGarbageCleanupDue() && !ProgramRecording(60))
                        {
                            _ = WmcUtilities.PerformGarbageCleanup();
                        }

                        // ensure no recordings are active if importing
                        if (!force && ProgramRecording(10))
                        {
                            Logger.WriteError($"A program recording is still in progress after {MaximumRecordingWaitHours} hours. Aborting the mxf file import.");
                            goto CompleteImport;
                        }
                        WmcStore.Close();

                        // import mxf file
                        if (!ImportMxfFile(filename))
                        {
                            Logger.WriteError("Failed to import .mxf file. Exiting.");
                            goto CompleteImport;
                        }

                        // perform verification
                        if (!noverify)
                        {
                            _ = new VerifyLoad(filename, verbose);
                        }

                        // get lineup and configure lineup type and devices
                        if (!WmcStore.ActivateEpg123LineupsInStore() || !WmcRegistries.ActivateGuide())
                        {
                            Logger.WriteError("Failed to locate any lineups from EPG123.");
                            goto CompleteImport;
                        }
                    }

                    // remove all channel logos
                    if (nologo)
                    {
                        WmcStore.ClearLineupChannelLogos();
                    }

                    // perform automatch
                    if (match)
                    {
                        try
                        {
                            WmcStore.AutoMapChannels();
                            Logger.WriteInformation("Completed the automatch of lineup stations to tuner channels.");
                        }
                        catch (Exception ex)
                        {
                            Logger.WriteError($"{ex.Message}");
                            Logger.WriteError("Failed to perform the automatch of lineup stations to tuner channels task.");
                        }
                    }

                    // import success
                    if (import)
                    {
                        // refresh the lineups after import
                        using (var mergedLineups = new MergedLineups(WmcStore.WmcObjectStore))
                        {
                            foreach (MergedLineup mergedLineup in mergedLineups)
                            {
                                _ = mergedLineup.Refresh();
                            }
                        }
                        Logger.WriteInformation("Completed lineup refresh.");

                        // reindex database
                        _ = WmcUtilities.ReindexPvrSchedule();
                        _ = WmcUtilities.ReindexDatabase();
                    }

                    // import complete
CompleteImport:
                    if (import)
                    {
                        // update status logo
                        statusLogo.StatusImage();

                        // signal the notification tray to update the icon
                        Helper.SendPipeMessage("Import Complete");
                    }

                    WmcStore.Close();

                    // all done
                    Logger.WriteInformation("Completed EPG123 client execution.");
                    Logger.WriteVerbose($"EPG123 client execution time was {DateTime.UtcNow - startTime}.");
                    Logger.Close();
                    NativeMethods.SetThreadExecutionState(prevThreadState | (uint)ExecutionFlags.ES_CONTINUOUS);
                }
            }
            Environment.Exit(0);
            return(0);
        }
Пример #3
0
 private void btnExit_Click(object sender, EventArgs e)
 {
     WmcStore.Close();
     Close();
 }