/// <summary> /// Entfernt veraltete Aufträge aus dem Archiv. /// </summary> internal void CleanupArchivedJobs() { // Not yet if (DateTime.UtcNow < m_nextArchiveCleanup) { return; } // Remember m_nextArchiveCleanup = DateTime.UtcNow.AddDays(1); // Access limit var firstValid = DateTime.UtcNow.AddDays(-7 * VCRConfiguration.Current.ArchiveLifeTime); var jobDirectory = ArchiveDirectory; // Protect to avoid parallel operations on the archive directory lock (m_Jobs) foreach (var file in jobDirectory.GetFiles("*" + VCRJob.FileSuffix)) { if (file.LastWriteTimeUtc < firstValid) { try { // Delete the log entry file.Delete(); } catch (Exception e) { // Report error VCRServer.Log(e); } } } }
/// <summary> /// Erzeugt eine neue Verwaltungsinstanz. /// </summary> /// <param name="server">Die primäre VCR.NET Instanz.</param> internal ProfileStateCollection(VCRServer server) { // Remember Server = server; // Profiles to use var profileNames = VCRProfiles.ProfileNames.ToArray(); var nameReport = string.Join(", ", profileNames); // Log VCRServer.Log(LoggingLevel.Full, Properties.Resources.LoadProfiles, nameReport); // Report Tools.ExtendedLogging("Loading Profile Collection: {0}", nameReport); // Load current profiles m_profiles = profileNames.ToDictionary(profileName => profileName, profileName => new ProfileState(this, profileName), ProfileManager.ProfileNameComparer); // Now we can create the planner m_planner = RecordingPlanner.Create(this); m_planThread = new Thread(PlanThread) { Name = "Recording Planner", IsBackground = true }; // Configure timer m_timer.OnTimerExpired += BeginNewPlan; // Start planner m_planThread.Start(); }
/// <summary> /// Bereinigt alle veralteten Protokolleinträge. /// </summary> internal void CleanupLogEntries() { // Check time if (DateTime.UtcNow < m_nextLogCleanup) { return; } // Not again for now m_nextLogCleanup = DateTime.UtcNow.AddDays(1); // For cleanup var firstValid = DateTime.Now.Date.AddDays(-7 * VCRConfiguration.Current.LogLifeTime).ToString(LogEntryDateFormat); // Load all jobs foreach (var file in LogDirectory.GetFiles("*" + VCRRecordingInfo.FileSuffix)) { if (file.Name.CompareTo(firstValid) < 0) { try { // Delete the log entry file.Delete(); } catch (Exception e) { // Report error VCRServer.Log(e); } } } }
static void Main_FindRecording( string[] args ) { // Create the server using (VCRServer server = new VCRServer( new DirectoryInfo( @"C:\temp\VCR.NET 3.9 Alpha\Jobs" ) )) { // Attach to the state of a profile ProfileState nexus = server.FindProfile( "Nexus" ); // Get the next job to execute VCRRecordingInfo next = nexus.NextJob; // Get recording information for the next jon bool incomplete; VCRRecordingInfo[] hidden; FullInfo full = nexus.FindNextRecording( DateTime.UtcNow, out incomplete, out hidden ); // Prepare it using (HardwareRequest request = nexus.CreateRecordingRequest( next, DateTime.UtcNow )) { // Set end time request.Recording.EndsAt = DateTime.UtcNow.AddSeconds( 30 ); // Report Console.WriteLine( "Recording {0}", request.Recording.FileName ); // Process it request.Start(); // Wait while (request.IsRunning) Thread.Sleep( 100 ); } } }
/// <summary> /// Startet aller Erweiterung einer bestimmten Art. /// </summary> /// <param name="extensionType">Die gewünschte Art von Erweiterungen.</param> /// <param name="environment">Aller Parameter für die Erweiterungen.</param> /// <returns>Die Prozessinformationen zu allen gestarten Erweiterungen.</returns> public static void RunSynchronousExtensions(string extensionType, Dictionary <string, string> environment) { // Forward foreach (var process in RunExtensions(GetExtensions(extensionType), environment)) { if (process != null) { try { // Wait on done try { // Do it process.WaitForExit(); } finally { // Get rid process.Dispose(); } } catch (Exception e) { // Report and catch all! VCRServer.Log(e); } } } }
/// <summary> /// Bereitet den VCR.NET Recording Service auf die endgültige Terminierung /// des Dienstes vor. /// </summary> private void Terminate() { // Get the hibernation control thread var hibTest = m_HibernateHelper; // Reset it m_HibernateHelper = null; // Unregister from power manager PowerManager.OnChanged -= HibernationChanged; // Wait for the web server starter thread to finish var webThread = Interlocked.Exchange(ref m_webStarter, null); if (webThread != null) { webThread.Join(); } // Stop web server - client requests are no longer accepted if (m_WebServer != null) { m_WebServer.Stop(); } // Stop all recordings using (VCRServer) VCRServer = null; // Finally wait for the hibernation helper to terminate (at most five seconds) if (hibTest != null) { hibTest.Join(); } }
static void Main7( string[] args ) { // Attach to job manager VCRServer server = new VCRServer( new DirectoryInfo( @"C:\temp\VCR.NET 3.9 Alpha\Jobs" ) ); JobManager jobs = server.JobManager; ProgramGuideEntries entries = new ProgramGuideEntries(); entries.Add( new ProgramGuideEntry { Name = "Te\x0005st" } ); SerializationTools.Save( entries, @"c:\temp\test.xml" ); ProgramGuideEntries reload = SerializationTools.Load<ProgramGuideEntries>( new FileInfo( @"c:\temp\test.xml" ) ); }
static void Main6( string[] args ) { // Attach to job manager VCRServer server = new VCRServer( new DirectoryInfo( @"C:\temp\VCR.NET 3.9 Alpha\Jobs" ) ); JobManager jobs = server.JobManager; // Create EPG collection using (ZappingRequest request = ZappingRequest.CreateDefault( "Nexus Scan", jobs )) if (null != request) { // Get the information FullInfo info0 = request.CreateFullInformation(); // Report Console.WriteLine( info0.Recording.JobType ); // Start it request.BeginExecute( false ); // Go to ZDF LiveModeStatus stat1 = request.SetSource( VCRProfiles.FindSource( "Nexus Scan", "ZDF [ZDFvision]" ), "localhost:5555" ); // Report Console.WriteLine( "ZDF on" ); Console.ReadLine(); // Get status LiveModeStatus stat2 = request.CreateStatus(); // Go to PREMIERE LiveModeStatus stat3 = request.SetSource( VCRProfiles.FindSource( "Nexus Scan", "PREMIERE DIREKT [PREMIERE]" ), "localhost:5555" ); // Report Console.WriteLine( "PREMIERE on" ); Console.ReadLine(); // Get status LiveModeStatus stat4 = request.CreateStatus(); // Stop it request.Stop(); // Get the information FullInfo info1 = request.CreateFullInformation(); } // Done Console.WriteLine( "Done" ); Console.ReadLine(); }
public static void Main(string[] args) { // Must be fully safe try { // See if debugger attached Tools.EnableTracing = Debugger.IsAttached; Tools.DomainName = "VCR.NET"; // Dump environment //foreach (System.Collections.DictionaryEntry env in Environment.GetEnvironmentVariables()) // Tools.ExtendedLogging( "Environment {0}={1}", env.Key, env.Value ); // Load configuration into main application domain VCRConfiguration.Startup(); // Cleanup mess from earlier version try { // Clear var target = Path.Combine(Path.Combine(Tools.ApplicationDirectory.Parent.FullName, "bin"), "JMS.DVB.SourceManagement.dll"); if (File.Exists(target)) { File.Delete(target); } } catch (Exception e) { // Report VCRServer.LogError("DVB.NET Cleanup failed: {0}", e.Message); } // Show startup Tools.ExtendedLogging("Starting Service"); // Run Service.Startup(args); // Show termination Tools.ExtendedLogging("Terminating Service"); } catch (Exception e) { // Report Tools.LogException("Main", e); // Re-Throw throw e; } }
static void Main_PSIRun( string[] args ) { // Create the server using (VCRServer server = new VCRServer( new DirectoryInfo( @"C:\temp\VCR.NET 3.9 Alpha\Jobs" ) )) { // Attach to the profile state of interest ProfileState nova = server.FindProfile( "DVB-S2" ); ProfileState nexus = server.FindProfile( "Nexus" ); // Report Console.WriteLine( "{0} {1}", nova.ProfileName, nova.NextSourceUpdateTime ); Console.WriteLine( "{0} {1}", nexus.ProfileName, nexus.NextSourceUpdateTime ); } }
/// <summary> /// Bestätigt den Abschluss einer Operation und die Bereitschaft, die nächste Operation /// zu starten. /// </summary> /// <param name="scheduleIdentifier">Die eindeutige Kennung der Operation.</param> /// <param name="isStart">Gesetzt, wenn es sich um einen Startbefehl handelt.</param> internal void ConfirmOperation(Guid scheduleIdentifier, bool isStart) { // Protect and check var planner = m_planner; if (planner == null) { return; } // Make sure that we synchronize with the planning thread lock (planner) if (m_pendingSchedule == null) { // Report VCRServer.Log(LoggingLevel.Errors, "There is no outstanding asynchronous Recording Request for Schedule '{0}'", scheduleIdentifier); } else if (m_pendingSchedule.Definition.UniqueIdentifier != scheduleIdentifier) { // Report VCRServer.Log(LoggingLevel.Errors, "Confirmed asynchronous Recording Request for Schedule '{0}' but waiting for '{1}'", scheduleIdentifier, m_pendingSchedule.Definition.UniqueIdentifier); } else { // Report VCRServer.Log(LoggingLevel.Schedules, "Confirmed asynchronous Recording Request for Schedule '{0}'", scheduleIdentifier); // Check mode if (isStart != m_pendingStart) { VCRServer.Log(LoggingLevel.Errors, "Recording Request confirmed wrong Type of Operation"); } // Finish if (m_pendingStart) { planner.Start(m_pendingSchedule); } else { planner.Stop(scheduleIdentifier); } // Reset m_pendingSchedule = null; } // See what to do next BeginNewPlan(); }
/// <summary> /// Meldet, dass eine Aufzeichnung nun beendet werden kann. /// </summary> /// <param name="item">Die betroffene Aufzeichnung.</param> /// <param name="planner">Die Planungsinstanz.</param> void IRecordingPlannerSite.Stop(IScheduleInformation item, RecordingPlanner planner) { // Report VCRServer.Log(LoggingLevel.Schedules, "Done recording '{0}'", item.Definition.Name); // Locate the profile - if we don't find it we are in big trouble! if (!m_profiles.TryGetValue(item.Resource.Name, out ProfileState profile)) { return; } // Mark as pending m_pendingSchedule = item; m_pendingStart = false; // Forward request to profile manager m_pendingActions += () => profile.EndRecording(item.Definition.UniqueIdentifier); }
/// <summary> /// Speichert ein Objekt im XML Format in eine Datei. Fehler werden protokolliert und /// nicht als Ausnahmen gemeldet. /// </summary> /// <param name="instance">Das zu speichernde Objekt.</param> /// <param name="path">Der Pfad zur Datei.</param> /// <returns>Gesetzt, wenn kein Fehler aufgetreten ist.</returns> public static bool SafeSave(object instance, string path) { // Be safe try { // Write it out SerializationTools.Save(instance, path); // Did it return(true); } catch (Exception e) { // Report VCRServer.Log(e); // Failed return(false); } }
/// <summary> /// Erzeugt eine neue Verwaltungsinstanz und lädt die aktuellen Auftragsliste. /// </summary> /// <param name="rootDirectory">Meldet das Verzeichnis, unterhalb dessen alle /// Aufträge und Protokolle angelegt werden.</param> /// <param name="server">Die VCR.NET Instanz, der diese Verwaltung zugeordnet ist.</param> internal JobManager( DirectoryInfo rootDirectory, VCRServer server ) { // Remember RootDirectory = rootDirectory; Server = server; // Create root directory RootDirectory.Create(); // Create working directories CollectorDirectory.Create(); ArchiveDirectory.Create(); JobDirectory.Create(); LogDirectory.Create(); // Load all jobs foreach (var job in VCRJob.Load( JobDirectory )) if (job.UniqueID.HasValue) m_Jobs[job.UniqueID.Value] = job; }
static void Main( string[] args ) { // Start server using (VCRServer server = new VCRServer( new DirectoryInfo( @"C:\temp\VCR.NET 3.9 Alpha\Jobs" ) )) { // Load the settings Settings settings = server.Settings; // Fire our first schedule PowerManager.OnResume(); // Report Console.WriteLine( "Running {4} {0} [Hibernate={1} S3={2} NVOD={3}]", string.Join( ",", settings.Profiles.ToArray() ), settings.MayHibernateSystem, settings.UseStandByForHibernation, settings.CanRecordNVOD, VCRServer.CurrentVersion ); Console.ReadLine(); } // Done Console.WriteLine( "Done" ); Console.ReadLine(); }
/// <summary> /// Aktualisiert einen Zeitwert in der Windows Registrierung. /// </summary> /// <param name="name">Der Name des Wertes.</param> /// <param name="value">Der neue Wert oder <i>null</i>, wenn dieser entfernt /// werden soll.</param> internal static void SetRegistryTime(string name, DateTime?value) { // Always be safe try { // Check mode if (value.HasValue) { VCRServer.ServiceRegistry.SetValue(name, value.Value.ToString("u")); } else { VCRServer.ServiceRegistry.DeleteValue(name, false); } } catch (Exception e) { // Report VCRServer.Log(e); } }
static void Main_EPGLookup( string[] args ) { // Create the server using (VCRServer server = new VCRServer( new DirectoryInfo( @"C:\temp\VCR.NET 3.9 Alpha\Jobs" ) )) { // Create filter GuideEntryFilter filter = new GuideEntryFilter { MaximumEntriesPerStation = 30, MinimumDateTime = DateTime.UtcNow, MinimumIsCurrent = true, Profile = null, Station = "ZDF [ZDFvision]", ContentFilter = null }; // Load a bit of events ProgramGuideEntry[] entries = server.GetProgramGuideEntries( filter ); } }
/// <summary> /// Startet eine einzelne Erweiterung. /// </summary> /// <param name="extension">Die gewünschte Erweiterung.</param> /// <param name="environment">Parameter für die Erweiterung.</param> /// <returns>Der gestartete Prozess oder <i>null</i>, wenn ein Start nicht möglich war.</returns> public static Process RunExtension(FileInfo extension, Dictionary <string, string> environment) { // Be safe try { // Create the start record var info = new ProcessStartInfo { WorkingDirectory = extension.DirectoryName, FileName = extension.FullName, UseShellExecute = false, CreateNoWindow = true, ErrorDialog = false, }; // Overwrite as wanted if (environment != null) { foreach (var env in environment) { info.EnvironmentVariables.Add(env.Key.Substring(1, env.Key.Length - 2), env.Value); } } // Log VCRServer.Log(LoggingLevel.Full, Properties.Resources.RunExtension, extension.FullName); // Start the process return(Process.Start(info)); } catch (Exception e) { // Report VCRServer.Log(e); } // Report return(null); }
/// <summary> /// Wendet eine Methode auf alle verwalteten Profile an. /// </summary> /// <param name="method">Die gewünschte Methode.</param> /// <param name="ignoreErrors">Gesetzt, wenn Fehler ignoriert werden sollen.</param> private void ForEachProfile(Action <ProfileState> method, bool ignoreErrors = false) { // Forward to all foreach (var state in m_profiles.Values) { try { // Forward method(state); } catch (Exception e) { // Report VCRServer.Log(e); // See if we are allowed to ignore if (!ignoreErrors) { throw; } } } }
static void Main_EPGScan( string[] args ) { // Create the server using (VCRServer server = new VCRServer( new DirectoryInfo( @"C:\temp\VCR.NET 3.9 Alpha\Jobs" ) )) { // Attach to the profile state of interest ProfileState state = server.FindProfile( "DVB-S2" ); // Report all Console.WriteLine( ProgramGuideManager.UpdateEnabled ); Console.WriteLine( state.ProgramGuide.NextUpdateTime ); // Create request using (ProgramGuideRequest request = state.CreateProgramGuideRequest()) if (null != request) { // Manipulate request.Recording.EndsAt = DateTime.UtcNow.AddSeconds( 30 ); // Get the information FullInfo info0 = request.CreateFullInformation(); // Start it request.Start(); // Wait for end for (; request.IsRunning; Thread.Sleep( 2500 )) Console.WriteLine( "Collecting... {0}", DateTime.Now ); // Get the information FullInfo info1 = request.CreateFullInformation(); // Report Console.WriteLine( info1.Recording.TotalSize ); } } }
/// <summary> /// Erzeugt eine neue Verwaltungsinstanz und lädt die aktuellen Auftragsliste. /// </summary> /// <param name="rootDirectory">Meldet das Verzeichnis, unterhalb dessen alle /// Aufträge und Protokolle angelegt werden.</param> /// <param name="server">Die VCR.NET Instanz, der diese Verwaltung zugeordnet ist.</param> internal JobManager(DirectoryInfo rootDirectory, VCRServer server) { // Remember RootDirectory = rootDirectory; Server = server; // Create root directory RootDirectory.Create(); // Create working directories CollectorDirectory.Create(); ArchiveDirectory.Create(); JobDirectory.Create(); LogDirectory.Create(); // Load all jobs foreach (var job in VCRJob.Load(JobDirectory)) { if (job.UniqueID.HasValue) { m_Jobs[job.UniqueID.Value] = job; } } }
/// <summary> /// Prüft, ob eine Datei in einem zulässigen Aufzeichnungsverzeichnis liegt. /// </summary> /// <param name="path">Der zu prüfende Dateipfad.</param> /// <returns>Gesetzt, wenn der Pfad gültig ist.</returns> public bool IsValidTarget(string path) { // Must habe a path if (string.IsNullOrEmpty(path)) { return(false); } // Test it foreach (var allowed in TargetDirectories) { if (path.StartsWith(allowed.FullName, StringComparison.InvariantCultureIgnoreCase)) { // Silent create the directory try { // Create the directory Directory.CreateDirectory(Path.GetDirectoryName(path)); // Yeah return(true); } catch (Exception e) { // Report VCRServer.Log(e); // Done return(false); } } } // No, not possible return(false); }
/// <summary> /// Beendet eine Aufzeichnung. /// </summary> /// <param name="scheduleIdentifier">Die eindeutige Kennung der Aufzeichnung.</param> public void EndRecording(Guid scheduleIdentifier) { // Protect current request against transistions lock (m_RequestLock) { // Attach to the current request var current = m_CurrentRequest; // See if it exists if (ReferenceEquals(current, null)) { // Report VCRServer.Log(LoggingLevel.Errors, "Request to end Recording '{0}' but there is no active Recording Process", scheduleIdentifier); // Better do it ourselves Collection.ConfirmOperation(scheduleIdentifier, false); } else { // Just stop current.Stop(scheduleIdentifier); } } }
static void Main5( string[] args ) { // Attach to job manager VCRServer server = new VCRServer( new DirectoryInfo( @"C:\temp\VCR.NET 3.9 Alpha\Jobs" ) ); JobManager jobs = server.JobManager; // Create EPG collection using (SourceScanRequest request = SourceScanRequest.CreateDefault( "Nexus Scan", jobs )) if (null != request) { // Get the information FullInfo info0 = request.CreateFullInformation(); // Report Console.WriteLine( info0.Recording.JobType ); // Start it request.BeginExecute( false ); // Wait for end Console.WriteLine( "Updateing..." ); // Process for (string line; !string.IsNullOrEmpty( line = Console.ReadLine() ); ) { // Get the information FullInfo info2 = request.CreateFullInformation(); // Report Console.WriteLine( info2.Recording.TotalSize ); } // Stop it request.Stop(); // Get the information FullInfo info1 = request.CreateFullInformation(); } // Done Console.WriteLine( "Done" ); Console.ReadLine(); }
/// <summary> /// Bereitet den VCR.NET Recording Service auf die endgültige Terminierung /// des Dienstes vor. /// </summary> private void Terminate() { // Get the hibernation control thread var hibTest = m_HibernateHelper; // Reset it m_HibernateHelper = null; // Unregister from power manager PowerManager.OnChanged -= HibernationChanged; // Wait for the web server starter thread to finish var webThread = Interlocked.Exchange( ref m_webStarter, null ); if (webThread != null) webThread.Join(); // Stop web server - client requests are no longer accepted if (m_WebServer != null) m_WebServer.Stop(); // Stop all recordings using (VCRServer) VCRServer = null; // Finally wait for the hibernation helper to terminate (at most five seconds) if (hibTest != null) hibTest.Join(); }
/// <summary> /// Meldet, dass eine Aufzeichnung nun beginnen sollte. /// </summary> /// <param name="item">Die zu startende Aufzeichnung.</param> /// <param name="planner">Die Planungsinstanz.</param> /// <param name="context">Zusatzinformationen zur Aufzeichnungsplanung.</param> void IRecordingPlannerSite.Start(IScheduleInformation item, RecordingPlanner planner, PlanContext context) { // We are no longer active - simulate start and do nothing if (!m_plannerActive) { // Make planner believe we did it planner.Start(item); // Make sure that we wake up after the grace period if (PowerManager.IsSuspended && VCRConfiguration.Current.SuppressDelayAfterForcedHibernation) { Tools.ExtendedLogging("Hibernation Delay is disabled and can not be enforced"); } else { m_timer.SecondsToWait = VCRConfiguration.Current.DelayAfterForcedHibernation.TotalSeconds; } // Done return; } // Report VCRServer.Log(LoggingLevel.Schedules, "Start recording '{0}'", item.Definition.Name); // Locate the profile - if we don't find it we are in big trouble! ProfileState profile; if (!m_profiles.TryGetValue(item.Resource.Name, out profile)) { return; } // Mark as pending m_pendingSchedule = item; m_pendingStart = true; // Create the recording var recording = VCRRecordingInfo.Create(item, context); // Check for EPG var guideUpdate = item.Definition as ProgramGuideTask; if (guideUpdate != null) { // Start a new guide collector m_pendingActions += ProgramGuideProxy.Create(profile, recording).Start; } else { // Check for PSI var sourceUpdate = item.Definition as SourceListTask; if (sourceUpdate != null) { // Start a new update m_pendingActions += SourceScanProxy.Create(profile, recording).Start; } else { // Start a regular recording - profile will decide if to join an existing recording m_pendingActions += () => profile.StartRecording(recording); } } }
/// <summary> /// Meldet, dass eine Aufzeichnung nicht ausgeführt werden kann. /// </summary> /// <param name="item">Die nicht ausgeführte Aufzeichnung.</param> void IRecordingPlannerSite.Discard(IScheduleDefinition item) { // Report VCRServer.Log(LoggingLevel.Schedules, "Could not record '{0}'", item.Name); }
/// <summary> /// Der SCM möchte den VCR.NET Recording Service starten. /// </summary> /// <param name="args">Befehlszeilenparameter für den Start.</param> protected override void OnStart(string[] args) { // Fully save try { // Report Tools.ExtendedLogging("SCM has requested a Service Start"); // Report delay if (!Tools.DebugMode) { RequestAdditionalTime(300000); } // Create server instance VCRServer = new VCRServer(Tools.ApplicationDirectory.Parent); // Create web server instance m_WebServer = new WebServer.ServerHost(VCRServer); // Report Tools.ExtendedLogging("Attaching Process"); // Get a token for this process IntPtr processToken; if (!OpenProcessToken(Process.GetCurrentProcess().Handle, 0x28, out processToken)) { return; } // Report Tools.ExtendedLogging("Aquiring Shutdown Privileges"); // Helper TokenPrivileges privileges = new TokenPrivileges(); // Lookup the privilege value if (LookupPrivilegeValue(null, "SeShutdownPrivilege", out privileges.Luid)) { // Finish privileges.PrivilegeCount = 1; privileges.Attributes = 2; // Update if (!AdjustTokenPrivileges(processToken, false, ref privileges, 0, IntPtr.Zero, IntPtr.Zero)) { VCRServer.Log(LoggingLevel.Security, EventLogEntryType.Warning, Properties.Resources.AquirePrivilegeFailed); } } else { // Report VCRServer.Log(LoggingLevel.Security, EventLogEntryType.Error, Properties.Resources.LookupPrivilegeFailed); } // Release CloseHandle(processToken); // Report Tools.ExtendedLogging("Web Server Start initiated from Thread {0}", Thread.CurrentThread.ManagedThreadId); // Create the web server on a separate thread m_webStarter = new Thread(() => { // Be safe try { // Report Tools.ExtendedLogging("Starting Web Server on Thread {0}", Thread.CurrentThread.ManagedThreadId); // Start Web Server m_WebServer.Start(); } catch (Exception e) { // Report EventLog.WriteEntry(e.ToString(), EventLogEntryType.Error); } }); // Start it m_webStarter.Start(); // Report Tools.ExtendedLogging("Final Initialisation started"); // Start our child process and report success VCRServer.Log(LoggingLevel.Full, Properties.Resources.ServiceStarted); // Register with power manager PowerManager.OnChanged += HibernationChanged; // Run initial scan PowerManager.OnResume(); // Create hibernate thread m_HibernateHelper = new Thread(ReTestShutdown) { Name = "Periodic Check for Hibernation" }; m_HibernateHelper.Start(); // Report Tools.ExtendedLogging("Returning Control to SCM"); } catch (Exception e) { // Report Tools.LogException("OnStart", e); // Process throw e; } }
/// <summary> /// Aktualisiert ständig die Planung. /// </summary> private void PlanThread() { // Always loop while (m_planThread != null) { // See if a new plan is requested lock (m_newPlanSync) while (!m_newPlan) { if (m_planThread == null) { return; } else { Monitor.Wait(m_newPlanSync); } } // At least we accepted the request m_newPlan = false; // See if we still have a planner var planner = m_planner; if (planner == null) { break; } // Just take a look what to do next using (PowerManager.StartForbidHibernation()) try { // Reset start actions m_pendingActions = null; // Protect planning. lock (planner) { // Report Tools.ExtendedLogging("Woke up for Plan Calculation at {0}", DateTime.Now); // Retest if (m_planThread == null) { break; } // See if we are allowed to take the next step in plan - we schedule only one activity at a time if (m_pendingSchedule == null) { // Release our lock AllowHibernation(); // Reset timer if (PowerManager.IsSuspended && VCRConfiguration.Current.SuppressDelayAfterForcedHibernation) { Tools.ExtendedLogging("VCR.NET is suspending - not updating Timer"); } else { m_timer.SecondsToWait = 0; } // Analyse plan planner.DispatchNextActivity(DateTime.UtcNow); // If we are shutting down better forget anything we did in the previous step - only timer setting matters! if (!m_plannerActive) { // Reset to initial state m_pendingSchedule = null; m_pendingActions = null; m_pendingStart = false; // And forget all allocations planner.Reset(); // Just in case allow hibernation again AllowHibernation(); } } } // Run start and stop actions outside the planning lock (to avoid deadlocks) but inside the hibernation protection (to forbid hibernation) var toStart = m_pendingActions; if (toStart != null) { toStart(); } } catch (Exception e) { // Report and ignore - we do not expect any error to occur VCRServer.Log(e); } // New plan is now available - beside termination this will do nothing at all but briefly aquiring an idle lock lock (m_planAvailableSync) Monitor.PulseAll(m_planAvailableSync); } }
static void Main3( string[] args ) { // Attach to job manager VCRServer server = new VCRServer( new DirectoryInfo( @"C:\temp\VCR.NET 3.9 Alpha\Jobs" ) ); JobManager jobs = server.JobManager; // Get the profile Profile nexus = VCRProfiles.FindProfile( "Nexus" ); // Find the next recording VCRRecordingInfo rec = jobs.FindNextJob( new DateTime( 2009, 2, 19, 20, 0, 0 ), null, nexus ); if (null != rec) if (rec.StartsAt.HasValue) using (RecordingRequest recording = jobs.CreateRecording( rec, rec.StartsAt.Value, nexus )) { // Get the information FullInfo info0 = recording.CreateFullInformation(); // Start it recording.BeginExecute( false ); // Report Console.WriteLine( "Recording..." ); Console.ReadLine(); // Get the information FullInfo info1 = recording.CreateFullInformation(); } // Done Console.WriteLine( "Done" ); Console.ReadLine(); }
/// <summary> /// Der SCM möchte den VCR.NET Recording Service starten. /// </summary> /// <param name="args">Befehlszeilenparameter für den Start.</param> protected override void OnStart( string[] args ) { // Fully save try { // Report Tools.ExtendedLogging( "SCM has requested a Service Start" ); // Report delay if (!Tools.DebugMode) RequestAdditionalTime( 300000 ); // Create server instance VCRServer = new VCRServer( Tools.ApplicationDirectory.Parent ); // Create web server instance m_WebServer = new WebServer.ServerHost( VCRServer ); // Report Tools.ExtendedLogging( "Attaching Process" ); // Get a token for this process IntPtr processToken; if (!OpenProcessToken( Process.GetCurrentProcess().Handle, 0x28, out processToken )) return; // Report Tools.ExtendedLogging( "Aquiring Shutdown Privileges" ); // Helper TokenPrivileges privileges = new TokenPrivileges(); // Lookup the privilege value if (LookupPrivilegeValue( null, "SeShutdownPrivilege", out privileges.Luid )) { // Finish privileges.PrivilegeCount = 1; privileges.Attributes = 2; // Update if (!AdjustTokenPrivileges( processToken, false, ref privileges, 0, IntPtr.Zero, IntPtr.Zero )) VCRServer.Log( LoggingLevel.Security, EventLogEntryType.Warning, Properties.Resources.AquirePrivilegeFailed ); } else { // Report VCRServer.Log( LoggingLevel.Security, EventLogEntryType.Error, Properties.Resources.LookupPrivilegeFailed ); } // Release CloseHandle( processToken ); // Report Tools.ExtendedLogging( "Web Server Start initiated from Thread {0}", Thread.CurrentThread.ManagedThreadId ); // Create the web server on a separate thread m_webStarter = new Thread( () => { // Be safe try { // Report Tools.ExtendedLogging( "Starting Web Server on Thread {0}", Thread.CurrentThread.ManagedThreadId ); // Start Web Server m_WebServer.Start(); } catch (Exception e) { // Report EventLog.WriteEntry( e.ToString(), EventLogEntryType.Error ); } } ); // Start it m_webStarter.Start(); // Report Tools.ExtendedLogging( "Final Initialisation started" ); // Start our child process and report success VCRServer.Log( LoggingLevel.Full, Properties.Resources.ServiceStarted ); // Register with power manager PowerManager.OnChanged += HibernationChanged; // Run initial scan PowerManager.OnResume(); // Create hibernate thread m_HibernateHelper = new Thread( ReTestShutdown ) { Name = "Periodic Check for Hibernation" }; m_HibernateHelper.Start(); // Report Tools.ExtendedLogging( "Returning Control to SCM" ); } catch (Exception e) { // Report Tools.LogException( "OnStart", e ); // Process throw e; } }
/// <summary> /// Lädt alle Profile erneut. /// </summary> internal static void Reset() { // Report Tools.ExtendedLogging("Reloading Profile List"); // Forward to profile manager ProfileManager.Refresh(); // Create a new state var newState = new _State(); // List of profiles var profiles = new List <Profile>(); // Load the setting var profileNames = VCRConfiguration.Current.ProfileNames; if (!string.IsNullOrEmpty(profileNames)) { foreach (var profileName in profileNames.Split('|')) { // Try to locate var profile = ProfileManager.FindProfile(profileName.Trim()); if (profile == null) { // This is not goot VCRServer.LogError(Properties.Resources.InternalError_NoProfile, profileName.Trim()); // Next continue; } // Report Tools.ExtendedLogging("Using Profile {0}", profile.Name); // Remember profiles.Add(profile); // Create the dictionary of sources var sourcesByIdentifier = new Dictionary <SourceIdentifier, SourceSelection>(); var sourcesByKey = new Dictionary <string, SourceSelection>(); // Load by name foreach (var byDisplayName in profile.AllSourcesByDisplayName) { sourcesByKey[byDisplayName.DisplayName] = byDisplayName; } // Remember it newState.SourceByIdentifierMap[profile.Name] = sourcesByIdentifier; newState.SourceBySelectionMap[profile.Name] = sourcesByKey; // Load list foreach (var source in sourcesByKey.Values) { // Just remember by identifier sourcesByIdentifier[source.Source] = source; // Correct back the name source.DisplayName = ((Station)source.Source).FullName; } } } // Fill it foreach (var profileMap in newState.SourceBySelectionMap.Values) { foreach (var mapEntry in profileMap) { newState.UniqueNameBySelectionMap[mapEntry.Value.SelectionKey] = mapEntry.Key; } } // Add all qualified names to allow semi-legacy clients to do a unique lookup foreach (var profileMap in newState.SourceBySelectionMap.Values) { foreach (var source in profileMap.ToList()) { if (!source.Key.Equals(source.Value.DisplayName)) { // Unmap the station var station = (Station)source.Value.Source; // Enter special notation profileMap[$"{station.Name} {station.ToStringKey()} [{station.Provider}]"] = source.Value; } } } // Use all newState.Profiles = profiles.ToArray(); newState.ProfileMap = profiles.ToDictionary(profile => profile.Name, newState.ProfileMap.Comparer); // Report Tools.ExtendedLogging("Activating new Profile Set"); // Use the new state CurrentState = newState; }
static void Main1( string[] args ) { // Attach to job manager VCRServer server = new VCRServer( new DirectoryInfo( @"C:\temp\VCR.NET 3.9 Alpha\Jobs" ) ); JobManager jobs = server.JobManager; // Process all profiles foreach (Profile profile in VCRProfiles.Profiles) { // Report Console.WriteLine( profile.Name ); // Start time DateTime start = DateTime.UtcNow; // Process a bit for (int i = 10; i-- > 0; ) { // Helper data VCRRecordingInfo[] included; bool inComplete; // Find the recording FullInfo info = jobs.FindNextRecording( start, profile, out inComplete, out included ); VCRRecordingInfo rec = info.Recording; VCRJob job = jobs[rec.JobUniqueID.Value]; VCRSchedule sched = job[rec.ScheduleUniqueID.Value]; // Report Console.WriteLine( "\t{0} {1} {2} ({3}) {4} {5} {6} {7}", rec.StartsAt.Value.ToLocalTime(), rec.EndsAt.ToLocalTime().TimeOfDay, job.Name, sched.Name, inComplete, included.Length, rec.JobUniqueID, rec.ScheduleUniqueID ); // Report foreach (VCRRecordingInfo include in included) Console.WriteLine( "\t\t{0} {1} {2} {3} {4}", include.Source.GetUniqueName(), include.StartsAt.Value.ToLocalTime(), include.EndsAt.ToLocalTime().TimeOfDay, include.JobUniqueID, include.ScheduleUniqueID ); // Report foreach (StreamInfo stream in info.Streams) foreach (ScheduleInfo schedule in stream.Schedules) Console.WriteLine( "\t\t{0} {1} {2} {3}", schedule.JobUniqueID, schedule.ScheduleUniqueID, schedule.StartsAt.ToLocalTime(), schedule.EndsAt.ToLocalTime().TimeOfDay ); // Advance start = rec.EndsAt; } // Helper data VCRRecordingInfo[] incDummy; bool dummyFlag; // Start timer Stopwatch timer = Stopwatch.StartNew(); // Measure for (int n = 0; ++n > 0; ) { // Find the recording jobs.FindNextRecording( DateTime.UtcNow, profile, out dummyFlag, out incDummy ); // Get the time TimeSpan delta = timer.Elapsed; if (delta.TotalSeconds >= 5) { // Report Console.WriteLine( "{0}ms", delta.TotalMilliseconds / n ); // Done break; } } } // Get the profile Profile nexus = VCRProfiles.FindProfile( "Nexus" ); // Find the next recording VCRRecordingInfo rec2 = jobs.FindNextJob( new DateTime( 2009, 2, 19, 20, 0, 0 ), null, nexus ); if (null != rec2) if (rec2.StartsAt.HasValue) using (RecordingRequest recording = jobs.CreateRecording( rec2, rec2.StartsAt.Value, nexus )) { // Get the information FullInfo info0 = recording.CreateFullInformation(); #if EXEC // Start it recording.BeginExecute( false ); // Report Console.WriteLine( "Recording..." ); Console.ReadLine(); // Get the information FullInfo info1 = recording.CreateFullInformation(); #endif } // Done Console.WriteLine( "Done" ); Console.ReadLine(); }