Update file handling logic

This commit is contained in:
Den Delimarsky
2021-04-22 08:14:07 -07:00
parent a0c5f8cc59
commit 919f7bacfe

View File

@@ -5,6 +5,7 @@ using System;
using System.CommandLine; using System.CommandLine;
using System.CommandLine.Invocation; using System.CommandLine.Invocation;
using System.IO; using System.IO;
using System.Runtime.InteropServices;
using System.Threading; using System.Threading;
namespace Espresso.Shell namespace Espresso.Shell
@@ -14,6 +15,9 @@ namespace Espresso.Shell
private static Mutex mutex = null; private static Mutex mutex = null;
private const string appName = "Espresso"; private const string appName = "Espresso";
const int ERROR_SHARING_VIOLATION = 32;
const int ERROR_LOCK_VIOLATION = 33;
static int Main(string[] args) static int Main(string[] args)
{ {
bool instantiated; bool instantiated;
@@ -106,6 +110,10 @@ namespace Espresso.Shell
Filter = Path.GetFileName(config) Filter = Path.GetFileName(config)
}; };
watcher.Changed += new FileSystemEventHandler(HandleEspressoConfigChange); watcher.Changed += new FileSystemEventHandler(HandleEspressoConfigChange);
// Initially the file might not be updated, so we need to start processing
// settings right away.
ProcessSettings(config);
} }
catch (Exception ex) catch (Exception ex)
{ {
@@ -151,56 +159,82 @@ namespace Espresso.Shell
} }
private static void HandleEspressoConfigChange(object sender, FileSystemEventArgs e) private static void HandleEspressoConfigChange(object sender, FileSystemEventArgs e)
{
ProcessSettings(e.FullPath);
}
private static void ProcessSettings(string fullPath)
{ {
Console.WriteLine("Detected a file change. Reacting..."); Console.WriteLine("Detected a file change. Reacting...");
try try
{ {
var settings = JsonConvert.DeserializeObject<EspressoSettingsModel>(File.ReadAllText(e.FullPath)); EspressoSettingsModel settings = null;
// If the settings were successfully processed, we need to set the right mode of operation. var fileStream = GetSettingsFile(fullPath, 10);
// INDEFINITE = 0 if (fileStream != null)
// TIMED = 1
switch (settings.Properties.Mode)
{ {
case 0: using (fileStream)
{ {
// Indefinite keep awake. using StreamReader reader = new StreamReader(fileStream);
bool success = APIHelper.SetIndefiniteKeepAwake(settings.Properties.KeepDisplayOn.Value); settings = JsonConvert.DeserializeObject<EspressoSettingsModel>(reader.ReadToEnd());
if (success) }
{
Console.WriteLine($"Currently in indefinite keep awake. Display always on: {settings.Properties.KeepDisplayOn.Value}");
}
else
{
Console.WriteLine("Could not set up the state to be indefinite keep awake.");
}
break;
}
case 1:
{
// Timed keep-awake.
long computedTime = (settings.Properties.Hours.Value * 60 * 60) + (settings.Properties.Minutes.Value * 60);
Console.WriteLine($"In timed keep-awake mode. Expecting to be awake for {computedTime} seconds.");
bool success = APIHelper.SetTimedKeepAwake(computedTime, settings.Properties.KeepDisplayOn.Value); if (settings != null)
if (success) {
{ // If the settings were successfully processed, we need to set the right mode of operation.
Console.WriteLine($"Finished execution of timed keep-awake."); // INDEFINITE = 0
// TIMED = 1
ResetNormalPowerState(); switch (settings.Properties.Mode)
}
else
{
Console.WriteLine("Could not set up the state to be timed keep awake.");
}
break;
}
default:
{ {
ForceExit("Could not select the right mode of operation. Existing...", 1); case 0:
break; {
// Indefinite keep awake.
bool success = APIHelper.SetIndefiniteKeepAwake(settings.Properties.KeepDisplayOn.Value);
if (success)
{
Console.WriteLine($"Currently in indefinite keep awake. Display always on: {settings.Properties.KeepDisplayOn.Value}");
}
else
{
Console.WriteLine("Could not set up the state to be indefinite keep awake.");
}
break;
}
case 1:
{
// Timed keep-awake.
long computedTime = (settings.Properties.Hours.Value * 60 * 60) + (settings.Properties.Minutes.Value * 60);
Console.WriteLine($"In timed keep-awake mode. Expecting to be awake for {computedTime} seconds.");
bool success = APIHelper.SetTimedKeepAwake(computedTime, settings.Properties.KeepDisplayOn.Value);
if (success)
{
Console.WriteLine($"Finished execution of timed keep-awake.");
ResetNormalPowerState();
}
else
{
Console.WriteLine("Could not set up the state to be timed keep awake.");
}
break;
}
default:
{
ForceExit("Could not select the right mode of operation. Existing...", 1);
break;
}
} }
}
else
{
Console.WriteLine("Settings are null.");
}
}
else
{
Console.WriteLine("Could not get handle on file.");
} }
} }
catch (Exception ex) catch (Exception ex)
@@ -209,6 +243,31 @@ namespace Espresso.Shell
} }
} }
private static FileStream GetSettingsFile(string path, int retries)
{
for (int i = 0; i < retries; i++)
{
FileStream fileStream = null;
try
{
fileStream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.None);
return fileStream;
}
catch (IOException ex)
{
var errorCode = Marshal.GetHRForException(ex) & ((1 << 16) - 1);
if (errorCode == ERROR_SHARING_VIOLATION || errorCode == ERROR_LOCK_VIOLATION)
{
Console.WriteLine("There was another process using the file, so couldn't pick the settings up.");
}
Thread.Sleep(50);
}
}
return null;
}
private static void ResetNormalPowerState() private static void ResetNormalPowerState()
{ {
bool success = APIHelper.SetNormalKeepAwake(); bool success = APIHelper.SetNormalKeepAwake();