static int Main(string[] args) { // setup catch to fatal program crash AppDomain.CurrentDomain.UnhandledException += MyUnhandledException; Application.ThreadException += MyThreadException; // verify WMC is installed if (!File.Exists(Helper.EhshellExeFilePath)) { MessageBox.Show("Could not verify Windows Media Center is installed on this machine. EPG123 Client cannot be started without WMC being present.", "Missing Windows Media Center", MessageBoxButtons.OK); return(-1); } // establish file/folder locations Logger.Initialize("Media Center", "epg123Client"); EstablishFileFolderPaths(); // create a mutex and keep alive until program exits using (Mutex mutex = new Mutex(false, "Global\\" + appGuid)) { bool match, nologo, import, force, showGui, advanced; match = nologo = import = force = showGui = advanced = false; if ((args != null) && (args.Length > 0)) { for (int 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) { if (!File.Exists(filename = args[++i])) { string err = string.Format("File \"{0}\" does not exist.", filename); Logger.WriteError(err); return(-1); } filename = new FileInfo(filename).FullName.ToLower(); string testNewFile = filename.Replace("\\epg123.mxf", "\\output\\epg123.mxf"); if (File.Exists(testNewFile)) { Logger.WriteWarning(string.Format("It appears the MXF file to import is incorrect. Changing the import file from \"{0}\" to \"{1}\".", filename, testNewFile)); filename = testNewFile; } statusLogo.mxfFile = filename; } else { string err = "Missing input filename and path."; Logger.WriteError(err); return(-1); } import = true; break; case "-f": force = true; break; case "-p": showProgress = true; break; case "-x": advanced = true; showGui = true; break; default: Console.WriteLine("ERROR: \"{0}\" is not a valid argument.", args[i]); return(-1); } } } else { showGui = true; } if (showGui) { // use another mutex if the GUI is open using (Mutex mutex2 = new Mutex(false, "Global\\" + guiGuid)) { // check for a gui instance already running if (!mutex2.WaitOne(2000, false)) { MessageBox.Show("An instance of EPG123 Client is already running.", "Initialization Aborted"); return(0); } Logger.WriteMessage("==============================================================================="); Logger.WriteMessage(string.Format(" Activating the epg123 client GUI. version {0}", Helper.epg123Version)); Logger.WriteMessage("==============================================================================="); clientForm client = new clientForm(advanced); client.ShowDialog(); mutex2.ReleaseMutex(); Logger.Close(); client.Dispose(); return(0); } } // prevent machine from entering sleep mode uint prevThreadState = NativeMethods.SetThreadExecutionState((uint)ExecutionFlags.ES_CONTINUOUS | (uint)ExecutionFlags.ES_SYSTEM_REQUIRED | (uint)ExecutionFlags.ES_AWAYMODE_REQUIRED); // and yet another mutex for the import action using (Mutex mutex3 = new Mutex(false, "Global\\" + impGuid)) { // check for an import instance is already running if (!mutex3.WaitOne(0, false)) { Logger.WriteError("An instance of EPG123 Client import is already running. Aborting this instance."); return(-1); } Logger.WriteMessage("==============================================================================="); Logger.WriteMessage(string.Format(" Beginning epg123 client execution. version {0}", Helper.epg123Version)); Logger.WriteMessage("==============================================================================="); Logger.WriteInformation(string.Format("Beginning epg123 client execution. {0:u}", DateTime.Now.ToUniversalTime())); Logger.WriteVerbose(string.Format("Import: {0} , Match: {1} , NoLogo: {2} , Force: {3} , ShowProgress: {4}", import, match, nologo, force, showProgress)); DateTime startTime = DateTime.UtcNow; // remove all channel logos if (nologo) { clearLineupChannelLogos(); } notifyIcon = new NotifyIcon() { Text = "EPG123\nImporting guide listings...", Icon = epg123.Properties.Resources.EPG123_import }; notifyIcon.Visible = true; // ensure no recordings are active if importing if (import && !force && programRecording()) { Logger.WriteError("A program recording is still in progress after 5 hours. Aborting the mxf file import."); Logger.Close(); NativeMethods.SetThreadExecutionState(prevThreadState | (uint)ExecutionFlags.ES_CONTINUOUS); mutex3.ReleaseMutex(); notifyIcon.Visible = false; notifyIcon.Dispose(); statusLogo.statusImage(); return(-1); } // import mxf file if (import && !importMxfFile(filename)) { Logger.WriteError("Failed to import .mxf file. Exiting."); Logger.Close(); NativeMethods.SetThreadExecutionState(prevThreadState | (uint)ExecutionFlags.ES_CONTINUOUS); mutex3.ReleaseMutex(); notifyIcon.Visible = false; notifyIcon.Dispose(); statusLogo.statusImage(); return(-1); } notifyIcon.Visible = false; notifyIcon.Dispose(); // get lineup and configure lineup type and devices if (import && !mxfImport.activateLineupAndGuide()) { Logger.WriteError("Failed to locate any lineups from EPG123."); Logger.Close(); NativeMethods.SetThreadExecutionState(prevThreadState | (uint)ExecutionFlags.ES_CONTINUOUS); mutex3.ReleaseMutex(); statusLogo.statusImage(); return(-1); } // perform automatch if (match) { try { matchLineups(); Logger.WriteInformation("Completed the automatch of lineup stations to tuner channels."); } catch { Logger.WriteError("Failed to perform the automatch of lineup stations to tuner channels task."); } } // refresh the lineups after import if (import) { using (MergedLineups mergedLineups = new MergedLineups(Store.objectStore)) { foreach (MergedLineup mergedLineup in mergedLineups) { mergedLineup.Refresh(); } } Logger.WriteInformation("Completed lineup refresh."); } // reindex database if (import) { mxfImport.reindexDatabase(); } // set all active recording requests to anyLanguage=true if (setSeriesRecordingRequestAnyLanguage() || import) { mxfImport.reindexPvrSchedule(); } // update status logo if (import) { statusLogo.statusImage(); } // all done Logger.WriteInformation("Completed EPG123 client execution."); Logger.WriteVerbose(string.Format("EPG123 client execution time was {0}.", DateTime.UtcNow - startTime)); Logger.Close(); mutex3.ReleaseMutex(); } NativeMethods.SetThreadExecutionState(prevThreadState | (uint)ExecutionFlags.ES_CONTINUOUS); return(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); }