Skip to content

Commit

Permalink
Added source code.
Browse files Browse the repository at this point in the history
  • Loading branch information
Stefan Tucker committed Feb 17, 2023
1 parent 2a3d5dc commit c918e1c
Show file tree
Hide file tree
Showing 23 changed files with 1,774 additions and 1 deletion.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
bin/
*.user
.vs/
38 changes: 38 additions & 0 deletions App.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
<section name="Sandman.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
</sectionGroup>
</configSections>
<!--
Apparently WMC is in .NET 2.
.NET 4 changed how it loads legacy frameworks.
So we need this attribute.
-->
<startup useLegacyV2RuntimeActivationPolicy="true">
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8" />
</startup>
<userSettings>
<Sandman.Properties.Settings>
<setting name="MinimumTimeBeforeNextRecording" serializeAs="String">
<value>00:30:00</value>
</setting>
<setting name="DelayBeforeSuspending" serializeAs="String">
<value>00:00:10</value>
</setting>
<setting name="TimeUserInactiveBeforeSuspending" serializeAs="String">
<value>00:30:00</value>
</setting>
<setting name="DelayAfterResume" serializeAs="String">
<value>00:10:00</value>
</setting>
<setting name="BlacklistedProcesses" serializeAs="String">
<value>ehshell;epg123;epg123client;hdhr2mxf;epg123Transfer;WMC_Status;vlc</value>
</setting>
<setting name="DelayForElevatedProcess" serializeAs="String">
<value>00:01:00</value>
</setting>
</Sandman.Properties.Settings>
</userSettings>
</configuration>
10 changes: 10 additions & 0 deletions App.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<Application x:Class="Sandman.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Sandman"
StartupUri="MainWindow.xaml"
ShutdownMode="OnExplicitShutdown"
>
<Application.Resources>
</Application.Resources>
</Application>
11 changes: 11 additions & 0 deletions App.xaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using System.Windows;

namespace Sandman
{
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App : Application
{
}
}
18 changes: 18 additions & 0 deletions MainWindow.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<Window x:Class="Sandman.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Sandman"
mc:Ignorable="d"
Title="Sandman" Width="600" Height="400"
Icon="/Sandman;component/Resources/weather_moon_half.png"
Loaded="Window_Loaded"
Closing="Window_Closing"
>
<Grid>
<TextBox TextWrapping="Wrap" Text="{Binding ConsoleLog, Mode=OneWay}"
BorderThickness="0" IsReadOnly="True" IsReadOnlyCaretVisible="True" VerticalScrollBarVisibility="Visible" HorizontalScrollBarVisibility="Auto"
/>
</Grid>
</Window>
99 changes: 99 additions & 0 deletions MainWindow.xaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Text;
using System.Threading;
using System.Windows;

namespace Sandman
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window, INotifyPropertyChanged
{
public static readonly string ExecutableFolder;
public StringBuilder ConsoleLog { get; set; } = new StringBuilder();

private readonly MyLibrary.NotificationIcon _notificationIcon = null;


static MainWindow()
{
var asm = System.Reflection.Assembly.GetEntryAssembly();
ExecutableFolder = Path.GetDirectoryName(asm.Location);
}
public MainWindow()
{
// remove original default trace listener
Trace.Listeners.Clear();

// form path to log file
string pathLog = Path.Combine(ExecutableFolder, "Sandman.log");

// add new default listener and set the filename
DefaultTraceListener listener = new DefaultTraceListener
{
LogFileName = pathLog
};
Trace.Listeners.Add(listener);
Trace.AutoFlush = true;

/*
* Set up notification area icon
*/
_notificationIcon = new MyLibrary.NotificationIcon(this, Properties.Resources.Sandman, nameof(Sandman), new System.Windows.Forms.MenuItem[0]);

InitializeComponent();
DataContext = this;
}


private async void Window_Loaded(object sender, RoutedEventArgs e)
{
await WatchWMC.StartAsync(this).ConfigureAwait(continueOnCapturedContext: false);
}


private void Window_Closing(object sender, CancelEventArgs e)
{
if (_notificationIcon.ShouldClose())
{
Application.Current.Shutdown();
return;
}

e.Cancel = true;
Hide();
Trace.Flush();
}


public void WriteOutput(string s)
{
string timestampedMessage = $"[{DateTimeOffset.Now:yyyy-MM-dd HH:mm:ss}] (Thread {Thread.CurrentThread.ManagedThreadId:00}) {s}";
Trace.TraceInformation(timestampedMessage);
ConsoleLog.AppendLine(timestampedMessage);

RaisePropertyChanged(nameof(ConsoleLog));
}


// Boilerplate code
#region IRaisePropertyChanged

#region INotifyPropertyChanged

public event PropertyChangedEventHandler PropertyChanged;

#endregion INotifyPropertyChanged

public void RaisePropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}

#endregion IRaisePropertyChanged
}
}
49 changes: 49 additions & 0 deletions NativeMethods.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
using System;
using System.Runtime.InteropServices;

namespace Sandman
{
public class NativeMethods
{
public static TimeSpan GetTimeSinceLastActivity()
{
LASTINPUTINFO lastInputInfo = LASTINPUTINFO.Create();
if (!GetLastInputInfo(ref lastInputInfo))
{
return TimeSpan.Zero;
}

// Even though it says "ticks," it's really milliseconds.
/// <see cref="https://docs.microsoft.com/en-us/dotnet/api/system.environment.tickcount"/>
uint msecEnvTicks = (uint)Environment.TickCount;
uint lastInputTick = lastInputInfo.dwTime;
uint idleTime = msecEnvTicks - lastInputTick;
return TimeSpan.FromMilliseconds(idleTime);
}


/// <see cref="https://www.pinvoke.net/default.aspx/Structures/LASTINPUTINFO.html"/>
[StructLayout(LayoutKind.Sequential)]
private struct LASTINPUTINFO
{
public static readonly int SizeOf = Marshal.SizeOf(typeof(LASTINPUTINFO));

[MarshalAs(UnmanagedType.U4)]
public UInt32 cbSize;
[MarshalAs(UnmanagedType.U4)]
public UInt32 dwTime; // Even though it says "ticks," it's really milliseconds.

public static LASTINPUTINFO Create() => new LASTINPUTINFO()
{
cbSize = (uint)SizeOf,
dwTime = 0,
};
}

/// <see cref="https://www.pinvoke.net/default.aspx/user32.GetLastInputInfo"/>
/// <param name="plii"></param>
/// <returns></returns>
[DllImport("user32.dll")]
private static extern bool GetLastInputInfo(ref LASTINPUTINFO plii);
}
}
Loading

0 comments on commit c918e1c

Please sign in to comment.