Skip to content

Commit

Permalink
Making sure the app can run well without a console window
Browse files Browse the repository at this point in the history
Only applicable when a PID is specified.
  • Loading branch information
dend committed May 12, 2021
1 parent 95bac54 commit ff486e5
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 18 deletions.
41 changes: 41 additions & 0 deletions src/modules/espresso/Espresso/Core/APIHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,15 @@
// See the LICENSE file in the project root for more information.

using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Win32;
using NLog;

#pragma warning disable SA1116 // Split parameters should start on line after declaration

namespace Espresso.Shell.Core
{
[Flags]
Expand All @@ -27,6 +30,11 @@ public enum EXECUTION_STATE : uint
public class APIHelper
{
private const string BuildRegistryLocation = @"SOFTWARE\Microsoft\Windows NT\CurrentVersion";
public const int StdOutputHandle = -11;
public const int StdInputHandle = -10;
public const int StdErrorHandle = -12;
public const uint GenericWrite = 0x40000000;
public const uint GenericRead = 0x80000000;

private static readonly Logger _log;
private static CancellationTokenSource _tokenSource;
Expand All @@ -36,12 +44,45 @@ public class APIHelper
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern EXECUTION_STATE SetThreadExecutionState(EXECUTION_STATE esFlags);

[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool AllocConsole();

[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr GetStdHandle(int nStdHandle);

[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool SetStdHandle(int nStdHandle, IntPtr hHandle);

[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]

public static extern IntPtr CreateFile([MarshalAs(UnmanagedType.LPTStr)] string filename,
[MarshalAs(UnmanagedType.U4)] uint access,
[MarshalAs(UnmanagedType.U4)] FileShare share,
IntPtr securityAttributes,
[MarshalAs(UnmanagedType.U4)] FileMode creationDisposition,
[MarshalAs(UnmanagedType.U4)] FileAttributes flagsAndAttributes,
IntPtr templateFile);

static APIHelper()
{
_log = LogManager.GetCurrentClassLogger();
_tokenSource = new CancellationTokenSource();
}

public static void AllocateConsole()
{
AllocConsole();

var outputHandle = GetStdHandle(StdOutputHandle);
var outputFilePointer = CreateFile("CONOUT$", GenericRead | GenericWrite, FileShare.Write, IntPtr.Zero, FileMode.OpenOrCreate, 0, IntPtr.Zero);
if (outputFilePointer != outputHandle)
{
SetStdHandle(StdOutputHandle, outputFilePointer);
Console.SetOut(new StreamWriter(Console.OpenStandardOutput(), Console.OutputEncoding) { AutoFlush = true });
}
}

/// <summary>
/// Sets the computer awake state using the native Win32 SetThreadExecutionState API. This
/// function is just a nice-to-have wrapper that helps avoid tracking the success or failure of
Expand Down
20 changes: 10 additions & 10 deletions src/modules/espresso/Espresso/Core/TrayHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,45 +63,45 @@ private static Action ExitCallback()
};
}

private static Action KeepDisplayOnCallback(string text)
private static Action KeepDisplayOnCallback(string moduleName)
{
return () =>
{
// Just changing the display mode.
var currentSettings = ModuleSettings.GetSettings<EspressoSettings>(text);
var currentSettings = ModuleSettings.GetSettings<EspressoSettings>(moduleName);
currentSettings.Properties.KeepDisplayOn.Value = !currentSettings.Properties.KeepDisplayOn.Value;
ModuleSettings.SaveSettings(JsonSerializer.Serialize(currentSettings), text);
ModuleSettings.SaveSettings(JsonSerializer.Serialize(currentSettings), moduleName);
};
}

private static Action<int, int> TimedKeepAwakeCallback(string text)
private static Action<int, int> TimedKeepAwakeCallback(string moduleName)
{
return (hours, minutes) =>
{
// Set timed keep awake.
var currentSettings = ModuleSettings.GetSettings<EspressoSettings>(text);
var currentSettings = ModuleSettings.GetSettings<EspressoSettings>(moduleName);
currentSettings.Properties.Mode = EspressoMode.TIMED;
currentSettings.Properties.Hours.Value = hours;
currentSettings.Properties.Minutes.Value = minutes;
ModuleSettings.SaveSettings(JsonSerializer.Serialize(currentSettings), text);
ModuleSettings.SaveSettings(JsonSerializer.Serialize(currentSettings), moduleName);
};
}

private static Action IndefiniteKeepAwakeCallback(string text)
private static Action IndefiniteKeepAwakeCallback(string moduleName)
{
return () =>
{
// Set indefinite keep awake.
var currentSettings = ModuleSettings.GetSettings<EspressoSettings>(text);
var currentSettings = ModuleSettings.GetSettings<EspressoSettings>(moduleName);
currentSettings.Properties.Mode = EspressoMode.INDEFINITE;
ModuleSettings.SaveSettings(JsonSerializer.Serialize(currentSettings), text);
ModuleSettings.SaveSettings(JsonSerializer.Serialize(currentSettings), moduleName);
};
}

internal static void SetTray(string text, bool keepDisplayOn, EspressoMode mode, Action indefiniteKeepAwakeCallback, Action<int, int> timedKeepAwakeCallback, Action keepDisplayOnCallback, Action exitCallback)
public static void SetTray(string text, bool keepDisplayOn, EspressoMode mode, Action indefiniteKeepAwakeCallback, Action<int, int> timedKeepAwakeCallback, Action keepDisplayOnCallback, Action exitCallback)
{
var contextMenuStrip = new ContextMenuStrip();

Expand Down
2 changes: 1 addition & 1 deletion src/modules/espresso/Espresso/Espresso.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\..\Version.props" />
<PropertyGroup>
<OutputType>Exe</OutputType>
<OutputType>WinExe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
<OutputPath>$(SolutionDir)$(Platform)\$(Configuration)\modules\Espresso</OutputPath>
<Nullable>enable</Nullable>
Expand Down
20 changes: 13 additions & 7 deletions src/modules/espresso/Espresso/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,10 @@ private static int Main(string[] args)

var configOption = new Option<bool>(
aliases: new[] { "--use-pt-config", "-c" },
getDefaultValue: () => true,
getDefaultValue: () => false,
description: "Specifies whether Espresso will be using the PowerToys configuration file for managing the state.")
{
Argument = new Argument<bool>(() => true)
Argument = new Argument<bool>(() => false)
{
Arity = ArgumentArity.ZeroOrOne,
},
Expand Down Expand Up @@ -130,17 +130,22 @@ private static void ForceExit(string message, int exitCode)

private static void HandleCommandLineArguments(bool usePtConfig, bool displayOn, long timeLimit, int pid)
{
if (pid == 0)
{
APIHelper.AllocateConsole();
}

_log.Info($"The value for --use-pt-config is: {usePtConfig}");
_log.Info($"The value for --display-on is: {displayOn}");
_log.Info($"The value for --time-limit is: {timeLimit}");
_log.Info($"The value for --pid is: {pid}");

if (usePtConfig)
{
#pragma warning disable CS8604 // Possible null reference argument.
TrayHelper.InitializeTray(AppName, new Icon(Application.GetResourceStream(new Uri("/Images/Espresso.ico", UriKind.Relative)).Stream));
TrayHelper.InitializeTray(AppName, new Icon(Application.GetResourceStream(new Uri("/Images/Espresso.ico", UriKind.Relative)).Stream));
#pragma warning restore CS8604 // Possible null reference argument.

if (usePtConfig)
{
// Configuration file is used, therefore we disregard any other command-line parameter
// and instead watch for changes in the file.
try
Expand Down Expand Up @@ -177,13 +182,14 @@ private static void HandleCommandLineArguments(bool usePtConfig, bool displayOn,
}
else
{
if (timeLimit <= 0)
var mode = timeLimit <= 0 ? EspressoMode.INDEFINITE : EspressoMode.TIMED;

if (mode == EspressoMode.INDEFINITE)
{
SetupIndefiniteKeepAwake(displayOn);
}
else
{
// Timed keep-awake.
SetupTimedKeepAwake(timeLimit, displayOn);
}
}
Expand Down

0 comments on commit ff486e5

Please sign in to comment.