@ -0,0 +1,559 @@ | |||
!*.gitkeep | |||
# User-specific files | |||
*.rsuser | |||
*.suo | |||
*.user | |||
*.userosscache | |||
*.sln.docstates | |||
# User-specific files (MonoDevelop/Xamarin Studio) | |||
*.userprefs | |||
# Mono auto generated files | |||
mono_crash.* | |||
# Build results | |||
[Dd]ebug/ | |||
[Dd]ebugPublic/ | |||
[Rr]elease/ | |||
[Rr]eleases/ | |||
x64/ | |||
x86/ | |||
[Ww][Ii][Nn]32/ | |||
[Aa][Rr][Mm]/ | |||
[Aa][Rr][Mm]64/ | |||
bld/ | |||
[Bb]in/ | |||
[Oo]bj/ | |||
[Ll]og/ | |||
[Ll]ogs/ | |||
# Visual Studio 2015/2017 cache/options directory | |||
.vs/ | |||
# Uncomment if you have tasks that create the project's static files in wwwroot | |||
#wwwroot/ | |||
# Visual Studio 2017 auto generated files | |||
Generated\ Files/ | |||
# MSTest test Results | |||
[Tt]est[Rr]esult*/ | |||
[Bb]uild[Ll]og.* | |||
# NUnit | |||
*.VisualState.xml | |||
TestResult.xml | |||
nunit-*.xml | |||
# Build Results of an ATL Project | |||
[Dd]ebugPS/ | |||
[Rr]eleasePS/ | |||
dlldata.c | |||
# Benchmark Results | |||
BenchmarkDotNet.Artifacts/ | |||
# .NET Core | |||
project.lock.json | |||
project.fragment.lock.json | |||
artifacts/ | |||
# ASP.NET Scaffolding | |||
ScaffoldingReadMe.txt | |||
# StyleCop | |||
StyleCopReport.xml | |||
# Files built by Visual Studio | |||
*_i.c | |||
*_p.c | |||
*_h.h | |||
*.ilk | |||
*.meta | |||
*.obj | |||
*.iobj | |||
*.pch | |||
*.pdb | |||
*.ipdb | |||
*.pgc | |||
*.pgd | |||
*.rsp | |||
*.sbr | |||
*.tlb | |||
*.tli | |||
*.tlh | |||
*.tmp | |||
*.tmp_proj | |||
*_wpftmp.csproj | |||
*.log | |||
*.tlog | |||
*.vspscc | |||
*.vssscc | |||
.builds | |||
*.pidb | |||
*.svclog | |||
*.scc | |||
# Chutzpah Test files | |||
_Chutzpah* | |||
# Visual C++ cache files | |||
ipch/ | |||
*.aps | |||
*.ncb | |||
*.opendb | |||
*.opensdf | |||
*.sdf | |||
*.cachefile | |||
*.VC.db | |||
*.VC.VC.opendb | |||
# Visual Studio profiler | |||
*.psess | |||
*.vsp | |||
*.vspx | |||
*.sap | |||
# Visual Studio Trace Files | |||
*.e2e | |||
# TFS 2012 Local Workspace | |||
$tf/ | |||
# Guidance Automation Toolkit | |||
*.gpState | |||
# ReSharper is a .NET coding add-in | |||
_ReSharper*/ | |||
*.[Rr]e[Ss]harper | |||
*.DotSettings.user | |||
# TeamCity is a build add-in | |||
_TeamCity* | |||
# DotCover is a Code Coverage Tool | |||
*.dotCover | |||
# AxoCover is a Code Coverage Tool | |||
.axoCover/* | |||
!.axoCover/settings.json | |||
# Coverlet is a free, cross platform Code Coverage Tool | |||
coverage*.json | |||
coverage*.xml | |||
coverage*.info | |||
# Visual Studio code coverage results | |||
*.coverage | |||
*.coveragexml | |||
# NCrunch | |||
_NCrunch_* | |||
.*crunch*.local.xml | |||
nCrunchTemp_* | |||
# MightyMoose | |||
*.mm.* | |||
AutoTest.Net/ | |||
# Web workbench (sass) | |||
.sass-cache/ | |||
# Installshield output folder | |||
[Ee]xpress/ | |||
# DocProject is a documentation generator add-in | |||
DocProject/buildhelp/ | |||
DocProject/Help/*.HxT | |||
DocProject/Help/*.HxC | |||
DocProject/Help/*.hhc | |||
DocProject/Help/*.hhk | |||
DocProject/Help/*.hhp | |||
DocProject/Help/Html2 | |||
DocProject/Help/html | |||
# Click-Once directory | |||
publish/ | |||
# Publish Web Output | |||
*.[Pp]ublish.xml | |||
*.azurePubxml | |||
# Note: Comment the next line if you want to checkin your web deploy settings, | |||
# but database connection strings (with potential passwords) will be unencrypted | |||
*.pubxml | |||
*.publishproj | |||
# Microsoft Azure Web App publish settings. Comment the next line if you want to | |||
# checkin your Azure Web App publish settings, but sensitive information contained | |||
# in these scripts will be unencrypted | |||
PublishScripts/ | |||
# NuGet Packages | |||
*.nupkg | |||
# NuGet Symbol Packages | |||
*.snupkg | |||
# The packages folder can be ignored because of Package Restore | |||
**/[Pp]ackages/* | |||
# except build/, which is used as an MSBuild target. | |||
!**/[Pp]ackages/build/ | |||
# Uncomment if necessary however generally it will be regenerated when needed | |||
#!**/[Pp]ackages/repositories.config | |||
# NuGet v3's project.json files produces more ignorable files | |||
*.nuget.props | |||
*.nuget.targets | |||
# Nuget personal access tokens and Credentials | |||
nuget.config | |||
# Microsoft Azure Build Output | |||
csx/ | |||
*.build.csdef | |||
# Microsoft Azure Emulator | |||
ecf/ | |||
rcf/ | |||
# Windows Store app package directories and files | |||
AppPackages/ | |||
BundleArtifacts/ | |||
Package.StoreAssociation.xml | |||
_pkginfo.txt | |||
*.appx | |||
*.appxbundle | |||
*.appxupload | |||
# Visual Studio cache files | |||
# files ending in .cache can be ignored | |||
*.[Cc]ache | |||
# but keep track of directories ending in .cache | |||
!?*.[Cc]ache/ | |||
# Others | |||
ClientBin/ | |||
~$* | |||
*~ | |||
*.dbmdl | |||
*.dbproj.schemaview | |||
*.jfm | |||
*.pfx | |||
*.publishsettings | |||
orleans.codegen.cs | |||
# Including strong name files can present a security risk | |||
# (https://github.com/github/gitignore/pull/2483#issue-259490424) | |||
#*.snk | |||
# Since there are multiple workflows, uncomment next line to ignore bower_components | |||
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) | |||
#bower_components/ | |||
# RIA/Silverlight projects | |||
Generated_Code/ | |||
# Backup & report files from converting an old project file | |||
# to a newer Visual Studio version. Backup files are not needed, | |||
# because we have git ;-) | |||
_UpgradeReport_Files/ | |||
Backup*/ | |||
UpgradeLog*.XML | |||
UpgradeLog*.htm | |||
ServiceFabricBackup/ | |||
*.rptproj.bak | |||
# SQL Server files | |||
*.mdf | |||
*.ldf | |||
*.ndf | |||
# Business Intelligence projects | |||
*.rdl.data | |||
*.bim.layout | |||
*.bim_*.settings | |||
*.rptproj.rsuser | |||
*- [Bb]ackup.rdl | |||
*- [Bb]ackup ([0-9]).rdl | |||
*- [Bb]ackup ([0-9][0-9]).rdl | |||
# Microsoft Fakes | |||
FakesAssemblies/ | |||
# GhostDoc plugin setting file | |||
*.GhostDoc.xml | |||
# Node.js Tools for Visual Studio | |||
.ntvs_analysis.dat | |||
node_modules/ | |||
# Visual Studio 6 build log | |||
*.plg | |||
# Visual Studio 6 workspace options file | |||
*.opt | |||
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) | |||
*.vbw | |||
# Visual Studio LightSwitch build output | |||
**/*.HTMLClient/GeneratedArtifacts | |||
**/*.DesktopClient/GeneratedArtifacts | |||
**/*.DesktopClient/ModelManifest.xml | |||
**/*.Server/GeneratedArtifacts | |||
**/*.Server/ModelManifest.xml | |||
_Pvt_Extensions | |||
# Paket dependency manager | |||
.paket/paket.exe | |||
paket-files/ | |||
# FAKE - F# Make | |||
.fake/ | |||
# CodeRush personal settings | |||
.cr/personal | |||
# Python Tools for Visual Studio (PTVS) | |||
__pycache__/ | |||
*.pyc | |||
# Cake - Uncomment if you are using it | |||
# tools/** | |||
# !tools/packages.config | |||
# Tabs Studio | |||
*.tss | |||
# Telerik's JustMock configuration file | |||
*.jmconfig | |||
# BizTalk build output | |||
*.btp.cs | |||
*.btm.cs | |||
*.odx.cs | |||
*.xsd.cs | |||
# OpenCover UI analysis results | |||
OpenCover/ | |||
# Azure Stream Analytics local run output | |||
ASALocalRun/ | |||
# MSBuild Binary and Structured Log | |||
*.binlog | |||
# NVidia Nsight GPU debugger configuration file | |||
*.nvuser | |||
# MFractors (Xamarin productivity tool) working folder | |||
.mfractor/ | |||
# Local History for Visual Studio | |||
.localhistory/ | |||
# BeatPulse healthcheck temp database | |||
healthchecksdb | |||
# Backup folder for Package Reference Convert tool in Visual Studio 2017 | |||
MigrationBackup/ | |||
# Ionide (cross platform F# VS Code tools) working folder | |||
.ionide/ | |||
# Fody - auto-generated XML schema | |||
FodyWeavers.xsd | |||
# VS Code files for those working on multiple tools | |||
.vscode/* | |||
!.vscode/settings.json | |||
!.vscode/tasks.json | |||
!.vscode/launch.json | |||
!.vscode/extensions.json | |||
*.code-workspace | |||
# Local History for Visual Studio Code | |||
.history/ | |||
# Windows Installer files from build outputs | |||
*.cab | |||
*.msi | |||
*.msix | |||
*.msm | |||
*.msp | |||
# JetBrains Rider | |||
.idea/ | |||
*.sln.iml | |||
### Git ### | |||
# Created by git for backups. To disable backups in Git: | |||
# $ git config --global mergetool.keepBackup false | |||
*.orig | |||
# Created by git when using merge tools for conflicts | |||
*.BACKUP.* | |||
*.BASE.* | |||
*.LOCAL.* | |||
*.REMOTE.* | |||
*_BACKUP_*.txt | |||
*_BASE_*.txt | |||
*_LOCAL_*.txt | |||
*_REMOTE_*.txt | |||
### vs ### | |||
# User-specific files | |||
# User-specific files (MonoDevelop/Xamarin Studio) | |||
# Mono auto generated files | |||
# Build results | |||
# Visual Studio 2015/2017 cache/options directory | |||
# Uncomment if you have tasks that create the project's static files in wwwroot | |||
# Visual Studio 2017 auto generated files | |||
# MSTest test Results | |||
# NUnit | |||
# Build Results of an ATL Project | |||
# Benchmark Results | |||
# .NET Core | |||
# StyleCop | |||
# Files built by Visual Studio | |||
# Chutzpah Test files | |||
# Visual C++ cache files | |||
# Visual Studio profiler | |||
# Visual Studio Trace Files | |||
# TFS 2012 Local Workspace | |||
# Guidance Automation Toolkit | |||
# ReSharper is a .NET coding add-in | |||
# TeamCity is a build add-in | |||
# DotCover is a Code Coverage Tool | |||
# AxoCover is a Code Coverage Tool | |||
# Coverlet is a free, cross platform Code Coverage Tool | |||
coverage*[.json, .xml, .info] | |||
# Visual Studio code coverage results | |||
# NCrunch | |||
# MightyMoose | |||
# Web workbench (sass) | |||
# Installshield output folder | |||
# DocProject is a documentation generator add-in | |||
# Click-Once directory | |||
# Publish Web Output | |||
# Note: Comment the next line if you want to checkin your web deploy settings, | |||
# but database connection strings (with potential passwords) will be unencrypted | |||
# Microsoft Azure Web App publish settings. Comment the next line if you want to | |||
# checkin your Azure Web App publish settings, but sensitive information contained | |||
# in these scripts will be unencrypted | |||
# NuGet Packages | |||
# NuGet Symbol Packages | |||
# The packages folder can be ignored because of Package Restore | |||
# except build/, which is used as an MSBuild target. | |||
# Uncomment if necessary however generally it will be regenerated when needed | |||
# NuGet v3's project.json files produces more ignorable files | |||
# Microsoft Azure Build Output | |||
# Microsoft Azure Emulator | |||
# Windows Store app package directories and files | |||
# Visual Studio cache files | |||
# files ending in .cache can be ignored | |||
# but keep track of directories ending in .cache | |||
# Others | |||
# Including strong name files can present a security risk | |||
# (https://github.com/github/gitignore/pull/2483#issue-259490424) | |||
# Since there are multiple workflows, uncomment next line to ignore bower_components | |||
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) | |||
# RIA/Silverlight projects | |||
# Backup & report files from converting an old project file | |||
# to a newer Visual Studio version. Backup files are not needed, | |||
# because we have git ;-) | |||
# SQL Server files | |||
# Business Intelligence projects | |||
# Microsoft Fakes | |||
# GhostDoc plugin setting file | |||
# Node.js Tools for Visual Studio | |||
# Visual Studio 6 build log | |||
# Visual Studio 6 workspace options file | |||
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) | |||
# Visual Studio LightSwitch build output | |||
# Paket dependency manager | |||
# FAKE - F# Make | |||
# CodeRush personal settings | |||
# Python Tools for Visual Studio (PTVS) | |||
# Cake - Uncomment if you are using it | |||
# tools/** | |||
# !tools/packages.config | |||
# Tabs Studio | |||
# Telerik's JustMock configuration file | |||
# BizTalk build output | |||
# OpenCover UI analysis results | |||
# Azure Stream Analytics local run output | |||
# MSBuild Binary and Structured Log | |||
# NVidia Nsight GPU debugger configuration file | |||
# MFractors (Xamarin productivity tool) working folder | |||
# Local History for Visual Studio | |||
# BeatPulse healthcheck temp database | |||
# Backup folder for Package Reference Convert tool in Visual Studio 2017 | |||
# Ionide (cross platform F# VS Code tools) working folder |
@ -0,0 +1,132 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Diagnostics; | |||
using System.IO; | |||
using System.Linq; | |||
using System.Runtime.InteropServices; | |||
using System.Security; | |||
using System.Text; | |||
using System.Threading; | |||
using amecs.Misc; | |||
using Ameliorated.ConsoleUtils; | |||
using Microsoft.Dism; | |||
namespace amecs.Actions | |||
{ | |||
public class _NET | |||
{ | |||
private static string _mountedPath; | |||
private static string _isoPath; | |||
private static void Unmount() | |||
{ | |||
if (_isoPath == "none") | |||
return; | |||
SelectWindowsImage.DismountIso(_isoPath); | |||
} | |||
public static bool Install() | |||
{ | |||
(_mountedPath, _isoPath, _, _, _) = SelectWindowsImage.GetMediaPath(true); | |||
if (_mountedPath == null) return false; | |||
if (!Directory.Exists(_mountedPath + @"\sources\sxs") || !Directory.GetFiles(_mountedPath + @"\sources\sxs", "*netfx3*").Any()) | |||
{ | |||
Unmount(); | |||
Console.WriteLine(); | |||
ConsoleTUI.OpenFrame.Close("ISO/USB/folder does not contain the required files.", | |||
ConsoleColor.Red, Console.BackgroundColor, new ChoicePrompt() { AnyKey = true, Text = "Press any key to return to the Menu: " }); | |||
return false; | |||
} | |||
ConsoleTUI.OpenFrame.WriteCentered("\r\nInstalling .NET 3.5"); | |||
var topCache = Console.CursorTop; | |||
var leftCache = Console.CursorLeft; | |||
Console.WriteLine(); | |||
var inProgress = false; | |||
try | |||
{ | |||
using var indicator = new ConsoleUtils.LoadingIndicator(); | |||
DismApi.Initialize(DismLogLevel.LogErrors); | |||
using (var session = DismApi.OpenOnlineSession()) | |||
{ | |||
var stdout = GetStdHandle(-11); | |||
var indicatorStopped = false; | |||
var maxHashTags = (ConsoleTUI.OpenFrame.DisplayWidth - 5); | |||
DismApi.EnableFeatureByPackagePath(session, "NetFX3", null, true, true, new List<string>() { _mountedPath + @"\sources\sxs" }, delegate(DismProgress progress) | |||
{ | |||
inProgress = true; | |||
if (!indicatorStopped) | |||
{ | |||
indicator.Stop(); | |||
Console.SetCursorPosition(leftCache, topCache); | |||
Console.WriteLine(" "); | |||
} | |||
indicatorStopped = true; | |||
var progressPercentage = progress.Current / 10; | |||
var currentHashTags = (int)Math.Ceiling(Math.Min(((double)progressPercentage / 100) * maxHashTags, maxHashTags)); | |||
var spaces = maxHashTags - currentHashTags + (4 - progressPercentage.ToString().Length); | |||
var sb = new StringBuilder(new string('#', currentHashTags) + new string(' ', spaces) + progressPercentage + "%"); | |||
WriteConsoleOutputCharacter(stdout, sb, (uint)sb.Length, new Languages.COORD((short)ConsoleTUI.OpenFrame.DisplayOffset, (short)Console.CursorTop), out _); | |||
inProgress = false; | |||
}); | |||
session.Close(); | |||
Thread.Sleep(100); | |||
var sb = new StringBuilder(new string('#', maxHashTags) + " 100%"); | |||
uint throwaway; | |||
WriteConsoleOutputCharacter(stdout, sb, (uint)sb.Length, new Languages.COORD((short)ConsoleTUI.OpenFrame.DisplayOffset, (short)Console.CursorTop), out throwaway); | |||
} | |||
DismApi.Shutdown(); | |||
Unmount(); | |||
} catch (Exception e) | |||
{ | |||
while (inProgress) | |||
{ | |||
Thread.Sleep(50); | |||
} | |||
Unmount(); | |||
Console.WriteLine(); | |||
Console.WriteLine(); | |||
ConsoleTUI.OpenFrame.Close("DISM error: " + e.Message, ConsoleColor.Red, Console.BackgroundColor, new ChoicePrompt() | |||
{ | |||
AnyKey = true, | |||
Text = "Press any key to return to the Menu: " | |||
}); | |||
return false; | |||
} | |||
Console.WriteLine(); | |||
Console.WriteLine(); | |||
ConsoleTUI.OpenFrame.Close(".NET 3.5 installed successfully", ConsoleColor.Green, Console.BackgroundColor, new ChoicePrompt() | |||
{ | |||
AnyKey = true, | |||
Text = "Press any key to return to the Menu: " | |||
}); | |||
return true; | |||
} | |||
[StructLayout(LayoutKind.Sequential)] | |||
public struct COORD | |||
{ | |||
public short X; | |||
public short Y; | |||
public COORD(short X, short Y) | |||
{ | |||
this.X = X; | |||
this.Y = Y; | |||
} | |||
}; | |||
[DllImport("kernel32.dll", SetLastError = true)] | |||
internal static extern bool WriteConsoleOutputCharacter(IntPtr hConsoleOutput, StringBuilder lpCharacter, uint nLength, Languages.COORD dwWriteCoord, out uint lpNumberOfCharsWritten); | |||
[DllImport("kernel32.dll", SetLastError = true)] | |||
static extern IntPtr GetStdHandle(int nStdHandle); | |||
} | |||
} |
@ -0,0 +1,313 @@ | |||
using System; | |||
using System.DirectoryServices.AccountManagement; | |||
using System.Runtime.InteropServices; | |||
using System.Text; | |||
using System.Threading; | |||
using Ameliorated.ConsoleUtils; | |||
namespace amecs.Actions | |||
{ | |||
public class AutoLogon | |||
{ | |||
internal static class SafeNativeMethods | |||
{ | |||
#region Structures | |||
[StructLayout(LayoutKind.Sequential)] | |||
public struct LSA_UNICODE_STRING : IDisposable | |||
{ | |||
public UInt16 Length; | |||
public UInt16 MaximumLength; | |||
public IntPtr Buffer; | |||
public void Dispose() | |||
{ | |||
this = new LSA_UNICODE_STRING(); | |||
} | |||
} | |||
public struct LSA_OBJECT_ATTRIBUTES | |||
{ | |||
public int Length; | |||
public IntPtr RootDirectory; | |||
public LSA_UNICODE_STRING ObjectName; | |||
public UInt32 Attributes; | |||
public IntPtr SecurityDescriptor; | |||
public IntPtr SecurityQualityOfService; | |||
} | |||
public enum LSA_AccessPolicy : long | |||
{ | |||
POLICY_VIEW_LOCAL_INFORMATION = 0x00000001L, | |||
POLICY_VIEW_AUDIT_INFORMATION = 0x00000002L, | |||
POLICY_GET_PRIVATE_INFORMATION = 0x00000004L, | |||
POLICY_TRUST_ADMIN = 0x00000008L, | |||
POLICY_CREATE_ACCOUNT = 0x00000010L, | |||
POLICY_CREATE_SECRET = 0x00000020L, | |||
POLICY_CREATE_PRIVILEGE = 0x00000040L, | |||
POLICY_SET_DEFAULT_QUOTA_LIMITS = 0x00000080L, | |||
POLICY_SET_AUDIT_REQUIREMENTS = 0x00000100L, | |||
POLICY_AUDIT_LOG_ADMIN = 0x00000200L, | |||
POLICY_SERVER_ADMIN = 0x00000400L, | |||
POLICY_LOOKUP_NAMES = 0x00000800L, | |||
POLICY_NOTIFICATION = 0x00001000L | |||
} | |||
#endregion | |||
#region DLL Imports | |||
[DllImport("advapi32")] | |||
public static extern IntPtr FreeSid(IntPtr pSid); | |||
[DllImport("advapi32.dll", PreserveSig = true)] | |||
public static extern UInt32 LsaOpenPolicy( | |||
ref LSA_UNICODE_STRING SystemName, | |||
ref LSA_OBJECT_ATTRIBUTES ObjectAttributes, | |||
Int32 DesiredAccess, | |||
out IntPtr PolicyHandle); | |||
[DllImport("advapi32.dll", SetLastError = true, PreserveSig = true)] | |||
public static extern uint LsaStorePrivateData( | |||
IntPtr PolicyHandle, | |||
LSA_UNICODE_STRING[] KeyName, | |||
LSA_UNICODE_STRING[] PrivateData); | |||
[DllImport("advapi32.dll", PreserveSig = true)] | |||
public static extern uint LsaRetrievePrivateData( | |||
IntPtr PolicyHandle, | |||
LSA_UNICODE_STRING[] KeyName, | |||
out IntPtr PrivateData); | |||
[DllImport("advapi32.dll", PreserveSig = true)] | |||
public static extern uint LsaNtStatusToWinError(uint status); | |||
[DllImport("advapi32.dll")] | |||
public static extern uint LsaClose(IntPtr ObjectHandle); | |||
#endregion | |||
} | |||
#region Functions | |||
/// <summary> | |||
/// Store Encrypted Data | |||
/// </summary> | |||
/// <param name="keyName"></param> | |||
/// <param name="Data"></param> | |||
/// <returns></returns> | |||
public static long StoreData(String keyName, String Data) | |||
{ | |||
long winErrorCode = 0; | |||
IntPtr sid = IntPtr.Zero; | |||
int sidSize = 0; | |||
//allocate buffers | |||
sid = Marshal.AllocHGlobal(sidSize); | |||
//initialize an empty unicode-string | |||
SafeNativeMethods.LSA_UNICODE_STRING systemName = new SafeNativeMethods.LSA_UNICODE_STRING(); | |||
//Set desired access rights (requested rights) | |||
int access = (int)(SafeNativeMethods.LSA_AccessPolicy.POLICY_CREATE_SECRET); | |||
//initialize a pointer for the policy handle | |||
IntPtr policyHandle = IntPtr.Zero; | |||
//these attributes are not used, but LsaOpenPolicy wants them to exists | |||
SafeNativeMethods.LSA_OBJECT_ATTRIBUTES ObjectAttributes = new SafeNativeMethods.LSA_OBJECT_ATTRIBUTES(); | |||
ObjectAttributes.Length = 0; | |||
ObjectAttributes.RootDirectory = IntPtr.Zero; | |||
ObjectAttributes.Attributes = 0; | |||
ObjectAttributes.SecurityDescriptor = IntPtr.Zero; | |||
ObjectAttributes.SecurityQualityOfService = IntPtr.Zero; | |||
//get a policy handle | |||
uint resultPolicy = SafeNativeMethods.LsaOpenPolicy(ref systemName, ref ObjectAttributes, access, out policyHandle); | |||
winErrorCode = SafeNativeMethods.LsaNtStatusToWinError(resultPolicy); | |||
if (winErrorCode != 0) | |||
{ | |||
ConsoleTUI.OpenFrame.WriteCenteredLine("OpenPolicy failed: " + winErrorCode); | |||
} | |||
else | |||
{ | |||
//initialize an unicode-string for the keyName | |||
SafeNativeMethods.LSA_UNICODE_STRING[] uKeyName = new SafeNativeMethods.LSA_UNICODE_STRING[1]; | |||
uKeyName[0] = new SafeNativeMethods.LSA_UNICODE_STRING(); | |||
uKeyName[0].Buffer = Marshal.StringToHGlobalUni(keyName); | |||
uKeyName[0].Length = (UInt16)(keyName.Length * UnicodeEncoding.CharSize); | |||
uKeyName[0].MaximumLength = (UInt16)((keyName.Length + 1) * UnicodeEncoding.CharSize); | |||
//initialize an unicode-string for the Data to encrypt | |||
SafeNativeMethods.LSA_UNICODE_STRING[] uData = new SafeNativeMethods.LSA_UNICODE_STRING[1]; | |||
uData[0] = new SafeNativeMethods.LSA_UNICODE_STRING(); | |||
uData[0].Buffer = Marshal.StringToHGlobalUni(Data); | |||
uData[0].Length = (UInt16)(Data.Length * UnicodeEncoding.CharSize); | |||
uData[0].MaximumLength = (UInt16)((Data.Length + 1) * UnicodeEncoding.CharSize); | |||
//Store Encrypted Data: | |||
SafeNativeMethods.LsaStorePrivateData(policyHandle, uKeyName, uData); | |||
//winErrorCode = LsaNtStatusToWinError(res); | |||
if (winErrorCode != 0) | |||
{ | |||
ConsoleTUI.OpenFrame.WriteCenteredLine("LsaStorePrivateData failed: " + winErrorCode); | |||
} | |||
SafeNativeMethods.LsaClose(policyHandle); | |||
} | |||
SafeNativeMethods.FreeSid(sid); | |||
return winErrorCode; | |||
} | |||
/// <summary> | |||
/// Retrieve Encrypted Data | |||
/// </summary> | |||
/// <param name="keyName"></param> | |||
/// <returns></returns> | |||
public static string RetrieveData(String keyName) | |||
{ | |||
string sout = ""; | |||
long winErrorCode = 0; | |||
IntPtr sid = IntPtr.Zero; | |||
int sidSize = 0; | |||
//allocate buffers | |||
sid = Marshal.AllocHGlobal(sidSize); | |||
//initialize an empty unicode-string | |||
SafeNativeMethods.LSA_UNICODE_STRING systemName = new SafeNativeMethods.LSA_UNICODE_STRING(); | |||
//Set desired access rights (requested rights) | |||
int access = (int)(SafeNativeMethods.LSA_AccessPolicy.POLICY_CREATE_SECRET); | |||
//initialize a pointer for the policy handle | |||
IntPtr policyHandle = IntPtr.Zero; | |||
//these attributes are not used, but LsaOpenPolicy wants them to exists | |||
SafeNativeMethods.LSA_OBJECT_ATTRIBUTES ObjectAttributes = new SafeNativeMethods.LSA_OBJECT_ATTRIBUTES(); | |||
ObjectAttributes.Length = 0; | |||
ObjectAttributes.RootDirectory = IntPtr.Zero; | |||
ObjectAttributes.Attributes = 0; | |||
ObjectAttributes.SecurityDescriptor = IntPtr.Zero; | |||
ObjectAttributes.SecurityQualityOfService = IntPtr.Zero; | |||
//get a policy handle | |||
uint resultPolicy = SafeNativeMethods.LsaOpenPolicy(ref systemName, ref ObjectAttributes, access, out policyHandle); | |||
winErrorCode = SafeNativeMethods.LsaNtStatusToWinError(resultPolicy); | |||
if (winErrorCode != 0) | |||
{ | |||
ConsoleTUI.OpenFrame.WriteCenteredLine("OpenPolicy failed: " + winErrorCode); | |||
} | |||
else | |||
{ | |||
//initialize an unicode-string for the keyName | |||
SafeNativeMethods.LSA_UNICODE_STRING[] uKeyName = new SafeNativeMethods.LSA_UNICODE_STRING[1]; | |||
uKeyName[0] = new SafeNativeMethods.LSA_UNICODE_STRING(); | |||
uKeyName[0].Buffer = Marshal.StringToHGlobalUni(keyName); | |||
uKeyName[0].Length = (UInt16)(keyName.Length * UnicodeEncoding.CharSize); | |||
uKeyName[0].MaximumLength = (UInt16)((keyName.Length + 1) * UnicodeEncoding.CharSize); | |||
//Store Encrypted Data: | |||
IntPtr pData; | |||
long result = SafeNativeMethods.LsaRetrievePrivateData(policyHandle, uKeyName, out pData); | |||
//winErrorCode = LsaNtStatusToWinError(res); | |||
if (winErrorCode != 0) | |||
{ | |||
ConsoleTUI.OpenFrame.WriteCenteredLine("LsaStorePrivateData failed: " + winErrorCode); | |||
} | |||
SafeNativeMethods.LSA_UNICODE_STRING ss = (SafeNativeMethods.LSA_UNICODE_STRING)Marshal.PtrToStructure(pData, typeof(SafeNativeMethods.LSA_UNICODE_STRING)); | |||
sout = Marshal.PtrToStringAuto(ss.Buffer); | |||
SafeNativeMethods.LsaClose(policyHandle); | |||
} | |||
SafeNativeMethods.FreeSid(sid); | |||
return sout; | |||
} | |||
#endregion | |||
private const string LogonKey = @"HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon"; | |||
public static bool Disable() => amecs.RunBasicAction("Disabling AutoLogon", "AutoLogon disabled successfully", new Action(() => | |||
{ | |||
new Reg.Value() { KeyName = LogonKey, ValueName = "DefaultUserName", Data = "", Type = Reg.RegistryValueType.REG_SZ}.Apply(); | |||
new Reg.Value() { KeyName = LogonKey, ValueName = "AutoAdminLogon", Operation = Reg.RegistryValueOperation.Delete}.Apply(); | |||
new Reg.Value() { KeyName = LogonKey, ValueName = "AutoLogonCount", Operation = Reg.RegistryValueOperation.Delete}.Apply(); | |||
new Reg.Value() { KeyName = LogonKey, ValueName = "ForceAutoLogon", Operation = Reg.RegistryValueOperation.Delete}.Apply(); | |||
new Reg.Value() { KeyName = LogonKey, ValueName = "DisableCAD", Operation = Reg.RegistryValueOperation.Delete}.Apply(); | |||
new Reg.Value() { KeyName = LogonKey, ValueName = "DefaultPassword", Operation = Reg.RegistryValueOperation.Delete}.Apply(); | |||
StoreData("DefaultPassword", ""); | |||
Thread.Sleep(1700); | |||
})); | |||
public static bool Enable() | |||
{ | |||
PrincipalContext context = new PrincipalContext(ContextType.Machine); | |||
string password = ""; | |||
while (true) | |||
{ | |||
password = new InputPrompt() { MaskInput = true, Text = "Enter your password, or press escape to quit: " }.Start(); | |||
if (password == null) | |||
return true; | |||
if (String.IsNullOrEmpty(password)) | |||
{ | |||
try | |||
{ | |||
Globals.User.ChangePassword("", ""); | |||
break; | |||
} catch {} | |||
} | |||
else if (context.ValidateCredentials(Globals.Username, password)) | |||
break; | |||
ConsoleTUI.OpenFrame.WriteLine("Incorrect password."); | |||
Console.WriteLine(); | |||
} | |||
try | |||
{ | |||
ConsoleTUI.OpenFrame.WriteCentered("\r\nEnabling AutoLogon"); | |||
using (new ConsoleUtils.LoadingIndicator(true)) | |||
{ | |||
new Reg.Value() { KeyName = LogonKey, ValueName = "DefaultUserName", Data = Globals.Username, Type = Reg.RegistryValueType.REG_SZ}.Apply(); | |||
new Reg.Value() { KeyName = LogonKey, ValueName = "DefaultDomainName", Data = Environment.MachineName, Type = Reg.RegistryValueType.REG_SZ}.Apply(); | |||
new Reg.Value() { KeyName = LogonKey, ValueName = "AutoAdminLogon", Data = 1, Type = Reg.RegistryValueType.REG_DWORD}.Apply(); | |||
new Reg.Value() { KeyName = LogonKey, ValueName = "AutoLogonCount", Operation = Reg.RegistryValueOperation.Delete}.Apply(); | |||
new Reg.Value() { KeyName = LogonKey, ValueName = "DisableCAD", Data = 1, Type = Reg.RegistryValueType.REG_DWORD}.Apply(); | |||
new Reg.Value() { KeyName = LogonKey, ValueName = "DefaultPassword", Operation = Reg.RegistryValueOperation.Delete}.Apply(); | |||
StoreData("DefaultPassword", password); | |||
Thread.Sleep(1700); | |||
} | |||
} catch (Exception e) | |||
{ | |||
Console.WriteLine(); | |||
ConsoleTUI.OpenFrame.Close("Error: " + e.Message.TrimEnd('\n').TrimEnd('\r'), ConsoleColor.Red, Console.BackgroundColor, new ChoicePrompt() | |||
{ | |||
AnyKey = true, | |||
Text = "Press any key to return to the Menu: " | |||
}); | |||
return false; | |||
} | |||
Console.WriteLine(); | |||
ConsoleTUI.OpenFrame.Close($"AutoLogon enabled successfully", ConsoleColor.Green, Console.BackgroundColor, new ChoicePrompt() | |||
{ | |||
AnyKey = true, | |||
Text = "Press any key to return to the Menu: " | |||
}); | |||
return true; | |||
} | |||
} | |||
} |
@ -0,0 +1,239 @@ | |||
using System; | |||
using System.Diagnostics; | |||
using System.IO; | |||
using System.Security.Principal; | |||
using System.Threading; | |||
using amecs.Misc; | |||
using Ameliorated.ConsoleUtils; | |||
using Microsoft.Win32; | |||
namespace amecs.Actions | |||
{ | |||
public class Deameliorate | |||
{ | |||
private static string _mountedPath; | |||
private static string _winVer; | |||
private static string _win11Setup = ""; | |||
private static bool _win11 = Environment.OSVersion.Version.Build >= 22000; | |||
private const string ExplorerPatcherId = "D17F1E1A-5919-4427-8F89-A1A8503CA3EB"; | |||
public static bool DeAme() | |||
{ | |||
if (new ChoicePrompt() | |||
{ | |||
Text = @" | |||
This will de-ameliorate by reinstalling Windows. | |||
Although user data should be kept, we strongly recommend | |||
making backups of any important user data. | |||
Continue? (Y/N): " | |||
}.Start().Value == 1) return true; | |||
Program.Frame.Clear(); | |||
(_mountedPath, _, _winVer, _, _) = SelectWindowsImage.GetMediaPath(); | |||
if (_mountedPath == null) return false; | |||
if (new ChoicePrompt {Text = $"\r\nYour Windows image is {_winVer}. Continue? (Y/N): "}.Start().Value == 1) | |||
return true; | |||
var fc = Console.ForegroundColor; | |||
Console.ForegroundColor = ConsoleColor.Yellow; | |||
string userSid = null; | |||
try | |||
{ | |||
NSudo.GetSystemPrivilege(); | |||
NSudo.RunAsUser(() => | |||
{ | |||
userSid = WindowsIdentity.GetCurrent().User.ToString(); | |||
}); | |||
} | |||
catch | |||
{ | |||
// do nothing | |||
} | |||
try | |||
{ | |||
ConsoleTUI.OpenFrame.WriteCentered("\r\nUninstalling AME-installed UI software..."); | |||
string openShellId = null; | |||
var key = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"); | |||
foreach (var item in key.GetSubKeyNames()) | |||
{ | |||
try | |||
{ | |||
if (((string)key.OpenSubKey(item).GetValue("DisplayName")).Equals("Open-Shell")) | |||
openShellId = item; | |||
} | |||
catch | |||
{ | |||
// do nothing | |||
} | |||
} | |||
if (openShellId != null) | |||
{ | |||
ConsoleTUI.OpenFrame.WriteCentered("\r\nUninstalling Open-Shell..."); | |||
Process.Start("MsiExec.exe", $"/X{openShellId} /quiet")?.WaitForExit(); | |||
if (userSid != null) | |||
{ | |||
var appData = (string)Registry.Users.OpenSubKey(userSid + @"\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders").GetValue("AppData"); | |||
if (Directory.Exists(Path.Combine(appData, "OpenShell"))) | |||
Directory.Delete(Path.Combine(appData, "OpenShell"), true); | |||
} | |||
} | |||
var epSetupPath = $@"{Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles)}\ExplorerPatcher\ep_setup.exe"; | |||
if (File.Exists(epSetupPath)) | |||
{ | |||
ConsoleTUI.OpenFrame.WriteCentered("\r\nUninstalling ExplorerPatcher..."); | |||
var winlogon = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon", true); | |||
winlogon?.SetValue("AutoRestartShell", 0); | |||
// kill processes that the files use | |||
foreach (var processName in new[] {"explorer.exe", "rundll32.exe", "dllhost.exe", "ShellExperienceHost.exe", "StartMenuExperienceHost.exe"}) | |||
{ | |||
foreach (var process in Process.GetProcessesByName(Path.GetFileNameWithoutExtension(processName))) | |||
{ | |||
process.Kill(); | |||
process.WaitForExit(); | |||
} | |||
} | |||
// delete DWM service that removes rounded corners | |||
Process.Start("sc", $"stop \"ep_dwm_{ExplorerPatcherId}\"")?.WaitForExit(); | |||
Process.Start("sc", $"delete \"ep_dwm_{ExplorerPatcherId}\"")?.WaitForExit(); | |||
// remove registered DLL | |||
var explorerPatcherDllPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), "ExplorerPatcher", "ExplorerPatcher.amd64.dll"); | |||
Process.Start("regsvr32.exe", $"/s /u \"{explorerPatcherDllPath}\"")?.WaitForExit(); | |||
// delete files | |||
foreach (var file in new[] | |||
{ | |||
Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Windows), | |||
@"SystemApps\ShellExperienceHost_cw5n1h2txyewy\dxgi.dll"), | |||
Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Windows), | |||
@"SystemApps\ShellExperienceHost_cw5n1h2txyewy\wincorlib.dll"), | |||
Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Windows), | |||
@"SystemApps\ShellExperienceHost_cw5n1h2txyewy\wincorlib_orig.dll"), | |||
Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Windows), | |||
@"SystemApps\Microsoft.Windows.StartMenuExperienceHost_cw5n1h2txyewy\dxgi.dll"), | |||
Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Windows), | |||
@"SystemApps\Microsoft.Windows.StartMenuExperienceHost_cw5n1h2txyewy\wincorlib.dll"), | |||
Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Windows), | |||
@"SystemApps\Microsoft.Windows.StartMenuExperienceHost_cw5n1h2txyewy\wincorlib_orig.dll"), | |||
Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Windows), | |||
"dxgi.dll") | |||
}) | |||
{ | |||
if (File.Exists(file)) File.Delete(file); | |||
} | |||
foreach (var folder in new[] | |||
{ | |||
Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), | |||
"ExplorerPatcher"), | |||
Path.Combine( | |||
Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), | |||
@"Microsoft\Windows\Start Menu\Programs\ExplorerPatcher") | |||
}) | |||
{ | |||
if (Directory.Exists(folder)) Directory.Delete(folder, true); | |||
} | |||
winlogon?.SetValue("AutoRestartShell", 1); | |||
} | |||
Program.Frame.Clear(); | |||
} catch (Exception e) | |||
{ | |||
ConsoleTUI.OpenFrame.Close( | |||
"Error when uninstalling software: " + e.Message, | |||
ConsoleColor.Red, Console.BackgroundColor, | |||
new ChoicePrompt { AnyKey = true, Text = "Press any key to continue anyways: " }); | |||
Program.Frame.Clear(); | |||
ConsoleTUI.OpenFrame.WriteCentered("\r\nContinuing without uninstalling software...\r\n"); | |||
} | |||
// restart Explorer | |||
if (Process.GetProcessesByName("explorer").Length == 0) | |||
NSudo.RunProcessAsUser(NSudo.GetUserToken(), "explorer.exe", "", 0); | |||
// all policies are cleared as a user that's de-ameliorating is unlikely to have their own policies in the first place | |||
// also clear ExplorerPatcher Registry entries | |||
ConsoleTUI.OpenFrame.WriteCentered("\r\nClearing policies..."); | |||
foreach (var keyPath in new[] { | |||
$@"HKU\{userSid}\Software\Microsoft\Windows\CurrentVersion\Policies", | |||
$@"HKU\{userSid}\Software\Policies", | |||
$@"HKU\{userSid}\Software\ExplorerPatcher", | |||
$@"HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{{{ExplorerPatcherId}}}_ExplorerPatcher", | |||
@"HKLM\Software\Microsoft\Windows\CurrentVersion\Policies", | |||
@"HKLM\Software\Policies", | |||
@"HKLM\Software\WOW6432Node\Microsoft\Windows\CurrentVersion\Policies" | |||
}) | |||
{ | |||
var hive = RegistryHive.LocalMachine; | |||
if (keyPath.StartsWith("HKU")) | |||
hive = RegistryHive.Users; | |||
var baseKey = RegistryKey.OpenBaseKey(hive, RegistryView.Default); | |||
var subKeyPath = keyPath.Substring(keyPath.IndexOf('\\') + 1); | |||
var key = baseKey.OpenSubKey(subKeyPath, true); | |||
if (key == null) continue; | |||
try | |||
{ | |||
baseKey.DeleteSubKeyTree(subKeyPath); | |||
} | |||
catch | |||
{ | |||
// do nothing - some values might fail, but almost all are deleted | |||
} | |||
key.Close(); | |||
} | |||
Thread.Sleep(3000); | |||
Program.Frame.Clear(); | |||
ConsoleTUI.OpenFrame.WriteCentered("\r\nCompleted initial setup!", ConsoleColor.Green); | |||
if (_win11) | |||
{ | |||
ConsoleTUI.OpenFrame.WriteCentered("\r\nWindows Setup will display as 'Windows Server,' but it's not actually installing Windows Server and is only set as such to bypass hardware requirements."); | |||
Console.WriteLine(); | |||
} | |||
ConsoleTUI.OpenFrame.WriteCentered("\r\nWaiting 10 seconds and starting Windows Setup..."); | |||
Console.ForegroundColor = fc; | |||
Thread.Sleep(10000); | |||
Console.WriteLine(); | |||
try | |||
{ | |||
if (_win11) _win11Setup = "/Product Server"; | |||
Process.Start(Path.Combine(_mountedPath, "setup.exe"), $"/Auto Upgrade /DynamicUpdate Disable {_win11Setup}"); | |||
} catch (Exception e) | |||
{ | |||
ConsoleTUI.OpenFrame.Close( | |||
$"There was an error when trying to run the Windows Setup: {e}\r\nTry running the Windows Setup manually from File Explorer.", | |||
ConsoleColor.Red, Console.BackgroundColor, | |||
new ChoicePrompt { AnyKey = true, Text = $"Press any key to exit: " }); | |||
return false; | |||
} | |||
ConsoleTUI.OpenFrame.Close( | |||
"Completed, Windows Setup should have started.", | |||
ConsoleColor.Cyan, Console.BackgroundColor, | |||
new ChoicePrompt { AnyKey = true, Text = $"Press any key to go back: " }); | |||
return true; | |||
} | |||
} | |||
} |
@ -0,0 +1,21 @@ | |||
using System; | |||
using System.Threading; | |||
namespace amecs.Actions | |||
{ | |||
public class Elevation | |||
{ | |||
public static bool Elevate() => amecs.RunBasicAction("Elevating user to Administrator", "The current user is now an Administrator", new Action(() => | |||
{ | |||
Globals.Administrators.Members.Add(Globals.User); | |||
Globals.Administrators.Save(); | |||
Thread.Sleep(1000); | |||
}), true); | |||
public static bool DeElevate() => amecs.RunBasicAction("Revoking Admin rights from the current user", "Admin rights have been revoked for the current user", new Action(() => | |||
{ | |||
Globals.Administrators.Members.Remove(Globals.User); | |||
Globals.Administrators.Save(); | |||
Thread.Sleep(1000); | |||
}), true); | |||
} | |||
} |
@ -0,0 +1,113 @@ | |||
using System; | |||
using System.Diagnostics; | |||
using System.IO; | |||
using System.Linq; | |||
using System.Security; | |||
using System.Threading; | |||
using Ameliorated.ConsoleUtils; | |||
using Microsoft.Win32; | |||
using System.Windows.Forms; | |||
namespace amecs.Actions | |||
{ | |||
public class Lockscreen | |||
{ | |||
public static bool ChangeImage() | |||
{ | |||
ConsoleTUI.OpenFrame.WriteCenteredLine("Select an image"); | |||
Thread.Sleep(1000); | |||
var dialog = new System.Windows.Forms.OpenFileDialog(); | |||
dialog.Filter = "Image Files (*.jpg; *.jpeg; *.png; *.bmp; *.jfif)| *.jpg; *.jpeg; *.png; *.bmp; *.jfif"; // Filter files by extension | |||
dialog.Multiselect = false; | |||
dialog.InitialDirectory = Globals.UserFolder; | |||
NativeWindow window = new NativeWindow(); | |||
window.AssignHandle(Process.GetCurrentProcess().MainWindowHandle); | |||
if (dialog.ShowDialog(window) == DialogResult.OK) | |||
{ | |||
string file; | |||
try | |||
{ | |||
file = dialog.FileName; | |||
} | |||
catch (SecurityException e) | |||
{ | |||
Console.WriteLine(); | |||
ConsoleTUI.OpenFrame.Close("Security error: " + e.Message, ConsoleColor.Red, Console.BackgroundColor, new ChoicePrompt() {AnyKey = true, Text = "Press any key to return to the Menu: "}); | |||
return false; | |||
} | |||
Console.WriteLine(); | |||
var choice = new ChoicePrompt() { Text = "Remove lockscreen blur? (Y/N): " }.Start(); | |||
if (!choice.HasValue) return true; | |||
bool blur = choice == 0; | |||
ConsoleTUI.OpenFrame.WriteCentered("\r\nSetting lockscreen image"); | |||
using (new ConsoleUtils.LoadingIndicator(true)) | |||
{ | |||
Thread.Sleep(500); | |||
try | |||
{ | |||
if (blur) | |||
new Reg.Value() | |||
{ | |||
KeyName = @"HKLM\SOFTWARE\Policies\Microsoft\Windows\System", | |||
ValueName = "DisableAcrylicBackgroundOnLogon", | |||
Type = Reg.RegistryValueType.REG_DWORD, | |||
Data = 1, | |||
}.Apply(); | |||
else | |||
new Reg.Value() | |||
{ | |||
KeyName = @"HKLM\SOFTWARE\Policies\Microsoft\Windows\System", | |||
ValueName = "DisableAcrylicBackgroundOnLogon", | |||
Type = Reg.RegistryValueType.REG_DWORD, | |||
Data = 0, | |||
}.Apply(); | |||
} catch { } | |||
new Reg.Value() | |||
{ | |||
KeyName = @"HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\LogonUI\Creative\" + Globals.UserSID, | |||
ValueName = "RotatingLockScreenEnabled", | |||
Type = Reg.RegistryValueType.REG_DWORD, | |||
Data = 0, | |||
}.Apply(); | |||
new Reg.Value() | |||
{ | |||
KeyName = @$"HKU\{Globals.UserSID}\SOFTWARE\Microsoft\Windows\CurrentVersion\ContentDeliveryManager", | |||
ValueName = "RotatingLockScreenEnabled", | |||
Type = Reg.RegistryValueType.REG_DWORD, | |||
Data = 0, | |||
}.Apply(); | |||
File.Delete(Environment.ExpandEnvironmentVariables(@"%WINDIR%\Web\Screen\img100.jpg")); | |||
File.Copy(file, Environment.ExpandEnvironmentVariables(@"%WINDIR%\Web\Screen\img100.jpg")); | |||
foreach (var dataDir in Directory.EnumerateDirectories(Environment.ExpandEnvironmentVariables(@"%PROGRAMDATA%\Microsoft\Windows\SystemData"))) | |||
{ | |||
var subDir = Path.Combine(dataDir, "ReadOnly"); | |||
if (!Directory.Exists(subDir)) | |||
continue; | |||
Directory.GetDirectories(subDir, "Lockscreen_*").ToList().ForEach(x => Directory.Delete(x, true)); | |||
} | |||
} | |||
Console.WriteLine(); | |||
ConsoleTUI.OpenFrame.Close("Lockscreen image changed successfully", ConsoleColor.Green, Console.BackgroundColor, new ChoicePrompt() {AnyKey = true, Text = "Press any key to return to the Menu: "}); | |||
return true; | |||
} | |||
else | |||
{ | |||
Console.WriteLine(); | |||
ConsoleTUI.OpenFrame.Close("You must select an image.", new ChoicePrompt() {AnyKey = true, Text = "Press any key to return to the Menu: "}); | |||
return true; | |||
} | |||
} | |||
} | |||
} |
@ -0,0 +1,124 @@ | |||
using System; | |||
using System.Diagnostics; | |||
using System.IO; | |||
using System.Linq; | |||
using System.Security; | |||
using System.Threading; | |||
using System.Windows.Forms; | |||
using Ameliorated.ConsoleUtils; | |||
using System.Drawing; | |||
using System.Security.AccessControl; | |||
using System.Security.Principal; | |||
namespace amecs.Actions | |||
{ | |||
public class Profile | |||
{ | |||
public static bool ChangeImage() | |||
{ | |||
ConsoleTUI.OpenFrame.WriteCenteredLine("Select an image"); | |||
Thread.Sleep(1000); | |||
var dialog = new System.Windows.Forms.OpenFileDialog(); | |||
dialog.Filter = "Image Files (*.jpg; *.jpeg; *.png; *.bmp; *.jfif)| *.jpg; *.jpeg; *.png; *.bmp; *.jfif"; // Filter files by extension | |||
dialog.Multiselect = false; | |||
dialog.InitialDirectory = Globals.UserFolder; | |||
NativeWindow window = new NativeWindow(); | |||
window.AssignHandle(Process.GetCurrentProcess().MainWindowHandle); | |||
if (dialog.ShowDialog(window) == DialogResult.OK) | |||
{ | |||
string file; | |||
try | |||
{ | |||
file = dialog.FileName; | |||
} | |||
catch (SecurityException e) | |||
{ | |||
Console.WriteLine(); | |||
ConsoleTUI.OpenFrame.Close("Security error: " + e.Message, ConsoleColor.Red, Console.BackgroundColor, new ChoicePrompt() {AnyKey = true, Text = "Press any key to return to the Menu: "}); | |||
return false; | |||
} | |||
ConsoleTUI.OpenFrame.WriteCentered("\r\nSetting profile image"); | |||
using (new ConsoleUtils.LoadingIndicator(true)) | |||
{ | |||
var pfpDir = Path.Combine(Environment.ExpandEnvironmentVariables("%PUBLIC%\\AccountPictures"), Globals.UserSID); | |||
if (Directory.Exists(pfpDir)) | |||
{ | |||
try | |||
{ | |||
Directory.Delete(pfpDir, true); | |||
} catch (Exception e) | |||
{ | |||
var logdi = new DirectoryInfo(pfpDir) { Attributes = FileAttributes.Normal }; | |||
try | |||
{ | |||
NSudo.GetOwnershipPrivilege(); | |||
var logdirsec = logdi.GetAccessControl(); | |||
logdirsec.SetOwner(WindowsIdentity.GetCurrent().User); | |||
logdi.SetAccessControl(logdirsec); | |||
logdirsec = new DirectorySecurity(); | |||
logdirsec.AddAccessRule(new FileSystemAccessRule(WindowsIdentity.GetCurrent().User, FileSystemRights.FullControl, InheritanceFlags.ObjectInherit | InheritanceFlags.ContainerInherit, PropagationFlags.NoPropagateInherit, AccessControlType.Allow)); | |||
logdi.SetAccessControl(logdirsec); | |||
} catch (Exception exception) | |||
{ | |||
} | |||
foreach (var info in logdi.GetFileSystemInfos("*", SearchOption.AllDirectories)) | |||
{ | |||
info.Attributes = FileAttributes.Normal; | |||
} | |||
Directory.Delete(pfpDir, true); | |||
} | |||
} | |||
Directory.CreateDirectory(pfpDir); | |||
var image = Image.FromFile(file); | |||
var pfpKey = @"HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\AccountPicture\Users\" + Globals.UserSID; | |||
new Reg.Key() { KeyName = pfpKey, Operation = RegistryOperation.Delete }.Apply(); | |||
foreach (var res in new [] { 32, 40, 48, 64, 96, 192, 208, 240, 424, 448, 1080 }) | |||
{ | |||
var bitmap = new Bitmap(res, res); | |||
var graph = Graphics.FromImage(bitmap); | |||
graph.DrawImage(image, 0, 0, res, res); | |||
var saveLoc = Path.Combine(pfpDir, $"{res}x{res}.png"); | |||
bitmap.Save(saveLoc); | |||
new Reg.Value() { KeyName = pfpKey, ValueName = "Image" + res, Type = Reg.RegistryValueType.REG_SZ, Data = saveLoc }.Apply(); | |||
} | |||
new Reg.Value() { KeyName = pfpKey, ValueName = "UserPicturePath", Type = Reg.RegistryValueType.REG_SZ, Data = Path.Combine(pfpDir, $"448x448.png") }.Apply(); | |||
try | |||
{ | |||
Process proc = new Process(); | |||
proc.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; | |||
proc.StartInfo.FileName = "gpupdate.exe"; | |||
proc.StartInfo.Arguments = "/force"; | |||
proc.Start(); | |||
proc.WaitForExit(20000); | |||
} catch { } | |||
} | |||
Console.WriteLine(); | |||
ConsoleTUI.OpenFrame.Close("Profile image changed successfully", ConsoleColor.Green, Console.BackgroundColor, new ChoicePrompt() {AnyKey = true, Text = "Press any key to return to the Menu: "}); | |||
return true; | |||
} | |||
else | |||
{ | |||
Console.WriteLine(); | |||
ConsoleTUI.OpenFrame.Close("You must select an image.", new ChoicePrompt() {AnyKey = true, Text = "Press any key to return to the Menu: "}); | |||
return true; | |||
} | |||
} | |||
} | |||
} |
@ -0,0 +1,220 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.DirectoryServices; | |||
using System.DirectoryServices.AccountManagement; | |||
using Ameliorated.ConsoleUtils; | |||
using System.Linq; | |||
using System.Security; | |||
using System.Text.RegularExpressions; | |||
using System.Threading; | |||
using System.Threading.Tasks; | |||
namespace amecs.Actions | |||
{ | |||
public static class UserPass | |||
{ | |||
public static bool ShowMenu() | |||
{ | |||
var mainMenu = new Ameliorated.ConsoleUtils.Menu() | |||
{ | |||
Choices = | |||
{ | |||
new Menu.MenuItem("Change Username", new Func<bool>(ChangeUsername)), | |||
new Menu.MenuItem("Change Password", new Func<bool>(ChangePassword)), | |||
new Menu.MenuItem("Change Display Name", new Func<bool>(ChangeDisplayName)), | |||
new Menu.MenuItem("Change Administrator Password", new Func<bool>(ChangeAdminPassword)), | |||
Menu.MenuItem.Blank, | |||
new Menu.MenuItem("Return to Menu", new Func<bool>(() => true)), | |||
new Menu.MenuItem("Exit", new Func<bool>(Globals.Exit)), | |||
}, | |||
SelectionForeground = ConsoleColor.Green | |||
}; | |||
mainMenu.Write(); | |||
var result = (Func<bool>)mainMenu.Load(); | |||
return result.Invoke(); | |||
} | |||
public static bool ChangeUsername() | |||
{ | |||
try | |||
{ | |||
while (true) | |||
{ | |||
var username = new InputPrompt() { Text = "Enter new username, or press escape to quit: " }.Start(); | |||
if (username == null) | |||
return true; | |||
if (String.IsNullOrEmpty(username) || !Regex.Match(username, @"^\w[\w\.\- ]{0,19}$").Success) | |||
{ | |||
ConsoleTUI.OpenFrame.WriteLine("Username is invalid."); | |||
Console.WriteLine(); | |||
continue; | |||
} | |||
if (Globals.Username.Equals(username)) | |||
{ | |||
ConsoleTUI.OpenFrame.WriteLine("Username matches the current username."); | |||
Console.WriteLine(); | |||
continue; | |||
} | |||
try | |||
{ | |||
ConsoleTUI.OpenFrame.WriteCentered("\r\nSetting new username"); | |||
using (new ConsoleUtils.LoadingIndicator(true)) | |||
{ | |||
DirectoryEntry entry = (DirectoryEntry)Globals.User.GetUnderlyingObject(); | |||
entry.Rename(username); | |||
entry.CommitChanges(); | |||
PrincipalContext context = new PrincipalContext(ContextType.Machine); | |||
PrincipalSearcher userPrincipalSearcher = new PrincipalSearcher(new UserPrincipal(context)); | |||
Globals.User = userPrincipalSearcher.FindAll().FirstOrDefault(x => (x is UserPrincipal) && x.Sid.Value == Globals.UserSID) as UserPrincipal; | |||
break; | |||
} | |||
} catch (System.Runtime.InteropServices.COMException e) | |||
{ | |||
if (e.ErrorCode != -2147022694) | |||
throw e; | |||
ConsoleTUI.OpenFrame.WriteLine("Username is invalid."); | |||
Console.WriteLine(); | |||
} | |||
} | |||
} catch (Exception e) | |||
{ | |||
Console.WriteLine(); | |||
ConsoleTUI.OpenFrame.Close("Error: " + e.Message.TrimEnd('\n').TrimEnd('\r'), ConsoleColor.Red, Console.BackgroundColor, new ChoicePrompt() {AnyKey = true, Text = "Press any key to return to the Menu: "}); | |||
return false; | |||
} | |||
Console.WriteLine(); | |||
if ((int?)ConsoleTUI.OpenFrame.Close("Username changed successfully", ConsoleColor.Green, Console.BackgroundColor, new ChoicePrompt() | |||
{ | |||
TextForeground = ConsoleColor.Yellow, | |||
Text = "Logoff to apply changes? (Y/N): " | |||
}) == 0) amecs.RestartWindows(true); | |||
return true; | |||
} | |||
public static bool ChangePassword() | |||
{ | |||
try | |||
{ | |||
while (true) | |||
{ | |||
var password = new InputPrompt() { MaskInput = true, Text = "Enter new password, or press escape to quit: " }.Start(); | |||
if (password == null) | |||
return true; | |||
ConsoleTUI.OpenFrame.WriteCentered("\r\nSetting new password"); | |||
try | |||
{ | |||
using (new ConsoleUtils.LoadingIndicator(true)) | |||
{ | |||
if (String.IsNullOrEmpty(password)) | |||
{ | |||
Globals.User.SetPassword(""); | |||
} | |||
else | |||
{ | |||
Globals.User.SetPassword(password); | |||
} | |||
Thread.Sleep(800); | |||
break; | |||
} | |||
} catch (PasswordException e) | |||
{ | |||
ConsoleTUI.OpenFrame.WriteLine("Could not set password: " + e.Message); | |||
Console.WriteLine(); | |||
} | |||
} | |||
} catch (Exception e) | |||
{ | |||
Console.WriteLine(); | |||
ConsoleTUI.OpenFrame.Close("Error: " + e.Message.TrimEnd('\n').TrimEnd('\r'), ConsoleColor.Red, Console.BackgroundColor, new ChoicePrompt() {AnyKey = true, Text = "Press any key to return to the Menu: "}); | |||
return false; | |||
} | |||
Console.WriteLine(); | |||
ConsoleTUI.OpenFrame.Close("Password changed successfully", ConsoleColor.Green, Console.BackgroundColor, new ChoicePrompt() {AnyKey = true, Text = "Press any key to return to the Menu: "}); | |||
return true; | |||
} | |||
public static bool ChangeAdminPassword() | |||
{ | |||
try | |||
{ | |||
PrincipalContext context = new PrincipalContext(ContextType.Machine); | |||
PrincipalSearcher userPrincipalSearcher = new PrincipalSearcher(new UserPrincipal(context)); | |||
var administrator = userPrincipalSearcher.FindAll().FirstOrDefault(x => (x is UserPrincipal) && x.Name == "Administrator") as UserPrincipal; | |||
while (true) | |||
{ | |||
var password = new InputPrompt() { MaskInput = true, Text = "Enter new Administrator password,\r\nor press escape to quit: " }.Start(); | |||
if (password == null) | |||
return true; | |||
ConsoleTUI.OpenFrame.WriteCentered("\r\nSetting new password"); | |||
try | |||
{ | |||
using (new ConsoleUtils.LoadingIndicator(true)) | |||
{ | |||
if (String.IsNullOrEmpty(password)) | |||
{ | |||
administrator.SetPassword(""); | |||
} | |||
else | |||
{ | |||
administrator.SetPassword(password); | |||
} | |||
Thread.Sleep(1000); | |||
break; | |||
} | |||
} catch (PasswordException e) | |||
{ | |||
ConsoleTUI.OpenFrame.WriteLine("Could not set password: " + e.Message); | |||
Console.WriteLine(); | |||
} | |||
} | |||
} catch (Exception e) | |||
{ | |||
Console.WriteLine(); | |||
ConsoleTUI.OpenFrame.Close("Error: " + e.Message.TrimEnd('\n').TrimEnd('\r'), ConsoleColor.Red, Console.BackgroundColor, new ChoicePrompt() {AnyKey = true, Text = "Press any key to return to the Menu: "}); | |||
return false; | |||
} | |||
Console.WriteLine(); | |||
ConsoleTUI.OpenFrame.Close("Administrator password changed successfully", ConsoleColor.Green, Console.BackgroundColor, new ChoicePrompt() {AnyKey = true, Text = "Press any key to return to the Menu: "}); | |||
return true; | |||
} | |||
public static bool ChangeDisplayName() | |||
{ | |||
try | |||
{ | |||
var name = new InputPrompt() { Text = "Enter new display name, or press escape to quit: " }.Start(); | |||
if (name == null) | |||
return true; | |||
ConsoleTUI.OpenFrame.WriteCentered("\r\nSetting new display name"); | |||
using (new ConsoleUtils.LoadingIndicator(true)) | |||
{ | |||
Globals.User.DisplayName = name; | |||
Globals.User.Save(); | |||
Thread.Sleep(800); | |||
} | |||
} catch (Exception e) | |||
{ | |||
Console.WriteLine(); | |||
ConsoleTUI.OpenFrame.Close("Error: " + e.Message.TrimEnd('\n').TrimEnd('\r'), ConsoleColor.Red, Console.BackgroundColor, new ChoicePrompt() {AnyKey = true, Text = "Press any key to return to the Menu: "}); | |||
return false; | |||
} | |||
Console.WriteLine(); | |||
ConsoleTUI.OpenFrame.Close("Display name changed successfully", ConsoleColor.Green, Console.BackgroundColor, new ChoicePrompt() {AnyKey = true, Text = "Press any key to return to the Menu: "}); | |||
return true; | |||
} | |||
} | |||
} |
@ -0,0 +1,19 @@ | |||
using System; | |||
using System.Threading; | |||
namespace amecs.Actions | |||
{ | |||
public class UsernameRequirement | |||
{ | |||
public static bool Enable() => amecs.RunBasicAction("Enabling username login requirement", "The username login requirement is now enabled", new Action(() => | |||
{ | |||
new Reg.Value() { KeyName = @"HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System", ValueName = "dontdisplaylastusername", Data = 1, Type = Reg.RegistryValueType.REG_DWORD }.Apply(); | |||
Thread.Sleep(1700); | |||
})); | |||
public static bool Disable() => amecs.RunBasicAction("Disabling username login requirement", "The username login requirement is now disabled", new Action(() => | |||
{ | |||
new Reg.Value() { KeyName = @"HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System", ValueName = "dontdisplaylastusername", Operation = Reg.RegistryValueOperation.Delete }.Apply(); | |||
Thread.Sleep(1700); | |||
})); | |||
} | |||
} |
@ -0,0 +1,299 @@ | |||
using System; | |||
using System.DirectoryServices; | |||
using System.DirectoryServices.AccountManagement; | |||
using System.Linq; | |||
using System.Security.AccessControl; | |||
using System.Security.Principal; | |||
using System.ServiceProcess; | |||
using System.Text.RegularExpressions; | |||
using System.Threading; | |||
using Ameliorated.ConsoleUtils; | |||
using Microsoft.Win32; | |||
namespace amecs.Actions | |||
{ | |||
public class Users | |||
{ | |||
public static bool ShowMenu() | |||
{ | |||
while (true) | |||
{ | |||
Program.Frame.Clear(); | |||
var mainMenu = new Ameliorated.ConsoleUtils.Menu() | |||
{ | |||
Choices = | |||
{ | |||
Globals.WinVer <= 19043 ? | |||
new Menu.MenuItem("Create New User (Legacy)", new Func<bool>(CreateNewUserLegacy)) : | |||
new Menu.MenuItem("Create New User", new Func<bool>(CreateNewUser)), | |||
Menu.MenuItem.Blank, | |||
new Menu.MenuItem("Return to Menu", null), | |||
new Menu.MenuItem("Exit", new Func<bool>(Globals.Exit)) | |||
}, | |||
SelectionForeground = ConsoleColor.Green | |||
}; | |||
Func<bool> result; | |||
try | |||
{ | |||
mainMenu.Write(); | |||
var res = mainMenu.Load(); | |||
if (res == null) | |||
return true; | |||
result = (Func<bool>)res; | |||
} catch (Exception e) | |||
{ | |||
Console.WriteLine(e); | |||
Console.ReadLine(); | |||
return false; | |||
} | |||
try | |||
{ | |||
result.Invoke(); | |||
} catch (Exception e) | |||
{ | |||
ConsoleTUI.ShowErrorBox("Error while running an action: " + e.ToString(), null); | |||
} | |||
} | |||
} | |||
private static bool CreateNewUserLegacy() | |||
{ | |||
var choice = new ChoicePrompt() { Text = "WARNING: This is a deprecated action, and the new user\r\nwill not be fully functional. Continue? (Y/N): ", TextForeground = ConsoleColor.Yellow}.Start(); | |||
if (choice == null || choice == 1) | |||
return false; | |||
ConsoleTUI.OpenFrame.WriteLine(); | |||
try | |||
{ | |||
if (CreateUser() == false) | |||
return true; | |||
} catch (Exception e) | |||
{ | |||
Console.WriteLine(); | |||
ConsoleTUI.OpenFrame.Close("Error: " + e.Message.TrimEnd('\n').TrimEnd('\r'), ConsoleColor.Red, Console.BackgroundColor, new ChoicePrompt() {AnyKey = true, Text = "Press any key to return to the Menu: "}); | |||
return false; | |||
} | |||
ConsoleTUI.OpenFrame.WriteCentered("\r\nConfiguring user"); | |||
try | |||
{ | |||
using (new ConsoleUtils.LoadingIndicator(true)) | |||
{ | |||
try { ServiceController.GetServices().First(x => x.ServiceName.Equals("AppReadiness")).Stop(); } catch (Exception e) { } | |||
NSudo.GetOwnershipPrivilege(); | |||
Reg.AcquirePrivileges(); | |||
var subKey = Registry.LocalMachine.OpenSubKey(@"SYSTEM\CurrentControlSet\Services\AppReadiness\Parameters", RegistryKeyPermissionCheck.ReadWriteSubTree, RegistryRights.TakeOwnership); | |||
if (subKey != null) | |||
{ | |||
var sec = subKey.GetAccessControl(); | |||
sec.SetOwner(new NTAccount("SYSTEM")); | |||
subKey.SetAccessControl(sec); | |||
subKey.Close(); | |||
subKey = Registry.LocalMachine.OpenSubKey(@"SYSTEM\CurrentControlSet\Services\AppReadiness\Parameters", RegistryKeyPermissionCheck.ReadWriteSubTree, RegistryRights.ChangePermissions); | |||
sec = subKey.GetAccessControl(); | |||
sec.AddAccessRule(new RegistryAccessRule("SYSTEM", RegistryRights.FullControl, InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit, PropagationFlags.None, AccessControlType.Allow)); | |||
subKey.SetAccessControl(sec); | |||
} | |||
new Reg.Key() { KeyName = @"HKLM\SYSTEM\CurrentControlSet\Services\AppReadiness" }.Apply(); | |||
new Reg.Value() { KeyName = @"HKLM\SOFTWARE\Policies\Microsoft\Windows\OOBE", ValueName = "DisablePrivacyExperience", Data = 1, Type = Reg.RegistryValueType.REG_DWORD}.Apply(); | |||
new Reg.Value() { KeyName = @"HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System", ValueName = "EnableFirstLogonAnimation", Data = 0, Type = Reg.RegistryValueType.REG_DWORD}.Apply(); | |||
Reg.LoadDefaultUserHive(); | |||
try | |||
{ | |||
new Reg.Value() { KeyName = @"HKU\DefaultUserHive\SOFTWARE\OpenShell", ValueName = "", Data = "", Type = Reg.RegistryValueType.REG_SZ }.Apply(); | |||
new Reg.Value() { KeyName = @"HKU\DefaultUserHive\SOFTWARE\OpenShell\OpenShell", ValueName = "", Data = "", Type = Reg.RegistryValueType.REG_SZ }.Apply(); | |||
new Reg.Value() { KeyName = @"HKU\DefaultUserHive\SOFTWARE\OpenShell\OpenShell\Settings", ValueName = "", Data = "", Type = Reg.RegistryValueType.REG_SZ }.Apply(); | |||
new Reg.Value() { KeyName = @"HKU\DefaultUserHive\SOFTWARE\OpenShell\StartMenu", ValueName = "", Data = "", Type = Reg.RegistryValueType.REG_SZ }.Apply(); | |||
new Reg.Value() { KeyName = @"HKU\DefaultUserHive\SOFTWARE\OpenShell\StartMenu\Settings", ValueName = "", Data = "", Type = Reg.RegistryValueType.REG_SZ }.Apply(); | |||
new Reg.Value() { KeyName = @"HKU\DefaultUserHive\SOFTWARE\OpenShell\ClassicExplorer", ValueName = "", Data = "", Type = Reg.RegistryValueType.REG_SZ }.Apply(); | |||
new Reg.Value() { KeyName = @"HKU\DefaultUserHive\SOFTWARE\OpenShell\ClassicExplorer\Settings", ValueName = "", Data = "", Type = Reg.RegistryValueType.REG_SZ }.Apply(); | |||
new Reg.Value() { KeyName = @"HKU\DefaultUserHive\SOFTWARE\OpenShell\ClassicExplorer", ValueName = "ShowedToolbar", Data = 1, Type = Reg.RegistryValueType.REG_DWORD }.Apply(); | |||
new Reg.Value() { KeyName = @"HKU\DefaultUserHive\SOFTWARE\OpenShell\ClassicExplorer", ValueName = "NewLine", Data = 0, Type = Reg.RegistryValueType.REG_DWORD }.Apply(); | |||
new Reg.Value() { KeyName = @"HKU\DefaultUserHive\SOFTWARE\OpenShell\ClassicExplorer\Settings", ValueName = "ShowStatusBar", Data = 0, Type = Reg.RegistryValueType.REG_DWORD }.Apply(); | |||
new Reg.Value() { KeyName = @"HKU\DefaultUserHive\SOFTWARE\OpenShell\StartMenu", ValueName = "ShowedStyle2", Data = 1, Type = Reg.RegistryValueType.REG_DWORD }.Apply(); | |||
new Reg.Value() { KeyName = @"HKU\DefaultUserHive\SOFTWARE\OpenShell\StartMenu", ValueName = "CSettingsDlg", Data = "c80100001a0100000000000000000000360d00000100000000000000", Type = Reg.RegistryValueType.REG_BINARY }.Apply(); | |||
new Reg.Value() { KeyName = @"HKU\DefaultUserHive\SOFTWARE\OpenShell\StartMenu", ValueName = "OldItems", Data = "00", Type = Reg.RegistryValueType.REG_BINARY }.Apply(); | |||
new Reg.Value() { KeyName = @"HKU\DefaultUserHive\SOFTWARE\OpenShell\StartMenu", ValueName = "ItemRanks", Data = "00", Type = Reg.RegistryValueType.REG_BINARY }.Apply(); | |||
new Reg.Value() { KeyName = @"HKU\DefaultUserHive\SOFTWARE\OpenShell\StartMenu\MRU", ValueName = "0", Data = @"%SYSTEMDRIVE%\Windows\regedit.exe", Type = Reg.RegistryValueType.REG_SZ }.Apply(); | |||
new Reg.Value() { KeyName = @"HKU\DefaultUserHive\SOFTWARE\OpenShell\StartMenu\Settings", ValueName = "Version", Data = 04040098, Type = Reg.RegistryValueType.REG_DWORD }.Apply(); | |||
new Reg.Value() { KeyName = @"HKU\DefaultUserHive\SOFTWARE\OpenShell\StartMenu\Settings", ValueName = "AllProgramsMetro", Data = 1, Type = Reg.RegistryValueType.REG_DWORD }.Apply(); | |||
new Reg.Value() { KeyName = @"HKU\DefaultUserHive\SOFTWARE\OpenShell\StartMenu\Settings", ValueName = "RecentMetroApps", Data = 1, Type = Reg.RegistryValueType.REG_DWORD }.Apply(); | |||
new Reg.Value() { KeyName = @"HKU\DefaultUserHive\SOFTWARE\OpenShell\StartMenu\Settings", ValueName = "StartScreenShortcut", Data = 0, Type = Reg.RegistryValueType.REG_DWORD }.Apply(); | |||
new Reg.Value() { KeyName = @"HKU\DefaultUserHive\SOFTWARE\OpenShell\StartMenu\Settings", ValueName = "SearchInternet", Data = 0, Type = Reg.RegistryValueType.REG_DWORD }.Apply(); | |||
new Reg.Value() { KeyName = @"HKU\DefaultUserHive\SOFTWARE\OpenShell\StartMenu\Settings", ValueName = "GlassOverride", Data = 1, Type = Reg.RegistryValueType.REG_DWORD }.Apply(); | |||
new Reg.Value() { KeyName = @"HKU\DefaultUserHive\SOFTWARE\OpenShell\StartMenu\Settings", ValueName = "GlassColor", Data = 0, Type = Reg.RegistryValueType.REG_DWORD }.Apply(); | |||
new Reg.Value() { KeyName = @"HKU\DefaultUserHive\SOFTWARE\OpenShell\StartMenu\Settings", ValueName = "SkinW7", Data = "Fluent-Metro", Type = Reg.RegistryValueType.REG_SZ }.Apply(); | |||
new Reg.Value() { KeyName = @"HKU\DefaultUserHive\SOFTWARE\OpenShell\StartMenu\Settings", ValueName = "SkinVariationW7", Data = "", Type = Reg.RegistryValueType.REG_SZ }.Apply(); | |||
new Reg.Value() { KeyName = @"HKU\DefaultUserHive\SOFTWARE\OpenShell\StartMenu\Settings", ValueName = "SkipMetro", Data = 1, Type = Reg.RegistryValueType.REG_DWORD }.Apply(); | |||
new Reg.Value() { KeyName = @"HKU\DefaultUserHive\SOFTWARE\OpenShell\StartMenu\Settings", ValueName = "MenuItems7", Data = @"Item1.Command=user_files\0Item1.Settings=NOEXPAND\0Item2.Command=user_documents\0Item2.Settings=NOEXPAND\0Item3.Command=user_pictures\0Item3.Settings=NOEXPAND\0Item4.Command=user_music\0Item4.Settings=NOEXPAND\0Item5.Command=user_videos\0Item5.Settings=NOEXPAND\0Item6.Command=downloads\0Item6.Settings=NOEXPAND\0Item7.Command=homegroup\0Item7.Settings=ITEM_DISABLED\0Item8.Command=separator\0Item9.Command=games\0Item9.Settings=TRACK_RECENT|NOEXPAND|ITEM_DISABLED\0Item10.Command=favorites\0Item10.Settings=ITEM_DISABLED\0Item11.Command=recent_documents\0Item12.Command=computer\0Item12.Settings=NOEXPAND\0Item13.Command=network\0Item13.Settings=ITEM_DISABLED\0Item14.Command=network_connections\0Item14.Settings=ITEM_DISABLED\0Item15.Command=separator\0Item16.Command=control_panel\0Item16.Settings=TRACK_RECENT\0Item17.Command=pc_settings\0Item17.Settings=TRACK_RECENT\0Item18.Command=admin\0Item18.Settings=TRACK_RECENT|ITEM_DISABLED\0Item19.Command=devices\0Item19.Settings=ITEM_DISABLED\0Item20.Command=defaults\0Item20.Settings=ITEM_DISABLED\0Item21.Command=help\0Item21.Settings=ITEM_DISABLED\0Item22.Command=run\0Item23.Command=apps\0Item23.Settings=ITEM_DISABLED\0Item24.Command=windows_security\0Item24.Settings=ITEM_DISABLED\0", Type = Reg.RegistryValueType.REG_MULTI_SZ }.Apply(); | |||
new Reg.Value() { KeyName = @"HKU\DefaultUserHive\SOFTWARE\OpenShell\StartMenu\Settings", ValueName = "SkinOptionsW7", Data = @"DARK_MAIN=0\0METRO_MAIN=0\0LIGHT_MAIN=0\0AUTOMODE_MAIN=1\0DARK_SUBMENU=0\0METRO_SUBMENU=0\0LIGHT_SUBMENU=0\0AUTOMODE_SUBMENU=1\0SUBMENU_SEPARATORS=1\0DARK_SEARCH=0\0METRO_SEARCH=0\0LIGHT_SEARCH=0\0AUTOMODE_SEARCH=1\0SEARCH_FRAME=1\0SEARCH_COLOR=0\0MODERN_SEARCH=1\0SEARCH_ITALICS=0\0NONE=0\0SEPARATOR=0\0TWO_TONE=1\0CLASSIC_SELECTOR=1\0HALF_SELECTOR=0\0CURVED_MENUSEL=1\0CURVED_SUBMENU=0\0SELECTOR_REVEAL=1\0TRANSPARENT=0\0OPAQUE_SUBMENU=1\0OPAQUE_MENU=0\0OPAQUE=0\0STANDARD=0\0SMALL_MAIN2=1\0SMALL_ICONS=0\0COMPACT_SUBMENU=0\0PRESERVE_MAIN2=0\0LESS_PADDING=0\0EXTRA_PADDING=1\024_PADDING=0\0LARGE_PROGRAMS=0\0TRANSPARENT_SHUTDOWN=0\0OUTLINE_SHUTDOWN=0\0BUTTON_SHUTDOWN=1\0EXPERIMENTAL_SHUTDOWN=0\0LARGE_FONT=0\0CONNECTED_BORDER=1\0FLOATING_BORDER=0\0LARGE_SUBMENU=0\0LARGE_LISTS=0\0THIN_MAIN2=0\0EXPERIMENTAL_MAIN2=1\0USER_IMAGE=1\0USER_OUTSIDE=0\0SCALING_USER=1\056=0\064=0\0TRANSPARENT_USER=0\0UWP_SCROLLBAR=0\0MODERN_SCROLLBAR=1\0SMALL_ARROWS=0\0ARROW_BACKGROUND=1\0ICON_FRAME=0\0SEARCH_SEPARATOR=0\0NO_PROGRAMS_BUTTON=0\0", Type = Reg.RegistryValueType.REG_MULTI_SZ }.Apply(); | |||
new Reg.Value() { KeyName = @"HKU\DefaultUserHive\SOFTWARE\Microsoft\Windows\CurrentVersion\Search", ValueName = "SearchboxTaskbarMode", Data = 0, Type = Reg.RegistryValueType.REG_DWORD }.Apply(); | |||
new Reg.Value() { KeyName = @"HKU\DefaultUserHive\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced", ValueName = "ShowTaskViewButton", Data = 0, Type = Reg.RegistryValueType.REG_DWORD }.Apply(); | |||
new Reg.Value() { KeyName = @"HKU\DefaultUserHive\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer", ValueName = "EnableAutoTray", Data = 0, Type = Reg.RegistryValueType.REG_DWORD }.Apply(); | |||
new Reg.Value() { KeyName = @"HKU\DefaultUserHive\SOFTWARE\Microsoft\Windows\CurrentVersion\AdvertisingInfo", ValueName = "Enabled", Data = 0, Type = Reg.RegistryValueType.REG_DWORD }.Apply(); | |||
new Reg.Value() { KeyName = @"HKU\DefaultUserHive\SOFTWARE\Microsoft\Windows\CurrentVersion\AppHost", ValueName = "EnableWebContentEvaluation", Data = 0, Type = Reg.RegistryValueType.REG_DWORD }.Apply(); | |||
new Reg.Value() { KeyName = @"HKU\DefaultUserHive\Control Panel\International\User Profile", ValueName = "HttpAcceptLanguageOptOut", Data = 1, Type = Reg.RegistryValueType.REG_DWORD }.Apply(); | |||
new Reg.Value() { KeyName = @"HKU\DefaultUserHive\SOFTWARE\Policies\Microsoft\Windows\Explorer", ValueName = "DisableNotificationCenter", Data = 1, Type = Reg.RegistryValueType.REG_DWORD }.Apply(); | |||
new Reg.Value() { KeyName = @"HKU\DefaultUserHive\SOFTWARE\Microsoft\Windows\CurrentVersion\GameDVR", ValueName = "AppCaptureEnabled", Data = 0, Type = Reg.RegistryValueType.REG_DWORD }.Apply(); | |||
new Reg.Value() { KeyName = @"HKU\DefaultUserHive\System\GameConfigStore", ValueName = "GameDVR_Enabled", Data = 0, Type = Reg.RegistryValueType.REG_DWORD }.Apply(); | |||
new Reg.Value() { KeyName = @"HKU\DefaultUserHive\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Attachments", ValueName = "SaveZoneInformation", Data = 1, Type = Reg.RegistryValueType.REG_DWORD }.Apply(); | |||
new Reg.Value() { KeyName = @"HKU\DefaultUserHive\SOFTWARE\Microsoft\Windows\CurrentVersion\AppHost", ValueName = "ContentEvaluation", Data = 0, Type = Reg.RegistryValueType.REG_DWORD }.Apply(); | |||
new Reg.Value() { KeyName = @"HKU\DefaultUserHive\Control Panel\Desktop", ValueName = "WaitToKillAppTimeOut", Data = "2000", Type = Reg.RegistryValueType.REG_SZ }.Apply(); | |||
new Reg.Key() { KeyName = @"HKU\DefaultUserHive\SOFTWARE\Microsoft\Windows\CurrentVersion\StorageSense" }.Apply(); | |||
new Reg.Value() { KeyName = @"HKU\DefaultUserHive\SOFTWARE\Microsoft\Windows\CurrentVersion\Search", ValueName = "BingSearchEnabled", Data = 0, Type = Reg.RegistryValueType.REG_DWORD }.Apply(); | |||
new Reg.Value() { KeyName = @"HKU\DefaultUserHive\SOFTWARE\Microsoft\Windows\CurrentVersion\Search", ValueName = "CortanaConsent", Data = 0, Type = Reg.RegistryValueType.REG_DWORD }.Apply(); | |||
new Reg.Value() { KeyName = @"HKU\DefaultUserHive\SOFTWARE\Microsoft\Windows\CurrentVersion\Search", ValueName = "CortanaInAmbientMode", Data = 0, Type = Reg.RegistryValueType.REG_DWORD }.Apply(); | |||
new Reg.Value() { KeyName = @"HKU\DefaultUserHive\SOFTWARE\Microsoft\Windows\CurrentVersion\Search", ValueName = "HistoryViewEnabled", Data = 0, Type = Reg.RegistryValueType.REG_DWORD }.Apply(); | |||
new Reg.Value() { KeyName = @"HKU\DefaultUserHive\SOFTWARE\Microsoft\Windows\CurrentVersion\Search", ValueName = "HasAboveLockTips", Data = 0, Type = Reg.RegistryValueType.REG_DWORD }.Apply(); | |||
new Reg.Value() { KeyName = @"HKU\DefaultUserHive\SOFTWARE\Microsoft\Windows\CurrentVersion\Search", ValueName = "AllowSearchToUseLocation", Data = 0, Type = Reg.RegistryValueType.REG_DWORD }.Apply(); | |||
new Reg.Value() { KeyName = @"HKU\DefaultUserHive\SOFTWARE\Microsoft\Windows\CurrentVersion\SearchSettings", ValueName = "SafeSearchMode", Data = 0, Type = Reg.RegistryValueType.REG_DWORD }.Apply(); | |||
new Reg.Value() { KeyName = @"HKU\DefaultUserHive\SOFTWARE\Policies\Microsoft\Windows\Explorer", ValueName = "DisableSearchBoxSuggestions", Data = 1, Type = Reg.RegistryValueType.REG_DWORD }.Apply(); | |||
new Reg.Value() { KeyName = @"HKU\DefaultUserHive\SOFTWARE\Microsoft\InputPersonalization", ValueName = "RestrictImplicitTextCollection", Data = 1, Type = Reg.RegistryValueType.REG_DWORD }.Apply(); | |||
new Reg.Value() { KeyName = @"HKU\DefaultUserHive\SOFTWARE\Microsoft\InputPersonalization", ValueName = "RestrictImplicitInkCollection", Data = 1, Type = Reg.RegistryValueType.REG_DWORD }.Apply(); | |||
new Reg.Value() { KeyName = @"HKU\DefaultUserHive\SOFTWARE\Microsoft\InputPersonalization\TrainedDataStore", ValueName = "AcceptedPrivacyPolicy", Data = 0, Type = Reg.RegistryValueType.REG_DWORD }.Apply(); | |||
new Reg.Value() { KeyName = @"HKU\DefaultUserHive\SOFTWARE\Microsoft\InputPersonalization\TrainedDataStore", ValueName = "HarvestContacts", Data = 0, Type = Reg.RegistryValueType.REG_DWORD }.Apply(); | |||
new Reg.Value() { KeyName = @"HKU\DefaultUserHive\SOFTWARE\Microsoft\Personalization\Settings", ValueName = "AcceptedPrivacyPolicy", Data = 0, Type = Reg.RegistryValueType.REG_DWORD }.Apply(); | |||
new Reg.Value() { KeyName = @"HKU\DefaultUserHive\SOFTWARE\Policies\Microsoft\Windows\Explorer", ValueName = "DisableSearchBoxSuggestions", Data = 1, Type = Reg.RegistryValueType.REG_DWORD }.Apply(); | |||
new Reg.Value() { KeyName = @"HKU\DefaultUserHive\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced", ValueName = "NavPaneShowAllFolders", Data = 0, Type = Reg.RegistryValueType.REG_DWORD }.Apply(); | |||
new Reg.Value() { KeyName = @"HKU\DefaultUserHive\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced", ValueName = "LaunchTo", Data = 1, Type = Reg.RegistryValueType.REG_DWORD }.Apply(); | |||
new Reg.Value() { KeyName = @"HKU\DefaultUserHive\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced", ValueName = "HideFileExt", Data = 0, Type = Reg.RegistryValueType.REG_DWORD }.Apply(); | |||
new Reg.Value() { KeyName = @"HKU\DefaultUserHive\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced", ValueName = "Hidden", Data = 1, Type = Reg.RegistryValueType.REG_DWORD }.Apply(); | |||
} catch (Exception e) | |||
{ | |||
Reg.UnloadDefaultUserHive(); | |||
throw e; | |||
} | |||
Reg.UnloadDefaultUserHive(); | |||
} | |||
} catch (Exception e) | |||
{ | |||
Console.WriteLine(); | |||
ConsoleTUI.OpenFrame.Close("Error: " + e.Message.TrimEnd('\n').TrimEnd('\r'), ConsoleColor.Red, Console.BackgroundColor, new ChoicePrompt() {AnyKey = true, Text = "Press any key to return to the Menu: "}); | |||
return false; | |||
} | |||
Console.WriteLine(); | |||
ConsoleTUI.OpenFrame.Close("User created successfully", ConsoleColor.Green, Console.BackgroundColor, new ChoicePrompt() {AnyKey = true, Text = "Press any key to return to the Menu: "}); | |||
return true; | |||
} | |||
private static bool CreateNewUser() | |||
{ | |||
try | |||
{ | |||
if (CreateUser() == false) | |||
return true; | |||
} catch (Exception e) | |||
{ | |||
Console.WriteLine(); | |||
ConsoleTUI.OpenFrame.Close("Error: " + e.Message.TrimEnd('\n').TrimEnd('\r'), ConsoleColor.Red, Console.BackgroundColor, new ChoicePrompt() {AnyKey = true, Text = "Press any key to return to the Menu: "}); | |||
return false; | |||
} | |||
Console.WriteLine(); | |||
ConsoleTUI.OpenFrame.Close("User created successfully", ConsoleColor.Green, Console.BackgroundColor, new ChoicePrompt() {AnyKey = true, Text = "Press any key to return to the Menu: "}); | |||
return true; | |||
} | |||
private static bool CreateUser() | |||
{ | |||
var choice = new ChoicePrompt() { Text = "Make user an Administrator? (Y/N): " }.Start(); | |||
if (choice == null) | |||
return false; | |||
bool makeAdmin = choice == 0; | |||
Console.WriteLine(); | |||
while (true) | |||
{ | |||
var username = new InputPrompt() { Text = "Enter name of new user, or press\r\nescape to quit: " }.Start(); | |||
if (username == null) | |||
return false; | |||
if (String.IsNullOrEmpty(username) || !Regex.Match(username, @"^\w[\w\.\- ]{0,19}$").Success) | |||
{ | |||
ConsoleTUI.OpenFrame.WriteLine("Username is invalid."); | |||
Console.WriteLine(); | |||
continue; | |||
} | |||
if (Globals.Username.Equals(username)) | |||
{ | |||
ConsoleTUI.OpenFrame.WriteLine("Specified user already exists."); | |||
Console.WriteLine(); | |||
continue; | |||
} | |||
var password = new InputPrompt() { MaskInput = true, Text = "\r\nEnter password for new user, or press\r\nescape to quit: " }.Start(); | |||
if (password == null) | |||
return false; | |||
var passwordConfirmation = new InputPrompt() { MaskInput = true, Text = "\r\nRe-enter your password, or press\r\nescape to quit: " }.Start(); | |||
if (passwordConfirmation == null) | |||
return false; | |||
if (password != passwordConfirmation) | |||
{ | |||
ConsoleTUI.OpenFrame.WriteLine("The password re-entered does not match your original password."); | |||
Console.WriteLine(); | |||
continue; | |||
} | |||
try | |||
{ | |||
ConsoleTUI.OpenFrame.WriteCentered("\r\nCreating user"); | |||
using (new ConsoleUtils.LoadingIndicator(true)) | |||
{ | |||
DirectoryEntry AD = new DirectoryEntry("WinNT://" + | |||
Environment.MachineName + ",computer"); | |||
DirectoryEntry NewUser = AD.Children.Add(username, "user"); | |||
NewUser.Invoke("SetPassword", new object[] { password }); | |||
NewUser.Invoke("Put", new object[] { "Description", "Normal User" }); | |||
NewUser.CommitChanges(); | |||
var ugrp = AD.Children.Find("Users", "group"); | |||
ugrp.Invoke("Add", new object[] { NewUser.Path.ToString() }); | |||
ugrp.CommitChanges(); | |||
if (makeAdmin) | |||
{ | |||
var agrp = AD.Children.Find("Administrators", "group"); | |||
agrp.Invoke("Add", new object[] { NewUser.Path.ToString() }); | |||
agrp.CommitChanges(); | |||
} | |||
} | |||
} catch (System.Runtime.InteropServices.COMException e) | |||
{ | |||
if (e.ErrorCode != -2147022694) | |||
throw e; | |||
ConsoleTUI.OpenFrame.WriteLine("Username is invalid."); | |||
Console.WriteLine(); | |||
} | |||
return true; | |||
} | |||
} | |||
} | |||
} |
@ -0,0 +1,201 @@ | |||
using System; | |||
using System.Diagnostics; | |||
using System.Runtime.InteropServices; | |||
using System.Windows.Forms; | |||
using amecs; | |||
namespace Ameliorated.ConsoleUtils | |||
{ | |||
public static partial class ConsoleTUI | |||
{ | |||
private const int MF_BYCOMMAND = 0x00000000; | |||
private const int SC_CLOSE = 0xF060; | |||
private const int SC_MINIMIZE = 0xF020; | |||
private const int SC_MAXIMIZE = 0xF030; | |||
private const int SC_SIZE = 0xF000; //resize | |||
private const uint CHECK_QUICK_EDIT = 0x0040; | |||
private const int ENABLE_QUICK_EDIT = 0x40 | 0x80; | |||
// STD_INPUT_HANDLE (DWORD): -10 is the standard input device. | |||
private const int STD_INPUT_HANDLE = -10; | |||
private static string PreviousTitle; | |||
private static int PreviousBufferHeight = 26; | |||
private static int PreviousBufferWidth = 80; | |||
private static int PreviousSizeHeight = 26; | |||
private static int PreviousSizeWidth = 80; | |||
private static bool IsInitialized; | |||
private static int InitializedWidth = 80; | |||
public static void ShowErrorBox(string message, string caption) | |||
{ | |||
NativeWindow window = new NativeWindow(); | |||
window.AssignHandle(Process.GetCurrentProcess().MainWindowHandle); | |||
MessageBox.Show(window, message, caption, MessageBoxButtons.OK, MessageBoxIcon.Error); | |||
} | |||
public enum BackdropType | |||
{ | |||
None = 1, | |||
Mica = 2, | |||
Acrylic = 3, | |||
Tabbed = 4 | |||
} | |||
[DllImport("dwmapi.dll")] | |||
private static extern int DwmSetWindowAttribute(IntPtr hwnd, int attribute, ref int pvAttribute, int cbAttribute); | |||
public static void Initialize(string title, int width = 80, int height = 26, bool resize = false, bool quickedit = false) | |||
{ | |||
if (width < 2) throw new ArgumentException("Width must be greater than one."); | |||
IsInitialized = true; | |||
PreviousSizeHeight = Console.WindowHeight; | |||
PreviousSizeWidth = Console.WindowWidth; | |||
PreviousBufferHeight = Console.BufferHeight; | |||
PreviousBufferWidth = Console.BufferWidth; | |||
Console.SetWindowSize(width, height); | |||
Console.SetBufferSize(width, height); | |||
Console.SetWindowSize(width, height); | |||
InitializedWidth = width; | |||
Console.Clear(); | |||
Console.CursorVisible = false; | |||
PreviousTitle = Console.Title; | |||
Console.Title = title; | |||
try | |||
{ | |||
if ((Console.CursorLeft == 0 && Console.CursorTop == 0) || ParentProcess.ProcessName.Equals("Explorer", StringComparison.OrdinalIgnoreCase)) | |||
{ | |||
var bd = (int)BackdropType.Mica; | |||
var trueA = 0x01; | |||
if (Globals.WinVer >= 22523) | |||
{ | |||
var handle = Process.GetCurrentProcess().MainWindowHandle; | |||
DwmSetWindowAttribute(handle, 38, ref bd, Marshal.SizeOf<int>()); | |||
DwmSetWindowAttribute(handle, 20, ref trueA, Marshal.SizeOf<int>()); | |||
} | |||
} | |||
} catch (Exception e) { } | |||
if (!resize) | |||
try | |||
{ | |||
DisableResize(); | |||
} catch (Exception e) | |||
{ | |||
ConsoleUtils.WriteError("Error disabling window resize - " + e.Message); | |||
} | |||
if (!quickedit) | |||
try | |||
{ | |||
DisableQuickEdit(); | |||
} catch (Exception e) | |||
{ | |||
ConsoleUtils.WriteError("Error disabling quickedit - " + e.Message); | |||
} | |||
} | |||
public static void Close() | |||
{ | |||
if (!IsInitialized) throw new MethodAccessException("Console TUI must be initialized before calling other TUI functions."); | |||
IsInitialized = false; | |||
var parent = ParentProcess.ProcessName; | |||
if (parent.Equals("Explorer", StringComparison.CurrentCultureIgnoreCase)) return; | |||
try | |||
{ | |||
EnableResize(); | |||
} catch (Exception e) | |||
{ | |||
ConsoleUtils.WriteError("Error enabling window resize - " + e.Message); | |||
} | |||
try | |||
{ | |||
EnableQuickEdit(); | |||
} catch (Exception e) | |||
{ | |||
ConsoleUtils.WriteError("Error enabling quickedit - " + e.Message); | |||
} | |||
Console.CursorVisible = true; | |||
Console.Clear(); | |||
Console.Title = PreviousTitle; | |||
Console.SetWindowSize(PreviousSizeWidth, PreviousSizeHeight); | |||
Console.SetBufferSize(PreviousBufferWidth, PreviousBufferHeight); | |||
} | |||
[DllImport("user32.dll")] | |||
public static extern int DeleteMenu(IntPtr hMenu, int nPosition, int wFlags); | |||
[DllImport("user32.dll")] | |||
private static extern IntPtr GetSystemMenu(IntPtr hWnd, bool bRevert); | |||
[DllImport("kernel32.dll", ExactSpelling = true)] | |||
private static extern IntPtr GetConsoleWindow(); | |||
private static void DisableResize() | |||
{ | |||
var handle = GetConsoleWindow(); | |||
var sysMenu = GetSystemMenu(handle, false); | |||
if (handle != IntPtr.Zero) | |||
{ | |||
//DeleteMenu(sysMenu, SC_CLOSE, MF_BYCOMMAND); | |||
//DeleteMenu(sysMenu, SC_MINIMIZE, MF_BYCOMMAND); | |||
DeleteMenu(sysMenu, SC_MAXIMIZE, MF_BYCOMMAND); | |||
DeleteMenu(sysMenu, SC_SIZE, MF_BYCOMMAND); //resize | |||
} | |||
} | |||
private static void EnableResize() | |||
{ | |||
var handle = GetConsoleWindow(); | |||
GetSystemMenu(handle, true); | |||
} | |||
[DllImport("kernel32.dll", SetLastError = true)] | |||
private static extern IntPtr GetStdHandle(int nStdHandle); | |||
[DllImport("kernel32.dll")] | |||
private static extern bool GetConsoleMode(IntPtr hConsoleHandle, out uint lpMode); | |||
[DllImport("kernel32.dll")] | |||
private static extern bool SetConsoleMode(IntPtr hConsoleHandle, uint dwMode); | |||
private static void DisableQuickEdit() | |||
{ | |||
var consoleHandle = GetStdHandle(STD_INPUT_HANDLE); | |||
// get current console mode | |||
uint consoleMode; | |||
GetConsoleMode(consoleHandle, out consoleMode); | |||
// set the new mode | |||
SetConsoleMode(consoleHandle, consoleMode &= ~CHECK_QUICK_EDIT); | |||
} | |||
private static void EnableQuickEdit() | |||
{ | |||
var consoleHandle = GetStdHandle(STD_INPUT_HANDLE); | |||
// get current console mode | |||
uint consoleMode; | |||
GetConsoleMode(consoleHandle, out consoleMode); | |||
// set the new mode | |||
SetConsoleMode(consoleHandle, consoleMode | ENABLE_QUICK_EDIT); | |||
} | |||
} | |||
} |
@ -0,0 +1,198 @@ | |||
using System; | |||
using System.Linq; | |||
namespace Ameliorated.ConsoleUtils | |||
{ | |||
public static partial class ConsoleTUI | |||
{ | |||
public static Frame OpenFrame; | |||
public partial class Frame | |||
{ | |||
private int _displayWidth; | |||
private int _sidePadding; | |||
/// <summary> | |||
/// Sets the visual "frame" to be used later. | |||
/// </summary> | |||
/// <param name="header">The header to be displayed just under the top of the frame.</param> | |||
/// <param name="ignoreHeader"> | |||
/// Indicates whether an exception should be raised if the header cannot be aligned with the | |||
/// frame. | |||
/// </param> | |||
/// <exception cref="MethodAccessException">Function was called before a TUI initialization.</exception> | |||
public Frame(string header, bool throwOnMisalignedHeader = true) | |||
{ | |||
if (!IsInitialized) throw new MethodAccessException("Console TUI must be initialized before calling other TUI functions."); | |||
if (header.Split(new[] | |||
{ "\r\n", "\n" }, StringSplitOptions.None).Any(x => x.Length > InitializedWidth)) throw new ArgumentException("Header must not be longer than the window width."); | |||
int frameWidth; | |||
if (InitializedWidth.IsEven()) | |||
{ | |||
if (!header.Length.IsEven() && throwOnMisalignedHeader) throw new ArgumentException("Header length should be even while window width is even."); | |||
frameWidth = (.725 * InitializedWidth).RoundToEven(); | |||
} else | |||
{ | |||
if (header.Length.IsEven() && throwOnMisalignedHeader) throw new ArgumentException("Header length should be odd while window width is odd."); | |||
frameWidth = (.725 * InitializedWidth).RoundToOdd(); | |||
} | |||
Header = header; | |||
FrameWidth = frameWidth; | |||
DisplayWidth = frameWidth - SidePadding * 2; | |||
DisplayOffset = (InitializedWidth - DisplayWidth) / 2; | |||
} | |||
public string Header { get; set; } | |||
public char FrameChar { get; set; } = '_'; | |||
public int FrameWidth { get; set; } | |||
public int SidePadding | |||
{ | |||
get => _sidePadding; | |||
set | |||
{ | |||
_sidePadding = value; | |||
DisplayWidth = FrameWidth - value * 2; | |||
DisplayOffset = (InitializedWidth - DisplayWidth) / 2; | |||
} | |||
} | |||
public int DisplayWidth | |||
{ | |||
get => _displayWidth; | |||
set | |||
{ | |||
_displayWidth = value; | |||
DisplayOffset = (InitializedWidth - value) / 2; | |||
} | |||
} | |||
internal int DisplayOffset { get; private set; } | |||
internal int DisplayHeight { get; } = Console.WindowHeight - 13; | |||
public void Open(bool paddingLines = true) | |||
{ | |||
Console.WriteLine(); | |||
var frameOffset = (InitializedWidth - FrameWidth) / 2; | |||
Console.WriteLine(new string(' ', frameOffset) + new string(FrameChar, FrameWidth)); | |||
Console.WriteLine(); | |||
WriteCenteredLine(Header); | |||
if (paddingLines) | |||
{ | |||
Console.WriteLine(); | |||
Console.WriteLine(); | |||
} | |||
OpenFrame = this; | |||
} | |||
public object Close(Prompt prompt = null, bool alignToBottom = false) | |||
{ | |||
OpenFrame = null; | |||
if (alignToBottom) | |||
Console.SetCursorPosition(0, Console.WindowHeight - 7); | |||
Console.WriteLine(); | |||
Console.WriteLine(); | |||
var frameOffset = (InitializedWidth - FrameWidth) / 2; | |||
Console.WriteLine(new string(' ', frameOffset) + new string(FrameChar, FrameWidth)); | |||
Console.WriteLine(); | |||
if (prompt != null) | |||
{ | |||
if (!prompt.MaxLength.HasValue) | |||
prompt.MaxLength = DisplayWidth - prompt.Text.LastLine().Length; | |||
prompt.BindToOpenFrame = false; | |||
prompt.Text = new string(' ', frameOffset) + prompt.Text; | |||
try { return ((ChoicePrompt)prompt).Start(); } catch (InvalidCastException) {} | |||
try { return ((InputPrompt)prompt).Start(); } catch (InvalidCastException) {} | |||
} | |||
return null; | |||
} | |||
public object Close(string text, Prompt prompt = null, bool alignToBottom = false) | |||
{ | |||
OpenFrame = null; | |||
if (alignToBottom) | |||
Console.SetCursorPosition(0, Console.WindowHeight - 7); | |||
Console.WriteLine(); | |||
WriteCenteredLine(text, true); | |||
var frameOffset = (InitializedWidth - FrameWidth) / 2; | |||
Console.WriteLine(new string(' ', frameOffset) + new string(FrameChar, FrameWidth)); | |||
Console.WriteLine(); | |||
if (prompt != null) | |||
{ | |||
if (!prompt.MaxLength.HasValue) | |||
prompt.MaxLength = DisplayWidth - prompt.Text.LastLine().Length; | |||
prompt.BindToOpenFrame = false; | |||
prompt.Text = new string(' ', frameOffset) + prompt.Text; | |||
try { return ((ChoicePrompt)prompt).Start(); } catch (InvalidCastException) {} | |||
try { return ((InputPrompt)prompt).Start(); } catch (InvalidCastException) {} | |||
} | |||
return null; | |||
} | |||
public object Close(string text, ConsoleColor foreground, ConsoleColor background, Prompt prompt = null, bool alignToBottom = false) | |||
{ | |||
OpenFrame = null; | |||
if (alignToBottom) | |||
Console.SetCursorPosition(0, Console.WindowHeight - 7); | |||
Console.WriteLine(); | |||
WriteCenteredLine(text, foreground, background, true); | |||
var frameOffset = (InitializedWidth - FrameWidth) / 2; | |||
Console.WriteLine(new string(' ', frameOffset) + new string(FrameChar, FrameWidth)); | |||
Console.WriteLine(); | |||
if (prompt != null) | |||
{ | |||
if (!prompt.MaxLength.HasValue) | |||
prompt.MaxLength = DisplayWidth - prompt.Text.LastLine().Length; | |||
prompt.BindToOpenFrame = false; | |||
prompt.Text = new string(' ', frameOffset) + prompt.Text; | |||
try { return ((ChoicePrompt)prompt).Start(); } catch (InvalidCastException) {} | |||
try { return ((InputPrompt)prompt).Start(); } catch (InvalidCastException) {} | |||
} | |||
return null; | |||
} | |||
public void Clear(int bottomOffset = 2) | |||
{ | |||
for (int i = 0; i < Console.WindowHeight - (6 + bottomOffset); i++) | |||
{ | |||
Console.SetCursorPosition(DisplayOffset, i + 6); | |||
Console.Write(new string(' ', DisplayWidth)); | |||
} | |||
Console.SetCursorPosition(0, 6); | |||
OpenFrame = this; | |||
} | |||
public int AvailableLines() | |||
{ | |||
var totalLines = DisplayHeight - (Math.Max(Console.CursorTop - 6, 0)); | |||
return totalLines; | |||
} | |||
public int AvailableChars() | |||
{ | |||
var totalChars = Math.Max(Console.CursorLeft - DisplayOffset, 0) + (AvailableLines() * DisplayWidth); | |||
return totalChars; | |||
} | |||
} | |||
} | |||
} |
@ -0,0 +1,397 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Diagnostics.Contracts; | |||
using System.Linq; | |||
namespace Ameliorated.ConsoleUtils | |||
{ | |||
public partial class ConsoleTUI | |||
{ | |||
public partial class Frame | |||
{ | |||
/// <summary> | |||
/// Centered Line | |||
/// </summary> | |||
public enum LineCenterOptions | |||
{ | |||
Word = 0, | |||
Character = 1 | |||
} | |||
/// <summary> | |||
/// Normal (Indented) Line | |||
/// </summary> | |||
public void WriteLine() | |||
{ | |||
Console.WriteLine(); | |||
} | |||
public void Write(string text) | |||
{ | |||
var lines = text.SplitByLine(); | |||
if (lines.Length > AvailableLines()) | |||
Clear(); | |||
foreach (var line in lines.Take(lines.Length - 1)) | |||
{ | |||
Console.WriteLine(line.Insert(0, new string(' ', DisplayOffset))); | |||
} | |||
Console.Write(lines.Last().Insert(0, new string(' ', DisplayOffset))); | |||
} | |||
public void WriteLine(string text) | |||
{ | |||
var lines = text.SplitByLine(); | |||
if (lines.Length > AvailableLines()) | |||
Clear(); | |||
foreach (var line in lines) | |||
{ | |||
Console.WriteLine(line.Insert(0, new string(' ', DisplayOffset))); | |||
} | |||
} | |||
public void WriteLine(string text, ConsoleColor? foreground) | |||
{ | |||
var lines = text.SplitByLine(); | |||
if (lines.Length > AvailableLines()) | |||
Clear(); | |||
foreach (var line in lines) | |||
{ | |||
Console.Write(new string(' ', DisplayOffset)); | |||
ConsoleUtils.SetColor(foreground); | |||
Console.WriteLine(line); | |||
ConsoleUtils.ResetColor(); | |||
} | |||
} | |||
public void WriteLine(string text, ConsoleColor? foreground, ConsoleColor? background) | |||
{ | |||
var lines = text.SplitByLine(); | |||
if (lines.Length > AvailableLines()) | |||
Clear(); | |||
foreach (var line in lines) | |||
{ | |||
Console.Write(new string(' ', DisplayOffset)); | |||
ConsoleUtils.SetColor(foreground, background); | |||
Console.WriteLine(text); | |||
ConsoleUtils.ResetColor(); | |||
} | |||
} | |||
public void WriteLine(string text, int offset) | |||
{ | |||
var lines = text.SplitByLine(); | |||
if (lines.Length > AvailableLines()) | |||
Clear(); | |||
foreach (var line in lines) | |||
{ | |||
Console.WriteLine(line.Insert(0, new string(' ', DisplayOffset + offset))); | |||
} | |||
} | |||
public void WriteLine(string text, int offset, ConsoleColor? foreground) | |||
{ | |||
var lines = text.SplitByLine(); | |||
if (lines.Length > AvailableLines()) | |||
Clear(); | |||
foreach (var line in lines) | |||
{ | |||
Console.Write(new string(' ', DisplayOffset + offset)); | |||
ConsoleUtils.SetColor(foreground); | |||
Console.WriteLine(line); | |||
ConsoleUtils.ResetColor(); | |||
} | |||
} | |||
public void WriteLine(string text, int offset, ConsoleColor? foreground, ConsoleColor? background) | |||
{ | |||
var lines = text.SplitByLine(); | |||
if (lines.Length > AvailableLines()) | |||
Clear(); | |||
foreach (var line in lines) | |||
{ | |||
Console.Write(new string(' ', DisplayOffset + offset)); | |||
ConsoleUtils.SetColor(foreground, background); | |||
Console.WriteLine(line); | |||
ConsoleUtils.ResetColor(); | |||
} | |||
} | |||
public void WriteCenteredLine(string text, bool ignoreDisplayHeight = false, LineCenterOptions options = LineCenterOptions.Word) | |||
{ | |||
var centeredLines = CenterLines(text, options); | |||
if (centeredLines.Count > AvailableLines() && !ignoreDisplayHeight) | |||
{ | |||
Clear(); | |||
centeredLines = CenterLines(text.TrimStart('\r').TrimStart('\n'), options); | |||
} | |||
foreach (var line in centeredLines) Console.WriteLine(line.Value); | |||
} | |||
public void WriteCenteredLine(string text, int maxWidth, bool ignoreDisplayHeight = false, LineCenterOptions options = LineCenterOptions.Word) | |||
{ | |||
Contract.Requires<ArgumentException>(maxWidth > 1); | |||
var centeredLines = CenterLines(text, options, maxWidth); | |||
if (centeredLines.Count >AvailableLines() && !ignoreDisplayHeight) | |||
Clear(); | |||
foreach (var line in centeredLines) Console.WriteLine(line.Value); | |||
} | |||
public void WriteCenteredLine(string text, ConsoleColor? foreground, bool ignoreDisplayHeight = false, LineCenterOptions options = LineCenterOptions.Word) | |||
{ | |||
var centeredLines = CenterLines(text, options); | |||
if (centeredLines.Count >AvailableLines() && !ignoreDisplayHeight) | |||
Clear(); | |||
foreach (var line in centeredLines) | |||
{ | |||
Console.Write(new string(' ', line.LeaderLength)); | |||
ConsoleUtils.SetColor(foreground); | |||
Console.WriteLine(line.RawString); | |||
ConsoleUtils.ResetColor(); | |||
} | |||
} | |||
public void WriteCenteredLine(string text, int maxWidth, ConsoleColor? foreground, bool ignoreDisplayHeight = false, LineCenterOptions options = LineCenterOptions.Word) | |||
{ | |||
Contract.Requires<ArgumentException>(maxWidth > 1); | |||
var centeredLines = CenterLines(text, options, maxWidth); | |||
if (centeredLines.Count >AvailableLines() && !ignoreDisplayHeight) | |||
Clear(); | |||
foreach (var line in centeredLines) | |||
{ | |||
Console.Write(new string(' ', line.LeaderLength)); | |||
ConsoleUtils.SetColor(foreground); | |||
Console.WriteLine(line.RawString); | |||
ConsoleUtils.ResetColor(); | |||
} | |||
} | |||
public void WriteCenteredLine(string text, ConsoleColor? foreground, ConsoleColor? background, bool ignoreDisplayHeight = false, LineCenterOptions options = LineCenterOptions.Word) | |||
{ | |||
var centeredLines = CenterLines(text, options); | |||
if (centeredLines.Count > AvailableLines() && !ignoreDisplayHeight) | |||
{ | |||
Clear(); | |||
centeredLines = CenterLines(text.TrimStart('\r').TrimStart('\n'), options); | |||
} | |||
foreach (var line in centeredLines) | |||
{ | |||
Console.Write(new string(' ', line.LeaderLength)); | |||
ConsoleUtils.SetColor(foreground, background); | |||
Console.WriteLine(line.RawString); | |||
ConsoleUtils.ResetColor(); | |||
} | |||
} | |||
public void WriteCenteredLine(string text, int maxWidth, ConsoleColor? foreground, ConsoleColor? background, bool ignoreDisplayHeight = false, LineCenterOptions options = LineCenterOptions.Word) | |||
{ | |||
Contract.Requires<ArgumentException>(maxWidth > 1); | |||
var centeredLines = CenterLines(text, options, maxWidth); | |||
if (centeredLines.Count >AvailableLines() && !ignoreDisplayHeight) | |||
Clear(); | |||
foreach (var line in centeredLines) | |||
{ | |||
Console.Write(new string(' ', line.LeaderLength)); | |||
ConsoleUtils.SetColor(foreground, background); | |||
Console.WriteLine(line.RawString); | |||
ConsoleUtils.ResetColor(); | |||
} | |||
} | |||
public void WriteCentered(string text, bool ignoreDisplayHeight = false, LineCenterOptions options = LineCenterOptions.Word) | |||
{ | |||
var centeredLines = CenterLines(text, options); | |||
if (centeredLines.Count > AvailableLines() && !ignoreDisplayHeight) | |||
{ | |||
Clear(); | |||
centeredLines = CenterLines(text.TrimStart('\r').TrimStart('\n'), options); | |||
} | |||
foreach (var line in centeredLines.Take(centeredLines.Count - 1)) Console.WriteLine(line.Value); | |||
Console.Write(centeredLines.Last().Value); | |||
} | |||
public void WriteCentered(string text, int maxWidth, bool ignoreDisplayHeight = false, LineCenterOptions options = LineCenterOptions.Word) | |||
{ | |||
Contract.Requires<ArgumentException>(maxWidth > 1); | |||
var centeredLines = CenterLines(text, options, maxWidth); | |||
if (centeredLines.Count >AvailableLines() && !ignoreDisplayHeight) | |||
Clear(); | |||
foreach (var line in centeredLines.Take(centeredLines.Count - 1)) Console.WriteLine(line.Value); | |||
Console.Write(centeredLines.Last().Value); | |||
} | |||
public void WriteCentered(string text, ConsoleColor? foreground, bool ignoreDisplayHeight = false, LineCenterOptions options = LineCenterOptions.Word) | |||
{ | |||
var centeredLines = CenterLines(text, options); | |||
if (centeredLines.Count >AvailableLines() && !ignoreDisplayHeight) | |||
Clear(); | |||
foreach (var line in centeredLines.Take(centeredLines.Count - 1)) | |||
{ | |||
Console.Write(new string(' ', line.LeaderLength)); | |||
ConsoleUtils.SetColor(foreground); | |||
Console.WriteLine(line.RawString); | |||
ConsoleUtils.ResetColor(); | |||
} | |||
Console.Write(new string(' ', centeredLines.Last().LeaderLength)); | |||
ConsoleUtils.SetColor(foreground); | |||
Console.WriteLine(centeredLines.Last().RawString); | |||
ConsoleUtils.ResetColor(); | |||
} | |||
public void WriteCentered(string text, int maxWidth, ConsoleColor? foreground, bool ignoreDisplayHeight = false, LineCenterOptions options = LineCenterOptions.Word) | |||
{ | |||
Contract.Requires<ArgumentException>(maxWidth > 1); | |||
var centeredLines = CenterLines(text, options, maxWidth); | |||
if (centeredLines.Count >AvailableLines() && !ignoreDisplayHeight) | |||
Clear(); | |||
foreach (var line in centeredLines.Take(centeredLines.Count - 1)) | |||
{ | |||
Console.Write(new string(' ', line.LeaderLength)); | |||
ConsoleUtils.SetColor(foreground); | |||
Console.WriteLine(line.RawString); | |||
ConsoleUtils.ResetColor(); | |||
} | |||
Console.Write(new string(' ', centeredLines.Last().LeaderLength)); | |||
ConsoleUtils.SetColor(foreground); | |||
Console.WriteLine(centeredLines.Last().RawString); | |||
ConsoleUtils.ResetColor(); | |||
} | |||
public void WriteCentered(string text, ConsoleColor? foreground, ConsoleColor? background, bool ignoreDisplayHeight = false, LineCenterOptions options = LineCenterOptions.Word) | |||
{ | |||
var centeredLines = CenterLines(text, options); | |||
if (centeredLines.Count >AvailableLines() && !ignoreDisplayHeight) | |||
Clear(); | |||
foreach (var line in centeredLines.Take(centeredLines.Count - 1)) | |||
{ | |||
Console.Write(new string(' ', line.LeaderLength)); | |||
ConsoleUtils.SetColor(foreground, background); | |||
Console.WriteLine(line.RawString); | |||
ConsoleUtils.ResetColor(); | |||
} | |||
Console.Write(new string(' ', centeredLines.Last().LeaderLength)); | |||
ConsoleUtils.SetColor(foreground, background); | |||
Console.WriteLine(centeredLines.Last().RawString); | |||
ConsoleUtils.ResetColor(); | |||
} | |||
public void WriteCentered(string text, int maxWidth, ConsoleColor? foreground, ConsoleColor? background, bool ignoreDisplayHeight = false, LineCenterOptions options = LineCenterOptions.Word) | |||
{ | |||
Contract.Requires<ArgumentException>(maxWidth > 1); | |||
var centeredLines = CenterLines(text, options, maxWidth); | |||
if (centeredLines.Count >AvailableLines() && !ignoreDisplayHeight) | |||
Clear(); | |||
foreach (var line in centeredLines.Take(centeredLines.Count - 1)) | |||
{ | |||
Console.Write(new string(' ', line.LeaderLength)); | |||
ConsoleUtils.SetColor(foreground, background); | |||
Console.WriteLine(line.RawString); | |||
ConsoleUtils.ResetColor(); | |||
} | |||
Console.Write(new string(' ', centeredLines.Last().LeaderLength)); | |||
ConsoleUtils.SetColor(foreground, background); | |||
Console.WriteLine(centeredLines.Last().RawString); | |||
ConsoleUtils.ResetColor(); | |||
} | |||
// TODO: Fix this splitting lines when a piece of text can fit on one line | |||
private List<CenteredString> CenterLines(string text, LineCenterOptions options, int maxWidth = 0) | |||
{ | |||
var _maxWidth = DisplayWidth; | |||
if (maxWidth != 0) _maxWidth = maxWidth; | |||
var list = new List<CenteredString>(); | |||
var lines = new List<string>(); | |||
foreach (var line in text.SplitByLine()) | |||
{ | |||
if (line == "") | |||
{ | |||
list.Add(new CenteredString | |||
{ Value = "", LeaderLength = 0 }); | |||
continue; | |||
} | |||
if (line.Length > _maxWidth) | |||
{ | |||
for (var index = 0; index < line.Length;) | |||
{ | |||
var splitLine = line.Substring(index, Math.Min(_maxWidth, line.Length - index)); | |||
var trimmedLength = splitLine.Length - splitLine.Trim(' ').Length; | |||
splitLine = splitLine.Trim(' '); | |||
var wordIndex = splitLine.LastIndexOf(' '); | |||
if (wordIndex != -1 && options == LineCenterOptions.Word) splitLine = splitLine.Substring(0, wordIndex); | |||
index += splitLine.Length + trimmedLength; | |||
list.Add(CenterLine(splitLine)); | |||
} | |||
continue; | |||
} | |||
list.Add(CenterLine(line)); | |||
} | |||
return list; | |||
} | |||
private CenteredString CenterLine(string text, int maxWidth = 0) | |||
{ | |||
var _maxWidth = DisplayWidth; | |||
if (maxWidth != 0) _maxWidth = maxWidth; | |||
var centeredString = new CenteredString(); | |||
var space = ""; | |||
if (!(text.Length % 2).Equals(0) && text.Length != _maxWidth) space = " "; | |||
var leadingLength = (_maxWidth - text.Length) / 2; | |||
centeredString.Value = space + text.PadLeft(text.Length + leadingLength, ' ').Insert(0, new string(' ', DisplayOffset)); | |||
centeredString.LeaderLength = leadingLength + DisplayOffset + space.Length; | |||
centeredString.RawString = text; | |||
return centeredString; | |||
} | |||
private class CenteredString | |||
{ | |||
public int LeaderLength; | |||
public string RawString; | |||
public string Value; | |||
} | |||
} | |||
} | |||
} |
@ -0,0 +1,433 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
using System.Threading; | |||
using System.Windows.Forms; | |||
using amecs; | |||
namespace Ameliorated.ConsoleUtils | |||
{ | |||
public class Menu | |||
{ | |||
public List<MenuItem> Choices { get; set; } = new List<MenuItem>(); | |||
private int TotalOffset = 2; | |||
private int? _offset = null; | |||
public int Offset | |||
{ | |||
get | |||
{ | |||
if (_offset == null) | |||
_offset = BindToOpenFrame ? 5 : 2; | |||
return _offset.Value; | |||
} | |||
set { _offset = value; } | |||
} | |||
public ConsoleColor? SelectionForeground { get; set; } = ConsoleColor.Green; | |||
public ConsoleColor? SelectionBackgound { get; set; } = null; | |||
public bool CloseFrame { get; set; } = true; | |||
private bool _bindToOpenFrame; | |||
public bool BindToOpenFrame { get; set; } = true; | |||
private int menuStart; | |||
private int pages; | |||
private int choicesPerPage; | |||
public void Write() | |||
{ | |||
if (Choices.Count < 1) throw new ArgumentException("Property Choices must have at least one choice."); | |||
_bindToOpenFrame = ConsoleTUI.OpenFrame != null && BindToOpenFrame; | |||
int totalStaticChoices = Choices.Count(x => x.IsStatic || x.IsNextButton || x.IsPreviousButton); | |||
if (_bindToOpenFrame) | |||
{ | |||
pages = (int)Math.Ceiling(((double)Choices.Count - totalStaticChoices) / (double)(ConsoleTUI.OpenFrame.DisplayHeight - totalStaticChoices + 1)); | |||
choicesPerPage = (ConsoleTUI.OpenFrame.DisplayHeight - totalStaticChoices + 1); | |||
} | |||
else | |||
{ | |||
pages = (int)Math.Ceiling(((double)Choices.Count - totalStaticChoices) / (double)(((Console.WindowHeight - Console.CursorTop) - totalStaticChoices))); | |||
choicesPerPage = (Console.WindowHeight - Console.CursorTop) - totalStaticChoices; | |||
} | |||
if (_bindToOpenFrame) | |||
ConsoleTUI.OpenFrame.Clear(); | |||
TotalOffset = _bindToOpenFrame ? ConsoleTUI.OpenFrame.DisplayOffset + Offset : Offset; | |||
menuStart = Console.CursorTop; | |||
if (_bindToOpenFrame) | |||
{ | |||
Console.SetCursorPosition(TotalOffset, Console.CursorTop); | |||
} | |||
var fluidChoices = Choices.Where(x => !x.IsStatic && !x.IsNextButton && !x.IsPreviousButton).Take(choicesPerPage); | |||
var staticChoices = Choices.Where(x => x.IsStatic || (pages > 1 && x.IsNextButton)); | |||
WriteChoiceList(fluidChoices.Concat(staticChoices)); | |||
Frame = ConsoleTUI.OpenFrame; | |||
if (_bindToOpenFrame && CloseFrame) | |||
{ | |||
try | |||
{ | |||
var offset = ConsoleTUI.OpenFrame.DisplayOffset; | |||
if (pages == 1) | |||
ConsoleTUI.OpenFrame.Close(); | |||
else | |||
ConsoleTUI.OpenFrame.Close($"Page 1/{pages}"); | |||
Console.WriteLine(new string(' ', offset) + "Use the arrow keys to navigate"); | |||
} catch (Exception e) | |||
{ | |||
Console.WriteLine(e); | |||
Console.ReadLine(); | |||
} | |||
} | |||
} | |||
private void WriteChoiceList(IEnumerable<MenuItem> list) | |||
{ | |||
bool selectedWritten = false; | |||
Console.SetCursorPosition(0, Console.CursorTop); | |||
foreach (MenuItem choice in list) | |||
{ | |||
if (_bindToOpenFrame) | |||
{ | |||
Console.Write( | |||
new string(' ', TotalOffset)); | |||
if (choice.IsEnabled && !selectedWritten) | |||
{ | |||
choice.WriteSelected(SelectionForeground, SelectionBackgound); | |||
selectedWritten = true; | |||
Console.WriteLine(); | |||
continue; | |||
} | |||
choice.Write(); | |||
} | |||
else | |||
{ | |||
Console.Write( | |||
new string(' ', TotalOffset)); | |||
if (choice.IsEnabled && !selectedWritten) | |||
{ | |||
choice.WriteSelected(SelectionForeground, SelectionBackgound); | |||
selectedWritten = true; | |||
Console.WriteLine(); | |||
continue; | |||
} | |||
choice.Write(); | |||
} | |||
Console.WriteLine(); | |||
} | |||
Console.SetCursorPosition(Console.CursorLeft, Console.CursorTop - 1); | |||
} | |||
private List<MenuItem> ValidChoices = new List<MenuItem>(); | |||
private ConsoleTUI.Frame Frame; | |||
public object Load() | |||
{ | |||
var visCache = Console.CursorVisible; | |||
Console.CursorVisible = false; | |||
int index = Math.Max(Choices.FindIndex(x => x.IsEnabled), 0); | |||
int validIndex = 0; | |||
ConsoleKey keyPressed; | |||
Console.SetCursorPosition(Console.CursorLeft, menuStart + index); | |||
var allFluidChoices = Choices.Where(x => !x.IsStatic && !x.IsNextButton && !x.IsPreviousButton).ToList(); | |||
var allStaticChoices = Choices.Where(x => x.IsStatic || x.IsNextButton || x.IsPreviousButton).ToList(); | |||
int pageIndex = 1; | |||
ConsoleUtils.ClearInputBuffer(); | |||
var currentChoices = allFluidChoices.Take(choicesPerPage).Concat(Choices.Where(x => x.IsStatic || (pages > 1 && x.IsNextButton))).ToList(); | |||
var currentValidChoices = currentChoices.Where(x => x.IsEnabled).ToList(); | |||
while (true) | |||
{ | |||
keyPressed = Console.ReadKey(true).Key; | |||
if (keyPressed == ConsoleKey.DownArrow || keyPressed == ConsoleKey.S) | |||
{ | |||
if (validIndex >= currentValidChoices.Count - 1) continue; | |||
Console.SetCursorPosition(Math.Max(TotalOffset - 2, 0), Console.CursorTop); | |||
Console.Write(" "); | |||
currentValidChoices[validIndex].Write(); | |||
var fromTop = currentChoices.Skip(index + 1).TakeWhile(x => !x.IsEnabled).Count() + 1; | |||
var choice = currentChoices.Skip(index + 1).First(x => x.IsEnabled); | |||
Console.SetCursorPosition(TotalOffset, Console.CursorTop + fromTop); | |||
choice.WriteSelected(SelectionForeground, SelectionBackgound); | |||
index += fromTop; | |||
validIndex += 1; | |||
} | |||
if (keyPressed == ConsoleKey.UpArrow || keyPressed == ConsoleKey.W) | |||
{ | |||
if (!(validIndex > 0)) continue; | |||
Console.SetCursorPosition(Math.Max(TotalOffset - 2, 0), Console.CursorTop); | |||
Console.Write(" "); | |||
currentValidChoices[validIndex].Write(); | |||
var fromTop = -currentChoices.Take(index).Reverse().TakeWhile(x => !x.IsEnabled).Count() - 1; | |||
var choice = currentChoices.Take(index).Last(x => x.IsEnabled); | |||
Console.SetCursorPosition(TotalOffset, Console.CursorTop + fromTop); | |||
choice.WriteSelected(SelectionForeground, SelectionBackgound); | |||
index += fromTop; | |||
validIndex -= 1; | |||
} | |||
if (keyPressed == ConsoleKey.RightArrow || keyPressed == ConsoleKey.A || keyPressed == ConsoleKey.PageUp || | |||
(keyPressed == ConsoleKey.Enter && currentValidChoices[validIndex].IsNextButton)) | |||
{ | |||
if (pageIndex == pages) | |||
continue; | |||
Frame.Clear(); | |||
pageIndex++; | |||
var pIndex = pageIndex; | |||
var fluidChoices = allFluidChoices.Skip((pIndex - 1) * choicesPerPage).Take(choicesPerPage).ToList(); | |||
var staticChoices = allStaticChoices.Where(x => !(pages <= pIndex && x.IsNextButton)); | |||
Console.SetCursorPosition(Console.CursorLeft, menuStart); | |||
currentChoices = fluidChoices.Concat(staticChoices).ToList(); | |||
WriteChoiceList(currentChoices); | |||
if (_bindToOpenFrame && CloseFrame) | |||
{ | |||
try | |||
{ | |||
var offset = ConsoleTUI.OpenFrame.DisplayOffset; | |||
if (pages == 1) | |||
ConsoleTUI.OpenFrame.Close(); | |||
else | |||
ConsoleTUI.OpenFrame.Close($"Page {pIndex}/{pages}"); | |||
Console.WriteLine(new string(' ', offset) + "Use the arrow keys to navigate"); | |||
} catch (Exception e) | |||
{ | |||
Console.WriteLine(e); | |||
Console.ReadLine(); | |||
} | |||
} | |||
Console.SetCursorPosition(Console.CursorLeft, menuStart); | |||
currentValidChoices = currentChoices.Where(x => x.IsEnabled).ToList(); | |||
index = 0; | |||
validIndex = 0; | |||
continue; | |||
} | |||
if (keyPressed == ConsoleKey.LeftArrow || keyPressed == ConsoleKey.D || keyPressed == ConsoleKey.PageDown || | |||
(keyPressed == ConsoleKey.Enter && currentValidChoices[validIndex].IsPreviousButton)) | |||
{ | |||
if (pageIndex == 1) | |||
continue; | |||
Frame.Clear(); | |||
pageIndex--; | |||
var pIndex = pageIndex; | |||
var fluidChoices = allFluidChoices.Skip((pIndex - 1) * choicesPerPage).Take(choicesPerPage).ToList(); | |||
var staticChoices = allStaticChoices.Where(x => !(pIndex <= 1 && x.IsPreviousButton)); | |||
Console.SetCursorPosition(Console.CursorLeft, menuStart); | |||
currentChoices = fluidChoices.Concat(staticChoices).ToList(); | |||
WriteChoiceList(currentChoices); | |||
if (_bindToOpenFrame && CloseFrame) | |||
{ | |||
try | |||
{ | |||
var offset = ConsoleTUI.OpenFrame.DisplayOffset; | |||
if (pages == 1) | |||
ConsoleTUI.OpenFrame.Close(); | |||
else | |||
ConsoleTUI.OpenFrame.Close($"Page {pIndex}/{pages}"); | |||
Console.WriteLine(new string(' ', offset) + "Use the arrow keys to navigate"); | |||
} catch (Exception e) | |||
{ | |||
Console.WriteLine(e); | |||
Console.ReadLine(); | |||
} | |||
} | |||
Console.SetCursorPosition(Console.CursorLeft, menuStart); | |||
currentValidChoices = currentChoices.Where(x => x.IsEnabled).ToList(); | |||
index = 0; | |||
validIndex = 0; | |||
continue; | |||
} | |||
if (keyPressed == ConsoleKey.Enter) | |||
{ | |||
break; | |||
} | |||
} | |||
if (CloseFrame) | |||
Frame.Clear(); | |||
Console.CursorVisible = visCache; | |||
return currentValidChoices[validIndex].ReturnValue; | |||
} | |||
private bool NextButtonPresent() | |||
{ | |||
return Choices.Any(x => x.IsNextButton); | |||
} | |||
private bool PreviousButtonPresent() | |||
{ | |||
return Choices.Any(x => x.IsNextButton); | |||
} | |||
public class MenuItem | |||
{ | |||
public object ReturnValue { get; set; } | |||
public static readonly MenuItem Blank = new MenuItem("", null); | |||
public static readonly MenuItem BlankStatic = new MenuItem("", null) { IsStatic = true }; | |||
public bool IsNextButton { get; set; } = false; | |||
public bool IsPreviousButton { get; set; } = false; | |||
public bool IsStatic { get; set; } = false; | |||
public string PrimaryText { get; set; } = ""; | |||
public string SecondaryText { get; set; } = ""; | |||
public MenuItem(string primaryText, object returnValue) | |||
{ | |||
PrimaryText = primaryText; | |||
ReturnValue = returnValue; | |||
} | |||
public bool AddBetweenSpace { get; set; } = true; | |||
private ConsoleColor? _primaryTextForeground = null; | |||
public ConsoleColor? PrimaryTextForeground | |||
{ | |||
get | |||
{ | |||
if (_primaryTextForeground.HasValue) | |||
return _primaryTextForeground; | |||
if (IsEnabled) return null; | |||
if (Console.ForegroundColor == ConsoleColor.White) return ConsoleColor.DarkGray; | |||
if (Console.ForegroundColor == ConsoleColor.White) return ConsoleColor.DarkGray; | |||
return null; | |||
} | |||
set { _primaryTextForeground = value; } | |||
} | |||
public ConsoleColor? PrimaryTextBackground { get; set; } = null; | |||
public ConsoleColor? SecondaryTextForeground { get; set; } = null; | |||
public ConsoleColor? SecondaryTextBackground { get; set; } = null; | |||
private bool? _isEnabled = null; | |||
public bool IsEnabled | |||
{ | |||
get | |||
{ | |||
if (_isEnabled.HasValue) | |||
return _isEnabled.Value; | |||
if (!String.IsNullOrEmpty(PrimaryText) || !String.IsNullOrEmpty(SecondaryText)) | |||
{ | |||
return true; | |||
} | |||
return false; | |||
} | |||
set { _isEnabled = value; } | |||
} | |||
public bool StretchSelection = false; | |||
public void Write() | |||
{ | |||
if (!String.IsNullOrEmpty(PrimaryText)) | |||
{ | |||
ConsoleUtils.SetColor(PrimaryTextForeground, PrimaryTextBackground); | |||
Console.Write(PrimaryText); | |||
ConsoleUtils.ResetColor(); | |||
if (AddBetweenSpace) | |||
Console.Write(' '); | |||
} | |||
if (String.IsNullOrEmpty(SecondaryText)) | |||
return; | |||
ConsoleUtils.SetColor(SecondaryTextForeground, SecondaryTextBackground); | |||
Console.Write(SecondaryText); | |||
ConsoleUtils.ResetColor(); | |||
} | |||
public void WriteSelected(ConsoleColor? foreground, ConsoleColor? background) | |||
{ | |||
Console.SetCursorPosition(Console.CursorLeft - 2, Console.CursorTop); | |||
if (!String.IsNullOrEmpty(PrimaryText)) | |||
{ | |||
ConsoleUtils.SetColor(foreground, background); | |||
Console.Write("> " + PrimaryText); | |||
if (!StretchSelection) | |||
ConsoleUtils.ResetColor(); | |||
if (AddBetweenSpace) | |||
Console.Write(' '); | |||
} | |||
if (String.IsNullOrEmpty(SecondaryText)) | |||
{ | |||
if (StretchSelection) | |||
ConsoleUtils.ResetColor(); | |||
return; | |||
} | |||
if (!String.IsNullOrEmpty(PrimaryText) && !StretchSelection) | |||
ConsoleUtils.SetColor(SecondaryTextForeground, SecondaryTextBackground); | |||
Console.Write(SecondaryText); | |||
ConsoleUtils.ResetColor(); | |||
} | |||
} | |||
} | |||
} |
@ -0,0 +1,196 @@ | |||
using System; | |||
using System.Runtime.InteropServices; | |||
using System.Threading; | |||
namespace Ameliorated.ConsoleUtils | |||
{ | |||
// TODO: Integrate this into ConsoleTUI.cs | |||
// https://stackoverflow.com/questions/1944481/console-app-mouse-click-x-y-coordinate-detection-comparison | |||
/* | |||
public class MouseInterface | |||
{ | |||
public static class ConsoleListener | |||
{ | |||
public static event ConsoleMouseEvent MouseEvent; | |||
public static event ConsoleKeyEvent KeyEvent; | |||
public static event ConsoleWindowBufferSizeEvent WindowBufferSizeEvent; | |||
private static bool Run = false; | |||
public static void Start() | |||
{ | |||
if (!Run) | |||
{ | |||
Run = true; | |||
IntPtr handleIn = GetStdHandle(STD_INPUT_HANDLE); | |||
new Thread(() => | |||
{ | |||
while (true) | |||
{ | |||
uint numRead = 0; | |||
INPUT_RECORD[] record = new INPUT_RECORD[1]; | |||
record[0] = new INPUT_RECORD(); | |||
ReadConsoleInput(handleIn, record, 1, ref numRead); | |||
if (Run) | |||
switch (record[0].EventType) | |||
{ | |||
case INPUT_RECORD.MOUSE_EVENT: | |||
MouseEvent?.Invoke(record[0].MouseEvent); | |||
break; | |||
case INPUT_RECORD.KEY_EVENT: | |||
KeyEvent?.Invoke(record[0].KeyEvent); | |||
break; | |||
case INPUT_RECORD.WINDOW_BUFFER_SIZE_EVENT: | |||
WindowBufferSizeEvent?.Invoke(record[0].WindowBufferSizeEvent); | |||
break; | |||
} | |||
else | |||
{ | |||
uint numWritten = 0; | |||
WriteConsoleInput(handleIn, record, 1, ref numWritten); | |||
return; | |||
} | |||
} | |||
}).Start(); | |||
} | |||
} | |||
public static void Stop() => Run = false; | |||
public delegate void ConsoleMouseEvent(MOUSE_EVENT_RECORD r); | |||
public delegate void ConsoleKeyEvent(KEY_EVENT_RECORD r); | |||
public delegate void ConsoleWindowBufferSizeEvent(WINDOW_BUFFER_SIZE_RECORD r); | |||
// NATIVE METHODS | |||
public struct COORD | |||
{ | |||
public short X; | |||
public short Y; | |||
public COORD(short x, short y) | |||
{ | |||
X = x; | |||
Y = y; | |||
} | |||
} | |||
[StructLayout(LayoutKind.Explicit)] | |||
public struct INPUT_RECORD | |||
{ | |||
public const ushort KEY_EVENT = 0x0001, | |||
MOUSE_EVENT = 0x0002, | |||
WINDOW_BUFFER_SIZE_EVENT = 0x0004; //more | |||
[FieldOffset(0)] public ushort EventType; | |||
[FieldOffset(4)] public KEY_EVENT_RECORD KeyEvent; | |||
[FieldOffset(4)] public MOUSE_EVENT_RECORD MouseEvent; | |||
[FieldOffset(4)] public WINDOW_BUFFER_SIZE_RECORD WindowBufferSizeEvent; | |||
/* | |||
and: | |||
MENU_EVENT_RECORD MenuEvent; | |||
FOCUS_EVENT_RECORD FocusEvent; | |||
~/ <--- end comment | |||
} | |||
public struct MOUSE_EVENT_RECORD | |||
{ | |||
public COORD dwMousePosition; | |||
public const uint FROM_LEFT_1ST_BUTTON_PRESSED = 0x0001, | |||
FROM_LEFT_2ND_BUTTON_PRESSED = 0x0004, | |||
FROM_LEFT_3RD_BUTTON_PRESSED = 0x0008, | |||
FROM_LEFT_4TH_BUTTON_PRESSED = 0x0010, | |||
RIGHTMOST_BUTTON_PRESSED = 0x0002; | |||
public uint dwButtonState; | |||
public const int CAPSLOCK_ON = 0x0080, | |||
ENHANCED_KEY = 0x0100, | |||
LEFT_ALT_PRESSED = 0x0002, | |||
LEFT_CTRL_PRESSED = 0x0008, | |||
NUMLOCK_ON = 0x0020, | |||
RIGHT_ALT_PRESSED = 0x0001, | |||
RIGHT_CTRL_PRESSED = 0x0004, | |||
SCROLLLOCK_ON = 0x0040, | |||
SHIFT_PRESSED = 0x0010; | |||
public uint dwControlKeyState; | |||
public const int DOUBLE_CLICK = 0x0002, | |||
MOUSE_HWHEELED = 0x0008, | |||
MOUSE_MOVED = 0x0001, | |||
MOUSE_WHEELED = 0x0004; | |||
public uint dwEventFlags; | |||
} | |||
[StructLayout(LayoutKind.Explicit, CharSet = CharSet.Unicode)] | |||
public struct KEY_EVENT_RECORD | |||
{ | |||
[FieldOffset(0)] public bool bKeyDown; | |||
[FieldOffset(4)] public ushort wRepeatCount; | |||
[FieldOffset(6)] public ushort wVirtualKeyCode; | |||
[FieldOffset(8)] public ushort wVirtualScanCode; | |||
[FieldOffset(10)] public char UnicodeChar; | |||
[FieldOffset(10)] public byte AsciiChar; | |||
public const int CAPSLOCK_ON = 0x0080, | |||
ENHANCED_KEY = 0x0100, | |||
LEFT_ALT_PRESSED = 0x0002, | |||
LEFT_CTRL_PRESSED = 0x0008, | |||
NUMLOCK_ON = 0x0020, | |||
RIGHT_ALT_PRESSED = 0x0001, | |||
RIGHT_CTRL_PRESSED = 0x0004, | |||
SCROLLLOCK_ON = 0x0040, | |||
SHIFT_PRESSED = 0x0010; | |||
[FieldOffset(12)] public uint dwControlKeyState; | |||
} | |||
public struct WINDOW_BUFFER_SIZE_RECORD | |||
{ | |||
public COORD dwSize; | |||
} | |||
public const uint STD_INPUT_HANDLE = unchecked((uint)-10), | |||
STD_OUTPUT_HANDLE = unchecked((uint)-11), | |||
STD_ERROR_HANDLE = unchecked((uint)-12); | |||
[DllImport("kernel32.dll")] | |||
public static extern IntPtr GetStdHandle(uint nStdHandle); | |||
public const uint ENABLE_MOUSE_INPUT = 0x0010, | |||
ENABLE_QUICK_EDIT_MODE = 0x0040, | |||
ENABLE_EXTENDED_FLAGS = 0x0080, | |||
ENABLE_ECHO_INPUT = 0x0004, | |||
ENABLE_WINDOW_INPUT = 0x0008; //more | |||
[DllImportAttribute("kernel32.dll")] | |||
public static extern bool GetConsoleMode(IntPtr hConsoleInput, ref uint lpMode); | |||
[DllImportAttribute("kernel32.dll")] | |||
public static extern bool SetConsoleMode(IntPtr hConsoleInput, uint dwMode); | |||
[DllImportAttribute("kernel32.dll", CharSet = CharSet.Unicode)] | |||
public static extern bool ReadConsoleInput(IntPtr hConsoleInput, [Out] INPUT_RECORD[] lpBuffer, uint nLength, ref uint lpNumberOfEventsRead); | |||
[DllImportAttribute("kernel32.dll", CharSet = CharSet.Unicode)] | |||
public static extern bool WriteConsoleInput(IntPtr hConsoleInput, INPUT_RECORD[] lpBuffer, uint nLength, ref uint lpNumberOfEventsWritten); | |||
} | |||
} | |||
*/ | |||
} |
@ -0,0 +1,604 @@ | |||
using System; | |||
using System.Collections; | |||
using System.Linq; | |||
using System.Security; | |||
using System.Text; | |||
using System.Threading; | |||
using System.Windows.Forms; | |||
using JetBrains.Annotations; | |||
namespace Ameliorated.ConsoleUtils | |||
{ | |||
/// <summary> | |||
/// Represents a input prompt to be used with the Start method. | |||
/// </summary> | |||
public class ChoicePrompt : Prompt | |||
{ | |||
public string Choices { get; set; } = "YN"; | |||
public bool BeepSound { get; set; } = true; | |||
public bool CaseSensitive { get; set; } = false; | |||
public bool AllowEscape { get; set; } = true; | |||
public bool AnyKey { get; set; } = false; | |||
public ConsoleColor? TextForeground { get; set; } | |||
private bool _bindToOpenFrame; | |||
[CanBeNull] | |||
public new int? Start() | |||
{ | |||
if (Choices.Length < 1 && !AnyKey) throw new ArgumentException("There must be at least 1 choice."); | |||
_bindToOpenFrame = ConsoleTUI.OpenFrame != null && BindToOpenFrame; | |||
if (_bindToOpenFrame && ConsoleTUI.OpenFrame.AvailableLines() < 1) | |||
ConsoleTUI.OpenFrame.Clear(); | |||
if (TextForeground.HasValue) | |||
ConsoleUtils.SetColor(TextForeground); | |||
if (_bindToOpenFrame) | |||
ConsoleTUI.OpenFrame.Write(Text); | |||
else | |||
Console.Write(Text); | |||
if (TextForeground.HasValue) | |||
ConsoleUtils.ResetColor(); | |||
var cursorVisibility = Console.CursorVisible; | |||
int? result; | |||
while (true) | |||
{ | |||
Console.CursorVisible = true; | |||
ConsoleUtils.ClearInputBuffer(); | |||
var key = Console.ReadKey(true); | |||
if (AnyKey) | |||
{ | |||
Console.CursorVisible = cursorVisibility; | |||
return key.KeyChar; | |||
} | |||
if (key.Key == ConsoleKey.Escape && AllowEscape) | |||
{ | |||
Console.CursorVisible = cursorVisibility; | |||
return null; | |||
} | |||
if (CaseSensitive) | |||
result = Choices.IndexOf(key.KeyChar.ToString(), StringComparison.Ordinal); | |||
else | |||
result = Choices.IndexOf(key.KeyChar.ToString(), StringComparison.OrdinalIgnoreCase); | |||
if (result >= 0) | |||
{ | |||
if (InputForeground.HasValue && InputBackground.HasValue) ConsoleUtils.SetColor(InputForeground.Value, InputBackground.Value); | |||
else if (InputForeground.HasValue) ConsoleUtils.SetColor(InputForeground.Value); | |||
else if (InputBackground.HasValue) ConsoleUtils.SetColor(Console.ForegroundColor, InputBackground.Value); | |||
if (!CaseSensitive) Console.Write(key.KeyChar.ToString().ToUpper()); | |||
else Console.Write(key.KeyChar.ToString()); | |||
if (InputForeground.HasValue || InputBackground.HasValue) ConsoleUtils.ResetColor(); | |||
break; | |||
} | |||
else if (BeepSound) Console.Beep(); | |||
} | |||
Console.CursorVisible = cursorVisibility; | |||
Console.WriteLine(); | |||
return result.Value; | |||
} | |||
} | |||
public class InputPrompt : Prompt | |||
{ | |||
[Optional] public ConsoleColor? BoxBackground { get; set; } | |||
public bool MaskInput { get; set; } = false; | |||
public bool AlignInput { get; set; } = true; | |||
[Optional] public int? SplitWidth { get; set; } | |||
private bool _bindToOpenFrame; | |||
private int? _splitWidth; | |||
[CanBeNull] | |||
public new string Start() | |||
{ | |||
if (SplitWidth.HasValue && !AlignInput) throw new ArgumentException("Property SplitWidth must not be used without property AlignInput set to true."); | |||
_bindToOpenFrame = ConsoleTUI.OpenFrame != null && BindToOpenFrame; | |||
if (_bindToOpenFrame && ConsoleTUI.OpenFrame.AvailableLines() < 1) | |||
ConsoleTUI.OpenFrame.Clear(); | |||
if (!MaxLength.HasValue) | |||
MaxLength = AlignInput ? ConsoleTUI.OpenFrame.AvailableChars() - (Text.LastLine().Length * ConsoleTUI.OpenFrame.AvailableLines()) : ConsoleTUI.OpenFrame.AvailableChars(); | |||
int startLeft = Console.CursorLeft + Text.LastLine().Length; | |||
_splitWidth = null; | |||
if (AlignInput && !_bindToOpenFrame) | |||
{ | |||
if (Text.LastLine().Length > Console.WindowWidth - 3) throw new ArgumentException("Last line of property Text must not be within 3 characters of the available width."); | |||
_splitWidth = Console.WindowWidth - startLeft; | |||
} | |||
if (_bindToOpenFrame) | |||
{ | |||
if (SplitWidth.HasValue && (SplitWidth.Value + startLeft + ConsoleTUI.OpenFrame.DisplayOffset >= Console.WindowWidth)) | |||
throw new ArgumentException($"Property SplitWidth must be less than the available width."); | |||
// TODO: BAD WORDING | |||
if (Text.LastLine().Length > ConsoleTUI.OpenFrame.DisplayWidth - 3) throw new ArgumentException("Last line of property Text must not be within 3 characters of the available width."); | |||
_splitWidth = ConsoleTUI.OpenFrame.DisplayWidth - (startLeft); | |||
if (!AlignInput) | |||
_splitWidth = ConsoleTUI.OpenFrame.DisplayWidth; | |||
} | |||
if (SplitWidth.HasValue) | |||
{ | |||
if (SplitWidth.Value + startLeft >= Console.WindowWidth) | |||
throw new ArgumentException($"Property SplitWidth must be less than the available width."); | |||
if (Text.LastLine().Length > Console.WindowWidth - 3) throw new ArgumentException("Last line of property Text must not be within 3 characters of the available width."); | |||
_splitWidth = SplitWidth.Value; | |||
} | |||
/* | |||
int maxLines = Console.WindowHeight - Console.CursorTop; | |||
if (_bindToOpenFrame) | |||
{ | |||
maxLines = ConsoleTUI.OpenFrame.DisplayHeight - (Console.CursorTop - 6) - Text.SplitByLine().Length; | |||
if (maxLines < 2) | |||
{ | |||
ConsoleTUI.OpenFrame.Clear(); | |||
if (_bindToOpenFrame) maxLines = ConsoleTUI.OpenFrame.DisplayHeight - (Console.CursorTop - 6) - Text.SplitByLine().Length; | |||
} | |||
} | |||
*/ | |||
ConsoleUtils.ClearInputBuffer(); | |||
if (_bindToOpenFrame) | |||
ConsoleTUI.OpenFrame.Write(Text); | |||
else | |||
Console.Write(Text); | |||
if (BoxBackground.HasValue && _splitWidth.HasValue) | |||
{ | |||
if (AlignInput) | |||
WriteBackground(_splitWidth.Value, BoxBackground.Value); | |||
else | |||
WriteBackground(_splitWidth.Value - Text.LastLine().Length, BoxBackground.Value); | |||
} | |||
if (BoxBackground.HasValue && !_splitWidth.HasValue) WriteBackground(Console.WindowWidth - Console.CursorLeft, BoxBackground.Value); | |||
var cursorVisibility = Console.CursorVisible; | |||
var input = new StringBuilder(); | |||
ConsoleKeyInfo key; | |||
do | |||
{ | |||
Console.CursorVisible = true; | |||
key = Console.ReadKey(true); | |||
if (key.Key == ConsoleKey.Backspace) | |||
{ | |||
if (input.Length <= 0) continue; | |||
input.Remove(input.Length - 1, 1); | |||
bool movedLines = false; | |||
if (_bindToOpenFrame) | |||
{ | |||
if ((((input.Length + 1) - _splitWidth.Value + Text.LastLine().Length).IsDivisibleBy(ConsoleTUI.OpenFrame.DisplayWidth) || input.Length + 1 == _splitWidth.Value - Text.LastLine().Length) && !AlignInput) | |||
{ | |||
if (BoxBackground.HasValue) WriteBackground(_splitWidth.Value - (Console.CursorLeft - ConsoleTUI.OpenFrame.DisplayOffset), Console.BackgroundColor); | |||
Console.SetCursorPosition((ConsoleTUI.OpenFrame.DisplayOffset) + _splitWidth.Value - 1, Console.CursorTop - 1); | |||
movedLines = true; | |||
} | |||
else if ((input.Length + 1).IsDivisibleBy(_splitWidth.Value) && AlignInput) | |||
{ | |||
if (BoxBackground.HasValue) WriteBackground(_splitWidth.Value, Console.BackgroundColor); | |||
Console.SetCursorPosition(ConsoleTUI.OpenFrame.DisplayOffset + startLeft + _splitWidth.Value - 1, Console.CursorTop - 1); | |||
movedLines = true; | |||
} | |||
} | |||
else if (AlignInput) | |||
{ | |||
if ((input.Length + 1).IsDivisibleBy(_splitWidth.Value)) | |||
{ | |||
if (BoxBackground.HasValue) WriteBackground(_splitWidth.Value, Console.BackgroundColor); | |||
Console.SetCursorPosition(startLeft + _splitWidth.Value, Console.CursorTop - 1); | |||
movedLines = true; | |||
} | |||
} | |||
else | |||
{ | |||
if (((input.Length + 1) - (Console.WindowWidth - startLeft)).IsDivisibleBy(Console.WindowWidth) || input.Length + 1 == Console.WindowWidth - startLeft) | |||
{ | |||
if (BoxBackground.HasValue) WriteBackground(Console.WindowWidth, Console.BackgroundColor); | |||
Console.SetCursorPosition(Console.WindowWidth - 1, Console.CursorTop - 1); | |||
movedLines = true; | |||
} | |||
} | |||
if (movedLines) | |||
{ | |||
if (BoxBackground.HasValue) ConsoleUtils.SetColor(Console.ForegroundColor, BoxBackground.Value); | |||
Console.Write(" \b"); | |||
if (BoxBackground.HasValue) ConsoleUtils.ResetColor(); | |||
} | |||
else | |||
{ | |||
if (BoxBackground.HasValue) ConsoleUtils.SetColor(Console.ForegroundColor, BoxBackground.Value); | |||
Console.Write("\b \b"); | |||
if (BoxBackground.HasValue) ConsoleUtils.ResetColor(); | |||
} | |||
if (MaxLength.HasValue && MaxLength.Value - 1 == input.Length) Console.CursorVisible = true; | |||
continue; | |||
} | |||
if (Char.IsControl(key.KeyChar)) continue; | |||
if (MaxLength.HasValue && MaxLength.Value <= input.Length) | |||
{ | |||
ConsoleUtils.SetColor(ConsoleColor.DarkRed, InputBackground); | |||
Console.CursorVisible = false; | |||
Console.Write("!"); | |||
Thread.Sleep(200); | |||
ConsoleUtils.ClearInputBuffer(); | |||
ConsoleUtils.ResetColor(); | |||
ConsoleUtils.SetColor(null, BoxBackground); | |||
Console.Write("\b \b"); | |||
ConsoleUtils.ResetColor(); | |||
continue; | |||
} | |||
input.Append(key.KeyChar); | |||
ConsoleUtils.SetColor(InputForeground, InputBackground); | |||
if (MaskInput) Console.Write("*"); | |||
else Console.Write(key.KeyChar); | |||
ConsoleUtils.ResetColor(); | |||
if (MaxLength.HasValue && MaxLength.Value <= input.Length + 1) | |||
continue; | |||
if (_bindToOpenFrame) | |||
{ | |||
if (((input.Length - _splitWidth.Value + Text.LastLine().Length).IsDivisibleBy(_splitWidth.Value) || input.Length == _splitWidth.Value - Text.LastLine().Length) && !AlignInput) | |||
{ | |||
Console.SetCursorPosition(ConsoleTUI.OpenFrame.DisplayOffset, Console.CursorTop + 1); | |||
if (BoxBackground.HasValue) WriteBackground(_splitWidth.Value, BoxBackground.Value); | |||
} | |||
else if (input.Length.IsDivisibleBy(_splitWidth.Value) && AlignInput) | |||
{ | |||
Console.SetCursorPosition(startLeft + ConsoleTUI.OpenFrame.DisplayOffset, Console.CursorTop + 1); | |||
if (BoxBackground.HasValue) WriteBackground(_splitWidth.Value, BoxBackground.Value); | |||
} | |||
} | |||
else if (AlignInput) | |||
{ | |||
if (input.Length.IsDivisibleBy(_splitWidth.Value)) | |||
{ | |||
if (SplitWidth.HasValue) | |||
Console.SetCursorPosition(startLeft, Console.CursorTop + 1); | |||
else | |||
// Console will have automatically moved the cursor down | |||
Console.SetCursorPosition(startLeft, Console.CursorTop); | |||
if (BoxBackground.HasValue) WriteBackground(_splitWidth.Value, BoxBackground.Value); | |||
} | |||
} | |||
else | |||
{ | |||
if ((input.Length - (Console.WindowWidth - startLeft)).IsDivisibleBy(Console.WindowWidth) || input.Length == Console.WindowWidth - startLeft) | |||
{ | |||
// Console will have automatically moved the cursor down | |||
Console.SetCursorPosition(startLeft - Text.LastLine().Length, Console.CursorTop); | |||
if (BoxBackground.HasValue) WriteBackground(Console.WindowWidth - (startLeft - Text.LastLine().Length), BoxBackground.Value); | |||
} | |||
} | |||
} while (key.Key != ConsoleKey.Enter && (!AllowEscape || (AllowEscape && key.Key != ConsoleKey.Escape))); | |||
if (input.Length == 0) | |||
{ | |||
ConsoleUtils.SetColor(ConsoleColor.DarkGray); | |||
Console.Write("None"); | |||
ConsoleUtils.ResetColor(); | |||
} | |||
Console.CursorVisible = cursorVisibility; | |||
Console.WriteLine(); | |||
if (key.Key == ConsoleKey.Escape && AllowEscape) return null; | |||
return input.ToString(); | |||
} | |||
} | |||
public class SecureInputPrompt : Prompt | |||
{ | |||
[Optional] public ConsoleColor? BoxBackground { get; set; } | |||
public bool MaskInput { get; set; } = true; | |||
public bool AlignInput { get; set; } = true; | |||
[Optional] public int? SplitWidth { get; set; } | |||
private bool _bindToOpenFrame; | |||
private int? _splitWidth; | |||
[CanBeNull] | |||
public new SecureString Start() | |||
{if (SplitWidth.HasValue && !AlignInput) throw new ArgumentException("Property SplitWidth must not be used without property AlignInput set to true."); | |||
_bindToOpenFrame = ConsoleTUI.OpenFrame != null && BindToOpenFrame; | |||
if (_bindToOpenFrame && ConsoleTUI.OpenFrame.AvailableLines() < 1) | |||
ConsoleTUI.OpenFrame.Clear(); | |||
if (!MaxLength.HasValue) | |||
MaxLength = AlignInput ? ConsoleTUI.OpenFrame.AvailableChars() - (Text.LastLine().Length * ConsoleTUI.OpenFrame.AvailableLines()) : ConsoleTUI.OpenFrame.AvailableChars(); | |||
int startLeft = Console.CursorLeft + Text.LastLine().Length; | |||
_splitWidth = null; | |||
if (AlignInput && !_bindToOpenFrame) | |||
{ | |||
if (Text.LastLine().Length > Console.WindowWidth - 3) throw new ArgumentException("Last line of property Text must not be within 3 characters of the available width."); | |||
_splitWidth = Console.WindowWidth - startLeft; | |||
} | |||
if (_bindToOpenFrame) | |||
{ | |||
if (SplitWidth.HasValue && (SplitWidth.Value + startLeft + ConsoleTUI.OpenFrame.DisplayOffset >= Console.WindowWidth)) | |||
throw new ArgumentException($"Property SplitWidth must be less than the available width."); | |||
// TODO: BAD WORDING | |||
if (Text.LastLine().Length > ConsoleTUI.OpenFrame.DisplayWidth - 3) throw new ArgumentException("Last line of property Text must not be within 3 characters of the available width."); | |||
_splitWidth = ConsoleTUI.OpenFrame.DisplayWidth - (startLeft); | |||
if (!AlignInput) | |||
_splitWidth = ConsoleTUI.OpenFrame.DisplayWidth; | |||
} | |||
if (SplitWidth.HasValue) | |||
{ | |||
if (SplitWidth.Value + startLeft >= Console.WindowWidth) | |||
throw new ArgumentException($"Property SplitWidth must be less than the available width."); | |||
if (Text.LastLine().Length > Console.WindowWidth - 3) throw new ArgumentException("Last line of property Text must not be within 3 characters of the available width."); | |||
_splitWidth = SplitWidth.Value; | |||
} | |||
/* | |||
int maxLines = Console.WindowHeight - Console.CursorTop; | |||
if (_bindToOpenFrame) | |||
{ | |||
maxLines = ConsoleTUI.OpenFrame.DisplayHeight - (Console.CursorTop - 6) - Text.SplitByLine().Length; | |||
if (maxLines < 2) | |||
{ | |||
ConsoleTUI.OpenFrame.Clear(); | |||
if (_bindToOpenFrame) maxLines = ConsoleTUI.OpenFrame.DisplayHeight - (Console.CursorTop - 6) - Text.SplitByLine().Length; | |||
} | |||
} | |||
*/ | |||
ConsoleUtils.ClearInputBuffer(); | |||
if (_bindToOpenFrame) | |||
ConsoleTUI.OpenFrame.Write(Text); | |||
else | |||
Console.Write(Text); | |||
if (BoxBackground.HasValue && _splitWidth.HasValue) | |||
{ | |||
if (AlignInput) | |||
WriteBackground(_splitWidth.Value, BoxBackground.Value); | |||
else | |||
WriteBackground(_splitWidth.Value - Text.LastLine().Length, BoxBackground.Value); | |||
} | |||
if (BoxBackground.HasValue && !_splitWidth.HasValue) WriteBackground(Console.WindowWidth - Console.CursorLeft, BoxBackground.Value); | |||
var cursorVisibility = Console.CursorVisible; | |||
var input = new SecureString(); | |||
ConsoleKeyInfo key; | |||
do | |||
{ | |||
Console.CursorVisible = true; | |||
key = Console.ReadKey(true); | |||
if (key.Key == ConsoleKey.Backspace) | |||
{ | |||
if (input.Length <= 0) continue; | |||
input.RemoveAt(input.Length - 1); | |||
bool movedLines = false; | |||
if (_bindToOpenFrame) | |||
{ | |||
if ((((input.Length + 1) - _splitWidth.Value + Text.LastLine().Length).IsDivisibleBy(ConsoleTUI.OpenFrame.DisplayWidth) || input.Length + 1 == _splitWidth.Value - Text.LastLine().Length) && !AlignInput) | |||
{ | |||
if (BoxBackground.HasValue) WriteBackground(_splitWidth.Value - (Console.CursorLeft - ConsoleTUI.OpenFrame.DisplayOffset), Console.BackgroundColor); | |||
Console.SetCursorPosition((ConsoleTUI.OpenFrame.DisplayOffset) + _splitWidth.Value - 1, Console.CursorTop - 1); | |||
movedLines = true; | |||
} | |||
else if ((input.Length + 1).IsDivisibleBy(_splitWidth.Value) && AlignInput) | |||
{ | |||
if (BoxBackground.HasValue) WriteBackground(_splitWidth.Value, Console.BackgroundColor); | |||
Console.SetCursorPosition(ConsoleTUI.OpenFrame.DisplayOffset + startLeft + _splitWidth.Value - 1, Console.CursorTop - 1); | |||
movedLines = true; | |||
} | |||
} | |||
else if (AlignInput) | |||
{ | |||
if ((input.Length + 1).IsDivisibleBy(_splitWidth.Value)) | |||
{ | |||
if (BoxBackground.HasValue) WriteBackground(_splitWidth.Value, Console.BackgroundColor); | |||
Console.SetCursorPosition(startLeft + _splitWidth.Value, Console.CursorTop - 1); | |||
movedLines = true; | |||
} | |||
} | |||
else | |||
{ | |||
if (((input.Length + 1) - (Console.WindowWidth - startLeft)).IsDivisibleBy(Console.WindowWidth) || input.Length + 1 == Console.WindowWidth - startLeft) | |||
{ | |||
if (BoxBackground.HasValue) WriteBackground(Console.WindowWidth, Console.BackgroundColor); | |||
Console.SetCursorPosition(Console.WindowWidth - 1, Console.CursorTop - 1); | |||
movedLines = true; | |||
} | |||
} | |||
if (movedLines) | |||
{ | |||
if (BoxBackground.HasValue) ConsoleUtils.SetColor(Console.ForegroundColor, BoxBackground.Value); | |||
Console.Write(" \b"); | |||
if (BoxBackground.HasValue) ConsoleUtils.ResetColor(); | |||
} | |||
else | |||
{ | |||
if (BoxBackground.HasValue) ConsoleUtils.SetColor(Console.ForegroundColor, BoxBackground.Value); | |||
Console.Write("\b \b"); | |||
if (BoxBackground.HasValue) ConsoleUtils.ResetColor(); | |||
} | |||
if (MaxLength.HasValue && MaxLength.Value - 1 == input.Length) Console.CursorVisible = true; | |||
} | |||
if (Char.IsControl(key.KeyChar)) continue; | |||
if (MaxLength.HasValue && MaxLength.Value <= input.Length) | |||
{ | |||
ConsoleUtils.SetColor(ConsoleColor.DarkRed, InputBackground); | |||
Console.CursorVisible = false; | |||
Console.Write("!"); | |||
Thread.Sleep(200); | |||
ConsoleUtils.ClearInputBuffer(); | |||
ConsoleUtils.ResetColor(); | |||
ConsoleUtils.SetColor(null, BoxBackground); | |||
Console.Write("\b \b"); | |||
ConsoleUtils.ResetColor(); | |||
continue; | |||
} | |||
input.AppendChar(key.KeyChar); | |||
ConsoleUtils.SetColor(InputForeground, InputBackground); | |||
if (MaskInput) Console.Write("*"); | |||
else Console.Write(key.KeyChar); | |||
ConsoleUtils.ResetColor(); | |||
if (MaxLength.HasValue && MaxLength.Value <= input.Length + 1) | |||
continue; | |||
if (_bindToOpenFrame) | |||
{ | |||
if (((input.Length - _splitWidth.Value + Text.LastLine().Length).IsDivisibleBy(_splitWidth.Value) || input.Length == _splitWidth.Value - Text.LastLine().Length) && !AlignInput) | |||
{ | |||
Console.SetCursorPosition(ConsoleTUI.OpenFrame.DisplayOffset, Console.CursorTop + 1); | |||
if (BoxBackground.HasValue) WriteBackground(_splitWidth.Value, BoxBackground.Value); | |||
} | |||
else if (input.Length.IsDivisibleBy(_splitWidth.Value) && AlignInput) | |||
{ | |||
Console.SetCursorPosition(startLeft + ConsoleTUI.OpenFrame.DisplayOffset, Console.CursorTop + 1); | |||
if (BoxBackground.HasValue) WriteBackground(_splitWidth.Value, BoxBackground.Value); | |||
} | |||
} | |||
else if (AlignInput) | |||
{ | |||
if (input.Length.IsDivisibleBy(_splitWidth.Value)) | |||
{ | |||
if (SplitWidth.HasValue) | |||
Console.SetCursorPosition(startLeft, Console.CursorTop + 1); | |||
else | |||
// Console will have automatically moved the cursor down | |||
Console.SetCursorPosition(startLeft, Console.CursorTop); | |||
if (BoxBackground.HasValue) WriteBackground(_splitWidth.Value, BoxBackground.Value); | |||
} | |||
} | |||
else | |||
{ | |||
if ((input.Length - (Console.WindowWidth - startLeft)).IsDivisibleBy(Console.WindowWidth) || input.Length == Console.WindowWidth - startLeft) | |||
{ | |||
// Console will have automatically moved the cursor down | |||
Console.SetCursorPosition(startLeft - Text.LastLine().Length, Console.CursorTop); | |||
if (BoxBackground.HasValue) WriteBackground(Console.WindowWidth - (startLeft - Text.LastLine().Length), BoxBackground.Value); | |||
} | |||
} | |||
} while (key.Key != ConsoleKey.Enter && (!AllowEscape || (AllowEscape && key.Key != ConsoleKey.Escape))); | |||
if (input.Length == 0) | |||
{ | |||
ConsoleUtils.SetColor(ConsoleColor.Gray); | |||
Console.Write("None"); | |||
ConsoleUtils.ResetColor(); | |||
} | |||
Console.CursorVisible = cursorVisibility; | |||
Console.WriteLine(); | |||
if (key.Key == ConsoleKey.Escape && AllowEscape) return null; | |||
return input; | |||
} | |||
} | |||
public abstract class Prompt | |||
{ | |||
/// <summary> | |||
/// Text to be displayed before the input. | |||
/// </summary> | |||
[Optional] | |||
public string Text { get; set; } = ""; | |||
[Optional] public int? MaxLength { get; set; } | |||
/// <summary> | |||
/// (Optional) | |||
/// </summary> | |||
[Optional] | |||
public ConsoleColor? InputForeground { get; set; } = null; | |||
[Optional] public ConsoleColor? InputBackground { get; set; } = null; | |||
public bool BindToOpenFrame { get; set; } = true; | |||
public bool AllowEscape { get; set; } = true; | |||
internal static void WriteBackground(int length, ConsoleColor color) | |||
{ | |||
if (Console.CursorLeft + length > Console.WindowWidth) throw new Exception("Critical Error"); | |||
int leftStart = Console.CursorLeft; | |||
int topStart = Console.CursorTop; | |||
ConsoleUtils.SetColor(Console.ForegroundColor, color); | |||
Console.Write(new string(' ', length)); | |||
ConsoleUtils.ResetColor(); | |||
Console.SetCursorPosition(leftStart, topStart); | |||
} | |||
} | |||
} |
@ -0,0 +1,250 @@ | |||
using System; | |||
using System.Threading; | |||
using System.Threading.Tasks; | |||
using JetBrains.Annotations; | |||
namespace Ameliorated.ConsoleUtils | |||
{ | |||
[AttributeUsage(AttributeTargets.Property)] | |||
internal sealed class OptionalAttribute : Attribute | |||
{ | |||
} | |||
public static class ConsoleUtils | |||
{ | |||
public class LoadingIndicator : IDisposable | |||
{ | |||
public LoadingIndicator() {} | |||
public LoadingIndicator(bool start) | |||
{ | |||
if (start) | |||
StartAsync(); | |||
} | |||
private CancellationTokenSource cts = new CancellationTokenSource(); | |||
Task currentTask = Task.CompletedTask; | |||
public async Task StartAsync() | |||
{ | |||
Console.CursorVisible = false; | |||
cts = new CancellationTokenSource(); | |||
currentTask = Task.Run(() => | |||
{ | |||
if (cts.IsCancellationRequested) | |||
{ | |||
Console.WriteLine("..."); | |||
return; | |||
} | |||
Console.Write('.'); | |||
while (true) | |||
{ | |||
Thread.Sleep(500); | |||
Console.Write('.'); | |||
Thread.Sleep(500); | |||
Console.Write('.'); | |||
Thread.Sleep(500); | |||
if (cts.IsCancellationRequested) | |||
{ | |||
Console.WriteLine(); | |||
return; | |||
} | |||
Console.Write("\b \b\b \b"); | |||
} | |||
}); | |||
await currentTask; | |||
} | |||
public void Stop() | |||
{ | |||
cts.Cancel(); | |||
currentTask.Wait(); | |||
} | |||
public void Dispose() | |||
{ | |||
Stop(); | |||
this.currentTask = null; | |||
this.cts = null; | |||
} | |||
} | |||
public static bool DisplayErrors { get; set; } = true; | |||
public static void ClearInputBuffer() | |||
{ | |||
while (Console.KeyAvailable) Console.ReadKey(true); | |||
} | |||
internal static void WriteError(string text) | |||
{ | |||
if (DisplayErrors) Console.WriteLine("ConsoleUtils: " + text); | |||
} | |||
private static ConsoleColor foregroundCache; | |||
private static ConsoleColor backgroundCache; | |||
private static bool? foregroundOnly; | |||
internal static void SetColor([CanBeNull] ConsoleColor? foreground) | |||
{ | |||
foregroundCache = Console.ForegroundColor; | |||
if (foreground.HasValue) | |||
Console.ForegroundColor = foreground.Value; | |||
foregroundOnly = true; | |||
} | |||
internal static void SetColor([CanBeNull] ConsoleColor? foreground, [CanBeNull] ConsoleColor? background) | |||
{ | |||
foregroundCache = Console.ForegroundColor; | |||
backgroundCache = Console.BackgroundColor; | |||
if (foreground.HasValue) | |||
Console.ForegroundColor = foreground.Value; | |||
if (background.HasValue) | |||
Console.BackgroundColor = background.Value; | |||
foregroundOnly = false; | |||
} | |||
internal static void ResetColor() | |||
{ | |||
if (!foregroundOnly.HasValue) throw new MethodAccessException("SetColor must be used before calling ResetColor."); | |||
if (foregroundOnly.Value) | |||
{ | |||
Console.ForegroundColor = foregroundCache; | |||
} else | |||
{ | |||
Console.ForegroundColor = foregroundCache; | |||
Console.BackgroundColor = backgroundCache; | |||
} | |||
foregroundOnly = null; | |||
} | |||
public static void WriteLine(string text, ConsoleColor? foreground) | |||
{ | |||
foreach (var line in text.SplitByLine()) | |||
{ | |||
ConsoleUtils.SetColor(foreground); | |||
Console.WriteLine(line); | |||
ConsoleUtils.ResetColor(); | |||
} | |||
} | |||
public static void WriteLine(string text, ConsoleColor? foreground, ConsoleColor? background) | |||
{ | |||
foreach (var line in text.SplitByLine()) | |||
{ | |||
ConsoleUtils.SetColor(foreground); | |||
Console.WriteLine(line); | |||
ConsoleUtils.ResetColor(); | |||
} | |||
} | |||
public static void WriteLine(string text, int offset) | |||
{ | |||
foreach (var line in text.SplitByLine()) | |||
{ | |||
Console.WriteLine(line.Insert(0, new string(' ', offset))); | |||
} | |||
} | |||
public static void WriteLine(string text, int offset, ConsoleColor? foreground) | |||
{ | |||
foreach (var line in text.SplitByLine()) | |||
{ | |||
Console.Write(new string(' ', offset)); | |||
ConsoleUtils.SetColor(foreground); | |||
Console.WriteLine(line); | |||
ConsoleUtils.ResetColor(); | |||
} | |||
} | |||
public static void WriteLine(string text, int offset, ConsoleColor? foreground, ConsoleColor? background) | |||
{ | |||
foreach (var line in text.SplitByLine()) | |||
{ | |||
Console.Write(new string(' ', offset)); | |||
ConsoleUtils.SetColor(foreground, background); | |||
Console.WriteLine(line); | |||
ConsoleUtils.ResetColor(); | |||
} | |||
} | |||
public static void Write(string text, ConsoleColor? foreground) | |||
{ | |||
foreach (var line in text.SplitByLine()) | |||
{ | |||
ConsoleUtils.SetColor(foreground); | |||
Console.Write(line); | |||
ConsoleUtils.ResetColor(); | |||
} | |||
} | |||
public static void Write(string text, ConsoleColor? foreground, ConsoleColor? background) | |||
{ | |||
foreach (var line in text.SplitByLine()) | |||
{ | |||
ConsoleUtils.SetColor(foreground); | |||
Console.Write(line); | |||
ConsoleUtils.ResetColor(); | |||
} | |||
} | |||
public static void Write(string text, int offset) | |||
{ | |||
foreach (var line in text.SplitByLine()) | |||
{ | |||
Console.Write(line.Insert(0, new string(' ', offset))); | |||
} | |||
} | |||
public static void Write(string text, int offset, ConsoleColor? foreground) | |||
{ | |||
foreach (var line in text.SplitByLine()) | |||
{ | |||
Console.Write(new string(' ', offset)); | |||
ConsoleUtils.SetColor(foreground); | |||
Console.Write(line); | |||
ConsoleUtils.ResetColor(); | |||
} | |||
} | |||
public static void Write(string text, int offset, ConsoleColor? foreground, ConsoleColor? background) | |||
{ | |||
foreach (var line in text.SplitByLine()) | |||
{ | |||
Console.Write(new string(' ', offset)); | |||
ConsoleUtils.SetColor(foreground, background); | |||
Console.Write(line); | |||
ConsoleUtils.ResetColor(); | |||
} | |||
} | |||
} | |||
} |
@ -0,0 +1,88 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
namespace Ameliorated.ConsoleUtils | |||
{ | |||
public static class Extensions | |||
{ | |||
public static bool IsEven(this int number) | |||
{ | |||
return number % 2 == 0; | |||
} | |||
/// <summary> | |||
/// Checks if number is divisble by a divisor. | |||
/// <param name="divisor">Divisor.</param> | |||
/// <param name="returnFalseOnZeroOrNegative">Indicates whether to return false on numbers that are zero or below. Default is true.</param> | |||
/// </summary> | |||
public static bool IsDivisibleBy(this int number, int divisor, bool returnFalseOnZeroOrNegative = true) | |||
{ | |||
if (returnFalseOnZeroOrNegative && number <= 0) return false; | |||
return number % divisor == 0; | |||
} | |||
public static int RoundToEven(this double number) | |||
{ | |||
var rounded = (int)Math.Round(number); | |||
if (!rounded.IsEven()) return rounded - 1; | |||
return rounded; | |||
} | |||
public static int RoundToEven(this int number) | |||
{ | |||
if (!number.IsEven()) return number - 1; | |||
return number; | |||
} | |||
public static int RoundToOdd(this double number) | |||
{ | |||
if (!((int)Math.Ceiling(number)).IsEven()) return (int)Math.Ceiling(number); | |||
if (!((int)Math.Floor(number)).IsEven()) return (int)Math.Floor(number); | |||
return (int)Math.Truncate(number) - 1; | |||
} | |||
public static int RoundToOdd(this int number) | |||
{ | |||
if (!number.IsEven()) return number - 1; | |||
return number; | |||
} | |||
public static string[] SplitByLine(this string text, StringSplitOptions options = StringSplitOptions.None) | |||
{ | |||
return text.Split(new[] | |||
{ "\r\n", "\n" }, options); | |||
} | |||
public static string LastLine(this string text, StringSplitOptions options = StringSplitOptions.None) | |||
{ | |||
return text.SplitByLine().Last(); | |||
} | |||
public static void ReplaceItem(this List<Menu.MenuItem> list, Menu.MenuItem oldItem, Menu.MenuItem newItem) | |||
{ | |||
var index = list.IndexOf(oldItem); | |||
if (index == -1) throw new ArgumentException("Could not find item index."); | |||
list.RemoveAt(index); | |||
list.Insert(index, newItem); | |||
} | |||
public static Menu.MenuItem Clone(this Menu.MenuItem item) | |||
{ | |||
return new Menu.MenuItem(item.PrimaryText, item.ReturnValue) | |||
{ | |||
AddBetweenSpace = item.AddBetweenSpace, | |||
IsEnabled = item.IsEnabled, | |||
IsNextButton = item.IsNextButton, | |||
IsPreviousButton = item.IsPreviousButton, | |||
IsStatic = item.IsStatic, | |||
PrimaryTextBackground = item.PrimaryTextBackground, | |||
PrimaryTextForeground = item.PrimaryTextForeground, | |||
SecondaryText = item.SecondaryText, | |||
SecondaryTextBackground = item.SecondaryTextBackground, | |||
SecondaryTextForeground = item.SecondaryTextForeground, | |||
StretchSelection = item.StretchSelection, | |||
}; | |||
} | |||
} | |||
} |
@ -0,0 +1,74 @@ | |||
using System; | |||
using System.Diagnostics; | |||
using System.Runtime.InteropServices; | |||
namespace Ameliorated.ConsoleUtils | |||
{ | |||
public static class ParentProcess | |||
{ | |||
private static readonly uint TH32CS_SNAPPROCESS = 2; | |||
public static string ProcessName = Get().ProcessName; | |||
public static Process Get() | |||
{ | |||
try | |||
{ | |||
var iParentPid = 0; | |||
var iCurrentPid = Process.GetCurrentProcess().Id; | |||
var oHnd = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); | |||
if (oHnd == IntPtr.Zero) | |||
return null; | |||
var oProcInfo = new PROCESSENTRY32(); | |||
oProcInfo.dwSize = | |||
(uint)Marshal.SizeOf(typeof(PROCESSENTRY32)); | |||
if (Process32First(oHnd, ref oProcInfo) == false) | |||
return null; | |||
do | |||
{ | |||
if (iCurrentPid == oProcInfo.th32ProcessID) | |||
iParentPid = (int)oProcInfo.th32ParentProcessID; | |||
} while (iParentPid == 0 && Process32Next(oHnd, ref oProcInfo)); | |||
if (iParentPid > 0) | |||
return Process.GetProcessById(iParentPid); | |||
return null; | |||
} catch (Exception e) | |||
{ | |||
return null; | |||
} | |||
} | |||
[DllImport("kernel32.dll", SetLastError = true)] | |||
private static extern IntPtr CreateToolhelp32Snapshot(uint dwFlags, uint th32ProcessID); | |||
[DllImport("kernel32.dll")] | |||
private static extern bool Process32First(IntPtr hSnapshot, ref PROCESSENTRY32 lppe); | |||
[DllImport("kernel32.dll")] | |||
private static extern bool Process32Next(IntPtr hSnapshot, ref PROCESSENTRY32 lppe); | |||
[StructLayout(LayoutKind.Sequential)] | |||
public struct PROCESSENTRY32 | |||
{ | |||
public uint dwSize; | |||
public uint cntUsage; | |||
public uint th32ProcessID; | |||
public IntPtr th32DefaultHeapID; | |||
public uint th32ModuleID; | |||
public uint cntThreads; | |||
public uint th32ParentProcessID; | |||
public int pcPriClassBase; | |||
public uint dwFlags; | |||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)] | |||
public string szExeFile; | |||
} | |||
} | |||
} |
@ -0,0 +1,6 @@ | |||
namespace Ameliorated.ConsoleUtils | |||
{ | |||
public class Payload | |||
{ | |||
} | |||
} |
@ -0,0 +1,10 @@ | |||
<?xml version="1.0" encoding="utf-8"?><configuration> | |||
<runtime> | |||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> | |||
<dependentAssembly> | |||
<assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> | |||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" /> | |||
</dependentAssembly> | |||
</assemblyBinding> | |||
</runtime> | |||
</configuration> |
@ -0,0 +1,342 @@ | |||
using System; | |||
using System.Diagnostics; | |||
using System.IO; | |||
using System.Linq; | |||
using System.Management; | |||
using System.Net.Http; | |||
using System.ServiceProcess; | |||
using System.Threading; | |||
using amecs.Actions; | |||
using Ameliorated.ConsoleUtils; | |||
namespace amecs.Extra | |||
{ | |||
public static partial class Extra | |||
{ | |||
public static bool ShowMenu() | |||
{ | |||
while (true) | |||
{ | |||
Program.Frame.Clear(); | |||
bool hibernation = new Reg.Value() | |||
{ | |||
KeyName = @"HKLM\SYSTEM\CurrentControlSet\Control\Power", | |||
ValueName = "HibernateEnabled", | |||
Data = 1, | |||
}.IsEqual() | |||
&& | |||
new Reg.Value() | |||
{ | |||
KeyName = @"HKLM\SYSTEM\CurrentControlSet\Control\Power", | |||
ValueName = "HiberFileType", | |||
Data = 2, | |||
}.IsEqual(); | |||
bool notifications = new Reg.Value() | |||
{ | |||
KeyName = "HKU\\" + Globals.UserSID + @"\SOFTWARE\Microsoft\Windows\CurrentVersion\PushNotifications", | |||
ValueName = "ToastEnabled", | |||
Data = 1, | |||
}.IsEqual(); | |||
bool notificationCenter = !new Reg.Value() | |||
{ | |||
KeyName = "HKU\\" + Globals.UserSID + @"\SOFTWARE\Policies\Microsoft\Windows\Explorer", | |||
ValueName = "DisableNotificationCenter", | |||
Data = 1, | |||
}.IsEqual(); | |||
bool vbsEnabled = new Reg.Value() | |||
{ | |||
KeyName = @"HKCR\.vbs", | |||
ValueName = "", | |||
Data = "VBSFile", | |||
Type = Reg.RegistryValueType.REG_SZ | |||
}.IsEqual(); | |||
bool ncsiEnabled = new Reg.Value() | |||
{ | |||
KeyName = @"HKLM\SYSTEM\CurrentControlSet\Services\NlaSvc\Parameters\Internet", | |||
ValueName = "EnableActiveProbing", | |||
Data = 1, | |||
}.IsEqual(); | |||
var mainMenu = new Ameliorated.ConsoleUtils.Menu() | |||
{ | |||
Choices = | |||
{ | |||
new Menu.MenuItem("Manage WSL", null) {IsEnabled = false, SecondaryText = "[Not Supported]", PrimaryTextForeground = ConsoleColor.DarkGray, SecondaryTextForeground = ConsoleColor.Red}, | |||
hibernation ? | |||
new Menu.MenuItem("Disable Hibernation", new Func<bool>(DisableHibernation)) : | |||
new Menu.MenuItem("Enable Hibernation", new Func<bool>(EnableHibernation)), | |||
notificationCenter ? | |||
new Menu.MenuItem("Disable Notification Center", new Func<bool>(DisableNotifCen)) : | |||
new Menu.MenuItem("Enable Notification Center", new Func<bool>(EnableNotifCen)), | |||
notifications ? | |||
new Menu.MenuItem("Disable Desktop Notifications", new Func<bool>(DisableNotifications)) : | |||
new Menu.MenuItem("Enable Desktop Notifications", new Func<bool>(EnableNotifications)), | |||
GetWSHItem(), | |||
vbsEnabled ? | |||
new Menu.MenuItem("Disable Visual Basic Script [VBS] (Legacy)", new Func<bool>(DisableVBS)) : | |||
new Menu.MenuItem("Enable Visual Basic Script [VBS] (Legacy)", new Func<bool>(EnableVBS)), | |||
ncsiEnabled ? | |||
new Menu.MenuItem("Disable NCSI Active Probing (Legacy)", new Func<bool>(DisableNCSI)) : | |||
new Menu.MenuItem("Enable NCSI Active Probing (Legacy)", new Func<bool>(EnableNCSI)), | |||
GetNVCPItem(), | |||
Menu.MenuItem.Blank, | |||
new Menu.MenuItem("Return to Menu", null), | |||
new Menu.MenuItem("Exit", new Func<bool>(Globals.Exit)) | |||
}, | |||
SelectionForeground = ConsoleColor.Green | |||
}; | |||
Func<bool> result; | |||
try | |||
{ | |||
mainMenu.Write(); | |||
var res = mainMenu.Load(); | |||
if (res == null) | |||
return true; | |||
result = (Func<bool>)res; | |||
} catch (Exception e) | |||
{ | |||
Console.WriteLine(e); | |||
Console.ReadLine(); | |||
return false; | |||
} | |||
try | |||
{ | |||
result.Invoke(); | |||
} catch (Exception e) | |||
{ | |||
ConsoleTUI.ShowErrorBox("Error while running an action: " + e.ToString(), null); | |||
} | |||
} | |||
} | |||
private static Menu.MenuItem GetNVCPItem() | |||
{ | |||
if (File.Exists(Environment.ExpandEnvironmentVariables(@"%PROGRAMFILES%\NVIDIA Control Panel\nvcplui.exe"))) | |||
return new Menu.MenuItem("Uninstall NVIDIA Control Panel", new Func<bool>(NVCP.Uninstall)); | |||
if (Globals.WinVer > 19043) | |||
return new Menu.MenuItem("Install NVIDIA Control Panel", null) {IsEnabled = false, PrimaryTextForeground = ConsoleColor.DarkGray, SecondaryTextForeground = ConsoleColor.Red, SecondaryText = "[Not Supported]"}; | |||
try | |||
{ | |||
ManagementObjectSearcher searcher = | |||
new ManagementObjectSearcher("SELECT NAME FROM Win32_VideoController"); | |||
bool foundGPU = false; | |||
foreach (ManagementObject mo in searcher.Get()) | |||
{ | |||
PropertyData Name = mo.Properties["Name"]; | |||
if (Name.Value != null) | |||
{ | |||
var name = ((string)Name.Value); | |||
if (name.Contains("NVIDIA") || name.Contains("GeForce") || name.Contains("GTX") || name.Contains("RTX")) | |||
{ | |||
foundGPU = true; | |||
break; | |||
} | |||
} | |||
} | |||
if (!foundGPU) | |||
{ | |||
return new Menu.MenuItem("Install NVIDIA Control Panel", null) {IsEnabled = false, PrimaryTextForeground = ConsoleColor.DarkGray, SecondaryTextForeground = ConsoleColor.Red, SecondaryText = "[No NVIDIA GPU]"}; | |||
} | |||
} catch {} | |||
try | |||
{ | |||
if (!ServiceController.GetServices().Any(x => x.ServiceName.Equals("NVDisplay.ContainerLocalSystem"))) | |||
return new Menu.MenuItem("Install NVIDIA Control Panel", null) {IsEnabled = false, PrimaryTextForeground = ConsoleColor.DarkGray, SecondaryTextForeground = ConsoleColor.Red, SecondaryText = "[No NVIDIA Driver]"}; | |||
} catch { } | |||
try | |||
{ | |||
var dir = Directory.EnumerateDirectories(Environment.ExpandEnvironmentVariables(@"%PROGRAMFILES%\WindowsApps")).First(x => x.Contains("NVIDIACorp.NVIDIAControlPanel")); | |||
if (File.Exists(Path.Combine(dir, "nvcplui.exe"))) | |||
return new Menu.MenuItem("Install NVIDIA Control Panel", new Func<bool>(() => NVCP.Install(dir))); | |||
} catch { } | |||
if (!amecs.IsInternetAvailable()) | |||
return new Menu.MenuItem("Install NVIDIA Control Panel", null) {IsEnabled = false, PrimaryTextForeground = ConsoleColor.DarkGray, SecondaryTextForeground = ConsoleColor.Red, SecondaryText = "[Internet Required]"}; | |||
if (!amecs.InternetCheckConnection("https://store.rg-adguard.net", 1, 0)) | |||
return new Menu.MenuItem("Install NVIDIA Control Panel", null) {IsEnabled = false, PrimaryTextForeground = ConsoleColor.DarkGray, SecondaryTextForeground = ConsoleColor.Red, SecondaryText = "[Server Unavailable]"}; | |||
if (!amecs.InternetCheckConnection("https://git.ameliorated.info/", 1, 0)) | |||
return new Menu.MenuItem("Install NVIDIA Control Panel", null) {IsEnabled = false, PrimaryTextForeground = ConsoleColor.DarkGray, SecondaryTextForeground = ConsoleColor.Red, SecondaryText = "[Git Unavailable]"}; | |||
try | |||
{ | |||
using (HttpClient client = new HttpClient()) | |||
{ | |||
using (HttpResponseMessage response = client.GetAsync("https://store.rg-adguard.net/").Result) | |||
{ | |||
using (HttpContent content = response.Content) | |||
{ | |||
string result = content.ReadAsStringAsync().Result; | |||
if (result.Contains("Cloudflare Ray ID")) | |||
return new Menu.MenuItem("Install NVIDIA Control Panel", null) {IsEnabled = false, PrimaryTextForeground = ConsoleColor.DarkGray, SecondaryTextForeground = ConsoleColor.Red, SecondaryText = "[Server Unavailable]"}; | |||
} | |||
} | |||
} | |||
} catch { } | |||
return new Menu.MenuItem("Install NVIDIA Control Panel", new Func<bool>(NVCP.InstallFromNetwork)); | |||
} | |||
private static Menu.MenuItem GetWSHItem() | |||
{ | |||
if (new Reg.Value() | |||
{ | |||
KeyName = Globals.UserHive + @"\SOFTWARE\Microsoft\Windows Script Host\Settings", | |||
ValueName = "Enabled", | |||
Data = 1, | |||
}.IsEqual()) | |||
return new Menu.MenuItem("Disable Windows Script Host [WSH] (Legacy)", new Func<bool>(WSH.Disable)); | |||
if (new Reg.Value() | |||
{ | |||
KeyName = Globals.UserHive + @"\SOFTWARE\Microsoft\Windows Script Host\Settings", | |||
ValueName = "Enabled", | |||
Data = 0, | |||
}.IsEqual()) | |||
return new Menu.MenuItem("Enable Windows Script Host [WSH] (Legacy)", new Func<bool>(WSH.Enable)); | |||
return new Reg.Value() | |||
{ | |||
KeyName = @"HKLM\SOFTWARE\Microsoft\Windows Script Host\Settings", | |||
ValueName = "Enabled", | |||
Data = 0, | |||
}.IsEqual() ? new Menu.MenuItem("Disable Windows Script Host [WSH] (Legacy)", new Func<bool>(WSH.Enable)) : new Menu.MenuItem("Disable Windows Script Host [WSH] (Legacy)", new Func<bool>(WSH.Disable)); | |||
} | |||
private static bool EnableHibernation() =>amecs.RunBasicAction("Enabling hibernation","Enabled hibernation successfully",() => | |||
{ | |||
Thread.Sleep(1600); | |||
Process proc = new Process(); | |||
proc.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; | |||
proc.StartInfo.FileName = "powercfg.exe"; | |||
proc.StartInfo.Arguments = "/HIBERNATE /TYPE FULL"; | |||
proc.Start(); | |||
proc.WaitForExit(20000); | |||
if (proc.ExitCode != 0) | |||
throw new Exception("powercfg exited with a non-zero exitcode.\r\nHibernation may not be supported by your hardware."); | |||
}); | |||
private static bool DisableHibernation() =>amecs.RunBasicAction("Disabling hibernation","Disabled hibernation successfully",() => | |||
{ | |||
Thread.Sleep(1600); | |||
Process proc = new Process(); | |||
proc.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; | |||
proc.StartInfo.FileName = "powercfg.exe"; | |||
proc.StartInfo.Arguments = "/HIBERNATE OFF"; | |||
proc.Start(); | |||
proc.WaitForExit(20000); | |||
if (proc.ExitCode != 0) | |||
throw new Exception("powercfg exited with a non-zero exitcode."); | |||
Thread.Sleep(1600); | |||
}); | |||
private static bool EnableNotifCen() =>amecs.RunBasicAction("Enabling Notification Center","Notification Center enabled successfully",() => | |||
{ | |||
new Reg.Value() | |||
{ | |||
KeyName = "HKU\\" + Globals.UserSID + @"\SOFTWARE\Policies\Microsoft\Windows\Explorer", | |||
ValueName = "DisableNotificationCenter", | |||
Operation = Reg.RegistryValueOperation.Delete | |||
}.Apply(); | |||
Thread.Sleep(1600); | |||
}, true); | |||
private static bool DisableNotifCen() =>amecs.RunBasicAction("Disabling Notification Center","Notification Center disabled successfully",() => | |||
{ | |||
new Reg.Value() | |||
{ | |||
KeyName = "HKU\\" + Globals.UserSID + @"\SOFTWARE\Policies\Microsoft\Windows\Explorer", | |||
ValueName = "DisableNotificationCenter", | |||
Data = 1, | |||
}.Apply(); | |||
Thread.Sleep(1600); | |||
}, true); | |||
private static bool EnableNotifications() =>amecs.RunBasicAction("Enabling desktop notifications","Enabled desktop notifications successfully",() => | |||
{ | |||
new Reg.Value() | |||
{ | |||
KeyName = "HKU\\" + Globals.UserSID + @"\SOFTWARE\Microsoft\Windows\CurrentVersion\PushNotifications", | |||
ValueName = "ToastEnabled", | |||
Data = 1, | |||
}.Apply(); | |||
Thread.Sleep(1600); | |||
}, true); | |||
private static bool DisableNotifications() =>amecs.RunBasicAction("Disabling desktop notifications","Disabled desktop notifications successfully",() => | |||
{ | |||
new Reg.Value() | |||
{ | |||
KeyName = "HKU\\" + Globals.UserSID + @"\SOFTWARE\Microsoft\Windows\CurrentVersion\PushNotifications", | |||
ValueName = "ToastEnabled", | |||
Data = 0, | |||
}.Apply(); | |||
Thread.Sleep(1600); | |||
}, true); | |||
private static bool EnableVBS() =>amecs.RunBasicAction("Enabling Visual Basic Script","Enabled VBS successfully",() => | |||
{ | |||
new Reg.Value() | |||
{ | |||
KeyName = @"HKCR\.vbs", | |||
ValueName = "", | |||
Data = "VBSFile", | |||
Type = Reg.RegistryValueType.REG_SZ | |||
}.Apply(); | |||
Thread.Sleep(1600); | |||
}); | |||
private static bool DisableVBS() =>amecs.RunBasicAction("Disabling Visual Basic Script","Disabled VBS successfully",() => | |||
{ | |||
new Reg.Value() | |||
{ | |||
KeyName = @"HKCR\.vbs", | |||
ValueName = "", | |||
Data = "", | |||
Type = Reg.RegistryValueType.REG_SZ | |||
}.Apply(); | |||
Thread.Sleep(1600); | |||
}); | |||
private static bool EnableNCSI() =>amecs.RunBasicAction("Enabling NCSI Active Probing","Enabled NCSI Active Probing successfully",() => | |||
{ | |||
new Reg.Value() | |||
{ | |||
KeyName = @"HKLM\SYSTEM\CurrentControlSet\Services\NlaSvc\Parameters\Internet", | |||
ValueName = "EnableActiveProbing", | |||
Data = 1, | |||
}.Apply(); | |||
Thread.Sleep(1600); | |||
}, false, true); | |||
private static bool DisableNCSI() =>amecs.RunBasicAction("Disabling NCSI Active Probing","Disabled NCSI Active Probing successfully",() => | |||
{ | |||
new Reg.Value() | |||
{ | |||
KeyName = @"HKLM\SYSTEM\CurrentControlSet\Services\NlaSvc\Parameters\Internet", | |||
ValueName = "EnableActiveProbing", | |||
Data = 0, | |||
}.Apply(); | |||
Thread.Sleep(1600); | |||
}, false, true); | |||
} | |||
} |
@ -0,0 +1,281 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Diagnostics; | |||
using System.IO; | |||
using System.IO.Compression; | |||
using System.Linq; | |||
using System.Net; | |||
using System.Net.Http; | |||
using System.Runtime.InteropServices; | |||
using System.Runtime.InteropServices.ComTypes; | |||
using System.Security.AccessControl; | |||
using System.ServiceProcess; | |||
using System.Text; | |||
using System.Text.RegularExpressions; | |||
using System.Threading; | |||
using amecs.Actions; | |||
using Ameliorated.ConsoleUtils; | |||
using IWshRuntimeLibrary; | |||
using File = System.IO.File; | |||
namespace amecs.Extra | |||
{ | |||
public class NVCP | |||
{ | |||
private static readonly string DestinationDir = Environment.ExpandEnvironmentVariables(@"%PROGRAMFILES%\NVIDIA Control Panel"); | |||
public static bool Install(string NVCP) => amecs.RunBasicAction("Installing NVIDIA Control Panel", "NVIDIA Control Panel installed successfully", () => | |||
{ | |||
Thread.Sleep(4000); | |||
try | |||
{ | |||
foreach (var proc in Process.GetProcessesByName("nvcplui")) | |||
proc.Kill(); | |||
} catch | |||
{ | |||
} | |||
if (Directory.Exists(DestinationDir)) | |||
Directory.Delete(DestinationDir, true); | |||
Directory.Move(NVCP, DestinationDir); | |||
var di = new DirectoryInfo(DestinationDir); | |||
var sec = di.GetAccessControl(); | |||
sec.AddAccessRule(new FileSystemAccessRule("Administrators", FileSystemRights.FullControl, InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit, PropagationFlags.None, AccessControlType.Allow)); | |||
sec.AddAccessRule(new FileSystemAccessRule("Users", FileSystemRights.ReadAndExecute, InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit, PropagationFlags.None, AccessControlType.Allow)); | |||
di.SetAccessControl(sec); | |||
Config(); | |||
}); | |||
public static bool InstallFromNetwork() | |||
{ | |||
try | |||
{ | |||
foreach (var proc in Process.GetProcessesByName("nvcplui")) | |||
proc.Kill(); | |||
} catch | |||
{ | |||
} | |||
if (Directory.Exists(DestinationDir)) | |||
Directory.Delete(DestinationDir, true); | |||
var choice = new ChoicePrompt() {Text = "NVIDIA Control Panel must be downloaded\r\nContinue? (Y/N): "}.Start(); | |||
if (!choice.HasValue || choice == 1) | |||
return false; | |||
string link; | |||
string filter; | |||
string size; | |||
ConsoleTUI.OpenFrame.WriteCentered("\r\nFetching download link"); | |||
try | |||
{ | |||
using (new ConsoleUtils.LoadingIndicator(true)) | |||
{ | |||
using (HttpClient client = new HttpClient()) | |||
{ | |||
using (HttpResponseMessage response = client.GetAsync("https://git.ameliorated.info/Styris/amecs/src/branch/master/links.txt").Result) | |||
{ | |||
using (HttpContent content = response.Content) | |||
{ | |||
string result = content.ReadAsStringAsync().Result; | |||
var line = result.SplitByLine().First(x => x.Contains("NVIDIA-Control-Panel = ")); | |||
var split = line.Split('|'); | |||
link = split[1]; | |||
filter = split[3]; | |||
if (link == "REMOVED") | |||
throw new Exception("Link is no longer available."); | |||
} | |||
} | |||
var values = new Dictionary<string, string> | |||
{ | |||
{ "type", "url" }, | |||
{ "url", link }, | |||
{ "ring", "Retail" } | |||
}; | |||
var request = new FormUrlEncodedContent(values); | |||
using (HttpResponseMessage response = client.PostAsync("https://store.rg-adguard.net/api/GetFiles", request).Result) | |||
{ | |||
using (HttpContent content = response.Content) | |||
{ | |||
string result = content.ReadAsStringAsync().Result; | |||
var regex = new Regex($".*{filter}.*"); | |||
var match = regex.Match(result).Value; | |||
var split = match.Split('"'); | |||
link = split[3]; | |||
size = split[12].Remove(0, 1).Remove(split[12].Length - 11); | |||
if (!size.Contains("MB") && !size.Contains("KB") && !size.Contains("GB")) | |||
size = "0 MB"; | |||
} | |||
} | |||
} | |||
} | |||
} catch (Exception e) | |||
{ | |||
Console.WriteLine(); | |||
ConsoleTUI.OpenFrame.Close("Could not fetch link: " + e.Message, ConsoleColor.Red, Console.BackgroundColor, new ChoicePrompt() {AnyKey = true, Text = "Press any key to return to the Menu: "}); | |||
return false; | |||
} | |||
var temp = Environment.ExpandEnvironmentVariables(@"%TEMP%\[amecs]-NVCP-" + new Random().Next(0, 9999) + ".zip"); | |||
try | |||
{ | |||
ConsoleTUI.OpenFrame.WriteCenteredLine($"\r\nDownloading NVIDIA Control Panel ({size})"); | |||
using (WebClient wc = new WebClient()) | |||
{ | |||
var stdout = GetStdHandle(-11); | |||
var maxHashTags = (ConsoleTUI.OpenFrame.DisplayWidth - 5); | |||
wc.DownloadProgressChanged += delegate(object sender, DownloadProgressChangedEventArgs e) | |||
{ | |||
var currentHashTags = (int)Math.Ceiling(Math.Min(((double)e.ProgressPercentage / 100) * maxHashTags, maxHashTags)); | |||
var spaces = maxHashTags - currentHashTags + (4 - e.ProgressPercentage.ToString().Length); | |||
var sb = new StringBuilder(new string('#', currentHashTags) + new string(' ', spaces) + e.ProgressPercentage + "%"); | |||
uint throwaway; | |||
WriteConsoleOutputCharacter(stdout, sb, (uint)sb.Length, new COORD((short)ConsoleTUI.OpenFrame.DisplayOffset, (short)Console.CursorTop), out throwaway); | |||
}; | |||
var task = wc.DownloadFileTaskAsync(new Uri(link), temp); | |||
task.Wait(); | |||
Thread.Sleep(100); | |||
var sb = new StringBuilder(new string('#', maxHashTags) + " 100%"); | |||
uint throwaway; | |||
WriteConsoleOutputCharacter(stdout, sb, (uint)sb.Length, new COORD((short)ConsoleTUI.OpenFrame.DisplayOffset, (short)Console.CursorTop), out throwaway); | |||
} | |||
Console.WriteLine(); | |||
ZipFile.ExtractToDirectory(temp, DestinationDir); | |||
if (!File.Exists(Path.Combine(DestinationDir, "nvcplui.exe"))) | |||
{ | |||
try { Directory.Delete(DestinationDir, true);} catch {} | |||
Console.WriteLine(); | |||
ConsoleTUI.OpenFrame.Close("Download is missing critical executable.", ConsoleColor.Red, Console.BackgroundColor, new ChoicePrompt() {AnyKey = true, Text = "Press any key to return to the Menu: "}); | |||
return false; | |||
} | |||
Config(); | |||
} catch (Exception e) | |||
{ | |||
Console.WriteLine(); | |||
ConsoleTUI.OpenFrame.Close("Error: " + e.Message.TrimEnd('\n').TrimEnd('\r'), ConsoleColor.Red, Console.BackgroundColor, new ChoicePrompt() {AnyKey = true, Text = "Press any key to return to the Menu: "}); | |||
return false; | |||
} | |||
Console.WriteLine(); | |||
ConsoleTUI.OpenFrame.Close("NVIDIA Control Panel installed successfully", ConsoleColor.Green, Console.BackgroundColor, new ChoicePrompt() {AnyKey = true, Text = "Press any key to return to the Menu: "}); | |||
return true; | |||
} | |||
public static bool Uninstall() => amecs.RunBasicAction("Uninstalling NVIDIA Control Panel", "NVIDIA Control Panel uninstalled successfully", () => | |||
{ | |||
var linkPath = Environment.ExpandEnvironmentVariables(@"%PROGRAMDATA%\Microsoft\Windows\Start Menu\Programs\NVIDIA Control Panel.lnk"); | |||
if (File.Exists(linkPath)) | |||
File.Delete(linkPath); | |||
Directory.Delete(DestinationDir, true); | |||
Thread.Sleep(2000); | |||
}); | |||
public static void Config() | |||
{ | |||
try | |||
{ | |||
new Reg.Value() { KeyName = @"HKLM\System\CurrentControlSet\Services\nvlddmkm\Global\NVTweak", ValueName = "DisableStoreNvCplNotifications", Type = Reg.RegistryValueType.REG_DWORD, Data = 1 }.Apply(); | |||
} catch (Exception e) | |||
{ | |||
ConsoleTUI.ShowErrorBox("Could not disable NVIDIA Microsoft Store notification: " + e.ToString(), "Error"); | |||
} | |||
var linkPath = Environment.ExpandEnvironmentVariables(@"%PROGRAMDATA%\Microsoft\Windows\Start Menu\Programs\NVIDIA Control Panel.lnk"); | |||
if (File.Exists(linkPath)) | |||
File.Delete(linkPath); | |||
try | |||
{ | |||
IShellLink link = (IShellLink)new ShellLink(); | |||
link.SetDescription("NVIDIA Control Panel"); | |||
link.SetPath(Path.Combine(DestinationDir, "nvcplui.exe")); | |||
IPersistFile file = (IPersistFile)link; | |||
file.Save(linkPath, false); | |||
} catch | |||
{ | |||
WshShell shell = new WshShell(); | |||
IWshShortcut shortcut = (IWshShortcut)shell.CreateShortcut(linkPath); | |||
shortcut.Description = "NVIDIA Control Panel"; | |||
shortcut.TargetPath = Path.Combine(DestinationDir, "nvcplui.exe"); | |||
shortcut.Save(); | |||
} | |||
new Reg.Value() { KeyName = @"HKLM\SYSTEM\CurrentControlSet\Services\NVDisplay.ContainerLocalSystem", ValueName = "Start", Type = Reg.RegistryValueType.REG_DWORD, Data = 2 }.Apply(); | |||
try { ServiceController.GetServices().First(x => x.ServiceName.Equals("NVDisplay.ContainerLocalSystem")).Start(); } catch (Exception e) { } | |||
} | |||
[DllImport("kernel32.dll", SetLastError = true)] | |||
internal static extern bool WriteConsoleOutputCharacter(IntPtr hConsoleOutput, StringBuilder lpCharacter, uint nLength, COORD dwWriteCoord, out uint lpNumberOfCharsWritten); | |||
[DllImport("kernel32.dll", SetLastError = true)] | |||
static extern IntPtr GetStdHandle(int nStdHandle); | |||
[StructLayout(LayoutKind.Sequential)] | |||
public struct COORD | |||
{ | |||
public short X; | |||
public short Y; | |||
public COORD(short X, short Y) | |||
{ | |||
this.X = X; | |||
this.Y = Y; | |||
} | |||
}; | |||
} | |||
[ComImport] | |||
[Guid("00021401-0000-0000-C000-000000000046")] | |||
internal class ShellLink | |||
{ | |||
} | |||
[ComImport] | |||
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] | |||
[Guid("000214F9-0000-0000-C000-000000000046")] | |||
internal interface IShellLink | |||
{ | |||
void GetPath([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszFile, int cchMaxPath, out IntPtr pfd, int fFlags); | |||
void GetIDList(out IntPtr ppidl); | |||
void SetIDList(IntPtr pidl); | |||
void GetDescription([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszName, int cchMaxName); | |||
void SetDescription([MarshalAs(UnmanagedType.LPWStr)] string pszName); | |||
void GetWorkingDirectory([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszDir, int cchMaxPath); | |||
void SetWorkingDirectory([MarshalAs(UnmanagedType.LPWStr)] string pszDir); | |||
void GetArguments([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszArgs, int cchMaxPath); | |||
void SetArguments([MarshalAs(UnmanagedType.LPWStr)] string pszArgs); | |||
void GetHotkey(out short pwHotkey); | |||
void SetHotkey(short wHotkey); | |||
void GetShowCmd(out int piShowCmd); | |||
void SetShowCmd(int iShowCmd); | |||
void GetIconLocation([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszIconPath, int cchIconPath, out int piIcon); | |||
void SetIconLocation([MarshalAs(UnmanagedType.LPWStr)] string pszIconPath, int iIcon); | |||
void SetRelativePath([MarshalAs(UnmanagedType.LPWStr)] string pszPathRel, int dwReserved); | |||
void Resolve(IntPtr hwnd, int fFlags); | |||
void SetPath([MarshalAs(UnmanagedType.LPWStr)] string pszFile); | |||
} | |||
} |
@ -0,0 +1,40 @@ | |||
namespace amecs.Extra | |||
{ | |||
public class WSH | |||
{ | |||
public static bool Enable() => amecs.RunBasicAction("Enabling Windows Script Host", "Enabled WSH successfully", i => | |||
{ | |||
new Reg.Value() | |||
{ | |||
KeyName = Globals.UserHive + @"\SOFTWARE\Microsoft\Windows Script Host\Settings", | |||
ValueName = "Enabled", | |||
Data = 1, | |||
Type = Reg.RegistryValueType.REG_DWORD | |||
}.Apply(); | |||
new Reg.Value() | |||
{ | |||
KeyName = @"HKLM\SOFTWARE\Microsoft\Windows Script Host\Settings", | |||
ValueName = "Enabled", | |||
Data = 1, | |||
Type = Reg.RegistryValueType.REG_DWORD | |||
}.Apply(); | |||
}); | |||
public static bool Disable() => amecs.RunBasicAction("Disabling Windows Script Host", "Disabled WSH successfully", i => | |||
{ | |||
new Reg.Value() | |||
{ | |||
KeyName = Globals.UserHive + @"\SOFTWARE\Microsoft\Windows Script Host\Settings", | |||
ValueName = "Enabled", | |||
Data = 0, | |||
Type = Reg.RegistryValueType.REG_DWORD | |||
}.Apply(); | |||
new Reg.Value() | |||
{ | |||
KeyName = @"HKLM\SOFTWARE\Microsoft\Windows Script Host\Settings", | |||
ValueName = "Enabled", | |||
Data = 0, | |||
Type = Reg.RegistryValueType.REG_DWORD | |||
}.Apply(); | |||
}); | |||
} | |||
} |
@ -0,0 +1,3 @@ | |||
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd"> | |||
<Costura /> | |||
</Weavers> |
@ -0,0 +1,41 @@ | |||
using System; | |||
using System.DirectoryServices.AccountManagement; | |||
using System.Threading.Tasks; | |||
using Ameliorated.ConsoleUtils; | |||
using Microsoft.Win32; | |||
namespace amecs | |||
{ | |||
public static class Globals | |||
{ | |||
public static string Username = null; | |||
public static string UserDomain = null; | |||
public static string UserSID = null; | |||
public static string UserFolder = null; | |||
public static bool UserElevated = false; | |||
public static string UserHive | |||
{ | |||
get | |||
{ | |||
return "HKU\\" + UserSID; | |||
} | |||
} | |||
public static Task UserLoadTask = Task.CompletedTask; | |||
public static ConsoleUtils.LoadingIndicator CurrentIndicator = new ConsoleUtils.LoadingIndicator(); | |||
public static GroupPrincipal Administrators; | |||
public static UserPrincipal User; | |||
public static bool Exit() | |||
{ | |||
ConsoleTUI.Close(); | |||
Environment.Exit(0); | |||
return true; | |||
} | |||
public static readonly int WinVer = int.Parse(Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion").GetValue("CurrentBuildNumber").ToString()); | |||
} | |||
} |
@ -0,0 +1,220 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Diagnostics; | |||
using System.Linq; | |||
using System.Runtime.InteropServices; | |||
using System.Runtime.InteropServices.ComTypes; | |||
namespace amecs.Misc | |||
{ | |||
public class FolderPicker | |||
{ | |||
private readonly List<string> _resultPaths = new List<string>(); | |||
private readonly List<string> _resultNames = new List<string>(); | |||
public IReadOnlyList<string> ResultPaths => _resultPaths; | |||
public IReadOnlyList<string> ResultNames => _resultNames; | |||
public string ResultPath => ResultPaths.FirstOrDefault(); | |||
public string ResultName => ResultNames.FirstOrDefault(); | |||
public virtual string InputPath { get; set; } | |||
public virtual bool ForceFileSystem { get; set; } | |||
public virtual bool Multiselect { get; set; } | |||
public virtual string Title { get; set; } | |||
public virtual string OkButtonLabel { get; set; } | |||
public virtual string FileNameLabel { get; set; } | |||
protected virtual int SetOptions(int options) | |||
{ | |||
if (ForceFileSystem) | |||
{ | |||
options |= (int)FOS.FOS_FORCEFILESYSTEM; | |||
} | |||
if (Multiselect) | |||
{ | |||
options |= (int)FOS.FOS_ALLOWMULTISELECT; | |||
} | |||
return options; | |||
} | |||
// for all .NET | |||
public virtual bool? ShowDialog(IntPtr owner, bool throwOnError = false) | |||
{ | |||
var dialog = (IFileOpenDialog)new FileOpenDialog(); | |||
if (!string.IsNullOrEmpty(InputPath)) | |||
{ | |||
if (CheckHr(SHCreateItemFromParsingName(InputPath, null, typeof(IShellItem).GUID, out var item), throwOnError) != 0) | |||
return null; | |||
dialog.SetFolder(item); | |||
} | |||
var options = FOS.FOS_PICKFOLDERS; | |||
options = (FOS)SetOptions((int)options); | |||
dialog.SetOptions(options); | |||
if (Title != null) | |||
{ | |||
dialog.SetTitle(Title); | |||
} | |||
if (OkButtonLabel != null) | |||
{ | |||
dialog.SetOkButtonLabel(OkButtonLabel); | |||
} | |||
if (FileNameLabel != null) | |||
{ | |||
dialog.SetFileName(FileNameLabel); | |||
} | |||
if (owner == IntPtr.Zero) | |||
{ | |||
owner = Process.GetCurrentProcess().MainWindowHandle; | |||
if (owner == IntPtr.Zero) | |||
{ | |||
owner = GetDesktopWindow(); | |||
} | |||
} | |||
var hr = dialog.Show(owner); | |||
if (hr == ERROR_CANCELLED) | |||
return null; | |||
if (CheckHr(hr, throwOnError) != 0) | |||
return null; | |||
if (CheckHr(dialog.GetResults(out var items), throwOnError) != 0) | |||
return null; | |||
items.GetCount(out var count); | |||
for (var i = 0; i < count; i++) | |||
{ | |||
items.GetItemAt(i, out var item); | |||
CheckHr(item.GetDisplayName(SIGDN.SIGDN_DESKTOPABSOLUTEPARSING, out var path), throwOnError); | |||
CheckHr(item.GetDisplayName(SIGDN.SIGDN_DESKTOPABSOLUTEEDITING, out var name), throwOnError); | |||
if (path != null || name != null) | |||
{ | |||
_resultPaths.Add(path); | |||
_resultNames.Add(name); | |||
} | |||
} | |||
return true; | |||
} | |||
private static int CheckHr(int hr, bool throwOnError) | |||
{ | |||
if (hr != 0 && throwOnError) Marshal.ThrowExceptionForHR(hr); | |||
return hr; | |||
} | |||
[DllImport("shell32")] | |||
private static extern int SHCreateItemFromParsingName([MarshalAs(UnmanagedType.LPWStr)] string pszPath, IBindCtx pbc, [MarshalAs(UnmanagedType.LPStruct)] Guid riid, out IShellItem ppv); | |||
[DllImport("user32")] | |||
private static extern IntPtr GetDesktopWindow(); | |||
#pragma warning disable IDE1006 // Naming Styles | |||
private const int ERROR_CANCELLED = unchecked((int)0x800704C7); | |||
#pragma warning restore IDE1006 // Naming Styles | |||
[ComImport, Guid("DC1C5A9C-E88A-4dde-A5A1-60F82A20AEF7")] // CLSID_FileOpenDialog | |||
private class FileOpenDialog { } | |||
[ComImport, Guid("d57c7288-d4ad-4768-be02-9d969532d960"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] | |||
private interface IFileOpenDialog | |||
{ | |||
[PreserveSig] int Show(IntPtr parent); // IModalWindow | |||
[PreserveSig] int SetFileTypes(); // not fully defined | |||
[PreserveSig] int SetFileTypeIndex(int iFileType); | |||
[PreserveSig] int GetFileTypeIndex(out int piFileType); | |||
[PreserveSig] int Advise(); // not fully defined | |||
[PreserveSig] int Unadvise(); | |||
[PreserveSig] int SetOptions(FOS fos); | |||
[PreserveSig] int GetOptions(out FOS pfos); | |||
[PreserveSig] int SetDefaultFolder(IShellItem psi); | |||
[PreserveSig] int SetFolder(IShellItem psi); | |||
[PreserveSig] int GetFolder(out IShellItem ppsi); | |||
[PreserveSig] int GetCurrentSelection(out IShellItem ppsi); | |||
[PreserveSig] int SetFileName([MarshalAs(UnmanagedType.LPWStr)] string pszName); | |||
[PreserveSig] int GetFileName([MarshalAs(UnmanagedType.LPWStr)] out string pszName); | |||
[PreserveSig] int SetTitle([MarshalAs(UnmanagedType.LPWStr)] string pszTitle); | |||
[PreserveSig] int SetOkButtonLabel([MarshalAs(UnmanagedType.LPWStr)] string pszText); | |||
[PreserveSig] int SetFileNameLabel([MarshalAs(UnmanagedType.LPWStr)] string pszLabel); | |||
[PreserveSig] int GetResult(out IShellItem ppsi); | |||
[PreserveSig] int AddPlace(IShellItem psi, int alignment); | |||
[PreserveSig] int SetDefaultExtension([MarshalAs(UnmanagedType.LPWStr)] string pszDefaultExtension); | |||
[PreserveSig] int Close(int hr); | |||
[PreserveSig] int SetClientGuid(); // not fully defined | |||
[PreserveSig] int ClearClientData(); | |||
[PreserveSig] int SetFilter([MarshalAs(UnmanagedType.IUnknown)] object pFilter); | |||
[PreserveSig] int GetResults(out IShellItemArray ppenum); | |||
[PreserveSig] int GetSelectedItems([MarshalAs(UnmanagedType.IUnknown)] out object ppsai); | |||
} | |||
[ComImport, Guid("43826D1E-E718-42EE-BC55-A1E261C37BFE"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] | |||
private interface IShellItem | |||
{ | |||
[PreserveSig] int BindToHandler(); // not fully defined | |||
[PreserveSig] int GetParent(); // not fully defined | |||
[PreserveSig] int GetDisplayName(SIGDN sigdnName, [MarshalAs(UnmanagedType.LPWStr)] out string ppszName); | |||
[PreserveSig] int GetAttributes(); // not fully defined | |||
[PreserveSig] int Compare(); // not fully defined | |||
} | |||
[ComImport, Guid("b63ea76d-1f85-456f-a19c-48159efa858b"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] | |||
private interface IShellItemArray | |||
{ | |||
[PreserveSig] int BindToHandler(); // not fully defined | |||
[PreserveSig] int GetPropertyStore(); // not fully defined | |||
[PreserveSig] int GetPropertyDescriptionList(); // not fully defined | |||
[PreserveSig] int GetAttributes(); // not fully defined | |||
[PreserveSig] int GetCount(out int pdwNumItems); | |||
[PreserveSig] int GetItemAt(int dwIndex, out IShellItem ppsi); | |||
[PreserveSig] int EnumItems(); // not fully defined | |||
} | |||
#pragma warning disable CA1712 // Do not prefix enum values with type name | |||
private enum SIGDN : uint | |||
{ | |||
SIGDN_DESKTOPABSOLUTEEDITING = 0x8004c000, | |||
SIGDN_DESKTOPABSOLUTEPARSING = 0x80028000, | |||
SIGDN_FILESYSPATH = 0x80058000, | |||
SIGDN_NORMALDISPLAY = 0, | |||
SIGDN_PARENTRELATIVE = 0x80080001, | |||
SIGDN_PARENTRELATIVEEDITING = 0x80031001, | |||
SIGDN_PARENTRELATIVEFORADDRESSBAR = 0x8007c001, | |||
SIGDN_PARENTRELATIVEPARSING = 0x80018001, | |||
SIGDN_URL = 0x80068000 | |||
} | |||
[Flags] | |||
private enum FOS | |||
{ | |||
FOS_OVERWRITEPROMPT = 0x2, | |||
FOS_STRICTFILETYPES = 0x4, | |||
FOS_NOCHANGEDIR = 0x8, | |||
FOS_PICKFOLDERS = 0x20, | |||
FOS_FORCEFILESYSTEM = 0x40, | |||
FOS_ALLNONSTORAGEITEMS = 0x80, | |||
FOS_NOVALIDATE = 0x100, | |||
FOS_ALLOWMULTISELECT = 0x200, | |||
FOS_PATHMUSTEXIST = 0x800, | |||
FOS_FILEMUSTEXIST = 0x1000, | |||
FOS_CREATEPROMPT = 0x2000, | |||
FOS_SHAREAWARE = 0x4000, | |||
FOS_NOREADONLYRETURN = 0x8000, | |||
FOS_NOTESTFILECREATE = 0x10000, | |||
FOS_HIDEMRUPLACES = 0x20000, | |||
FOS_HIDEPINNEDPLACES = 0x40000, | |||
FOS_NODEREFERENCELINKS = 0x100000, | |||
FOS_OKBUTTONNEEDSINTERACTION = 0x200000, | |||
FOS_DONTADDTORECENT = 0x2000000, | |||
FOS_FORCESHOWHIDDEN = 0x10000000, | |||
FOS_DEFAULTNOMINIMODE = 0x20000000, | |||
FOS_FORCEPREVIEWPANEON = 0x40000000, | |||
FOS_SUPPORTSTREAMABLEITEMS = unchecked((int)0x80000000) | |||
} | |||
#pragma warning restore CA1712 // Do not prefix enum values with type name | |||
} | |||
} |
@ -0,0 +1,261 @@ | |||
using System; | |||
using System.Diagnostics; | |||
using System.IO; | |||
using System.Linq; | |||
using System.Security; | |||
using System.Windows.Forms; | |||
using Ameliorated.ConsoleUtils; | |||
using Microsoft.Dism; | |||
// Asks user to select Windows installation media, and mounts it if applicable | |||
// Returns path to where it's mounted | |||
namespace amecs.Misc | |||
{ | |||
public static class SelectWindowsImage | |||
{ | |||
private static string _fileViolationTest; | |||
private static bool CheckFileViolation(string inputFile) | |||
{ | |||
try | |||
{ | |||
_fileViolationTest = inputFile; | |||
} | |||
catch (SecurityException e) | |||
{ | |||
Console.WriteLine(); | |||
ConsoleTUI.OpenFrame.Close("Security exception: " + e.Message, ConsoleColor.Red, Console.BackgroundColor, new ChoicePrompt { AnyKey = true, Text = "Press any key to return to the Menu: " }); | |||
return true; | |||
} | |||
return false; | |||
} | |||
public static string GetWindowsVersion(float majorMinor, int isoBuild) | |||
{ | |||
return (majorMinor, isoBuild) switch | |||
{ | |||
(6, _) => "Windows Vista", | |||
(6.1f, _) => "Windows 7", | |||
(6.2f, _) => "Windows 8", | |||
(6.3f, _) => "Windows 8.1", | |||
(10, var a) when a < 19041 => "Windows 10 (Old)", | |||
(10, var a) when a >= 22000 => "Windows 11", | |||
(10, _) => "Windows 10", | |||
_ => "Unknown" | |||
}; | |||
} | |||
public static bool DismountIso(string imagePath) | |||
{ | |||
var startInfo = new ProcessStartInfo | |||
{ | |||
CreateNoWindow = false, | |||
UseShellExecute = false, | |||
FileName = "PowerShell.exe", | |||
WindowStyle = ProcessWindowStyle.Hidden, | |||
Arguments = $"-NoP -C \"Dismount-DiskImage '{imagePath}'\"", | |||
RedirectStandardOutput = true | |||
}; | |||
var proc = Process.Start(startInfo); | |||
if (proc == null) return false; | |||
proc.WaitForExit(); | |||
return true; | |||
} | |||
private static string _mountedPath; | |||
private static string _isoPath; | |||
private static string _isoWinVer; | |||
private static int _isoBuild; | |||
/// <summary> | |||
/// Asks user to select Windows installation media, mounts it if applicable, and checks its version | |||
/// </summary> | |||
/// <param name="winVersionsMustMatch">If true when ISO and host versions mismatch, prompts user that things can break if they continue</param> | |||
/// <param name="isoBuildMustBeReturned">If true and the ISO build can't be retrieved, prompts a user with an error</param> | |||
public static ( | |||
string MountedPath, string IsoPath, string Winver, int? Build, bool? VersionsMatch | |||
) GetMediaPath(bool winVersionsMustMatch = false, bool isoBuildMustBeReturned = false) | |||
{ | |||
var error = ((string)null, "none", (string)null, (int?)null, (bool?)null); | |||
var choice = | |||
new ChoicePrompt { Text = "To continue, Windows installation media is needed.\r\nDo you have a Windows USB instead of an ISO file? (Y/N): " }.Start(); | |||
if (!choice.HasValue) return error; | |||
// Folder/drive chosen | |||
var usingFolder = choice == 0; | |||
if (usingFolder) | |||
{ | |||
var dlg = new FolderPicker | |||
{ | |||
InputPath = Globals.UserFolder | |||
}; | |||
if (dlg.ShowDialog(IntPtr.Zero).GetValueOrDefault()) | |||
{ | |||
if (CheckFileViolation(dlg.ResultPath)) | |||
return error; | |||
_mountedPath = dlg.ResultPath; | |||
} | |||
else | |||
{ | |||
Console.WriteLine(); | |||
ConsoleTUI.OpenFrame.Close("\r\nYou must select a folder or drive containing Windows installation media.", | |||
new ChoicePrompt { AnyKey = true, Text = "Press any key to return to the Menu: " }); | |||
return error; | |||
} | |||
} | |||
else | |||
{ | |||
// Mounting the ISO | |||
var dialog = new OpenFileDialog(); | |||
dialog.Filter = "ISO Files (*.ISO)| *.ISO"; | |||
dialog.Multiselect = false; | |||
dialog.InitialDirectory = Globals.UserFolder; | |||
var window = new NativeWindow(); | |||
window.AssignHandle(Process.GetCurrentProcess().MainWindowHandle); | |||
if (dialog.ShowDialog(window) == DialogResult.OK) | |||
{ | |||
_isoPath = dialog.FileName; | |||
if (CheckFileViolation(_isoPath)) return error; | |||
Console.WriteLine(); | |||
ConsoleTUI.OpenFrame.WriteCentered("\r\nMounting ISO"); | |||
} | |||
else | |||
{ | |||
Console.WriteLine(); | |||
ConsoleTUI.OpenFrame.Close("\r\nYou must select an ISO.", | |||
new ChoicePrompt { AnyKey = true, Text = "Press any key to return to the Menu: " }); | |||
return error; | |||
} | |||
using (new ConsoleUtils.LoadingIndicator(true)) | |||
{ | |||
var startInfo = new ProcessStartInfo | |||
{ | |||
CreateNoWindow = false, | |||
UseShellExecute = false, | |||
FileName = "PowerShell.exe", | |||
WindowStyle = ProcessWindowStyle.Hidden, | |||
Arguments = $"-NoP -C \"(Mount-DiskImage '{_isoPath}' -PassThru | Get-Volume).DriveLetter + ':\'\"", | |||
RedirectStandardOutput = true | |||
}; | |||
var proc = Process.Start(startInfo); | |||
if (proc == null) return error; | |||
proc.WaitForExit(); | |||
_mountedPath = proc.StandardOutput.ReadLine(); | |||
} | |||
} | |||
// Check WIM version | |||
var wimOrEsdPath = new[] { $@"{_mountedPath}\sources\install.esd", $@"{_mountedPath}\sources\install.wim" }.FirstOrDefault(File.Exists); | |||
if (!string.IsNullOrEmpty(wimOrEsdPath)) | |||
{ | |||
try | |||
{ | |||
DismApi.Initialize(DismLogLevel.LogErrors); | |||
string previousIndexVersion = null; | |||
string isoFullVersion = null; | |||
var multiVersion = false; | |||
var imageInfos = DismApi.GetImageInfo(wimOrEsdPath); | |||
foreach (var imageInfo in imageInfos) | |||
{ | |||
isoFullVersion = imageInfo.ProductVersion.ToString(); | |||
if (isoFullVersion != previousIndexVersion && previousIndexVersion != null) | |||
{ | |||
// If it's multi-version, WinVer will be "Unknown" as well | |||
multiVersion = true; | |||
isoFullVersion = "0.0.0.0"; | |||
break; | |||
} | |||
previousIndexVersion = isoFullVersion; | |||
} | |||
switch (multiVersion) | |||
{ | |||
case true when isoBuildMustBeReturned: | |||
ConsoleTUI.OpenFrame.Close( | |||
"Multiple Windows versions were found in the Windows image, can't determine which Windows build it is. Please use an unmodified Windows ISO.", | |||
ConsoleColor.Red, Console.BackgroundColor, | |||
new ChoicePrompt { AnyKey = true, Text = "Press any key to return to the Menu: " }); | |||
return error; | |||
case true when winVersionsMustMatch: | |||
ConsoleTUI.OpenFrame.Close( | |||
"Multiple Windows versions were found in the Windows image, can't determine which Windows build it is. If your Windows version doesn't match the ISO, there will be problems.", | |||
ConsoleColor.Red, Console.BackgroundColor, | |||
new ChoicePrompt { AnyKey = true, Text = "Press any key to continue anyways: " }); | |||
Program.Frame.Clear(); | |||
ConsoleTUI.OpenFrame.WriteCentered("\r\nContinuing without version check...\r\n"); | |||
break; | |||
} | |||
var buildSplit = isoFullVersion.Split('.'); | |||
_isoBuild = int.Parse(buildSplit[2]); | |||
_isoWinVer = GetWindowsVersion(float.Parse($"{buildSplit[0]}.{buildSplit[1]}"), _isoBuild); | |||
} | |||
catch (Exception e) | |||
{ | |||
Console.WriteLine(); | |||
ConsoleTUI.OpenFrame.Close( | |||
"Error checking ISO version: " + e.Message.TrimEnd('\n').TrimEnd('\r'), | |||
ConsoleColor.Red, Console.BackgroundColor, | |||
new ChoicePrompt { AnyKey = true, Text = "Press any key to return to the Menu: " }); | |||
return error; | |||
} | |||
finally | |||
{ | |||
try | |||
{ | |||
DismApi.Shutdown(); | |||
} | |||
catch | |||
{ | |||
// do nothing | |||
} | |||
} | |||
// Check the current OS version | |||
var hostVersion = Environment.OSVersion.Version; | |||
var hostWinver = GetWindowsVersion(float.Parse($"{hostVersion.Major}.{hostVersion.Minor}"), hostVersion.Build); | |||
// If it all matches & winVersionsMustMatch | |||
if (hostWinver == _isoWinVer) return (_mountedPath, _isoPath, _isoWinVer, _isoBuild, true); | |||
// If ISO version doesn't match host version & winVersionsMustMatch | |||
if (hostWinver != _isoWinVer && winVersionsMustMatch) | |||
{ | |||
if (!string.IsNullOrEmpty(_isoPath)) DismountIso(_isoPath); | |||
ConsoleTUI.OpenFrame.Close( | |||
$"You're on {hostWinver}, but the selected image is {_isoWinVer}. You can only use an ISO that matches your Windows version.", | |||
ConsoleColor.Red, Console.BackgroundColor, | |||
new ChoicePrompt { AnyKey = true, Text = "Press any key to return to the Menu: " }); | |||
return error; | |||
} | |||
// If ISO version doesn't match host version, and winVersionsMustMatch is true | |||
if (hostWinver != _isoWinVer) return (_mountedPath, _isoPath, _isoWinVer, _isoBuild, false); | |||
} | |||
var noWimText = isoBuildMustBeReturned | |||
? "Press any key to return to the Menu" | |||
: "Press any key to continue anyways"; | |||
ConsoleTUI.OpenFrame.Close( | |||
"No Windows installation image was found inside the selected Windows media. No version check can be done, things might break.", | |||
ConsoleColor.Red, Console.BackgroundColor, | |||
new ChoicePrompt { AnyKey = true, Text = $"{noWimText}: " }); | |||
Program.Frame.Clear(); | |||
ConsoleTUI.OpenFrame.WriteCentered("\r\nContinuing without version check\r\n"); | |||
return isoBuildMustBeReturned ? error : (_mountedPath, _isoPath, null, null, null); | |||
} | |||
} | |||
} |
@ -0,0 +1,525 @@ | |||
using System; | |||
using System.Diagnostics; | |||
using System.IO; | |||
using System.Runtime.ConstrainedExecution; | |||
using System.Runtime.InteropServices; | |||
using System.Security; | |||
using System.Security.Principal; | |||
using System.Threading; | |||
using System.Threading.Tasks; | |||
using Microsoft.Win32.SafeHandles; | |||
namespace amecs | |||
{ | |||
[StructLayout(LayoutKind.Sequential)] | |||
public class NSudo | |||
{ | |||
private struct SECURITY_ATTRIBUTES | |||
{ | |||
public int nLength; | |||
public unsafe byte* lpSecurityDescriptor; | |||
public int bInheritHandle; | |||
} | |||
private enum SECURITY_IMPERSONATION_LEVEL | |||
{ | |||
SecurityAnonymous, | |||
SecurityIdentification, | |||
SecurityImpersonation, | |||
SecurityDelegation | |||
} | |||
private enum TOKEN_TYPE { | |||
TokenPrimary = 1, | |||
TokenImpersonation | |||
} | |||
[StructLayout(LayoutKind.Sequential)] | |||
private struct LUID { | |||
public uint LowPart; | |||
public uint HighPart; | |||
} | |||
[StructLayout(LayoutKind.Sequential, Pack = 4)] | |||
private struct LUID_AND_ATTRIBUTES { | |||
public LUID Luid; | |||
public UInt32 Attributes; | |||
} | |||
private struct TOKEN_PRIVILEGES { | |||
public int PrivilegeCount; | |||
[MarshalAs(UnmanagedType.ByValArray, SizeConst=1)] | |||
public LUID_AND_ATTRIBUTES[] Privileges; | |||
} | |||
private static UInt32 MAXIMUM_ALLOWED = (UInt32)TokenAccessLevels.MaximumAllowed; | |||
[DllImport("advapi32.dll", SetLastError=true)] | |||
[return: MarshalAs(UnmanagedType.Bool)] | |||
private static extern bool OpenProcessToken(IntPtr ProcessHandle, | |||
UInt32 DesiredAccess, out IntPtr TokenHandle); | |||
[DllImport("advapi32.dll", CharSet=CharSet.Auto, SetLastError=true)] | |||
private static extern bool DuplicateTokenEx( | |||
IntPtr hExistingToken, | |||
uint dwDesiredAccess, | |||
IntPtr lpTokenAttributes, | |||
SECURITY_IMPERSONATION_LEVEL ImpersonationLevel, | |||
TOKEN_TYPE TokenType, | |||
out IntPtr phNewToken ); | |||
[DllImport("advapi32.dll", CharSet=CharSet.Auto, SetLastError=true)] | |||
private static extern bool DuplicateTokenEx( | |||
IntPtr hExistingToken, | |||
uint dwDesiredAccess, | |||
ref SECURITY_ATTRIBUTES lpTokenAttributes, | |||
SECURITY_IMPERSONATION_LEVEL ImpersonationLevel, | |||
TOKEN_TYPE TokenType, | |||
out IntPtr phNewToken ); | |||
[DllImport("advapi32.dll")] | |||
static extern bool LookupPrivilegeValue(IntPtr lpSystemName, string lpName, | |||
ref LUID lpLuid); | |||
internal const int SE_PRIVILEGE_ENABLED = 0x00000002; | |||
// Use this signature if you do not want the previous state | |||
[DllImport("advapi32.dll", SetLastError=true)] | |||
[return: MarshalAs(UnmanagedType.Bool)] | |||
static extern bool AdjustTokenPrivileges(IntPtr TokenHandle, | |||
[MarshalAs(UnmanagedType.Bool)]bool DisableAllPrivileges, | |||
ref TOKEN_PRIVILEGES NewState, | |||
UInt32 Zero, | |||
IntPtr Null1, | |||
IntPtr Null2); | |||
[System.Runtime.InteropServices.DllImport("advapi32.dll", SetLastError = true)] | |||
private static extern bool SetThreadToken(IntPtr pHandle, | |||
IntPtr hToken); | |||
[DllImport("wtsapi32.dll", SetLastError=true)] | |||
static extern bool WTSQueryUserToken(UInt32 sessionId, out IntPtr Token); | |||
[DllImport("advapi32.dll", SetLastError = true)] | |||
static extern Boolean SetTokenInformation(IntPtr TokenHandle, TOKEN_INFORMATION_CLASS TokenInformationClass, | |||
ref UInt32 TokenInformation, UInt32 TokenInformationLength); | |||
[DllImport("userenv.dll", SetLastError=true)] | |||
static extern bool CreateEnvironmentBlock(out IntPtr lpEnvironment, IntPtr hToken, bool bInherit ); | |||
public static bool GetUserPrivilege(IntPtr Token) | |||
{ | |||
IntPtr NewToken; | |||
DuplicateTokenEx(Token, MAXIMUM_ALLOWED, IntPtr.Zero, SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation, TOKEN_TYPE.TokenImpersonation, out NewToken); | |||
SetThreadToken(IntPtr.Zero, NewToken); | |||
return true; | |||
} | |||
[DllImport("advapi32.dll", SetLastError=true, CharSet=CharSet.Unicode)] | |||
static extern bool CreateProcessAsUser( | |||
IntPtr hToken, | |||
string lpApplicationName, | |||
string lpCommandLine, | |||
ref SECURITY_ATTRIBUTES lpProcessAttributes, | |||
ref SECURITY_ATTRIBUTES lpThreadAttributes, | |||
bool bInheritHandles, | |||
uint dwCreationFlags, | |||
IntPtr lpEnvironment, | |||
string lpCurrentDirectory, | |||
ref STARTUPINFO lpStartupInfo, | |||
out PROCESS_INFORMATION lpProcessInformation); | |||
[Flags] | |||
enum CreationFlags | |||
{ | |||
CREATE_SUSPENDED = 0x00000004, | |||
CREATE_UNICODE_ENVIRONMENT = 0x00000400, | |||
CREATE_NO_WINDOW = 0x08000000, | |||
CREATE_NEW_CONSOLE = 0x00000010 | |||
} | |||
[DllImport("advapi32.dll", SetLastError = true, BestFitMapping = false, ThrowOnUnmappableChar = true)] | |||
[return: MarshalAs(UnmanagedType.Bool)] | |||
internal static extern bool LogonUser( | |||
[MarshalAs(UnmanagedType.LPStr)] string pszUserName, | |||
[MarshalAs(UnmanagedType.LPStr)] string pszDomain, | |||
[MarshalAs(UnmanagedType.LPStr)] string pszPassword, | |||
int dwLogonType, | |||
int dwLogonProvider, | |||
ref IntPtr phToken); | |||
public static int? RunProcessAsUser(IntPtr Token, string Executable, string Arguments, uint timeout = 0xFFFFFFFF) | |||
{ | |||
GetAssignPrivilege(); | |||
GetQuotaPrivilege(); | |||
var startupInfo = new STARTUPINFO(); | |||
startupInfo.cb = Marshal.SizeOf(startupInfo); | |||
startupInfo.dwFlags = 0x00000001; | |||
startupInfo.wShowWindow = 1; | |||
var procAttrs = new SECURITY_ATTRIBUTES(); | |||
var threadAttrs = new SECURITY_ATTRIBUTES(); | |||
procAttrs.nLength = Marshal.SizeOf(procAttrs); | |||
threadAttrs.nLength = Marshal.SizeOf(threadAttrs); | |||
// Log on user temporarily in order to start console process in its security context. | |||
var hUserTokenDuplicate = IntPtr.Zero; | |||
var pEnvironmentBlock = IntPtr.Zero; | |||
DuplicateTokenEx(Token, MAXIMUM_ALLOWED, IntPtr.Zero, SECURITY_IMPERSONATION_LEVEL.SecurityIdentification, TOKEN_TYPE.TokenPrimary, out hUserTokenDuplicate); | |||
CreateEnvironmentBlock(out pEnvironmentBlock, Token, false); | |||
PROCESS_INFORMATION _processInfo; | |||
if (!CreateProcessAsUser(hUserTokenDuplicate, null, String.IsNullOrEmpty(Arguments) ? $"\"{Executable}\"" : $"\"{Executable}\" {Arguments}", | |||
ref procAttrs, ref threadAttrs, false, (uint)CreationFlags.CREATE_NO_WINDOW | | |||
(uint)CreationFlags.CREATE_UNICODE_ENVIRONMENT, | |||
pEnvironmentBlock, null, ref startupInfo, out _processInfo)) return null; | |||
uint exitCode; | |||
WaitForSingleObject(_processInfo.hProcess, timeout); | |||
GetExitCodeProcess(_processInfo.hProcess, out exitCode); | |||
return (int)exitCode; | |||
/* | |||
uint dwCreationFlags = (uint)CreationFlags.CREATE_UNICODE_ENVIRONMENT; | |||
startupInfo.cb = Marshal.SizeOf(startupInfo); | |||
SECURITY_ATTRIBUTES throwaway = new SECURITY_ATTRIBUTES(); | |||
SECURITY_ATTRIBUTES throwaway2 = new SECURITY_ATTRIBUTES(); | |||
Console.WriteLine(Marshal.GetLastWin32Error() + "-3"); | |||
Console.WriteLine(CreateProcessAsUser(hUserToken, String.Empty, "\"C:\\Windows\\notepad.exe\"", ref throwaway, ref throwaway2, false, 0, IntPtr.Zero, String.Empty, ref StartupInfo, out ProcessInfo)); | |||
Console.WriteLine(Marshal.GetLastWin32Error() + "-4"); | |||
return Process.GetProcessById(ProcessInfo.dwProcessId); | |||
*/ | |||
} | |||
[DllImport("kernel32.dll", SetLastError = true)] | |||
[return: MarshalAs(UnmanagedType.Bool)] | |||
static extern bool GetExitCodeProcess(IntPtr hProcess, out uint lpExitCode); | |||
[DllImport("kernel32.dll", SetLastError=true)] | |||
static extern UInt32 WaitForSingleObject(IntPtr hHandle, UInt32 dwMilliseconds); | |||
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] | |||
struct STARTUPINFO | |||
{ | |||
public Int32 cb; | |||
public IntPtr lpReserved; | |||
public IntPtr lpDesktop; | |||
public IntPtr lpTitle; | |||
public Int32 dwX; | |||
public Int32 dwY; | |||
public Int32 dwXSize; | |||
public Int32 dwYSize; | |||
public Int32 dwXCountChars; | |||
public Int32 dwYCountChars; | |||
public Int32 dwFillAttribute; | |||
public Int32 dwFlags; | |||
public Int16 wShowWindow; | |||
public Int16 cbReserved2; | |||
public IntPtr lpReserved2; | |||
public IntPtr hStdInput; | |||
public IntPtr hStdOutput; | |||
public IntPtr hStdError; | |||
} | |||
[StructLayout(LayoutKind.Sequential)] | |||
internal struct PROCESS_INFORMATION | |||
{ | |||
public IntPtr hProcess; | |||
public IntPtr hThread; | |||
public int dwProcessId; | |||
public int dwThreadId; | |||
} | |||
public static IntPtr GetUserToken() | |||
{ | |||
IntPtr Token; | |||
WTSQueryUserToken((uint)SessionID, out Token); | |||
return Token; | |||
} | |||
private static int SessionID = -1; | |||
public static bool GetSystemPrivilege() | |||
{ | |||
IntPtr CurrentProcessToken; | |||
OpenProcessToken(Process.GetCurrentProcess().Handle, MAXIMUM_ALLOWED, out CurrentProcessToken); | |||
IntPtr DuplicatedCurrentProcessToken; | |||
DuplicateTokenEx(CurrentProcessToken, MAXIMUM_ALLOWED, IntPtr.Zero, SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation, TOKEN_TYPE.TokenImpersonation, out DuplicatedCurrentProcessToken); | |||
LUID_AND_ATTRIBUTES RawPrivilege = new LUID_AND_ATTRIBUTES(); | |||
LookupPrivilegeValue(IntPtr.Zero, "SeDebugPrivilege", ref RawPrivilege.Luid); | |||
RawPrivilege.Attributes = SE_PRIVILEGE_ENABLED; | |||
TOKEN_PRIVILEGES TokenPrivilege = new TOKEN_PRIVILEGES(); | |||
TokenPrivilege.Privileges = new LUID_AND_ATTRIBUTES[] { RawPrivilege }; | |||
TokenPrivilege.PrivilegeCount = 1; | |||
AdjustTokenPrivileges(DuplicatedCurrentProcessToken, false, ref TokenPrivilege, 0, IntPtr.Zero, IntPtr.Zero); | |||
SetThreadToken(IntPtr.Zero, DuplicatedCurrentProcessToken); | |||
SessionID = GetActiveSession(); | |||
IntPtr OriginalProcessToken = new IntPtr(-1); | |||
CreateSystemToken((int)MAXIMUM_ALLOWED, SessionID, ref OriginalProcessToken); | |||
IntPtr SystemToken; | |||
DuplicateTokenEx(OriginalProcessToken, MAXIMUM_ALLOWED, IntPtr.Zero, SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation, TOKEN_TYPE.TokenImpersonation, out SystemToken); | |||
SetThreadToken(IntPtr.Zero, SystemToken); | |||
return true; | |||
} | |||
[DllImport("advapi32.dll", SetLastError=true)] | |||
static extern bool GetTokenInformation( | |||
IntPtr TokenHandle, | |||
TOKEN_INFORMATION_CLASS TokenInformationClass, | |||
IntPtr TokenInformation, | |||
int TokenInformationLength, | |||
out int ReturnLength); | |||
enum TOKEN_INFORMATION_CLASS | |||
{ | |||
TokenUser = 1, | |||
TokenGroups, | |||
TokenPrivileges, | |||
TokenOwner, | |||
TokenPrimaryGroup, | |||
TokenDefaultDacl, | |||
TokenSource, | |||
TokenType, | |||
TokenImpersonationLevel, | |||
TokenStatistics, | |||
TokenRestrictedSids, | |||
TokenSessionId, | |||
TokenGroupsAndPrivileges, | |||
TokenSessionReference, | |||
TokenSandBoxInert, | |||
TokenAuditPolicy, | |||
TokenOrigin | |||
} | |||
private static int GetActiveSession() | |||
{ | |||
IntPtr pSessionInfo = IntPtr.Zero; | |||
Int32 Count = 0; | |||
var retval = WTSEnumerateSessions((IntPtr)null, 0, 1, ref pSessionInfo, ref Count); | |||
Int32 dataSize = Marshal.SizeOf(typeof(WTS_SESSION_INFO)); | |||
Int64 current = (Int64)pSessionInfo; | |||
int result = -1; | |||
if (retval != 0) | |||
{ | |||
for (int i = 0; i < Count; i++) | |||
{ | |||
WTS_SESSION_INFO si = (WTS_SESSION_INFO)Marshal.PtrToStructure((System.IntPtr)current, typeof(WTS_SESSION_INFO)); | |||
current += dataSize; | |||
if (si.State == WTS_CONNECTSTATE_CLASS.WTSActive) | |||
{ | |||
result = si.SessionID; | |||
break; | |||
} | |||
} | |||
WTSFreeMemory(pSessionInfo); | |||
} | |||
return result; | |||
} | |||
private static void CreateSystemToken(int DesiredAccess, int dwSessionID, ref IntPtr TokenHandle) | |||
{ | |||
int dwLsassPID = -1; | |||
int dwWinLogonPID = -1; | |||
WTS_PROCESS_INFO[] pProcesses; | |||
IntPtr pProcessInfo = IntPtr.Zero; | |||
int dwProcessCount = 0; | |||
if (WTSEnumerateProcesses((IntPtr)null, 0, 1, ref pProcessInfo, ref dwProcessCount)) | |||
{ | |||
IntPtr pMemory = pProcessInfo; | |||
pProcesses = new WTS_PROCESS_INFO[dwProcessCount]; | |||
for (int i = 0; i < dwProcessCount; i++) | |||
{ | |||
pProcesses[i] = (WTS_PROCESS_INFO)Marshal.PtrToStructure(pProcessInfo, typeof(WTS_PROCESS_INFO)); | |||
pProcessInfo = (IntPtr)((long)pProcessInfo + Marshal.SizeOf(pProcesses[i])); | |||
var processName = Marshal.PtrToStringAnsi(pProcesses[i].ProcessName); | |||
ConvertSidToStringSid(pProcesses[i].UserSid, out string sid); | |||
string strSid; | |||
if (processName == null || pProcesses[i].UserSid == default || sid != "S-1-5-18") | |||
continue; | |||
if ((-1 == dwLsassPID) && (0 == pProcesses[i].SessionID) && (processName == "lsass.exe")) | |||
{ | |||
dwLsassPID = pProcesses[i].ProcessID; | |||
continue; | |||
} | |||
if ((-1 == dwWinLogonPID) && (dwSessionID == pProcesses[i].SessionID) && (processName == "winlogon.exe")) | |||
{ | |||
dwWinLogonPID = pProcesses[i].ProcessID; | |||
continue; | |||
} | |||
} | |||
WTSFreeMemory(pMemory); | |||
} | |||
bool Result = false; | |||
IntPtr SystemProcessHandle = IntPtr.Zero; | |||
try | |||
{ | |||
SystemProcessHandle = Process.GetProcessById(dwLsassPID).Handle; | |||
} catch | |||
{ | |||
SystemProcessHandle = Process.GetProcessById(dwWinLogonPID).Handle; | |||
} | |||
IntPtr SystemTokenHandle = IntPtr.Zero; | |||
if (OpenProcessToken(SystemProcessHandle, TOKEN_DUPLICATE, out SystemTokenHandle)) | |||
{ | |||
Result = DuplicateTokenEx(SystemTokenHandle, (uint)DesiredAccess, IntPtr.Zero, SECURITY_IMPERSONATION_LEVEL.SecurityIdentification, TOKEN_TYPE.TokenPrimary, out TokenHandle); | |||
CloseHandle(SystemTokenHandle); | |||
} | |||
CloseHandle(SystemProcessHandle); | |||
// return Result; | |||
return; | |||
} | |||
[DllImport("kernel32.dll", SetLastError = true)] | |||
public static extern IntPtr OpenProcess( | |||
uint processAccess, | |||
bool bInheritHandle, | |||
uint processId | |||
); | |||
public const UInt32 TOKEN_DUPLICATE = 0x0002; | |||
[DllImport("advapi32", CharSet = CharSet.Auto, SetLastError = true)] | |||
static extern bool ConvertSidToStringSid(IntPtr pSid, out string strSid); | |||
[DllImport("kernel32.dll", SetLastError=true)] | |||
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] | |||
[SuppressUnmanagedCodeSecurity] | |||
[return: MarshalAs(UnmanagedType.Bool)] | |||
static extern bool CloseHandle(IntPtr hObject); | |||
[DllImport("wtsapi32.dll", SetLastError=true)] | |||
static extern int WTSEnumerateSessions( | |||
System.IntPtr hServer, | |||
int Reserved, | |||
int Version, | |||
ref System.IntPtr ppSessionInfo, | |||
ref int pCount); | |||
[StructLayout(LayoutKind.Sequential)] | |||
private struct WTS_SESSION_INFO | |||
{ | |||
public Int32 SessionID; | |||
[MarshalAs(UnmanagedType.LPStr)] | |||
public String pWinStationName; | |||
public WTS_CONNECTSTATE_CLASS State; | |||
} | |||
public enum WTS_CONNECTSTATE_CLASS | |||
{ | |||
WTSActive, | |||
WTSConnected, | |||
WTSConnectQuery, | |||
WTSShadow, | |||
WTSDisconnected, | |||
WTSIdle, | |||
WTSListen, | |||
WTSReset, | |||
WTSDown, | |||
WTSInit | |||
} | |||
[DllImport("wtsapi32.dll")] | |||
static extern void WTSFreeMemory(IntPtr pMemory); | |||
[DllImport("wtsapi32.dll", SetLastError=true)] | |||
static extern bool WTSEnumerateProcesses( | |||
IntPtr serverHandle, // Handle to a terminal server. | |||
Int32 reserved, // must be 0 | |||
Int32 version, // must be 1 | |||
ref IntPtr ppProcessInfo, // pointer to array of WTS_PROCESS_INFO | |||
ref Int32 pCount // pointer to number of processes | |||
); | |||
struct WTS_PROCESS_INFO | |||
{ | |||
public int SessionID; | |||
public int ProcessID; | |||
//This is a pointer to string... | |||
public IntPtr ProcessName; | |||
public IntPtr UserSid; | |||
} | |||
[DllImport("ntdll.dll", SetLastError = true)] | |||
static extern IntPtr RtlAdjustPrivilege(int Privilege, bool bEnablePrivilege, bool IsThreadPrivilege, out bool PreviousValue); | |||
[DllImport("advapi32.dll")] | |||
static extern bool LookupPrivilegeValue(IntPtr lpSystemName, string lpName, ref UInt64 lpLuid); | |||
public static void GetOwnershipPrivilege() | |||
{ | |||
ulong luid = 0; | |||
bool throwaway; | |||
LookupPrivilegeValue(IntPtr.Zero, "SeTakeOwnershipPrivilege", ref luid); | |||
RtlAdjustPrivilege((int)luid, true, true, out throwaway); | |||
} | |||
public static void GetAssignPrivilege() | |||
{ | |||
ulong luid = 0; | |||
bool throwaway; | |||
LookupPrivilegeValue(IntPtr.Zero, "SeAssignPrimaryTokenPrivilege", ref luid); | |||
RtlAdjustPrivilege((int)luid, true, true, out throwaway); | |||
} | |||
public static void GetQuotaPrivilege() | |||
{ | |||
ulong luid = 0; | |||
bool throwaway; | |||
LookupPrivilegeValue(IntPtr.Zero, "SeIncreaseQuotaPrivilege", ref luid); | |||
RtlAdjustPrivilege((int)luid, true, true, out throwaway); | |||
} | |||
public static void GetShutdownPrivilege() | |||
{ | |||
ulong luid = 0; | |||
bool throwaway; | |||
LookupPrivilegeValue(IntPtr.Zero, "SeShutdownPrivilege", ref luid); | |||
RtlAdjustPrivilege((int)luid, true, true, out throwaway); | |||
} | |||
public static void RunAsUser(Action action) | |||
{ | |||
var token = NSudo.GetUserToken(); | |||
Task.Run((Action)Delegate.Combine((Action)(() => { NSudo.GetUserPrivilege(token); }), | |||
action)).Wait(); | |||
Marshal.FreeHGlobal(token); | |||
} | |||
private static async Task RunAsUserAsync(Action action) | |||
{ | |||
var token = NSudo.GetUserToken(); | |||
await Task.Run((Action)Delegate.Combine((Action)(() => { NSudo.GetUserPrivilege(token); }), | |||
action)); | |||
Marshal.FreeHGlobal(token); | |||
} | |||
} | |||
} |
@ -0,0 +1,141 @@ | |||
using System; | |||
using System.DirectoryServices.AccountManagement; | |||
using System.Linq; | |||
using System.Security.Principal; | |||
using Ameliorated.ConsoleUtils; | |||
using Microsoft.Win32; | |||
using amecs.Actions; | |||
using Menu = Ameliorated.ConsoleUtils.Menu; | |||
namespace amecs | |||
{ | |||
internal class Program | |||
{ | |||
private const string Ver = "2.1"; | |||
public static ConsoleTUI.Frame Frame; | |||
[STAThread] | |||
public static void Main(string[] args) | |||
{ | |||
ConsoleTUI.Initialize("Central AME Script"); | |||
try | |||
{ | |||
NSudo.GetSystemPrivilege(); | |||
if (!WindowsIdentity.GetCurrent().IsSystem) | |||
throw new Exception("Identity did not change."); | |||
NSudo.RunAsUser(() => | |||
{ | |||
Globals.Username = WindowsIdentity.GetCurrent().Name.Split('\\').Last(); | |||
Globals.UserDomain = WindowsIdentity.GetCurrent().Name.Split('\\').FirstOrDefault(); | |||
Globals.UserSID = WindowsIdentity.GetCurrent().User.ToString(); | |||
}); | |||
try | |||
{ | |||
Globals.UserFolder = Registry.Users.OpenSubKey(Globals.UserSID + "\\Volatile Environment").GetValue("USERPROFILE").ToString(); | |||
} catch (Exception e) | |||
{ | |||
Console.WriteLine(Globals.Username); | |||
ConsoleTUI.ShowErrorBox($"Could not fetch user folder information from user with SID '{Globals.UserSID}': " + e, "Central AME Script"); | |||
Environment.Exit(1); | |||
} | |||
PrincipalContext context = new PrincipalContext(ContextType.Machine); | |||
PrincipalSearcher userPrincipalSearcher = new PrincipalSearcher(new UserPrincipal(context)); | |||
Globals.User = userPrincipalSearcher.FindAll().FirstOrDefault(x => (x is UserPrincipal) && x.Sid.Value == Globals.UserSID) as UserPrincipal; | |||
PrincipalSearcher groupPrincipalSearcher = new PrincipalSearcher(new GroupPrincipal(context)); | |||
Globals.Administrators = groupPrincipalSearcher.FindAll().FirstOrDefault(x => (x is GroupPrincipal) && x.Sid.IsWellKnown(WellKnownSidType.BuiltinAdministratorsSid)) as GroupPrincipal; | |||
} catch (Exception e) | |||
{ | |||
ConsoleTUI.ShowErrorBox("Could not acquire System privileges: " + e, "Central AME Script"); | |||
Environment.Exit(1); | |||
} | |||
Frame = new ConsoleTUI.Frame($"| Central AME Script v{Ver} |", false); | |||
Frame.Open(); | |||
while (true) | |||
{ | |||
Globals.UserElevated = Globals.User.IsMemberOf(Globals.Administrators); | |||
Frame.Clear(); | |||
bool usernameRequirement = new Reg.Value() | |||
{ | |||
KeyName = @"HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System", | |||
ValueName = "dontdisplaylastusername", | |||
Data = 1, | |||
}.IsEqual(); | |||
bool autoLogonEnabled = new Reg.Value() | |||
{ | |||
KeyName = @"HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon", | |||
ValueName = "DefaultUsername", | |||
Data = Globals.Username, | |||
}.IsEqual() && | |||
new Reg.Value() | |||
{ | |||
KeyName = @"HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon", | |||
ValueName = "AutoAdminLogon", | |||
Data = "1", | |||
}.IsEqual(); | |||
bool netInstalled = new Reg.Key() | |||
{ | |||
KeyName = @"HKLM\SOFTWARE\Microsoft\NET Framework Setup\NDP\v3.5", | |||
Operation = RegistryOperation.Add | |||
}.IsEqual(); | |||
var mainMenu = new Ameliorated.ConsoleUtils.Menu() | |||
{ | |||
Choices = | |||
{ | |||
new Menu.MenuItem("Change Username or Password", new Func<bool>(UserPass.ShowMenu)), | |||
new Menu.MenuItem("Change Lockscreen Image", new Func<bool>(Lockscreen.ChangeImage)), | |||
new Menu.MenuItem("Change Profile Image", new Func<bool>(Profile.ChangeImage)), | |||
Globals.UserElevated ? | |||
new Menu.MenuItem( "De-elevate User", new Func<bool>(Elevation.DeElevate)) : | |||
new Menu.MenuItem("Elevate User to Administrator", new Func<bool>(Elevation.Elevate)), | |||
usernameRequirement ? | |||
new Menu.MenuItem( "Disable Username Login Requirement", new Func<bool>(UsernameRequirement.Disable)) : | |||
new Menu.MenuItem("Enable Username Login Requirement", new Func<bool>(UsernameRequirement.Enable)), | |||
autoLogonEnabled ? | |||
new Menu.MenuItem( "Disable AutoLogon", new Func<bool>(AutoLogon.Disable)) : | |||
new Menu.MenuItem("Enable AutoLogon", new Func<bool>(AutoLogon.Enable)), | |||
new Menu.MenuItem("Manage Language Settings", new Func<bool>(Languages.ShowMenu)), | |||
new Menu.MenuItem("Manage Users", new Func<bool>(Users.ShowMenu)), | |||
!netInstalled ? | |||
new Menu.MenuItem("Install .NET 3.5", new Func<bool>(_NET.Install)) : | |||
new Menu.MenuItem("Install .NET 3.5", new Func<bool>(_NET.Install)) {SecondaryText = "[Installed]", SecondaryTextForeground = ConsoleColor.Yellow, PrimaryTextForeground = ConsoleColor.DarkGray}, | |||
Menu.MenuItem.Blank, | |||
new Menu.MenuItem("Uninstall AME", new Func<bool>(Deameliorate.DeAme)), | |||
new Menu.MenuItem("Extra", new Func<bool>(Extra.Extra.ShowMenu)), | |||
new Menu.MenuItem("Exit", new Func<bool>(Globals.Exit)) | |||
}, | |||
SelectionForeground = ConsoleColor.Green | |||
}; | |||
Func<bool> result; | |||
try | |||
{ | |||
mainMenu.Write(); | |||
result = (Func<bool>)mainMenu.Load(); | |||
} catch (Exception e) | |||
{ | |||
Console.WriteLine(e); | |||
Console.ReadLine(); | |||
return; | |||
} | |||
try | |||
{ | |||
result.Invoke(); | |||
} catch (Exception e) | |||
{ | |||
ConsoleTUI.ShowErrorBox("Error while running an action: " + e.ToString(), null); | |||
} | |||
} | |||
} | |||
} | |||
} |
@ -0,0 +1,35 @@ | |||
using System.Reflection; | |||
using System.Runtime.InteropServices; | |||
// General Information about an assembly is controlled through the following | |||
// set of attributes. Change these attribute values to modify the information | |||
// associated with an assembly. | |||
[assembly: AssemblyTitle("Central AME Script")] | |||
[assembly: AssemblyDescription("Tool for automating a large assortment of AME related actions.")] | |||
[assembly: AssemblyConfiguration("")] | |||
[assembly: AssemblyCompany("")] | |||
[assembly: AssemblyProduct("amecs")] | |||
[assembly: AssemblyCopyright("MIT License")] | |||
[assembly: AssemblyTrademark("")] | |||
[assembly: AssemblyCulture("")] | |||
// Setting ComVisible to false makes the types in this assembly not visible | |||
// to COM components. If you need to access a type in this assembly from | |||
// COM, set the ComVisible attribute to true on that type. | |||
[assembly: ComVisible(false)] | |||
// The following GUID is for the ID of the typelib if this project is exposed to COM | |||
[assembly: Guid("BD020697-9E9B-4A46-8804-BC47F0FC2806")] | |||
// Version information for an assembly consists of the following four values: | |||
// | |||
// Major Version | |||
// Minor Version | |||
// Build Number | |||
// Revision | |||
// | |||
// You can specify all the values or you can default the Build and Revision Numbers | |||
// by using the '*' as shown below: | |||
// [assembly: AssemblyVersion("1.0.*")] | |||
[assembly: AssemblyVersion("2.1")] | |||
[assembly: AssemblyFileVersion("2.1")] |
@ -0,0 +1,375 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
using System.Runtime.InteropServices; | |||
using System.Text.RegularExpressions; | |||
using System.Threading.Tasks; | |||
using Microsoft.Win32; | |||
namespace amecs | |||
{ | |||
public enum RegistryOperation | |||
{ | |||
Delete = 0, | |||
Add = 1 | |||
} | |||
public class Reg | |||
{ | |||
public class Key | |||
{ | |||
public string KeyName { get; set; } | |||
//public Scope Scope { get; set; } = Scope.AllUsers; | |||
public RegistryOperation Operation { get; set; } = RegistryOperation.Delete; | |||
private List<RegistryKey> GetRoots() | |||
{ | |||
var hive = KeyName.Split('\\').GetValue(0).ToString().ToUpper(); | |||
var list = new List<RegistryKey>(); | |||
list.Add(hive switch | |||
{ | |||
"HKCU" => RegistryKey.OpenBaseKey(RegistryHive.CurrentUser, RegistryView.Default), | |||
"HKEY_CURRENT_USER" => RegistryKey.OpenBaseKey(RegistryHive.CurrentUser, RegistryView.Default), | |||
"HKLM" => RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Default), | |||
"HKEY_LOCAL_MACHINE" => RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Default), | |||
"HKCR" => RegistryKey.OpenBaseKey(RegistryHive.ClassesRoot, RegistryView.Default), | |||
"HKEY_CLASSES_ROOT" => RegistryKey.OpenBaseKey(RegistryHive.ClassesRoot, RegistryView.Default), | |||
"HKU" => RegistryKey.OpenBaseKey(RegistryHive.Users, RegistryView.Default), | |||
"HKEY_USERS" => RegistryKey.OpenBaseKey(RegistryHive.Users, RegistryView.Default), | |||
_ => throw new ArgumentException($"Key '{KeyName}' does not specify a valid registry hive.") | |||
}); | |||
return list; | |||
} | |||
public string GetSubKey() => KeyName.Substring(KeyName.IndexOf('\\') + 1); | |||
public bool IsEqual() | |||
{ | |||
try | |||
{ | |||
var roots = GetRoots(); | |||
foreach (var _root in roots) | |||
{ | |||
var root = _root; | |||
var subKey = GetSubKey(); | |||
var openedSubKey = root.OpenSubKey(subKey); | |||
if (Operation == RegistryOperation.Delete && openedSubKey != null) | |||
{ | |||
return false; | |||
} | |||
if (Operation == RegistryOperation.Add && openedSubKey == null) | |||
{ | |||
return false; | |||
} | |||
} | |||
} catch (Exception e) | |||
{ | |||
return false; | |||
} | |||
return true; | |||
} | |||
public bool Apply() | |||
{ | |||
var roots = GetRoots(); | |||
foreach (var _root in roots) | |||
{ | |||
var root = _root; | |||
var subKey = GetSubKey(); | |||
var openedSubKey = root.OpenSubKey(subKey); | |||
if (openedSubKey != null) openedSubKey.Close(); | |||
if (Operation == RegistryOperation.Add && openedSubKey == null) | |||
{ | |||
root.CreateSubKey(subKey)?.Close(); | |||
} | |||
if (Operation == RegistryOperation.Delete) | |||
{ | |||
root.DeleteSubKeyTree(subKey, false); | |||
} | |||
root.Close(); | |||
} | |||
return true; | |||
} | |||
} | |||
public enum RegistryValueOperation | |||
{ | |||
Delete = 0, | |||
Add = 1, | |||
// This indicates to skip the action if the specified value does not already exist | |||
Set = 2 | |||
} | |||
public enum RegistryValueType | |||
{ | |||
REG_SZ = RegistryValueKind.String, | |||
REG_MULTI_SZ = RegistryValueKind.MultiString, | |||
REG_EXPAND_SZ = RegistryValueKind.ExpandString, | |||
REG_DWORD = RegistryValueKind.DWord, | |||
REG_QWORD = RegistryValueKind.QWord, | |||
REG_BINARY = RegistryValueKind.Binary, | |||
REG_NONE = RegistryValueKind.None, | |||
REG_UNKNOWN = RegistryValueKind.Unknown | |||
} | |||
public class Value | |||
{ | |||
public string KeyName { get; set; } | |||
public string ValueName { get; set; } = ""; | |||
public object? Data { get; set; } | |||
public RegistryValueType Type { get; set; } | |||
//public Scope Scope { get; set; } = Scope.AllUsers; | |||
public RegistryValueOperation Operation { get; set; } = RegistryValueOperation.Add; | |||
private List<RegistryKey> GetRoots() | |||
{ | |||
var hive = KeyName.Split('\\').GetValue(0).ToString().ToUpper(); | |||
var list = new List<RegistryKey>(); | |||
list.Add(hive switch | |||
{ | |||
"HKCU" => RegistryKey.OpenBaseKey(RegistryHive.CurrentUser, RegistryView.Default), | |||
"HKEY_CURRENT_USER" => RegistryKey.OpenBaseKey(RegistryHive.CurrentUser, RegistryView.Default), | |||
"HKLM" => RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Default), | |||
"HKEY_LOCAL_MACHINE" => RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Default), | |||
"HKCR" => RegistryKey.OpenBaseKey(RegistryHive.ClassesRoot, RegistryView.Default), | |||
"HKEY_CLASSES_ROOT" => RegistryKey.OpenBaseKey(RegistryHive.ClassesRoot, RegistryView.Default), | |||
"HKU" => RegistryKey.OpenBaseKey(RegistryHive.Users, RegistryView.Default), | |||
"HKEY_USERS" => RegistryKey.OpenBaseKey(RegistryHive.Users, RegistryView.Default), | |||
_ => throw new ArgumentException($"Key '{KeyName}' does not specify a valid registry hive.") | |||
}); | |||
return list; | |||
} | |||
public string GetSubKey() => KeyName.Substring(KeyName.IndexOf('\\') + 1); | |||
public object? GetCurrentValue(RegistryKey root) | |||
{ | |||
var subkey = GetSubKey(); | |||
return Registry.GetValue(root.Name + "\\" + subkey, ValueName, null); | |||
} | |||
public static byte[] StringToByteArray(string hex) | |||
{ | |||
return Enumerable.Range(0, hex.Length) | |||
.Where(x => x % 2 == 0) | |||
.Select(x => Convert.ToByte(hex.Substring(x, 2), 16)) | |||
.ToArray(); | |||
} | |||
public bool IsEqual() | |||
{ | |||
try | |||
{ | |||
var roots = GetRoots(); | |||
foreach (var _root in roots) | |||
{ | |||
var root = _root; | |||
var subKey = GetSubKey(); | |||
var openedSubKey = root.OpenSubKey(subKey); | |||
if (openedSubKey == null && (Operation == RegistryValueOperation.Set || Operation == RegistryValueOperation.Delete)) | |||
continue; | |||
if (openedSubKey == null) return false; | |||
var value = openedSubKey.GetValue(ValueName); | |||
if (value == null) | |||
{ | |||
if (Operation == RegistryValueOperation.Set || Operation == RegistryValueOperation.Delete) | |||
continue; | |||
return false; | |||
} | |||
if (Operation == RegistryValueOperation.Delete) return false; | |||
if (Data == null) return false; | |||
bool matches; | |||
try | |||
{ | |||
matches = Type switch | |||
{ | |||
RegistryValueType.REG_SZ => | |||
Data.ToString() == value.ToString(), | |||
RegistryValueType.REG_EXPAND_SZ => | |||
// RegistryValueOptions.DoNotExpandEnvironmentNames above did not seem to work. | |||
Environment.ExpandEnvironmentVariables(Data.ToString()) == value.ToString(), | |||
RegistryValueType.REG_MULTI_SZ => | |||
Data.ToString() == "" ? ((string[])value).SequenceEqual(new string[] { }) : ((string[])value).SequenceEqual(Data.ToString().Split(new string[] { "\\0" }, StringSplitOptions.None)), | |||
RegistryValueType.REG_DWORD => | |||
unchecked((int)Convert.ToUInt32(Data)) == (int)value, | |||
RegistryValueType.REG_QWORD => | |||
Convert.ToUInt64(Data) == (ulong)value, | |||
RegistryValueType.REG_BINARY => | |||
((byte[])value).SequenceEqual(StringToByteArray(Data.ToString())), | |||
RegistryValueType.REG_NONE => | |||
((byte[])value).SequenceEqual(new byte[0]), | |||
RegistryValueType.REG_UNKNOWN => | |||
Data.ToString() == value.ToString(), | |||
_ => throw new ArgumentException("Impossible.") | |||
}; | |||
} catch (InvalidCastException) | |||
{ | |||
matches = false; | |||
} | |||
if (!matches) return false; | |||
} | |||
} catch (Exception e) | |||
{ | |||
return false; | |||
} | |||
return true; | |||
} | |||
public bool Apply() | |||
{ | |||
var roots = GetRoots(); | |||
foreach (var _root in roots) | |||
{ | |||
var root = _root; | |||
var subKey = GetSubKey(); | |||
if (GetCurrentValue(root) == Data) continue; | |||
var opened = root.OpenSubKey(subKey); | |||
if (opened == null && Operation == RegistryValueOperation.Set) continue; | |||
if (opened == null && Operation == RegistryValueOperation.Add) root.CreateSubKey(subKey)?.Close(); | |||
if (opened != null) opened.Close(); | |||
if (Operation == RegistryValueOperation.Delete) | |||
{ | |||
var key = root.OpenSubKey(subKey, true); | |||
key?.DeleteValue(ValueName); | |||
key?.Close(); | |||
root.Close(); | |||
continue; | |||
} | |||
if (Type == RegistryValueType.REG_BINARY) | |||
{ | |||
var data = StringToByteArray(Data.ToString()); | |||
Registry.SetValue(root.Name + "\\" + subKey, ValueName, data, (RegistryValueKind)Type); | |||
} | |||
else if (Type == RegistryValueType.REG_DWORD) | |||
{ | |||
// DWORD values using the highest bit set fail without this, for example '2962489444'. | |||
// See https://stackoverflow.com/questions/6608400/how-to-put-a-dword-in-the-registry-with-the-highest-bit-set; | |||
var value = unchecked((int)Convert.ToUInt32(Data)); | |||
Registry.SetValue(root.Name + "\\" + subKey, ValueName, value, (RegistryValueKind)Type); | |||
} | |||
else if (Type == RegistryValueType.REG_QWORD) | |||
{ | |||
Registry.SetValue(root.Name + "\\" + subKey, ValueName, Convert.ToUInt64(Data), (RegistryValueKind)Type); | |||
} | |||
else if (Type == RegistryValueType.REG_NONE) | |||
{ | |||
byte[] none = new byte[0]; | |||
Registry.SetValue(root.Name + "\\" + subKey, ValueName, none, (RegistryValueKind)Type); | |||
} | |||
else if (Type == RegistryValueType.REG_MULTI_SZ) | |||
{ | |||
string[] data; | |||
if (Data.ToString() == "") data = new string[] { }; | |||
else data = Data.ToString().Split(new string[] { "\\0" }, StringSplitOptions.None); | |||
Registry.SetValue(root.Name + "\\" + subKey, ValueName, data, (RegistryValueKind)Type); | |||
} | |||
else | |||
{ | |||
Registry.SetValue(root.Name + "\\" + subKey, ValueName, Data, (RegistryValueKind)Type); | |||
} | |||
root.Close(); | |||
} | |||
return true; | |||
} | |||
} | |||
[DllImport("advapi32.dll", SetLastError = true)] | |||
static extern int RegLoadKey(IntPtr hKey, string lpSubKey, string lpFile); | |||
[DllImport("advapi32.dll", SetLastError = true)] | |||
static extern int RegSaveKey(IntPtr hKey, string lpFile, uint securityAttrPtr = 0); | |||
[DllImport("advapi32.dll", SetLastError = true)] | |||
static extern int RegUnLoadKey(IntPtr hKey, string lpSubKey); | |||
[DllImport("ntdll.dll", SetLastError = true)] | |||
static extern IntPtr RtlAdjustPrivilege(int Privilege, bool bEnablePrivilege, bool IsThreadPrivilege, out bool PreviousValue); | |||
[DllImport("advapi32.dll")] | |||
static extern bool LookupPrivilegeValue(string lpSystemName, string lpName, ref UInt64 lpLuid); | |||
[DllImport("advapi32.dll")] | |||
static extern bool LookupPrivilegeValue(IntPtr lpSystemName, string lpName, ref UInt64 lpLuid); | |||
public static void LoadDefaultUserHive() | |||
{ | |||
var parentKey = RegistryKey.OpenBaseKey(RegistryHive.Users, RegistryView.Default); | |||
IntPtr parentHandle = parentKey.Handle.DangerousGetHandle(); | |||
AcquirePrivileges(); | |||
RegLoadKey(parentHandle, "DefaultUserHive", Environment.ExpandEnvironmentVariables(@"%SYSTEMDRIVE%\Users\Default\NTUSER.dat")); | |||
parentKey.Close(); | |||
} | |||
public static void UnloadDefaultUserHive() | |||
{ | |||
var parentKey = RegistryKey.OpenBaseKey(RegistryHive.Users, RegistryView.Default); | |||
AcquirePrivileges(); | |||
RegUnLoadKey(parentKey.Handle.DangerousGetHandle(), "DefaultUserHive"); | |||
parentKey.Close(); | |||
} | |||
public static void AcquirePrivileges() | |||
{ | |||
ulong luid = 0; | |||
bool throwaway; | |||
LookupPrivilegeValue(IntPtr.Zero, "SeRestorePrivilege", ref luid); | |||
RtlAdjustPrivilege((int)luid, true, true, out throwaway); | |||
LookupPrivilegeValue(IntPtr.Zero, "SeBackupPrivilege", ref luid); | |||
RtlAdjustPrivilege((int)luid, true, true, out throwaway); | |||
} | |||
public static void ReturnPrivileges() | |||
{ | |||
ulong luid = 0; | |||
bool throwaway; | |||
LookupPrivilegeValue(IntPtr.Zero, "SeRestorePrivilege", ref luid); | |||
RtlAdjustPrivilege((int)luid, false, true, out throwaway); | |||
LookupPrivilegeValue(IntPtr.Zero, "SeBackupPrivilege", ref luid); | |||
RtlAdjustPrivilege((int)luid, false, true, out throwaway); | |||
} | |||
} | |||
} |
@ -0,0 +1,263 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Diagnostics; | |||
using System.IO; | |||
using System.Net; | |||
using System.Runtime.InteropServices; | |||
using System.Threading.Tasks; | |||
using Ameliorated.ConsoleUtils; | |||
namespace amecs | |||
{ | |||
public class amecs | |||
{ | |||
public static bool RunBasicAction(string status, string result, Action action, bool logoff = false, bool restart = false) | |||
{ | |||
ConsoleTUI.OpenFrame.WriteCentered(status); | |||
try | |||
{ | |||
using (new ConsoleUtils.LoadingIndicator(true)) | |||
{ | |||
action.Invoke(); | |||
} | |||
} catch (Exception e) | |||
{ | |||
Console.WriteLine(); | |||
ConsoleTUI.OpenFrame.Close("Error: " + e.Message.TrimEnd('\n').TrimEnd('\r'), ConsoleColor.Red, Console.BackgroundColor, new ChoicePrompt() { AnyKey = true, Text = "Press any key to return to the Menu: " }); | |||
return false; | |||
} | |||
Console.WriteLine(); | |||
if (logoff) | |||
{ | |||
if ((int?)ConsoleTUI.OpenFrame.Close(result, ConsoleColor.Green, Console.BackgroundColor, new ChoicePrompt() | |||
{ | |||
TextForeground = ConsoleColor.Yellow, | |||
Text = "Logoff to apply changes? (Y/N): " | |||
}) == 0) amecs.RestartWindows(true); | |||
return true; | |||
} | |||
if (restart) | |||
{ | |||
if ((int?)ConsoleTUI.OpenFrame.Close(result, ConsoleColor.Green, Console.BackgroundColor, new ChoicePrompt() | |||
{ | |||
TextForeground = ConsoleColor.Yellow, | |||
Text = "Restart to apply changes? (Y/N): " | |||
}) == 0) amecs.RestartWindows(false); | |||
return true; | |||
} | |||
ConsoleTUI.OpenFrame.Close(result, ConsoleColor.Green, Console.BackgroundColor, new ChoicePrompt() {AnyKey = true, Text = "Press any key to return to the Menu: "}); | |||
return true; | |||
} | |||
public static bool RunBasicAction(string status, string result, Action<int> action, ChoicePrompt prompt = null, bool logoff = false, bool restart = false) | |||
{ | |||
int choice = -1; | |||
if (prompt != null) | |||
{ | |||
var choiceRes = prompt.Start(); | |||
if (!choiceRes.HasValue) | |||
return true; | |||
choice = choiceRes.Value; | |||
} | |||
ConsoleTUI.OpenFrame.WriteCentered(status); | |||
try | |||
{ | |||
using (new ConsoleUtils.LoadingIndicator(true)) | |||
{ | |||
action.Invoke(choice); | |||
} | |||
} catch (Exception e) | |||
{ | |||
Console.WriteLine(); | |||
ConsoleTUI.OpenFrame.Close("Error: " + e.Message.TrimEnd('\n').TrimEnd('\r'), ConsoleColor.Red, Console.BackgroundColor, new ChoicePrompt() { AnyKey = true, Text = "Press any key to return to the Menu: " }); | |||
return false; | |||
} | |||
Console.WriteLine(); | |||
if (logoff) | |||
{ | |||
if ((int?)ConsoleTUI.OpenFrame.Close(result, ConsoleColor.Green, Console.BackgroundColor, new ChoicePrompt() | |||
{ | |||
TextForeground = ConsoleColor.Yellow, | |||
Text = "Logoff to apply changes? (Y/N): " | |||
}) == 0) amecs.RestartWindows(true); | |||
return true; | |||
} | |||
if (restart) | |||
{ | |||
if ((int?)ConsoleTUI.OpenFrame.Close(result, ConsoleColor.Green, Console.BackgroundColor, new ChoicePrompt() | |||
{ | |||
TextForeground = ConsoleColor.Yellow, | |||
Text = "Restart to apply changes? (Y/N): " | |||
}) == 0) amecs.RestartWindows(false); | |||
return true; | |||
} | |||
ConsoleTUI.OpenFrame.Close(result, ConsoleColor.Green, Console.BackgroundColor, new ChoicePrompt() {AnyKey = true, Text = "Press any key to return to the Menu: "}); | |||
return true; | |||
} | |||
[Flags] | |||
enum ExitWindows : uint | |||
{ | |||
// ONE of the following five: | |||
LogOff = 0x00, | |||
ShutDown = 0x01, | |||
Reboot = 0x02, | |||
PowerOff = 0x08, | |||
RestartApps = 0x40, | |||
// plus AT MOST ONE of the following two: | |||
Force = 0x04, | |||
ForceIfHung = 0x10, | |||
} | |||
[Flags] | |||
enum ShutdownReason : uint | |||
{ | |||
MajorApplication = 0x00040000, | |||
MajorHardware = 0x00010000, | |||
MajorLegacyApi = 0x00070000, | |||
MajorOperatingSystem = 0x00020000, | |||
MajorOther = 0x00000000, | |||
MajorPower = 0x00060000, | |||
MajorSoftware = 0x00030000, | |||
MajorSystem = 0x00050000, | |||
MinorBlueScreen = 0x0000000F, | |||
MinorCordUnplugged = 0x0000000b, | |||
MinorDisk = 0x00000007, | |||
MinorEnvironment = 0x0000000c, | |||
MinorHardwareDriver = 0x0000000d, | |||
MinorHotfix = 0x00000011, | |||
MinorHung = 0x00000005, | |||
MinorInstallation = 0x00000002, | |||
MinorMaintenance = 0x00000001, | |||
MinorMMC = 0x00000019, | |||
MinorNetworkConnectivity = 0x00000014, | |||
MinorNetworkCard = 0x00000009, | |||
MinorOther = 0x00000000, | |||
MinorOtherDriver = 0x0000000e, | |||
MinorPowerSupply = 0x0000000a, | |||
MinorProcessor = 0x00000008, | |||
MinorReconfig = 0x00000004, | |||
MinorSecurity = 0x00000013, | |||
MinorSecurityFix = 0x00000012, | |||
MinorSecurityFixUninstall = 0x00000018, | |||
MinorServicePack = 0x00000010, | |||
MinorServicePackUninstall = 0x00000016, | |||
MinorTermSrv = 0x00000020, | |||
MinorUnstable = 0x00000006, | |||
MinorUpgrade = 0x00000003, | |||
MinorWMI = 0x00000015, | |||
FlagUserDefined = 0x40000000, | |||
FlagPlanned = 0x80000000 | |||
} | |||
[DllImport("user32.dll")] | |||
static extern bool ExitWindowsEx(uint uFlags, uint dwReason); | |||
[DllImport("advapi32.dll", CharSet=CharSet.Auto, SetLastError=true)] | |||
private static extern bool InitiateSystemShutdownEx( | |||
string lpMachineName, | |||
string lpMessage, | |||
uint dwTimeout, | |||
bool bForceAppsClosed, | |||
bool bRebootAfterShutdown, | |||
ShutdownReason dwReason); | |||
public static void RestartWindows(bool logoff, bool cmd = false) | |||
{ | |||
if (cmd) | |||
{ | |||
var psi = new ProcessStartInfo("shutdown","/r /t 0"); | |||
psi.CreateNoWindow = true; | |||
psi.UseShellExecute = false; | |||
Process.Start(psi); | |||
Environment.Exit(0); | |||
} | |||
if (!logoff) | |||
{ | |||
NSudo.GetShutdownPrivilege(); | |||
InitiateSystemShutdownEx(null, null, 0, false, true, ShutdownReason.MinorInstallation); | |||
} else | |||
ExitWindowsEx((uint)ExitWindows.LogOff | (uint)ExitWindows.ForceIfHung, (uint)ShutdownReason.MinorInstallation); | |||
Environment.Exit(0); | |||
} | |||
public static object ShowDefaultMenu(List<Menu.MenuItem> list) | |||
{ | |||
list.AddRange(new [] { | |||
Menu.MenuItem.BlankStatic, | |||
new Menu.MenuItem("Next Page", null) { IsNextButton = true }, | |||
new Menu.MenuItem("Previous Page", null) { IsPreviousButton = true }, | |||
new Menu.MenuItem("Return to Menu", new Func<bool>(() => true)) { IsStatic = true }, | |||
new Menu.MenuItem("Exit", new Func<bool>(Globals.Exit)) { IsStatic = true }, | |||
}); | |||
var mainMenu = new Menu() | |||
{ | |||
Choices = list, | |||
SelectionForeground = ConsoleColor.Green | |||
}; | |||
mainMenu.Write(); | |||
return mainMenu.Load(); | |||
} | |||
[DllImport("wininet.dll", SetLastError = true)] | |||
public static extern bool InternetCheckConnection(string lpszUrl, int dwFlags, int dwReserved); | |||
[DllImport("wininet.dll", SetLastError=true)] | |||
private extern static bool InternetGetConnectedState(out int lpdwFlags, int dwReserved); | |||
public static bool IsInternetAvailable() | |||
{ | |||
try | |||
{ | |||
try | |||
{ | |||
if (!InternetCheckConnection("http://archlinux.org", 1, 0)) | |||
{ | |||
if (!InternetCheckConnection("http://google.com", 1, 0)) | |||
return false; | |||
} | |||
return true; | |||
} | |||
catch | |||
{ | |||
var request = (HttpWebRequest)WebRequest.Create("http://google.com"); | |||
request.KeepAlive = false; | |||
request.Timeout = 5000; | |||
using (var response = (HttpWebResponse)request.GetResponse()) | |||
return true; | |||
} | |||
} | |||
catch | |||
{ | |||
return false; | |||
} | |||
} | |||
} | |||
} |
@ -0,0 +1,266 @@ | |||
<?xml version="1.0" encoding="utf-8"?> | |||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | |||
<Import Project="packages\Costura.Fody.5.7.0\build\Costura.Fody.props" Condition="Exists('packages\Costura.Fody.5.7.0\build\Costura.Fody.props')" /> | |||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" /> | |||
<PropertyGroup> | |||
<ApplicationManifest>app.manifest</ApplicationManifest> | |||
<ApplicationIcon>amecs.ico</ApplicationIcon> | |||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> | |||
</PropertyGroup> | |||
<PropertyGroup> | |||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> | |||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> | |||
<ProjectGuid>{BD020697-9E9B-4A46-8804-BC47F0FC2806}</ProjectGuid> | |||
<OutputType>Exe</OutputType> | |||
<AppDesignerFolder>Properties</AppDesignerFolder> | |||
<RootNamespace>amecs</RootNamespace> | |||
<AssemblyName>amecs</AssemblyName> | |||
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion> | |||
<FileAlignment>512</FileAlignment> | |||
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects> | |||
<LangVersion>8</LangVersion> | |||
</PropertyGroup> | |||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> | |||
<PlatformTarget>x64</PlatformTarget> | |||
<DebugSymbols>true</DebugSymbols> | |||
<DebugType>embedded</DebugType> | |||
<Optimize>false</Optimize> | |||
<OutputPath>bin\Debug\</OutputPath> | |||
<DefineConstants>DEBUG;TRACE</DefineConstants> | |||
<ErrorReport>prompt</ErrorReport> | |||
<WarningLevel>4</WarningLevel> | |||
<Prefer32bit>false</Prefer32bit> | |||
</PropertyGroup> | |||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> | |||
<PlatformTarget>x64</PlatformTarget> | |||
<DebugType>embedded</DebugType> | |||
<Optimize>true</Optimize> | |||
<OutputPath>bin\Release\</OutputPath> | |||
<DefineConstants>RELEASE;TRACE</DefineConstants> | |||
<ErrorReport>prompt</ErrorReport> | |||
<WarningLevel>4</WarningLevel> | |||
<Prefer32bit>false</Prefer32bit> | |||
</PropertyGroup> | |||
<ItemGroup> | |||
<Reference Include="Costura, Version=5.7.0.0, Culture=neutral, processorArchitecture=MSIL"> | |||
<HintPath>packages\Costura.Fody.5.7.0\lib\netstandard1.0\Costura.dll</HintPath> | |||
</Reference> | |||
<Reference Include="JetBrains.Annotations, Version=4242.42.42.42, Culture=neutral, PublicKeyToken=1010a0d8d6380325, processorArchitecture=MSIL"> | |||
<HintPath>packages\JetBrains.Annotations.2023.3.0\lib\net20\JetBrains.Annotations.dll</HintPath> | |||
</Reference> | |||
<Reference Include="Microsoft.CSharp" /> | |||
<Reference Include="Microsoft.Dism, Version=1.0.0.0, Culture=neutral, PublicKeyToken=5bba90053b345501, processorArchitecture=MSIL"> | |||
<HintPath>packages\Microsoft.Dism.3.1.0\lib\net40\Microsoft.Dism.dll</HintPath> | |||
</Reference> | |||
<Reference Include="Microsoft.Win32.Primitives, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> | |||
<HintPath>packages\Microsoft.Win32.Primitives.4.3.0\lib\net46\Microsoft.Win32.Primitives.dll</HintPath> | |||
</Reference> | |||
<Reference Include="mscorlib" /> | |||
<Reference Include="System" /> | |||
<Reference Include="System.AppContext, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> | |||
<HintPath>packages\System.AppContext.4.3.0\lib\net463\System.AppContext.dll</HintPath> | |||
</Reference> | |||
<Reference Include="System.Buffers, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL"> | |||
<HintPath>packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll</HintPath> | |||
</Reference> | |||
<Reference Include="System.CodeDom, Version=8.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL"> | |||
<HintPath>packages\System.CodeDom.8.0.0\lib\net462\System.CodeDom.dll</HintPath> | |||
</Reference> | |||
<Reference Include="System.ComponentModel.Composition" /> | |||
<Reference Include="System.Configuration" /> | |||
<Reference Include="System.Console, Version=4.0.1.1, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> | |||
<HintPath>packages\System.Console.4.3.1\lib\net46\System.Console.dll</HintPath> | |||
</Reference> | |||
<Reference Include="System.Core" /> | |||
<Reference Include="System.Data" /> | |||
<Reference Include="System.Data.OracleClient" /> | |||
<Reference Include="System.Diagnostics.DiagnosticSource, Version=8.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL"> | |||
<HintPath>packages\System.Diagnostics.DiagnosticSource.8.0.0\lib\net462\System.Diagnostics.DiagnosticSource.dll</HintPath> | |||
</Reference> | |||
<Reference Include="System.Diagnostics.Tracing, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> | |||
<HintPath>packages\System.Diagnostics.Tracing.4.3.0\lib\net462\System.Diagnostics.Tracing.dll</HintPath> | |||
</Reference> | |||
<Reference Include="System.DirectoryServices" /> | |||
<Reference Include="System.DirectoryServices.AccountManagement" /> | |||
<Reference Include="System.Drawing" /> | |||
<Reference Include="System.Drawing.Primitives, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> | |||
<HintPath>packages\System.Drawing.Primitives.4.3.0\lib\net45\System.Drawing.Primitives.dll</HintPath> | |||
</Reference> | |||
<Reference Include="System.Globalization.Calendars, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> | |||
<HintPath>packages\System.Globalization.Calendars.4.3.0\lib\net46\System.Globalization.Calendars.dll</HintPath> | |||
</Reference> | |||
<Reference Include="System.IO, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> | |||
<HintPath>packages\System.IO.4.3.0\lib\net462\System.IO.dll</HintPath> | |||
</Reference> | |||
<Reference Include="System.IO.Compression, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL"> | |||
<HintPath>packages\System.IO.Compression.4.3.0\lib\net46\System.IO.Compression.dll</HintPath> | |||
</Reference> | |||
<Reference Include="System.IO.Compression.FileSystem" /> | |||
<Reference Include="System.IO.Compression.ZipFile, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL"> | |||
<HintPath>packages\System.IO.Compression.ZipFile.4.3.0\lib\net46\System.IO.Compression.ZipFile.dll</HintPath> | |||
</Reference> | |||
<Reference Include="System.IO.FileSystem, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> | |||
<HintPath>packages\System.IO.FileSystem.4.3.0\lib\net46\System.IO.FileSystem.dll</HintPath> | |||
</Reference> | |||
<Reference Include="System.IO.FileSystem.AccessControl, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> | |||
<HintPath>packages\System.IO.FileSystem.AccessControl.5.0.0\lib\net461\System.IO.FileSystem.AccessControl.dll</HintPath> | |||
<Private>False</Private> | |||
</Reference> | |||
<Reference Include="System.IO.FileSystem.Primitives, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> | |||
<HintPath>packages\System.IO.FileSystem.Primitives.4.3.0\lib\net46\System.IO.FileSystem.Primitives.dll</HintPath> | |||
</Reference> | |||
<Reference Include="System.Linq, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> | |||
<HintPath>packages\System.Linq.4.3.0\lib\net463\System.Linq.dll</HintPath> | |||
</Reference> | |||
<Reference Include="System.Linq.Expressions, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> | |||
<HintPath>packages\System.Linq.Expressions.4.3.0\lib\net463\System.Linq.Expressions.dll</HintPath> | |||
</Reference> | |||
<Reference Include="System.Management" /> | |||
<Reference Include="System.Memory, Version=4.0.1.2, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL"> | |||
<HintPath>packages\System.Memory.4.5.5\lib\net461\System.Memory.dll</HintPath> | |||
</Reference> | |||
<Reference Include="System.Net" /> | |||
<Reference Include="System.Net.Http, Version=4.1.1.3, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> | |||
<HintPath>packages\System.Net.Http.4.3.4\lib\net46\System.Net.Http.dll</HintPath> | |||
</Reference> | |||
<Reference Include="System.Net.Sockets, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> | |||
<HintPath>packages\System.Net.Sockets.4.3.0\lib\net46\System.Net.Sockets.dll</HintPath> | |||
</Reference> | |||
<Reference Include="System.Numerics" /> | |||
<Reference Include="System.Numerics.Vectors, Version=4.1.4.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> | |||
<HintPath>packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll</HintPath> | |||
</Reference> | |||
<Reference Include="System.Reflection, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> | |||
<HintPath>packages\System.Reflection.4.3.0\lib\net462\System.Reflection.dll</HintPath> | |||
</Reference> | |||
<Reference Include="System.Runtime, Version=4.1.1.1, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> | |||
<HintPath>packages\System.Runtime.4.3.1\lib\net462\System.Runtime.dll</HintPath> | |||
</Reference> | |||
<Reference Include="System.Runtime.CompilerServices.Unsafe, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> | |||
<HintPath>packages\System.Runtime.CompilerServices.Unsafe.6.0.0\lib\net461\System.Runtime.CompilerServices.Unsafe.dll</HintPath> | |||
</Reference> | |||
<Reference Include="System.Runtime.Extensions, Version=4.1.1.1, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> | |||
<HintPath>packages\System.Runtime.Extensions.4.3.1\lib\net462\System.Runtime.Extensions.dll</HintPath> | |||
</Reference> | |||
<Reference Include="System.Runtime.InteropServices, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> | |||
<HintPath>packages\System.Runtime.InteropServices.4.3.0\lib\net463\System.Runtime.InteropServices.dll</HintPath> | |||
</Reference> | |||
<Reference Include="System.Runtime.InteropServices.RuntimeInformation, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> | |||
<HintPath>packages\System.Runtime.InteropServices.RuntimeInformation.4.3.0\lib\net45\System.Runtime.InteropServices.RuntimeInformation.dll</HintPath> | |||
</Reference> | |||
<Reference Include="System.Security" /> | |||
<Reference Include="System.Security.AccessControl, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> | |||
<HintPath>packages\System.Security.AccessControl.6.0.0\lib\net461\System.Security.AccessControl.dll</HintPath> | |||
<Private>False</Private> | |||
</Reference> | |||
<Reference Include="System.Security.Cryptography.Algorithms, Version=4.2.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> | |||
<HintPath>packages\System.Security.Cryptography.Algorithms.4.3.1\lib\net463\System.Security.Cryptography.Algorithms.dll</HintPath> | |||
</Reference> | |||
<Reference Include="System.Security.Cryptography.Encoding, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> | |||
<HintPath>packages\System.Security.Cryptography.Encoding.4.3.0\lib\net46\System.Security.Cryptography.Encoding.dll</HintPath> | |||
</Reference> | |||
<Reference Include="System.Security.Cryptography.Primitives, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> | |||
<HintPath>packages\System.Security.Cryptography.Primitives.4.3.0\lib\net46\System.Security.Cryptography.Primitives.dll</HintPath> | |||
</Reference> | |||
<Reference Include="System.Security.Cryptography.X509Certificates, Version=4.1.1.2, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> | |||
<HintPath>packages\System.Security.Cryptography.X509Certificates.4.3.2\lib\net461\System.Security.Cryptography.X509Certificates.dll</HintPath> | |||
</Reference> | |||
<Reference Include="System.Security.Permissions, Version=8.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL"> | |||
<HintPath>packages\System.Security.Permissions.8.0.0\lib\net462\System.Security.Permissions.dll</HintPath> | |||
</Reference> | |||
<Reference Include="System.Security.Principal.Windows, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> | |||
<HintPath>packages\System.Security.Principal.Windows.5.0.0\lib\net461\System.Security.Principal.Windows.dll</HintPath> | |||
<Private>False</Private> | |||
</Reference> | |||
<Reference Include="System.ServiceProcess" /> | |||
<Reference Include="System.Text.RegularExpressions, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> | |||
<HintPath>packages\System.Text.RegularExpressions.4.3.1\lib\net463\System.Text.RegularExpressions.dll</HintPath> | |||
</Reference> | |||
<Reference Include="System.Transactions" /> | |||
<Reference Include="System.Windows.Forms" /> | |||
<Reference Include="System.Xml" /> | |||
<Reference Include="System.Xml.Linq" /> | |||
<Reference Include="System.Xml.ReaderWriter, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> | |||
<HintPath>packages\System.Xml.ReaderWriter.4.3.1\lib\net46\System.Xml.ReaderWriter.dll</HintPath> | |||
</Reference> | |||
<Reference Include="WindowsBase" /> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<Compile Include="Actions\.NET.cs" /> | |||
<Compile Include="Actions\AutoLogon.cs" /> | |||
<Compile Include="Actions\Deameliorate.cs" /> | |||
<Compile Include="Actions\Elevation.cs" /> | |||
<Compile Include="Actions\Languages.cs" /> | |||
<Compile Include="Actions\Lockscreen.cs" /> | |||
<Compile Include="Actions\Profile.cs" /> | |||
<Compile Include="Actions\UsernameRequirement.cs" /> | |||
<Compile Include="Actions\UserPass.cs" /> | |||
<Compile Include="Actions\Users.cs" /> | |||
<Compile Include="amecs.cs" /> | |||
<Compile Include="Ameliorated.ConsoleUtils\ConsoleTUI\ConsoleTUI.cs" /> | |||
<Compile Include="Ameliorated.ConsoleUtils\ConsoleTUI\Frame.cs" /> | |||
<Compile Include="Ameliorated.ConsoleUtils\ConsoleTUI\FrameWriteMethods.cs" /> | |||
<Compile Include="Ameliorated.ConsoleUtils\ConsoleTUI\Menu.cs" /> | |||
<Compile Include="Ameliorated.ConsoleUtils\ConsoleTUI\MouseInterface.cs" /> | |||
<Compile Include="Ameliorated.ConsoleUtils\ConsoleTUI\Prompt.cs" /> | |||
<Compile Include="Ameliorated.ConsoleUtils\ConsoleUtils.cs" /> | |||
<Compile Include="Ameliorated.ConsoleUtils\Extensions.cs" /> | |||
<Compile Include="Ameliorated.ConsoleUtils\ParentProcess.cs" /> | |||
<Compile Include="Ameliorated.ConsoleUtils\Payload.cs" /> | |||
<Compile Include="Extra\Extra.cs" /> | |||
<Compile Include="Extra\NVCP.cs" /> | |||
<Compile Include="Extra\WSH.cs" /> | |||
<Compile Include="Globals.cs" /> | |||
<Compile Include="Misc\FolderPicker.cs" /> | |||
<Compile Include="Misc\SelectWindowsImage.cs" /> | |||
<Compile Include="NSudo.cs" /> | |||
<Compile Include="Program.cs" /> | |||
<Compile Include="Properties\AssemblyInfo.cs" /> | |||
<Compile Include="Registry.cs" /> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<None Include="amecs.ico" /> | |||
<None Include="amecs.png" /> | |||
<None Include="App.config" /> | |||
<None Include="packages.config" /> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<Folder Include="Menus" /> | |||
<Folder Include="NSudo" /> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<Content Include="app.manifest" /> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<COMReference Include="IWshRuntimeLibrary"> | |||
<Guid>{F935DC20-1CF0-11D0-ADB9-00C04FD58A0B}</Guid> | |||
<VersionMajor>1</VersionMajor> | |||
<VersionMinor>0</VersionMinor> | |||
<Lcid>0</Lcid> | |||
<WrapperTool>tlbimp</WrapperTool> | |||
<Isolated>False</Isolated> | |||
<EmbedInteropTypes>True</EmbedInteropTypes> | |||
</COMReference> | |||
</ItemGroup> | |||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> | |||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild"> | |||
<PropertyGroup> | |||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105.The missing file is {0}.</ErrorText> | |||
</PropertyGroup> | |||
<Error Condition="!Exists('packages\Costura.Fody.5.7.0\build\Costura.Fody.props')" Text="$([System.String]::Format('$(ErrorText)', 'packages\Costura.Fody.5.7.0\build\Costura.Fody.props'))" /> | |||
<Error Condition="!Exists('packages\Costura.Fody.5.7.0\build\Costura.Fody.targets')" Text="$([System.String]::Format('$(ErrorText)', 'packages\Costura.Fody.5.7.0\build\Costura.Fody.targets'))" /> | |||
<Error Condition="!Exists('packages\Fody.6.8.0\build\Fody.targets')" Text="$([System.String]::Format('$(ErrorText)', 'packages\Fody.6.8.0\build\Fody.targets'))" /> | |||
<Error Condition="!Exists('packages\NETStandard.Library.2.0.3\build\netstandard2.0\NETStandard.Library.targets')" Text="$([System.String]::Format('$(ErrorText)', 'packages\NETStandard.Library.2.0.3\build\netstandard2.0\NETStandard.Library.targets'))" /> | |||
</Target> | |||
<Import Project="packages\Costura.Fody.5.7.0\build\Costura.Fody.targets" Condition="Exists('packages\Costura.Fody.5.7.0\build\Costura.Fody.targets')" /> | |||
<Import Project="packages\Fody.6.8.0\build\Fody.targets" Condition="Exists('packages\Fody.6.8.0\build\Fody.targets')" /> | |||
<Import Project="packages\NETStandard.Library.2.0.3\build\netstandard2.0\NETStandard.Library.targets" Condition="Exists('packages\NETStandard.Library.2.0.3\build\netstandard2.0\NETStandard.Library.targets')" /> | |||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it. | |||
Other similar extension points exist, see Microsoft.Common.targets. | |||
<Target Name="BeforeBuild"> | |||
</Target> | |||
<Target Name="AfterBuild"> | |||
</Target> | |||
--> | |||
</Project> |
@ -0,0 +1,16 @@ | |||
| |||
Microsoft Visual Studio Solution File, Format Version 12.00 | |||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "amecs", "amecs.csproj", "{BD020697-9E9B-4A46-8804-BC47F0FC2806}" | |||
EndProject | |||
Global | |||
GlobalSection(SolutionConfigurationPlatforms) = preSolution | |||
Debug|Any CPU = Debug|Any CPU | |||
Release|Any CPU = Release|Any CPU | |||
EndGlobalSection | |||
GlobalSection(ProjectConfigurationPlatforms) = postSolution | |||
{BD020697-9E9B-4A46-8804-BC47F0FC2806}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | |||
{BD020697-9E9B-4A46-8804-BC47F0FC2806}.Debug|Any CPU.Build.0 = Debug|Any CPU | |||
{BD020697-9E9B-4A46-8804-BC47F0FC2806}.Release|Any CPU.ActiveCfg = Release|Any CPU | |||
{BD020697-9E9B-4A46-8804-BC47F0FC2806}.Release|Any CPU.Build.0 = Release|Any CPU | |||
EndGlobalSection | |||
EndGlobal |
@ -0,0 +1,17 @@ | |||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> | |||
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> | |||
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3"> | |||
<security> | |||
<requestedPrivileges> | |||
<requestedExecutionLevel level="requireAdministrator" uiAccess="false"/> | |||
</requestedPrivileges> | |||
</security> | |||
</trustInfo> | |||
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1"> | |||
<application> | |||
<!-- Support Windows 10 and above - needed for certain functions to return | |||
correct Windows version. https://learn.microsoft.com/en-us/windows/win32/sbscs/application-manifests#supportedOS --> | |||
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" /> | |||
</application> | |||
</compatibility> | |||
</assembly> |
@ -0,0 +1,66 @@ | |||
<?xml version="1.0" encoding="utf-8"?> | |||
<packages> | |||
<package id="Costura.Fody" version="5.7.0" targetFramework="net472" developmentDependency="true" /> | |||
<package id="Fody" version="6.8.0" targetFramework="net472" developmentDependency="true" /> | |||
<package id="JetBrains.Annotations" version="2023.3.0" targetFramework="net472" /> | |||
<package id="Microsoft.Dism" version="3.1.0" targetFramework="net472" /> | |||
<package id="Microsoft.NETCore.Platforms" version="7.0.4" targetFramework="net472" /> | |||
<package id="Microsoft.Win32.Primitives" version="4.3.0" targetFramework="net472" /> | |||
<package id="NETStandard.Library" version="2.0.3" targetFramework="net472" /> | |||
<package id="System.AppContext" version="4.3.0" targetFramework="net472" /> | |||
<package id="System.CodeDom" version="8.0.0" targetFramework="net472" /> | |||
<package id="System.Console" version="4.3.1" targetFramework="net472" /> | |||
<package id="System.Diagnostics.DiagnosticSource" version="8.0.0" targetFramework="net472" /> | |||
<package id="System.DirectoryServices" version="8.0.0" targetFramework="net472" /> | |||
<package id="System.DirectoryServices.AccountManagement" version="8.0.0" targetFramework="net472" /> | |||
<package id="System.Management" version="8.0.0" targetFramework="net472" /> | |||
<package id="System.Net.Http" version="4.3.4" targetFramework="net472" /> | |||
<package id="System.Runtime.Extensions" version="4.3.1" targetFramework="net472" /> | |||
<package id="System.Security.Cryptography.Algorithms" version="4.3.1" targetFramework="net472" /> | |||
<package id="System.Security.Cryptography.X509Certificates" version="4.3.2" targetFramework="net472" /> | |||
<package id="System.Security.Permissions" version="8.0.0" targetFramework="net472" /> | |||
<package id="System.Text.RegularExpressions" version="4.3.1" targetFramework="net472" /> | |||
<package id="System.Xml.ReaderWriter" version="4.3.1" targetFramework="net472" /> | |||
<package id="System.Memory" version="4.5.5" targetFramework="net472" /> | |||
<package id="System.Net.Primitives" version="4.3.1" targetFramework="net472" /> | |||
<package id="System.Runtime" version="4.3.1" targetFramework="net472" /> | |||
<package id="System.Buffers" version="4.5.1" targetFramework="net472" /> | |||
<package id="System.Collections" version="4.3.0" targetFramework="net472" /> | |||
<package id="System.Collections.Concurrent" version="4.3.0" targetFramework="net472" /> | |||
<package id="System.Diagnostics.Debug" version="4.3.0" targetFramework="net472" /> | |||
<package id="System.Diagnostics.Tools" version="4.3.0" targetFramework="net472" /> | |||
<package id="System.Diagnostics.Tracing" version="4.3.0" targetFramework="net472" /> | |||
<package id="System.Drawing.Primitives" version="4.3.0" targetFramework="net472" /> | |||
<package id="System.Globalization" version="4.3.0" targetFramework="net472" /> | |||
<package id="System.Globalization.Calendars" version="4.3.0" targetFramework="net472" /> | |||
<package id="System.IO" version="4.3.0" targetFramework="net472" /> | |||
<package id="System.IO.Compression" version="4.3.0" targetFramework="net472" /> | |||
<package id="System.IO.Compression.ZipFile" version="4.3.0" targetFramework="net472" /> | |||
<package id="System.IO.FileSystem" version="4.3.0" targetFramework="net472" /> | |||
<package id="System.IO.FileSystem.AccessControl" version="5.0.0" targetFramework="net472" /> | |||
<package id="System.IO.FileSystem.Primitives" version="4.3.0" targetFramework="net472" /> | |||
<package id="System.Linq" version="4.3.0" targetFramework="net472" /> | |||
<package id="System.Linq.Expressions" version="4.3.0" targetFramework="net472" /> | |||
<package id="System.Net.Sockets" version="4.3.0" targetFramework="net472" /> | |||
<package id="System.Numerics.Vectors" version="4.5.0" targetFramework="net472" /> | |||
<package id="System.ObjectModel" version="4.3.0" targetFramework="net472" /> | |||
<package id="System.Reflection" version="4.3.0" targetFramework="net472" /> | |||
<package id="System.Reflection.Extensions" version="4.3.0" targetFramework="net472" /> | |||
<package id="System.Reflection.Primitives" version="4.3.0" targetFramework="net472" /> | |||
<package id="System.Resources.ResourceManager" version="4.3.0" targetFramework="net472" /> | |||
<package id="System.Runtime.CompilerServices.Unsafe" version="6.0.0" targetFramework="net472" /> | |||
<package id="System.Runtime.Handles" version="4.3.0" targetFramework="net472" /> | |||
<package id="System.Runtime.InteropServices" version="4.3.0" targetFramework="net472" /> | |||
<package id="System.Runtime.InteropServices.RuntimeInformation" version="4.3.0" targetFramework="net472" /> | |||
<package id="System.Runtime.Numerics" version="4.3.0" targetFramework="net472" /> | |||
<package id="System.Security.AccessControl" version="6.0.0" targetFramework="net472" /> | |||
<package id="System.Security.Cryptography.Encoding" version="4.3.0" targetFramework="net472" /> | |||
<package id="System.Security.Cryptography.Primitives" version="4.3.0" targetFramework="net472" /> | |||
<package id="System.Security.Principal.Windows" version="5.0.0" targetFramework="net472" /> | |||
<package id="System.Text.Encoding" version="4.3.0" targetFramework="net472" /> | |||
<package id="System.Text.Encoding.Extensions" version="4.3.0" targetFramework="net472" /> | |||
<package id="System.Threading" version="4.3.0" targetFramework="net472" /> | |||
<package id="System.Threading.Tasks" version="4.3.0" targetFramework="net472" /> | |||
<package id="System.Threading.Timer" version="4.3.0" targetFramework="net472" /> | |||
<package id="System.Xml.XDocument" version="4.3.0" targetFramework="net472" /> | |||
</packages> |