-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathProgram.cs
137 lines (114 loc) · 4.2 KB
/
Program.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
using System.Diagnostics;
using System.Media;
using System.Runtime.InteropServices;
// Initialize logger.
Logger logger = new Logger(Path.GetTempPath());
logger.WriteLog("SleepWell started.");
// Test for operating system as this program only runs on Windows.
if (!OperatingSystem.IsWindows())
{
string problemText = "This application only runs on Windows operating systems!";
logger.WriteLog(problemText);
throw new Exception(problemText);
}
else
{
logger.WriteLog("The operating system is Windows. SleepWell can be executed properly.");
}
// Ensure that the system is not idle when initiating shutdown.
InputInfo input = new InputInfo();
DateTime lastSystemInteraction = input.GetLastInputTime();
DateTime sleepWellStarted = DateTime.Now;
if (sleepWellStarted - lastSystemInteraction > TimeSpan.FromSeconds(30.0))
{
bool hasUserReturned = false;
while (!hasUserReturned)
{
logger.WriteLog("The system has not seen user input for the last 30 seconds. Postponing shutdown for 5 minutes");
// Every 5 minutes, check if there has been system interaction after SleepWell has been started that is not older than 30 seconds (user has returned and left again).
Thread.Sleep(5 * 60 * 1000);
lastSystemInteraction = input.GetLastInputTime();
if (sleepWellStarted < lastSystemInteraction && DateTime.Now - lastSystemInteraction < TimeSpan.FromSeconds(30.0))
{
hasUserReturned = true;
}
}
}
logger.WriteLog("The system has seen user input in the last 30 seconds. Initiating shutdown sequence.");
// Set up sound player.
string pathToFile = @".\Applause.wav";
SoundPlayer soundPlayer = new SoundPlayer();
try
{
soundPlayer.SoundLocation = pathToFile;
soundPlayer.Load();
logger.WriteLog("Sound player loaded successfully.");
}
catch (System.Exception)
{
string problemText = "The sound file was not found! Path: " + pathToFile;
logger.WriteLog(problemText);
throw new FileNotFoundException("The sound file was not found! Path: " + pathToFile, pathToFile);
}
// Synchronously play the sound and wait for 2 and 1 minutes. Synchronous to make sure, that the sound is played before the shutdown is initiated.
soundPlayer.PlaySync();
logger.WriteLog("Applause is played for the first time. 3 minutes to shutdown");
Thread.Sleep(2 * 60 * 1000);
soundPlayer.PlaySync();
logger.WriteLog("Applause is played for the second time. 1 minute to shutdown");
Thread.Sleep(1 * 60 * 1000);
soundPlayer.PlaySync();
logger.WriteLog("Applause is played for the second time. Shutdown now.");
// Test if any other users are logged on.
var psi2 = new ProcessStartInfo("quser");
var process2 = new Process();
process2!.StartInfo = psi2;
process2!.StartInfo.RedirectStandardOutput = true;
process2.Start();
process2!.WaitForExit();
string userList = process2!.StandardOutput.ReadToEnd();
int loggedOnUsersAmount = userList.Count(t => t == '\n') - 1;
if (loggedOnUsersAmount > 1)
{
string problemText = "There are other users logged on. Not shutting down.";
logger.WriteLog(problemText);
throw new Exception(problemText);
}
// Shutting down.
logger.WriteLog("Shutting down.");
var psi = new ProcessStartInfo("shutdown", "/s /t 0");
psi.CreateNoWindow = true;
psi.UseShellExecute = false;
Process.Start(psi);
class InputInfo
{
[DllImport("User32.dll")]
public static extern bool GetLastInputInfo(ref LASTINPUTINFO plii);
public DateTime GetLastInputTime()
{
var lastInputInfo = new LASTINPUTINFO();
lastInputInfo.cbSize = (uint)Marshal.SizeOf(lastInputInfo);
GetLastInputInfo(ref lastInputInfo);
return DateTime.Now.AddMilliseconds(-(Environment.TickCount - lastInputInfo.dwTime));
}
[StructLayout(LayoutKind.Sequential)]
internal struct LASTINPUTINFO
{
public uint cbSize;
public uint dwTime;
}
}
class Logger
{
private StreamWriter logFile;
public Logger(string Path)
{
string folder = Path + "SleepWell_Log_" + DateTime.Now.ToString("HH.mm.ss") + ".txt";
logFile = new StreamWriter(folder, append: true);
logFile.AutoFlush = true;
}
public void WriteLog(string LogText)
{
logFile.WriteLine(DateTime.Now + ": " + LogText);
}
}