Compare commits

..
23 Commits
Author SHA1 Message Date
Belim bad09ce2c4 Delete Write-an-Extension.md 2025-09-07 15:50:04 +02:00
Belim f001c0c076 Delete Flyoobe.Extensions/Info.MD 2025-09-07 15:49:48 +02:00
Belim 4b5fdc2366 Create Write-an-Extension.md 2025-09-07 15:49:40 +02:00
Belim f1b5e4edb4 Create Info.MD 2025-09-07 15:49:11 +02:00
Belim c15b200a08 Delete Flyoobe.Extensions 2025-09-07 15:48:44 +02:00
Belim 25a23cf32e Create Flyoobe.Extensions 2025-09-07 15:48:32 +02:00
Belim d34e522d0e Update Write-an-Extension.md 2025-09-07 15:47:31 +02:00
Belim 4250d61c02 Create Write-an-Extension.md 2025-09-07 15:45:36 +02:00
Belim 377014f571 Merge pull request #284 from bovirus/main
Update Strings.it.resx
2025-09-05 08:06:58 +02:00
Belim dea23eaf28 Merge branch 'main' of https://github.com/builtbybel/Flyby11 2025-09-04 18:10:17 +02:00
Belim 257d6cd6c3 Commit InstallView, UpgradeView 2025-09-04 18:10:14 +02:00
Belim 421d3b2fb2 Update Flyoobe_Profile_Community.txt 2025-09-03 12:49:13 +02:00
Belim 2f2b2b2a17 Add files via upload 2025-09-03 12:47:02 +02:00
Belim 88fa2c6efb Create Info.md 2025-09-03 12:45:06 +02:00
bovirus 310521ab05 Update Strings.it.resx 2025-08-30 11:01:33 +02:00
Belim cfed49d76d Init-Flyoobe-part 2025-08-29 18:32:23 +02:00
Belim 9c7dbaa938 Update README.md 2025-08-27 10:10:56 +02:00
Belim 8f57b0e66e Merge pull request #237 from JohnFowler58/patch-1
Update Strings.hu.resx
2025-08-26 15:36:29 +02:00
Belim 0eda51cd73 Update README.md 2025-08-10 17:58:51 +02:00
Belim 49f8b087cd Update README.md 2025-08-10 10:31:31 +02:00
Belim dee378192c Update README.md 2025-08-02 18:01:08 +02:00
Belim 967f674c4c Update README.md 2025-07-30 17:18:38 +02:00
John Fowler feecd81887 Update Strings.hu.resx
Translate a new string.
2025-07-28 12:56:50 +02:00
121 changed files with 10848 additions and 43 deletions

No files matched your search

+2 -2
View File
@@ -280,6 +280,6 @@
<value>Kiválasztás a számítógépről</value>
</data>
<data name="msgClosing" xml:space="preserve">
<value>Thank you for using my app!\n\nI developed this application in my free time to help you upgrade from Windows 10 to Windows 11 – even on PCs that, according to Microsoft's hardware requirements, would normally not be supported.\n\nMy app helps you avoid purchasing a new computer and actively contributes to reducing unnecessary electronic waste.\n\nNormally, I do not charge anything for my projects – neither for development nor for support.\nHowever, since this app is significantly more comprehensive, offers more features, and requires more support, I would be grateful if you would consider making a small voluntary donation, if you are able to.\n\nOf course, only if you want to and can afford it.\n\nWould you like to donate on PayPal now?</value>
<value>Köszönöm, hogy használja az alkalmazásomat!\n\nEzt az alkalmazást a szabadidőmben fejlesztettem ki, hogy segítsek frissíteni a Windows 10-ről a Windows 11-re - még olyan számítógépeken is, amelyek a Microsoft hardverkövetelményei szerint normál esetben nem támogatottak.\n\nAz alkalmazásom segít elkerülni az új számítógép vásárlását, és aktívan hozzájárul a felesleges elektronikai hulladék csökkentéséhez. \nNormális esetben nem számítok fel semmit a projektjeimért - sem a fejlesztésért, sem a támogatásért.\nMivel azonban ez az alkalmazás lényegesen átfogóbb, több funkciót kínál, és több támogatást igényel, hálás lennék, ha fontolóra venné egy kis önkéntes adományozás lehetőségét, ha képes rá.\nTermészetesen csak akkor, ha szeretné és megengedheti magának.\n\nSzeretne most adományozni a PayPal-on?</value>
</data>
</root>
</root>
+12 -12
View File
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
@@ -242,44 +242,44 @@
</data>
<data name="msg_InstallReady" xml:space="preserve">
<value>L'installazione di Windows 11 può ora procedere. Segui le istruzioni nella finestra di configurazione.</value>
<comment>Installa</comment>
<comment>Install</comment>
</data>
<data name="_debugInstallReady" xml:space="preserve">
<value>Sei pronto per installare Windows 11 con hardware non supportato! Ignora il prompt "Windows Server"; tutto è pronto!</value>
<comment>Installa</comment>
<comment>Install</comment>
</data>
<data name="_debugInstallRunElevated" xml:space="preserve">
<value>Avvio processo configurazione con privilegi elevati ...</value>
<comment>Installa</comment>
<comment>Install</comment>
</data>
<data name="_debugStatusHandleIsoEx" xml:space="preserve">
<value>Oops! Qualcosa è andato storto:</value>
<comment>Montaggio</comment>
<comment>Mounting</comment>
</data>
<data name="_debugStatusMounting" xml:space="preserve">
<value>Montaggio file...</value>
<comment>Montaggio</comment>
<comment>Mounting</comment>
</data>
<data name="_debugStatusMountingFailed" xml:space="preserve">
<value>Impossibile montare il file ISO. Riprova.</value>
<comment>Montaggio</comment>
<comment>Mounting</comment>
</data>
<data name="_debugStatusMountingSuccess" xml:space="preserve">
<value>File ISO montato correttamente! Procediamo con l'installazione di Windows 11!</value>
<comment>Montaggio</comment>
<comment>Mounting</comment>
</data>
<data name="_debugStatusRunning" xml:space="preserve">
<value>Ci siamo quasi! Preparazione installazione ...</value>
<comment>Installazione</comment>
<comment>Install</comment>
</data>
<data name="_debugStatusSetupFileNotFound" xml:space="preserve">
<value>File configurazione non trovato in</value>
<comment>Montaggio</comment>
<comment>Mounting</comment>
</data>
<data name="ctl_linkSelectComputer" xml:space="preserve">
<value>Seleziona dal computer</value>
</data>
<data name="msgClosing" xml:space="preserve">
<value />
<value>Grazie per aver usato questa app!\n\nHo sviluppato questa app nel mio tempo libero per aiutarti ad aggiornare da Windows 10 a Windows 11 - anche su PC che, secondo i requisiti hardware di Microsoft, normalmente non sarebbero supportati.\nQuesta app ti aiuta ad evitare di acquistare un nuovo computer e contribuisce attivamente ad evitare di produrre rifiuti elettronici inutili.\nNormalmnte non chiedo nulla per i miei progetti - né per lo sviluppo né per il supporto.\nQuesta app è significativamente completa, offre tante funzionalità e richiede più supporto, ti sarei grato se considereresti di fare una piccola donazione volontaria, se sei in grado di farlo.\n\nOvviamente , solo se vuoi e puoi permettertelo.\nVuoi donare un piccolo contributo con Paypal?</value>
</data>
</root>
</root>
+38
View File
@@ -0,0 +1,38 @@
# 🆕 Setup Extensions: Host + Options Support
The **Setup Extensions** system now supports extended script metadata in the header.
This allows script authors to define dropdown menus and control how the script is executed.
---
## ✅ New Metadata Parameters
### `# Description: <string>`
- Short, user-friendly description of what the script does.
- Displayed in the Extensions page below the title.
### `# Host: embedded | console`
- **embedded** = run inside OOBE, output is captured and shown in the app.
- **console** = run in an external PowerShell window with `-NoExit`.
- **Default:** `embedded` (if not specified).
### `# Options: value1; value2; value3; ...`
- Defines multiple selectable actions for a single script.
- A dropdown is automatically shown in the Extensions page.
- The selected value is passed to the script as `$choice`.
---
## 📄 Example Script Header
```powershell
# Description: File Explorer tweaks
# Host: embedded
# Options: Show file extensions; Hide file extensions; Open This PC
param([string]$choice)
switch ($choice) {
"Show file extensions" { ... }
"Hide file extensions" { ... }
"Open This PC" { ... }
}
+25
View File
@@ -0,0 +1,25 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.14.36414.22
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Flyoobe.Spot", "Flyoobe.ToolSpot\Flyoobe.Spot.csproj", "{1133824D-6F42-48D4-8F18-A93AB7403DB7}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{1133824D-6F42-48D4-8F18-A93AB7403DB7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1133824D-6F42-48D4-8F18-A93AB7403DB7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1133824D-6F42-48D4-8F18-A93AB7403DB7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1133824D-6F42-48D4-8F18-A93AB7403DB7}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {B22B36E3-C594-46AF-AF57-3C03B2F97541}
EndGlobalSection
EndGlobal
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8.1" />
</startup>
</configuration>
@@ -0,0 +1,88 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{1133824D-6F42-48D4-8F18-A93AB7403DB7}</ProjectGuid>
<OutputType>WinExe</OutputType>
<RootNamespace>Flyoobe.Spot</RootNamespace>
<AssemblyName>spot</AssemblyName>
<TargetFrameworkVersion>v4.8.1</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<Deterministic>true</Deterministic>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup>
<ApplicationManifest>app.manifest</ApplicationManifest>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Deployment" />
<Reference Include="System.Drawing" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="MainForm.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="MainForm.Designer.cs">
<DependentUpon>MainForm.cs</DependentUpon>
</Compile>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<EmbeddedResource Include="MainForm.resx">
<DependentUpon>MainForm.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
<SubType>Designer</SubType>
</EmbeddedResource>
<Compile Include="Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Resources.resx</DependentUpon>
<DesignTime>True</DesignTime>
</Compile>
<None Include="app.manifest" />
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
<Compile Include="Properties\Settings.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Settings.settings</DependentUpon>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile>
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
+105
View File
@@ -0,0 +1,105 @@
namespace Flyoobe.ToolSpot
{
partial class MainForm
{
/// <summary>
/// Erforderliche Designervariable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Verwendete Ressourcen bereinigen.
/// </summary>
/// <param name="disposing">True, wenn verwaltete Ressourcen gelöscht werden sollen; andernfalls False.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Vom Windows Form-Designer generierter Code
/// <summary>
/// Erforderliche Methode für die Designerunterstützung.
/// Der Inhalt der Methode darf nicht mit dem Code-Editor geändert werden.
/// </summary>
private void InitializeComponent()
{
this.listResults = new System.Windows.Forms.ListBox();
this.textSearch = new System.Windows.Forms.TextBox();
this.labelStatus = new System.Windows.Forms.Label();
this.SuspendLayout();
//
// listResults
//
this.listResults.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.listResults.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(249)))), ((int)(((byte)(243)))), ((int)(((byte)(240)))));
this.listResults.BorderStyle = System.Windows.Forms.BorderStyle.None;
this.listResults.Font = new System.Drawing.Font("Segoe UI Variable Small Semilig", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.listResults.FormattingEnabled = true;
this.listResults.ItemHeight = 17;
this.listResults.Location = new System.Drawing.Point(25, 72);
this.listResults.Name = "listResults";
this.listResults.Size = new System.Drawing.Size(504, 170);
this.listResults.TabIndex = 5;
this.listResults.TabStop = false;
this.listResults.DoubleClick += new System.EventHandler(this.listResults_DoubleClick);
this.listResults.KeyDown += new System.Windows.Forms.KeyEventHandler(this.listResults_KeyDown);
//
// textSearch
//
this.textSearch.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.textSearch.Font = new System.Drawing.Font("Segoe UI Variable Small Semilig", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.textSearch.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64)))));
this.textSearch.Location = new System.Drawing.Point(25, 26);
this.textSearch.Name = "textSearch";
this.textSearch.Size = new System.Drawing.Size(504, 29);
this.textSearch.TabIndex = 1;
this.textSearch.Text = "Search";
this.textSearch.Click += new System.EventHandler(this.textSearch_Click);
this.textSearch.TextChanged += new System.EventHandler(this.textSearch_TextChanged);
//
// labelStatus
//
this.labelStatus.Dock = System.Windows.Forms.DockStyle.Bottom;
this.labelStatus.Font = new System.Drawing.Font("Segoe UI Variable Small Semilig", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.labelStatus.Location = new System.Drawing.Point(0, 251);
this.labelStatus.Name = "labelStatus";
this.labelStatus.Size = new System.Drawing.Size(557, 21);
this.labelStatus.TabIndex = 2;
//
// MainForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(242)))), ((int)(((byte)(244)))), ((int)(((byte)(244)))));
this.ClientSize = new System.Drawing.Size(557, 272);
this.Controls.Add(this.labelStatus);
this.Controls.Add(this.textSearch);
this.Controls.Add(this.listResults);
this.Name = "MainForm";
this.ShowIcon = false;
this.ShowInTaskbar = false;
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "Spot";
this.Load += new System.EventHandler(this.Form1_Load);
this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.Form1_KeyDown);
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.ListBox listResults;
private System.Windows.Forms.TextBox textSearch;
private System.Windows.Forms.Label labelStatus;
}
}
@@ -0,0 +1,209 @@
/// This tool is part of my Flyoobe app
using System;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Windows.Forms;
namespace Flyoobe.ToolSpot
{
public partial class MainForm : Form
{ // Path of the text DB
public string DatabasePath { get; set; } =
Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "spot.txt");
// In-memory list of all tools
private readonly List<ToolItem> _all = new List<ToolItem>();
public MainForm()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
LoadDatabase();
//ApplyFilter(); // show all initially
textSearch.Focus();
}
private void SetStatus(string text)
{
if (labelStatus != null) labelStatus.Text = text;
}
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Escape)
{
// close it
var form = this.FindForm();
form?.Close();
}
}
private void listResults_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter) { LaunchSelected(); e.Handled = true; }
}
private void listResults_DoubleClick(object sender, EventArgs e) => LaunchSelected();
private void textSearch_TextChanged(object sender, EventArgs e) => ApplyFilter();
/// <summary>
/// Reads toolspot.txt (Name;Command). Ignores empty and comment lines.
/// </summary>
private void LoadDatabase()
{
_all.Clear();
if (!File.Exists(DatabasePath))
{
SetStatus($"Database not found: {DatabasePath}");
return;
}
foreach (var line in File.ReadAllLines(DatabasePath))
{
var trimmed = line.Trim();
if (string.IsNullOrEmpty(trimmed)) continue;
if (trimmed.StartsWith("#")) continue;
var item = ParseLine(trimmed);
if (item != null) _all.Add(item);
}
SetStatus($"Loaded {_all.Count} tools.");
}
/// <summary>
/// Parses "Name;Command" lines. Returns null if malformed.
/// </summary>
private ToolItem ParseLine(string line)
{
var parts = line.Split(new[] { ';' }, 2);
if (parts.Length != 2) return null;
var name = parts[0].Trim();
var cmd = parts[1].Trim();
if (name.Length == 0 || cmd.Length == 0) return null;
return new ToolItem(name, cmd);
}
/// <summary>
/// Filters list by substring (case-insensitive) from textSearch.
/// </summary>
private void ApplyFilter()
{
var q = (textSearch.Text ?? string.Empty).Trim().ToLower();
var list = string.IsNullOrEmpty(q)
? _all
: _all.Where(t => t.Name.ToLower().Contains(q)).ToList();
listResults.BeginUpdate();
listResults.Items.Clear();
foreach (var t in list) listResults.Items.Add(t);
listResults.EndUpdate();
if (listResults.Items.Count > 0) listResults.SelectedIndex = 0;
SetStatus(listResults.Items.Count > 0 ? $"{listResults.Items.Count} result(s)" : "No results");
}
/// <summary>
/// Launches the selected tool's command. Supports URIs, .msc/.cpl, exe + args.
/// </summary>
private void LaunchSelected()
{
if (!(listResults.SelectedItem is ToolItem t)) return;
try
{
// Split command into FileName + Arguments (handles quoted paths)
SplitCommand(t.Command, out var fileName, out var args);
var psi = new ProcessStartInfo
{
FileName = fileName,
Arguments = args,
UseShellExecute = true // required for ms-settings:, .msc/.cpl
};
Process.Start(psi);
}
catch (Exception ex)
{
MessageBox.Show("Could not launch: " + ex.Message, "Quick Tools",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
/// <summary>
/// Splits a command line into executable and arguments.
/// Examples:
/// notepad.exe
/// "C:\Path With Spaces\app.exe" --flag
/// chrome.exe --settings
/// For URIs / shell verbs (e.g., ms-settings:...), no split is needed.
/// </summary>
private void SplitCommand(string command, out string fileName, out string args)
{
command = command.Trim();
// If it's a URI-like command (ms-settings:, http:, etc.), pass as-is.
if (command.Contains(":") && !command.Contains("\\"))
{
fileName = command;
args = string.Empty;
return;
}
// Quoted path case: "C:\Program Files\App\app.exe" arg1 arg2
if (command.StartsWith("\""))
{
int end = command.IndexOf('"', 1);
if (end > 0)
{
fileName = command.Substring(1, end - 1);
args = command.Substring(end + 1).TrimStart();
return;
}
}
// Unquoted: split on first space
int space = command.IndexOf(' ');
if (space > 0)
{
fileName = command.Substring(0, space);
args = command.Substring(space + 1);
}
else
{
fileName = command;
args = string.Empty;
}
}
private class ToolItem
{
public string Name { get; }
public string Command { get; }
public ToolItem(string name, string command)
{ Name = name; Command = command; }
public override string ToString() => Name; // shown in ListBox
}
private void textSearch_Click(object sender, EventArgs e)
{
textSearch.Clear();
}
}
}
@@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>
@@ -0,0 +1,22 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Flyoobe.ToolSpot
{
internal static class Program
{
/// <summary>
/// Der Haupteinstiegspunkt für die Anwendung.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new MainForm());
}
}
}
@@ -0,0 +1,33 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// Allgemeine Informationen über eine Assembly werden über die folgenden
// Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern,
// die einer Assembly zugeordnet sind.
[assembly: AssemblyTitle("Spot")]
[assembly: AssemblyDescription("Flyoobe Spot")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Builtbybel")]
[assembly: AssemblyProduct("Flyoobe Spot")]
[assembly: AssemblyCopyright("Copyright © 2025")]
[assembly: AssemblyTrademark("A Belim app creation")]
[assembly: AssemblyCulture("")]
// Durch Festlegen von ComVisible auf FALSE werden die Typen in dieser Assembly
// für COM-Komponenten unsichtbar. Wenn Sie auf einen Typ in dieser Assembly von
// COM aus zugreifen müssen, sollten Sie das ComVisible-Attribut für diesen Typ auf "True" festlegen.
[assembly: ComVisible(false)]
// Die folgende GUID bestimmt die ID der Typbibliothek, wenn dieses Projekt für COM verfügbar gemacht wird
[assembly: Guid("1133824d-6f42-48d4-8f18-a93ab7403db7")]
// Versionsinformationen für eine Assembly bestehen aus den folgenden vier Werten:
//
// Hauptversion
// Nebenversion
// Buildnummer
// Revision
//
[assembly: AssemblyVersion("0.2.0.0")]
[assembly: AssemblyFileVersion("0.2.0.0")]
@@ -0,0 +1,63 @@
//------------------------------------------------------------------------------
// <auto-generated>
// Dieser Code wurde von einem Tool generiert.
// Laufzeitversion:4.0.30319.42000
//
// Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn
// der Code erneut generiert wird.
// </auto-generated>
//------------------------------------------------------------------------------
namespace Flyoobe.Spot.Properties {
using System;
/// <summary>
/// Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw.
/// </summary>
// Diese Klasse wurde von der StronglyTypedResourceBuilder automatisch generiert
// -Klasse über ein Tool wie ResGen oder Visual Studio automatisch generiert.
// Um einen Member hinzuzufügen oder zu entfernen, bearbeiten Sie die .ResX-Datei und führen dann ResGen
// mit der /str-Option erneut aus, oder Sie erstellen Ihr VS-Projekt neu.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources() {
}
/// <summary>
/// Gibt die zwischengespeicherte ResourceManager-Instanz zurück, die von dieser Klasse verwendet wird.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Flyoobe.Spot.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Überschreibt die CurrentUICulture-Eigenschaft des aktuellen Threads für alle
/// Ressourcenzuordnungen, die diese stark typisierte Ressourcenklasse verwenden.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
}
}
@@ -0,0 +1,117 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>
@@ -0,0 +1,26 @@
//------------------------------------------------------------------------------
// <auto-generated>
// Dieser Code wurde von einem Tool generiert.
// Laufzeitversion:4.0.30319.42000
//
// Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn
// der Code erneut generiert wird.
// </auto-generated>
//------------------------------------------------------------------------------
namespace Flyoobe.Spot.Properties {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.14.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
public static Settings Default {
get {
return defaultInstance;
}
}
}
}
@@ -0,0 +1,7 @@
<?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)">
<Profiles>
<Profile Name="(Default)" />
</Profiles>
<Settings />
</SettingsFile>
@@ -0,0 +1,79 @@
<?xml version="1.0" encoding="utf-8"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
<assemblyIdentity version="1.0.0.0" name="MyApplication.app"/>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
<security>
<requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
<!-- UAC-Manifestoptionen
Wenn Sie die Ebene der Benutzerkontensteuerung für Windows ändern möchten, ersetzen Sie den
Knoten "requestedExecutionLevel" wie folgt.
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
<requestedExecutionLevel level="highestAvailable" uiAccess="false" />
Durch Angabe des Elements "requestedExecutionLevel" wird die Datei- und Registrierungsvirtualisierung deaktiviert.
Entfernen Sie dieses Element, wenn diese Virtualisierung aus Gründen der Abwärtskompatibilität
für die Anwendung erforderlich ist.
-->
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
</requestedPrivileges>
</security>
</trustInfo>
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
<!-- Eine Liste der Windows-Versionen, unter denen diese Anwendung getestet
und für die sie entwickelt wurde. Wenn Sie die Auskommentierung der entsprechenden Elemente aufheben,
wird von Windows automatisch die kompatibelste Umgebung ausgewählt. -->
<!-- Windows Vista -->
<!--<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}" />-->
<!-- Windows 7 -->
<!--<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}" />-->
<!-- Windows 8 -->
<!--<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}" />-->
<!-- Windows 8.1 -->
<!--<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}" />-->
<!-- Windows 10 -->
<!--<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />-->
</application>
</compatibility>
<!-- Gibt an, dass die Anwendung mit DPI-Werten kompatibel ist und von Windows nicht automatisch auf höhere
DPI-Werte skaliert wird. WPF-Anwendungen (Windows Presentation Foundation) sind automatisch mit DPI-Werten kompatibel, eine Aktivierung
ist nicht erforderlich. Für Windows Forms-Anwendungen für .NET Framework 4.6, die diese Einstellung aktivieren, muss
auch die Einstellung "'EnableWindowsFormsHighDpiAutoResizing" in der Datei "app.config" auf TRUE festgelegt werden.
Hierdurch können für die Anwendung lange Pfade verwendet werden. Weitere Informationen finden Sie unter https://docs.microsoft.com/windows/win32/fileio/maximum-file-path-limitation.-->
<application xmlns="urn:schemas-microsoft-com:asm.v3">
<windowsSettings>
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware>
<longPathAware xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">true</longPathAware>
</windowsSettings>
</application>
<!-- Designs für allgemeine Windows-Steuerelemente und -Dialogfelder (Windows XP und höher) aktivieren -->
<!--
<dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0"
processorArchitecture="*"
publicKeyToken="6595b64144ccf1df"
language="*"
/>
</dependentAssembly>
</dependency>
-->
</assembly>
+216
View File
@@ -0,0 +1,216 @@
namespace Flyoobe
{
partial class AboutForm
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.panel1 = new System.Windows.Forms.Panel();
this.linkAppVersion = new System.Windows.Forms.LinkLabel();
this.chkDonated = new System.Windows.Forms.CheckBox();
this.btnDonate = new System.Windows.Forms.Button();
this.lblHeader = new System.Windows.Forms.Label();
this.lblCopyright = new System.Windows.Forms.Label();
this.btnGitHub = new System.Windows.Forms.Button();
this.btnClose = new System.Windows.Forms.Button();
this.panel1.SuspendLayout();
this.SuspendLayout();
//
// panel1
//
this.panel1.Anchor = System.Windows.Forms.AnchorStyles.Top;
this.panel1.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(240)))), ((int)(((byte)(230)))), ((int)(((byte)(220)))));
this.panel1.Controls.Add(this.linkAppVersion);
this.panel1.Controls.Add(this.chkDonated);
this.panel1.Controls.Add(this.btnDonate);
this.panel1.Controls.Add(this.lblHeader);
this.panel1.Controls.Add(this.lblCopyright);
this.panel1.Controls.Add(this.btnGitHub);
this.panel1.Location = new System.Drawing.Point(13, 63);
this.panel1.Name = "panel1";
this.panel1.Size = new System.Drawing.Size(411, 274);
this.panel1.TabIndex = 322;
//
// linkAppVersion
//
this.linkAppVersion.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.linkAppVersion.AutoEllipsis = true;
this.linkAppVersion.Font = new System.Drawing.Font("Segoe UI Variable Small Semibol", 11.75F, System.Drawing.FontStyle.Bold);
this.linkAppVersion.LinkBehavior = System.Windows.Forms.LinkBehavior.HoverUnderline;
this.linkAppVersion.LinkColor = System.Drawing.Color.Black;
this.linkAppVersion.Location = new System.Drawing.Point(3, 75);
this.linkAppVersion.Name = "linkAppVersion";
this.linkAppVersion.Size = new System.Drawing.Size(405, 46);
this.linkAppVersion.TabIndex = 334;
this.linkAppVersion.TabStop = true;
this.linkAppVersion.Text = "Version";
this.linkAppVersion.TextAlign = System.Drawing.ContentAlignment.TopCenter;
this.linkAppVersion.UseCompatibleTextRendering = true;
this.linkAppVersion.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.linkAppVersion_LinkClicked);
//
// chkDonated
//
this.chkDonated.Anchor = System.Windows.Forms.AnchorStyles.Bottom;
this.chkDonated.AutoSize = true;
this.chkDonated.Font = new System.Drawing.Font("Segoe UI Variable Small Semilig", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.chkDonated.ForeColor = System.Drawing.Color.Black;
this.chkDonated.Location = new System.Drawing.Point(14, 255);
this.chkDonated.Name = "chkDonated";
this.chkDonated.Size = new System.Drawing.Size(141, 19);
this.chkDonated.TabIndex = 333;
this.chkDonated.Text = "I have already donated";
this.chkDonated.UseVisualStyleBackColor = true;
this.chkDonated.CheckedChanged += new System.EventHandler(this.chkDonated_CheckedChanged);
//
// btnDonate
//
this.btnDonate.Anchor = System.Windows.Forms.AnchorStyles.None;
this.btnDonate.AutoEllipsis = true;
this.btnDonate.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(29)))), ((int)(((byte)(27)))), ((int)(((byte)(26)))));
this.btnDonate.Cursor = System.Windows.Forms.Cursors.Hand;
this.btnDonate.FlatAppearance.BorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(141)))), ((int)(((byte)(141)))), ((int)(((byte)(141)))));
this.btnDonate.FlatAppearance.BorderSize = 0;
this.btnDonate.FlatAppearance.MouseOverBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(243)))), ((int)(((byte)(243)))), ((int)(((byte)(243)))));
this.btnDonate.FlatStyle = System.Windows.Forms.FlatStyle.System;
this.btnDonate.Font = new System.Drawing.Font("Segoe UI Variable Display Semib", 11F, System.Drawing.FontStyle.Bold);
this.btnDonate.ForeColor = System.Drawing.Color.White;
this.btnDonate.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft;
this.btnDonate.Location = new System.Drawing.Point(12, 214);
this.btnDonate.Name = "btnDonate";
this.btnDonate.Size = new System.Drawing.Size(388, 38);
this.btnDonate.TabIndex = 331;
this.btnDonate.TabStop = false;
this.btnDonate.Text = "Donate";
this.btnDonate.UseCompatibleTextRendering = true;
this.btnDonate.UseVisualStyleBackColor = false;
this.btnDonate.Click += new System.EventHandler(this.btnDonate_Click);
//
// lblHeader
//
this.lblHeader.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.lblHeader.AutoEllipsis = true;
this.lblHeader.Font = new System.Drawing.Font("Segoe UI Variable Small Semibol", 20.75F, System.Drawing.FontStyle.Bold);
this.lblHeader.ForeColor = System.Drawing.Color.Black;
this.lblHeader.Location = new System.Drawing.Point(3, 20);
this.lblHeader.Name = "lblHeader";
this.lblHeader.Size = new System.Drawing.Size(405, 38);
this.lblHeader.TabIndex = 330;
this.lblHeader.Text = "Flyoobe";
this.lblHeader.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
this.lblHeader.UseCompatibleTextRendering = true;
//
// lblCopyright
//
this.lblCopyright.Anchor = System.Windows.Forms.AnchorStyles.None;
this.lblCopyright.BackColor = System.Drawing.Color.Transparent;
this.lblCopyright.Font = new System.Drawing.Font("Segoe UI Variable Small Semilig", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.lblCopyright.ForeColor = System.Drawing.Color.Black;
this.lblCopyright.Location = new System.Drawing.Point(3, 127);
this.lblCopyright.Name = "lblCopyright";
this.lblCopyright.Size = new System.Drawing.Size(405, 21);
this.lblCopyright.TabIndex = 319;
this.lblCopyright.Text = "A Belim app creation (C) 2025";
this.lblCopyright.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
this.lblCopyright.UseCompatibleTextRendering = true;
//
// btnGitHub
//
this.btnGitHub.Anchor = System.Windows.Forms.AnchorStyles.None;
this.btnGitHub.AutoEllipsis = true;
this.btnGitHub.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(29)))), ((int)(((byte)(27)))), ((int)(((byte)(26)))));
this.btnGitHub.Cursor = System.Windows.Forms.Cursors.Hand;
this.btnGitHub.FlatAppearance.BorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(141)))), ((int)(((byte)(141)))), ((int)(((byte)(141)))));
this.btnGitHub.FlatAppearance.BorderSize = 0;
this.btnGitHub.FlatAppearance.MouseOverBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(243)))), ((int)(((byte)(243)))), ((int)(((byte)(243)))));
this.btnGitHub.FlatStyle = System.Windows.Forms.FlatStyle.System;
this.btnGitHub.Font = new System.Drawing.Font("Segoe UI Variable Display Semib", 11F, System.Drawing.FontStyle.Bold);
this.btnGitHub.ForeColor = System.Drawing.Color.White;
this.btnGitHub.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft;
this.btnGitHub.Location = new System.Drawing.Point(12, 170);
this.btnGitHub.Name = "btnGitHub";
this.btnGitHub.Size = new System.Drawing.Size(388, 38);
this.btnGitHub.TabIndex = 317;
this.btnGitHub.TabStop = false;
this.btnGitHub.Text = "GitHub";
this.btnGitHub.UseCompatibleTextRendering = true;
this.btnGitHub.UseVisualStyleBackColor = false;
this.btnGitHub.Click += new System.EventHandler(this.btnGitHub_Click);
//
// btnClose
//
this.btnClose.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.btnClose.AutoSize = true;
this.btnClose.BackColor = System.Drawing.Color.Transparent;
this.btnClose.FlatAppearance.BorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(252)))), ((int)(((byte)(247)))), ((int)(((byte)(242)))));
this.btnClose.FlatAppearance.BorderSize = 0;
this.btnClose.FlatAppearance.MouseDownBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(252)))), ((int)(((byte)(247)))), ((int)(((byte)(242)))));
this.btnClose.FlatAppearance.MouseOverBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(252)))), ((int)(((byte)(247)))), ((int)(((byte)(242)))));
this.btnClose.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.btnClose.Font = new System.Drawing.Font("Segoe MDL2 Assets", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.btnClose.ForeColor = System.Drawing.Color.Black;
this.btnClose.Location = new System.Drawing.Point(387, 15);
this.btnClose.Name = "btnClose";
this.btnClose.Size = new System.Drawing.Size(30, 29);
this.btnClose.TabIndex = 332;
this.btnClose.Text = "...";
this.btnClose.UseVisualStyleBackColor = false;
this.btnClose.Click += new System.EventHandler(this.btnClose_Click);
//
// AboutForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(240)))), ((int)(((byte)(230)))), ((int)(((byte)(220)))));
this.ClientSize = new System.Drawing.Size(436, 349);
this.Controls.Add(this.btnClose);
this.Controls.Add(this.panel1);
this.Name = "AboutForm";
this.Opacity = 0.95D;
this.ShowIcon = false;
this.ShowInTaskbar = false;
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
this.Load += new System.EventHandler(this.AboutForm_Load);
this.panel1.ResumeLayout(false);
this.panel1.PerformLayout();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Panel panel1;
private System.Windows.Forms.Label lblCopyright;
private System.Windows.Forms.Button btnGitHub;
private System.Windows.Forms.Label lblHeader;
private System.Windows.Forms.Button btnClose;
private System.Windows.Forms.Button btnDonate;
private System.Windows.Forms.CheckBox chkDonated;
private System.Windows.Forms.LinkLabel linkAppVersion;
}
}
+212
View File
@@ -0,0 +1,212 @@
using System;
using System.Diagnostics;
using System.Drawing;
using System.Net.Http;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Flyoobe
{
public partial class AboutForm : Form
{
public AboutForm()
{
InitializeComponent();
this.FormBorderStyle = FormBorderStyle.None;
this.DoubleBuffered = true;
linkAppVersion.Text = $"You have Flyoobe version {Program.GetAppVersion()}\n" +
"(Fetching updates...)";
btnClose.Text = "\uEF2C";
ApplyRoundedCorners();
chkDonated.Checked = DonationHelper.HasDonated();
}
private async void AboutForm_Load(object sender, EventArgs e)
{
await Task.Delay(1000);
// Call update check when form loads
await CheckForUpdateAsync();
}
private void ApplyRoundedCorners()
{
int radius = 60; // Corner radius
var path = new System.Drawing.Drawing2D.GraphicsPath();
path.AddArc(0, 0, radius, radius, 180, 90); // top-left
path.AddArc(this.Width - radius, 0, radius, radius, 270, 90); // top-right
path.AddArc(this.Width - radius, this.Height - radius, radius, radius, 0, 90); // bottom-right
path.AddArc(0, this.Height - radius, radius, radius, 90, 90); // bottom-left
path.CloseFigure();
this.Region = new Region(path); // Apply the rounded shape
}
protected override void OnResize(EventArgs e)
{
base.OnResize(e);
ApplyRoundedCorners(); // Reapply on resize
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
int radius = 45;
int borderWidth = 1;
// Adjust drawing rectangle
var rect = new Rectangle(borderWidth / 2, borderWidth / 2, Width - borderWidth, Height - borderWidth);
radius = Math.Min(radius, Math.Min(rect.Width, rect.Height) / 2); // Clamp radius
var path = new System.Drawing.Drawing2D.GraphicsPath();
path.AddArc(rect.Left, rect.Top, radius * 2, radius * 2, 180, 90);
path.AddArc(rect.Right - radius * 2, rect.Top, radius * 2, radius * 2, 270, 90);
path.AddArc(rect.Right - radius * 2, rect.Bottom - radius * 2, radius * 2, radius * 2, 0, 90);
path.AddArc(rect.Left, rect.Bottom - radius * 2, radius * 2, radius * 2, 90, 90);
path.CloseFigure();
e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
e.Graphics.DrawPath(new Pen(Color.Gray, borderWidth), path); // Draw border
this.Region = new Region(path); // apply rounded region
}
private void btnGitHub_Click(object sender, EventArgs e)
{
Process.Start("https://github.com/builtbybel/Flyby11");
}
private void btnClose_Click(object sender, EventArgs e)
{
this.Close();
}
private void btnDonate_Click(object sender, EventArgs e)
{
System.Diagnostics.Process.Start(new System.Diagnostics.ProcessStartInfo
{
FileName = "https://www.paypal.com/donate?hosted_button_id=MY7HX4QLYR4KG",
UseShellExecute = true
});
}
private void chkDonated_CheckedChanged(object sender, EventArgs e)
{
DonationHelper.SetDonationStatus(chkDonated.Checked);
}
private Version NormalizeVersionString(string version)
{
// Split by dot
var parts = version.Split('.');
// Add missing zeros to have at least 3 parts
while (parts.Length < 3)
{
version += ".0";
parts = version.Split('.');
}
return Version.Parse(version);
}
private async Task CheckForUpdateAsync()
{
const string githubApiUrl = "https://api.github.com/repos/builtbybel/Flyby11/releases/latest";
try
{
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.UserAgent.ParseAdd("FlyoobeUpdateChecker");
var response = await client.GetAsync(githubApiUrl);
response.EnsureSuccessStatusCode();
string json = await response.Content.ReadAsStringAsync();
const string tagKey = "\"tag_name\":\"";
int index = json.IndexOf(tagKey);
if (index < 0)
{
UpdateLabel($"Flyoobe v{Program.GetAppVersion()}");
return;
}
int start = index + tagKey.Length;
int end = json.IndexOf("\"", start);
if (end <= start)
{
UpdateLabel($"Flyoobe version {Program.GetAppVersion()}");
return;
}
string latestTag = json.Substring(start, end - start);
if (latestTag.StartsWith("v"))
latestTag = latestTag.Substring(1);
string currentVersionString = Program.GetAppVersion();
Version latestVersion = NormalizeVersionString(latestTag);
Version currentVersion = NormalizeVersionString(currentVersionString);
if (latestVersion > currentVersion)
{
UpdateLabel($"Update available: v{latestVersion}", clickable: true);
}
else if (latestVersion == currentVersion)
{
UpdateLabel($"Flyoobe version {currentVersion} (up-to-date)");
}
else
{
// User has a dev or newer version
UpdateLabel($"Flyoobe version {currentVersion} (dev version?)");
}
}
}
catch (Exception ex)
{
UpdateLabel($"Update check failed: {ex.Message}");
}
}
// Helper method to update label safely on UI thread
private void UpdateLabel(string text, bool clickable = false)
{
// Update label text
linkAppVersion.Text = text;
// If clickable,
// show bold ; underline ; make cursor a hand
if (clickable)
{
linkAppVersion.Font = new Font(linkAppVersion.Font, FontStyle.Bold | FontStyle.Underline);
linkAppVersion.Enabled = true;
linkAppVersion.Cursor = Cursors.Hand;
}
else
{
// Otherwise normal font and default cursor
linkAppVersion.Font = new Font(linkAppVersion.Font, FontStyle.Regular);
linkAppVersion.Enabled = false;
linkAppVersion.Cursor = Cursors.Default;
}
}
private void linkAppVersion_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
{
Process.Start(new ProcessStartInfo
{
FileName = "https://github.com/builtbybel/Flyby11/releases/latest",
UseShellExecute = true
});
}
}
}
+120
View File
@@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>
+6
View File
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8"/>
</startup>
</configuration>
Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

+71
View File
@@ -0,0 +1,71 @@
using Microsoft.Win32;
using Flyoobe;
using System;
using System.Threading.Tasks;
namespace Settings.UI
{
/// <summary>
/// Disables the Click to Do feature, which also removes its entry from the right-click context menu.
/// Only available on Copilot+ PCs running Windows 11 24H2 or newer.
/// Requires a PC with an NPU (Neural Processing Unit).
/// </summary>
internal class ClickToDo : FeatureBase
{
private const string keyName = @"HKEY_CURRENT_USER\Software\Microsoft\Windows\Shell\ClickToDo";
private const string valueName = "DisableClickToDo";
private const int recommendedValue = 1; // 1 = fully disabled, including context menu
public override string GetFeatureDetails()
{
return $"{keyName} | Value: {valueName} | Set to: {recommendedValue} (disables Click to Do, removing it from context menus). " +
"Note: This setting only applies on Copilot+ PCs with Windows 11 24H2 or newer.";
}
public override string ID()
{
return "Disable Click to Do (Only Copilot+ PCs)";
}
public override string Info()
{
return "Disables Click to Do entirely, including its context menu entry which uses on-device AI to suggest actions based on screen content. Only available on Copilot+ PCs with Windows 11 24H2 or newer.";
}
public override string SupportedOS() => "Windows 11";
public override bool IsRecommended => true;
public override Task<bool> CheckFeature()
{
return Task.FromResult(Utils.IntEquals(keyName, valueName, recommendedValue));
}
public override Task<bool> DoFeature()
{
try
{
Registry.SetValue(keyName, valueName, recommendedValue, RegistryValueKind.DWord);
return Task.FromResult(true);
}
catch (Exception ex)
{
Logger.Log("Error disabling Click to Do: " + ex.Message, LogLevel.Error);
return Task.FromResult(false);
}
}
public override bool UndoFeature()
{
try
{
Registry.SetValue(keyName, valueName, 0, RegistryValueKind.DWord);
return true;
}
catch (Exception ex)
{
Logger.Log("Error re-enabling Click to Do: " + ex.Message, LogLevel.Error);
return false;
}
}
}
}
+67
View File
@@ -0,0 +1,67 @@
using Microsoft.Win32;
using Flyoobe;
using System;
using System.Threading.Tasks;
namespace Settings.AI
{
internal class CopilotTaskbar : FeatureBase
{
private const string keyName = @"HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\WindowsCopilot";
private const string valueName = "TurnOffWindowsCopilot";
private const int recommendedValue = 1;
public override string GetFeatureDetails()
{
return $"{keyName} | Value: {valueName} | Recommended Value: {recommendedValue}";
}
public override string ID()
{
return "Don't Show Copilot in Taskbar";
}
public override string Info()
{
return "This feature will disable Copilot in Taskbar.";
}
public override string SupportedOS() => "Windows 11";
public override bool IsRecommended => true;
public override Task<bool> CheckFeature()
{
return Task.FromResult(Utils.IntEquals(keyName, valueName, 1));
}
public override Task<bool> DoFeature()
{
try
{
Registry.SetValue(keyName, valueName, recommendedValue, RegistryValueKind.DWord);
return Task.FromResult(true);
}
catch (Exception ex)
{
Logger.Log("Code red in " + ex.Message, LogLevel.Error);
}
return Task.FromResult(false);
}
public override bool UndoFeature()
{
try
{
Registry.SetValue(keyName, valueName, 0, RegistryValueKind.DWord);
return true;
}
catch (Exception ex)
{
Logger.Log("Code red in " + ex.Message, LogLevel.Error);
}
return false;
}
}
}
+77
View File
@@ -0,0 +1,77 @@
using Microsoft.Win32;
using Flyoobe;
using System;
using System.Threading.Tasks;
namespace Settings.AI
{
internal class Recall : FeatureBase
{
private const string keyName = @"HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsAI";
private const string valueName = "AllowRecallEnablement";
private const int recommendedValue = 0;
public override string GetFeatureDetails()
{
return $"{keyName} | Value: {valueName} | Recommended: {recommendedValue} (Recall off – protect your privacy, prevent AI from accessing personal data)";
}
public override string ID()
{
return "Turn off Recall in Windows 11";
}
public override string Info()
{
return "This will remove Recall from Windows 11 24H2";
}
public override string SupportedOS() => "Windows 11";
public override bool IsRecommended => true;
public override Task<bool> CheckFeature()
{
// Check if reg key exists
object value = Registry.GetValue(keyName, valueName, null);
if (value == null)
{
// Key does not exist, turn off feature
return Task.FromResult(false);
}
// Key exists, check if value is desired value
return Task.FromResult((int)value == recommendedValue);
}
public override Task<bool> DoFeature()
{
try
{
Registry.SetValue(keyName, valueName, recommendedValue, Microsoft.Win32.RegistryValueKind.DWord);
Logger.Log("You've even disabled system-wide Snapshots for all users now.", LogLevel.Info);
return Task.FromResult(true);
}
catch (Exception ex)
{
Logger.Log("Code red in " + ex.Message, LogLevel.Error);
}
return Task.FromResult(false);
}
public override bool UndoFeature()
{
try
{
Registry.SetValue(keyName, valueName, 1, Microsoft.Win32.RegistryValueKind.DWord);
return true;
}
catch (Exception ex)
{
Logger.Log("Code red in " + ex.Message, LogLevel.Error);
}
return false;
}
}
}
+69
View File
@@ -0,0 +1,69 @@
using Microsoft.Win32;
using Flyoobe;
using System;
using System.Threading.Tasks;
namespace Settings.Ads
{
internal class FileExplorerAds : FeatureBase
{
private const string keyName = @"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced";
private const string valueName = "ShowSyncProviderNotifications";
private const int recommendedValue = 0;
public override string ID()
{
return "Disable File Explorer Ads";
}
public override string Info()
{
return "This feature will disable ads in File Explorer.";
}
public override string SupportedOS() => "Windows 11";
public override bool IsRecommended => true;
public override string GetFeatureDetails()
{
return $"{keyName} | Value: {valueName} | Recommended Value: {recommendedValue}";
}
public override Task<bool> CheckFeature()
{
return Task.FromResult(Utils.IntEquals(keyName, valueName, recommendedValue));
}
public override Task<bool> DoFeature()
{
try
{
Registry.SetValue(keyName, valueName, 0, RegistryValueKind.DWord);
Logger.Log("File Explorer Ads disabled", LogLevel.Info);
return Task.FromResult(true);
}
catch (Exception ex)
{
Logger.Log("Code red in " + ex.Message, LogLevel.Error);
}
return Task.FromResult(false);
}
public override bool UndoFeature()
{
try
{
Registry.SetValue(keyName, valueName, 1, RegistryValueKind.DWord);
Logger.Log("File Explorer Ads enabled", LogLevel.Info);
return true;
}
catch (Exception ex)
{
Logger.Log("Code red in " + ex.Message, LogLevel.Error);
}
return false;
}
}
}
+64
View File
@@ -0,0 +1,64 @@
using Microsoft.Win32;
using Flyoobe;
using System;
using System.Threading.Tasks;
namespace Settings.Ads
{
internal class FinishSetupAds : FeatureBase
{
private const string keyName = @"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\UserProfileEngagement";
private const string valueName = "ScoobeSystemSettingEnabled";
private const int recommendedValue = 0;
public override string ID() => "Disable Finish Setup Ads";
public override string Info() => "This feature will disable the \"Lets finish setting up your device\" and other advertising.";
public override string SupportedOS() => "Windows 11";
public override bool IsRecommended => true;
public override string GetFeatureDetails()
{
return $"{keyName} | Value: {valueName} | Recommended Value: {recommendedValue}";
}
public override Task<bool> CheckFeature()
{
return
Task.FromResult(Utils.IntEquals(keyName, valueName, 0));
}
public override Task<bool> DoFeature()
{
try
{
Registry.SetValue(keyName, valueName, 0, Microsoft.Win32.RegistryValueKind.DWord);
return Task.FromResult(true);
}
catch (Exception ex)
{
Logger.Log("Code red in " + ex.Message, LogLevel.Error);
}
return Task.FromResult(false);
}
public override bool UndoFeature()
{
try
{
Registry.SetValue(keyName, valueName, 1, Microsoft.Win32.RegistryValueKind.DWord);
return true;
}
catch (Exception ex)
{
Logger.Log("Code red in " + ex.Message, LogLevel.Error);
}
return false;
}
}
}
+68
View File
@@ -0,0 +1,68 @@
using Microsoft.Win32;
using Flyoobe;
using System;
using System.Threading.Tasks;
namespace Settings.Ads
{
internal class LockScreenAds : FeatureBase
{
private const string keyName = @"HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\ContentDeliveryManager";
private const string valueName = "RotatingLockScreenOverlayEnabled";
private const string valueName2 = "SubscribedContent-338387Enabled";
private const int recommendedValue = 0;
public override string ID() => "Disable Lock Screen Tips and Ads";
public override string Info() => "This feature will disable tips and ads on the lock screen.";
public override string SupportedOS() => "Windows 11";
public override bool IsRecommended => true;
public override string GetFeatureDetails()
{
return $"{keyName} | Value: {valueName} | Recommended Value: {recommendedValue}";
}
public override Task<bool> CheckFeature()
{
return Task.FromResult(Utils.IntEquals(keyName, valueName, recommendedValue) &&
Utils.IntEquals(keyName, valueName2, recommendedValue)
);
}
public override Task<bool> DoFeature()
{
try
{
Registry.SetValue(keyName, valueName, 0, Microsoft.Win32.RegistryValueKind.DWord);
Registry.SetValue(keyName, valueName2, 0, Microsoft.Win32.RegistryValueKind.DWord);
return Task.FromResult(true);
}
catch (Exception ex)
{
Logger.Log("Code red in " + ex.Message, LogLevel.Error);
}
return Task.FromResult(false);
}
public override bool UndoFeature()
{
try
{
Registry.SetValue(keyName, valueName, 1, Microsoft.Win32.RegistryValueKind.DWord);
Registry.SetValue(keyName, valueName2, 1, Microsoft.Win32.RegistryValueKind.DWord);
return true;
}
catch (Exception ex)
{
Logger.Log("Code red in " + ex.Message, LogLevel.Error);
}
return false;
}
}
}
+63
View File
@@ -0,0 +1,63 @@
using Microsoft.Win32;
using Flyoobe;
using System;
using System.Threading.Tasks;
namespace Settings.Ads
{
public class PersonalizedAds : FeatureBase
{
private const string keyName = @"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\AdvertisingInfo";
private const string valueName = "Enabled";
private const int recommendedValue = 0;
public override string ID() => "Disable Personalized Ads";
public override string Info() => "This feature will disable personalized ads.";
public override string SupportedOS() => "Windows 11";
public override bool IsRecommended => true;
public override string GetFeatureDetails()
{
return $"{keyName} | Value: {valueName} | Recommended Value: {recommendedValue}";
}
public override Task<bool> CheckFeature()
{
return Task.FromResult(Utils.IntEquals(keyName, valueName, 0));
}
public override Task<bool> DoFeature()
{
try
{
Registry.SetValue(keyName, valueName, 0, Microsoft.Win32.RegistryValueKind.DWord);
return Task.FromResult(true);
}
catch (Exception ex)
{
Logger.Log("Code red in " + ex.Message, LogLevel.Error);
}
return Task.FromResult(false);
}
public override bool UndoFeature()
{
try
{
Registry.SetValue(keyName, valueName, 1, Microsoft.Win32.RegistryValueKind.DWord);
return true;
}
catch (Exception ex)
{
Logger.Log("Code red in " + ex.Message, LogLevel.Error);
}
return false;
}
}
}
+73
View File
@@ -0,0 +1,73 @@
using Microsoft.Win32;
using Flyoobe;
using System;
using System.Threading.Tasks;
namespace Settings.Ads
{
internal class SettingsAds : FeatureBase
{
private const string keyName = @"HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\ContentDeliveryManager";
private const string valueName = "SubscribedContent-338393Enabled";
private const string valueName2 = "SubscribedContent-353694Enabled";
private const string valueName3 = "SubscribedContent-353696Enabled";
private const int recommendedValue = 0;
public override string ID() => "Disable Settings Ads";
public override string Info() => "This feature will disable ads in settings.";
public override string SupportedOS() => "Windows 11";
public override bool IsRecommended => true;
public override string GetFeatureDetails()
{
return $"{keyName} | Value: {valueName} + {valueName2} + {valueName3} | Recommended Value: {recommendedValue}";
}
public override Task<bool> CheckFeature()
{
return Task.FromResult(Utils.IntEquals(keyName, valueName, recommendedValue) &&
Utils.IntEquals(keyName, valueName2, recommendedValue) &&
Utils.IntEquals(keyName, valueName3, recommendedValue)
);
}
public override Task<bool> DoFeature()
{
try
{
Registry.SetValue(keyName, valueName, 0, Microsoft.Win32.RegistryValueKind.DWord);
Registry.SetValue(keyName, valueName2, 0, Microsoft.Win32.RegistryValueKind.DWord);
Registry.SetValue(keyName, valueName3, 0, Microsoft.Win32.RegistryValueKind.DWord);
return Task.FromResult(true);
}
catch (Exception ex)
{
Logger.Log("Code red in " + ex.Message, LogLevel.Error);
}
return Task.FromResult(false);
}
public override bool UndoFeature()
{
try
{
Registry.SetValue(keyName, valueName, 1, Microsoft.Win32.RegistryValueKind.DWord);
Registry.SetValue(keyName, valueName2, 1, Microsoft.Win32.RegistryValueKind.DWord);
Registry.SetValue(keyName, valueName3, 1, Microsoft.Win32.RegistryValueKind.DWord);
return true;
}
catch (Exception ex)
{
Logger.Log("Code red in " + ex.Message, LogLevel.Error);
}
return false;
}
}
}
+69
View File
@@ -0,0 +1,69 @@
using Microsoft.Win32;
using Flyoobe;
using System;
using System.Threading.Tasks;
namespace Settings.Ads
{
internal class StartmenuAds : FeatureBase
{
private const string keyName = @"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced";
private const string valueName = "Start_IrisRecommendations";
private const int recommendedValue = 0;
public override string GetFeatureDetails()
{
return $"{keyName} | Value: {valueName} | Recommended Value: {recommendedValue}";
}
public override string ID()
{
return "Disable Start menu Ads";
}
public override string Info()
{
return "This feature will disable ads in the start menu.";
}
public override string SupportedOS() => "Windows 11";
public override bool IsRecommended => true;
public override Task<bool> CheckFeature()
{
return Task.FromResult(
Utils.IntEquals(keyName, valueName, recommendedValue)
);
}
public override Task<bool> DoFeature()
{
try
{
Registry.SetValue(keyName, valueName, 0, RegistryValueKind.DWord);
return Task.FromResult(true);
}
catch (Exception ex)
{
Logger.Log("Code red in " + ex.Message, LogLevel.Error);
}
return Task.FromResult(false);
}
public override bool UndoFeature()
{
try
{
Registry.SetValue(keyName, valueName, 1, RegistryValueKind.DWord);
return true;
}
catch (Exception ex)
{
Logger.Log("Code red in " + ex.Message, LogLevel.Error);
}
return false;
}
}
}
@@ -0,0 +1,69 @@
using Microsoft.Win32;
using Flyoobe;
using System;
using System.Threading.Tasks;
namespace Settings.Ads
{
internal class TailoredExperiences : FeatureBase
{
private const string keyName = @"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Privacy";
private const string valueName = "TailoredExperiencesWithDiagnosticDataEnabled";
private const int recommendedValue = 0;
public override string GetFeatureDetails()
{
return $"{keyName} | Value: {valueName} | Recommended Value: {recommendedValue}";
}
public override string ID()
{
return "Disable Tailored experiences";
}
public override string Info()
{
return "Tailored Experiences allows Microsoft to get information from you to deliver personalized tips, ads, and recommendations. Many people would call this telemetry, or even spying.";
}
public override string SupportedOS() => "Windows 11";
public override bool IsRecommended => true;
public override Task<bool> CheckFeature()
{
return Task.FromResult(
Utils.IntEquals(keyName, valueName, recommendedValue)
);
}
public override Task<bool> DoFeature()
{
try
{
Registry.SetValue(keyName, valueName, 0, RegistryValueKind.DWord);
return Task.FromResult(true);
}
catch (Exception ex)
{
Logger.Log("Code red in " + ex.Message, LogLevel.Error);
}
return Task.FromResult(false);
}
public override bool UndoFeature()
{
try
{
Registry.SetValue(keyName, valueName, 1, RegistryValueKind.DWord);
return true;
}
catch (Exception ex)
{
Logger.Log("Code red in " + ex.Message, LogLevel.Error);
}
return false;
}
}
}
@@ -0,0 +1,64 @@
using Microsoft.Win32;
using Flyoobe;
using System;
using System.Threading.Tasks;
namespace Settings.Ads
{
internal class TipsAndSuggestions : FeatureBase
{
private const string keyName = @"HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\ContentDeliveryManager";
private const string valueName = "SubscribedContent-338389Enabled";
private const int recommendedValue = 0;
public override string ID() => "Disable General Tips and Ads";
public override string Info() => "This feature will disable general tips and ads.";
public override string SupportedOS() => "Windows 11";
public override bool IsRecommended => true;
public override string GetFeatureDetails()
{
return $"{keyName} | Value: {valueName} | Recommended Value: {recommendedValue}";
}
public override Task<bool> CheckFeature()
{
return Task.FromResult(Utils.IntEquals(keyName, valueName, recommendedValue)
);
}
public override Task<bool> DoFeature()
{
try
{
Registry.SetValue(keyName, valueName, 0, Microsoft.Win32.RegistryValueKind.DWord);
return Task.FromResult(true);
}
catch (Exception ex)
{
Logger.Log("Code red in " + ex.Message, LogLevel.Error);
}
return Task.FromResult(false);
}
public override bool UndoFeature()
{
try
{
Registry.SetValue(keyName, valueName, 1, Microsoft.Win32.RegistryValueKind.DWord);
return true;
}
catch (Exception ex)
{
Logger.Log("Code red in " + ex.Message, LogLevel.Error);
}
return false;
}
}
}
@@ -0,0 +1,63 @@
using Microsoft.Win32;
using Flyoobe;
using System;
using System.Threading.Tasks;
namespace Settings.Ads
{
public class WelcomeExperienceAds : FeatureBase
{
private const string keyName = @"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager";
private const string valueName = "SubscribedContent-310093Enabled";
private const int recommendedValue = 0;
public override string ID() => "Disable Welcome Experience Ads";
public override string Info() => "This feature will disable ads in the welcome experience.";
public override string SupportedOS() => "Windows 11";
public override bool IsRecommended => true;
public override string GetFeatureDetails()
{
return $"{keyName} | Value: {valueName} | Recommended Value: {recommendedValue}";
}
public override Task<bool> CheckFeature()
{
return Task.FromResult(Utils.IntEquals(keyName, valueName, 0));
}
public override Task<bool> DoFeature()
{
try
{
Registry.SetValue(keyName, valueName, 0, Microsoft.Win32.RegistryValueKind.DWord);
return Task.FromResult(true);
}
catch (Exception ex)
{
Logger.Log("Code red in " + ex.Message, LogLevel.Error);
}
return Task.FromResult(false);
}
public override bool UndoFeature()
{
try
{
Registry.SetValue(keyName, valueName, 1, Microsoft.Win32.RegistryValueKind.DWord);
return true;
}
catch (Exception ex)
{
Logger.Log("Code red in " + ex.Message, LogLevel.Error);
}
return false;
}
}
}
+63
View File
@@ -0,0 +1,63 @@
using Microsoft.Win32;
using Flyoobe;
using System;
using System.Threading.Tasks;
namespace Settings.Edge
{
public class BrowserSignin : FeatureBase
{
private const string keyName = @"HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Edge";
private const string valueName = "BrowserSignin";
private const int recommendedValue = 0;
public override string GetFeatureDetails()
{
return $"{keyName} | Value: {valueName} | Recommended Value: {recommendedValue}";
}
public override string ID() => "Disable Browser sign in and sync services";
public override string Info() => "This setting controls whether a user can sign into Microsoft Edge with an account to use services such as sync and single sign on";
public override string SupportedOS() => "Windows 10, Windows 11";
public override bool IsRecommended => false;
public override Task<bool> CheckFeature()
{
return Task.FromResult(Utils.IntEquals(keyName, valueName, recommendedValue));
}
public override Task<bool> DoFeature()
{
try
{
Registry.SetValue(keyName, valueName, 0, Microsoft.Win32.RegistryValueKind.DWord);
return Task.FromResult(true);
}
catch (Exception ex)
{
Logger.Log("Code red in " + ex.Message, LogLevel.Error);
}
return Task.FromResult(false);
}
public override bool UndoFeature()
{
try
{
Registry.SetValue(keyName, valueName, 1, Microsoft.Win32.RegistryValueKind.DWord);
return true;
}
catch (Exception ex)
{
Logger.Log("Code red in " + ex.Message, LogLevel.Error);
}
return false;
}
}
}
+63
View File
@@ -0,0 +1,63 @@
using Microsoft.Win32;
using Flyoobe;
using System;
using System.Threading.Tasks;
namespace Settings.Edge
{
public class DefaultTopSites : FeatureBase
{
private const string keyName = @"HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Edge";
private const string valueName = "NewTabPageHideDefaultTopSites";
private const int recommendedValue = 1;
public override string GetFeatureDetails()
{
return $"{keyName} | Value: {valueName} | Recommended Value: {recommendedValue}";
}
public override string ID() => "Don't Show Sponsored links in new tab page";
public override string Info() => "Hide default top sites from the new tab page in Microsoft Edge";
public override string SupportedOS() => "Windows 10, Windows 11";
public override bool IsRecommended => false;
public override Task<bool> CheckFeature()
{
return Task.FromResult(Utils.IntEquals(keyName, valueName, recommendedValue));
}
public override Task<bool> DoFeature()
{
try
{
Registry.SetValue(keyName, valueName, recommendedValue, Microsoft.Win32.RegistryValueKind.DWord);
return Task.FromResult(true);
}
catch (Exception ex)
{
Logger.Log("Code red in " + ex.Message, LogLevel.Error);
}
return Task.FromResult(false);
}
public override bool UndoFeature()
{
try
{
Registry.SetValue(keyName, valueName, 0, Microsoft.Win32.RegistryValueKind.DWord);
return true;
}
catch (Exception ex)
{
Logger.Log("Code red in " + ex.Message, LogLevel.Error);
}
return false;
}
}
}
@@ -0,0 +1,63 @@
using Microsoft.Win32;
using Flyoobe;
using System;
using System.Threading.Tasks;
namespace Settings.Edge
{
public class DefautBrowserSetting : FeatureBase
{
private const string keyName = @"HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Edge";
private const string valueName = "DefaultBrowserSettingEnabled";
private const int recommendedValue = 0;
public override string GetFeatureDetails()
{
return $"{keyName} | Value: {valueName} | Recommended Value: {recommendedValue}";
}
public override string ID() => "Disable Microsoft Edge as default browser";
public override string Info() => "Force Edge to stop asking to change default browser";
public override string SupportedOS() => "Windows 10, Windows 11";
public override bool IsRecommended => false;
public override Task<bool> CheckFeature()
{
return Task.FromResult(Utils.IntEquals(keyName, valueName, recommendedValue));
}
public override Task<bool> DoFeature()
{
try
{
Registry.SetValue(keyName, valueName, 0, Microsoft.Win32.RegistryValueKind.DWord);
return Task.FromResult(true);
}
catch (Exception ex)
{
Logger.Log("Code red in " + ex.Message, LogLevel.Error);
}
return Task.FromResult(false);
}
public override bool UndoFeature()
{
try
{
Registry.SetValue(keyName, valueName, 1, Microsoft.Win32.RegistryValueKind.DWord);
return true;
}
catch (Exception ex)
{
Logger.Log("Code red in " + ex.Message, LogLevel.Error);
}
return false;
}
}
}
+63
View File
@@ -0,0 +1,63 @@
using Microsoft.Win32;
using Flyoobe;
using System;
using System.Threading.Tasks;
namespace Settings.Edge
{
public class EdgeCollections : FeatureBase
{
private const string keyName = @"HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Edge";
private const string valueName = "EdgeCollectionsEnabled";
private const int recommendedValue = 0;
public override string ID() => "Disable Access to Collections feature";
public override string Info() => "Enables users to access the Collections feature, allowing them to gather, organize, share, and export content more efficiently with Office integration";
public override string SupportedOS() => "Windows 10, Windows 11";
public override bool IsRecommended => false;
public override string GetFeatureDetails()
{
return $"{keyName} | Value: {valueName} | Recommended Value: {recommendedValue}";
}
public override Task<bool> CheckFeature()
{
return Task.FromResult(Utils.IntEquals(keyName, valueName, recommendedValue));
}
public override Task<bool> DoFeature()
{
try
{
Registry.SetValue(keyName, valueName, 0, Microsoft.Win32.RegistryValueKind.DWord);
return Task.FromResult(true);
}
catch (Exception ex)
{
Logger.Log("Code red in " + ex.Message, LogLevel.Error);
}
return Task.FromResult(false);
}
public override bool UndoFeature()
{
try
{
Registry.SetValue(keyName, valueName, 1, Microsoft.Win32.RegistryValueKind.DWord);
return true;
}
catch (Exception ex)
{
Logger.Log("Code red in " + ex.Message, LogLevel.Error);
}
return false;
}
}
}
@@ -0,0 +1,63 @@
using Microsoft.Win32;
using Flyoobe;
using System;
using System.Threading.Tasks;
namespace Settings.Edge
{
public class EdgeShoppingAssistant : FeatureBase
{
private const string keyName = @"HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Edge";
private const string valueName = "EdgeShoppingAssistantEnabled";
private const int recommendedValue = 0;
public override string GetFeatureDetails()
{
return $"{keyName} | Value: {valueName} | Recommended Value: {recommendedValue}";
}
public override string ID() => "Disable Shopping assistant";
public override string Info() => "Shopping in Microsoft Edge feature will automatically find you the best prices and coupons from across the web as you shop";
public override string SupportedOS() => "Windows 10, Windows 11";
public override bool IsRecommended => false;
public override Task<bool> CheckFeature()
{
return Task.FromResult(Utils.IntEquals(keyName, valueName, recommendedValue));
}
public override Task<bool> DoFeature()
{
try
{
Registry.SetValue(keyName, valueName, 0, Microsoft.Win32.RegistryValueKind.DWord);
return Task.FromResult(true);
}
catch (Exception ex)
{
Logger.Log("Code red in " + ex.Message, LogLevel.Error);
}
return Task.FromResult(false);
}
public override bool UndoFeature()
{
try
{
Registry.SetValue(keyName, valueName, 1, Microsoft.Win32.RegistryValueKind.DWord);
return true;
}
catch (Exception ex)
{
Logger.Log("Code red in " + ex.Message, LogLevel.Error);
}
return false;
}
}
}
@@ -0,0 +1,63 @@
using Microsoft.Win32;
using Flyoobe;
using System;
using System.Threading.Tasks;
namespace Settings.Edge
{
public class FirstRunExperience : FeatureBase
{
private const string keyName = @"HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Edge";
private const string valueName = "HideFirstRunExperience";
private const int recommendedValue = 1;
public override string GetFeatureDetails()
{
return $"{keyName} | Value: {valueName} | Recommended Value: {recommendedValue}";
}
public override string ID() => "Don't Show First Run Experience";
public override string Info() => "Hide home screen and 'Getting Started' on initial launch (from version 80 onwards)";
public override string SupportedOS() => "Windows 10, Windows 11";
public override bool IsRecommended => true;
public override Task<bool> CheckFeature()
{
return Task.FromResult(Utils.IntEquals(keyName, valueName, recommendedValue));
}
public override Task<bool> DoFeature()
{
try
{
Registry.SetValue(keyName, valueName, 1, Microsoft.Win32.RegistryValueKind.DWord);
return Task.FromResult(true);
}
catch (Exception ex)
{
Logger.Log("Code red in " + ex.Message, LogLevel.Error);
}
return Task.FromResult(false);
}
public override bool UndoFeature()
{
try
{
Registry.SetValue(keyName, valueName, 0, Microsoft.Win32.RegistryValueKind.DWord);
return true;
}
catch (Exception ex)
{
Logger.Log("Code red in " + ex.Message, LogLevel.Error);
}
return false;
}
}
}
+63
View File
@@ -0,0 +1,63 @@
using Microsoft.Win32;
using Flyoobe;
using System;
using System.Threading.Tasks;
namespace Settings.Edge
{
public class GamerMode : FeatureBase
{
private const string keyName = @"HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Edge";
private const string valueName = "GamerModeEnabled";
private const int recommendedValue = 0;
public override string GetFeatureDetails()
{
return $"{keyName} | Value: {valueName} | Recommended Value: {recommendedValue}";
}
public override string ID() => "Disable Gamer Mode";
public override string Info() => "Microsoft Edge Gamer Mode allows gamers to personalize their browser with gaming themes and gives them the option of enabling Efficiency Mode for PC gaming, the Gaming feed on new tabs, sidebar apps for gamers, and more";
public override string SupportedOS() => "Windows 10, Windows 11";
public override bool IsRecommended => true;
public override Task<bool> CheckFeature()
{
return Task.FromResult(Utils.IntEquals(keyName, valueName, recommendedValue));
}
public override Task<bool> DoFeature()
{
try
{
Registry.SetValue(keyName, valueName, 0, Microsoft.Win32.RegistryValueKind.DWord);
return Task.FromResult(true);
}
catch (Exception ex)
{
Logger.Log("Code red in " + ex.Message, LogLevel.Error);
}
return Task.FromResult(false);
}
public override bool UndoFeature()
{
try
{
Registry.SetValue(keyName, valueName, 1, Microsoft.Win32.RegistryValueKind.DWord);
return true;
}
catch (Exception ex)
{
Logger.Log("Code red in " + ex.Message, LogLevel.Error);
}
return false;
}
}
}
+63
View File
@@ -0,0 +1,63 @@
using Microsoft.Win32;
using Flyoobe;
using System;
using System.Threading.Tasks;
namespace Settings.Edge
{
public class HubsSidebar : FeatureBase
{
private const string keyName = @"HKEY_CURRENT_USER\Software\Policies\Microsoft\Edge";
private const string valueName = "HubsSidebarEnabled";
private const int recommendedValue = 0;
public override string GetFeatureDetails()
{
return $"{keyName} | Value: {valueName} | Recommended Value: {recommendedValue}";
}
public override string ID() => "Disable Copilot Symbol in Edge";
public override string Info() => "This feature will disable Copilot in Microsoft Edge.";
public override string SupportedOS() => "Windows 10, Windows 11";
public override bool IsRecommended => false;
public override Task<bool> CheckFeature()
{
return Task.FromResult(Utils.IntEquals(keyName, valueName, 0));
}
public override Task<bool> DoFeature()
{
try
{
Registry.SetValue(keyName, valueName, 0, Microsoft.Win32.RegistryValueKind.DWord);
return Task.FromResult(true);
}
catch (Exception ex)
{
Logger.Log("Code red in " + ex.Message, LogLevel.Error);
}
return Task.FromResult(false);
}
public override bool UndoFeature()
{
try
{
Registry.SetValue(keyName, valueName, 1, Microsoft.Win32.RegistryValueKind.DWord);
return true;
}
catch (Exception ex)
{
Logger.Log("Code red in " + ex.Message, LogLevel.Error);
}
return false;
}
}
}
@@ -0,0 +1,63 @@
using Microsoft.Win32;
using Flyoobe;
using System;
using System.Threading.Tasks;
namespace Settings.Edge
{
public class ImportOnEachLaunch : FeatureBase
{
private const string keyName = @"HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Edge";
private const string valueName = "ImportOnEachLaunch";
private const int recommendedValue = 0;
public override string GetFeatureDetails()
{
return $"{keyName} | Value: {valueName} | Recommended Value: {recommendedValue}";
}
public override string ID() => "Don't Allow to Import of data from other browsers on each launch";
public override string Info() => "Allow import of data from other browsers on each Microsoft Edge launch";
public override string SupportedOS() => "Windows 10, Windows 11";
public override bool IsRecommended => true;
public override Task<bool> CheckFeature()
{
return Task.FromResult(Utils.IntEquals(keyName, valueName, recommendedValue));
}
public override Task<bool> DoFeature()
{
try
{
Registry.SetValue(keyName, valueName, 0, Microsoft.Win32.RegistryValueKind.DWord);
return Task.FromResult(true);
}
catch (Exception ex)
{
Logger.Log("Code red in " + ex.Message, LogLevel.Error);
}
return Task.FromResult(false);
}
public override bool UndoFeature()
{
try
{
Registry.SetValue(keyName, valueName, 1, Microsoft.Win32.RegistryValueKind.DWord);
return true;
}
catch (Exception ex)
{
Logger.Log("Code red in " + ex.Message, LogLevel.Error);
}
return false;
}
}
}
+63
View File
@@ -0,0 +1,63 @@
using Microsoft.Win32;
using Flyoobe;
using System;
using System.Threading.Tasks;
namespace Settings.Edge
{
public class StartupBoost : FeatureBase
{
private const string keyName = @"HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Edge";
private const string valueName = "StartupBoostEnabled";
private const int recommendedValue = 0;
public override string GetFeatureDetails()
{
return $"{keyName} | Value: {valueName} | Recommended Value: {recommendedValue}";
}
public override string ID() => "Disable Start Boost";
public override string Info() => "Enables Microsoft Edge processes to initialize at operating system startup and restart in the background after the last browser window has been closed";
public override string SupportedOS() => "Windows 10, Windows 11";
public override bool IsRecommended => true;
public override Task<bool> CheckFeature()
{
return Task.FromResult(Utils.IntEquals(keyName, valueName, recommendedValue));
}
public override Task<bool> DoFeature()
{
try
{
Registry.SetValue(keyName, valueName, 0, Microsoft.Win32.RegistryValueKind.DWord);
return Task.FromResult(true);
}
catch (Exception ex)
{
Logger.Log("Code red in " + ex.Message, LogLevel.Error);
}
return Task.FromResult(false);
}
public override bool UndoFeature()
{
try
{
Registry.SetValue(keyName, valueName, 1, Microsoft.Win32.RegistryValueKind.DWord);
return true;
}
catch (Exception ex)
{
Logger.Log("Code red in " + ex.Message, LogLevel.Error);
}
return false;
}
}
}
@@ -0,0 +1,63 @@
using Microsoft.Win32;
using Flyoobe;
using System;
using System.Threading.Tasks;
namespace Settings.Edge
{
public class TabPageQuickLinks : FeatureBase
{
private const string keyName = @"HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Edge";
private const string valueName = "NewTabPageQuickLinksEnabled";
private const int recommendedValue = 0;
public override string GetFeatureDetails()
{
return $"{keyName} | Value: {valueName} | Recommended Value: {recommendedValue}";
}
public override string ID() => "Don't Show Quick links in new tab page";
public override string Info() => "By default, when you open a new tab, you see a Bing search bar, Bing image of the day set as the page background. For supported websites, Quick Links on the New Tab page can display recent updates right in the tile";
public override string SupportedOS() => "Windows 10, Windows 11";
public override bool IsRecommended => false;
public override Task<bool> CheckFeature()
{
return Task.FromResult(Utils.IntEquals(keyName, valueName, recommendedValue));
}
public override Task<bool> DoFeature()
{
try
{
Registry.SetValue(keyName, valueName, 0, Microsoft.Win32.RegistryValueKind.DWord);
return Task.FromResult(true);
}
catch (Exception ex)
{
Logger.Log("Code red in " + ex.Message, LogLevel.Error);
}
return Task.FromResult(false);
}
public override bool UndoFeature()
{
try
{
Registry.SetValue(keyName, valueName, 1, Microsoft.Win32.RegistryValueKind.DWord);
return true;
}
catch (Exception ex)
{
Logger.Log("Code red in " + ex.Message, LogLevel.Error);
}
return false;
}
}
}
+63
View File
@@ -0,0 +1,63 @@
using Microsoft.Win32;
using Flyoobe;
using System;
using System.Threading.Tasks;
namespace Settings.Edge
{
public class UserFeedback : FeatureBase
{
private const string keyName = @"HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Edge";
private const string valueName = "UserFeedbackAllowed";
private const int recommendedValue = 0;
public override string GetFeatureDetails()
{
return $"{keyName} | Value: {valueName} | Recommended Value: {recommendedValue}";
}
public override string ID() => "Don't Submit user feedback option";
public override string Info() => "Allow the submission of feedback, suggestions, or customer surveys, as well as reporting issues with the browser";
public override string SupportedOS() => "Windows 10, Windows 11";
public override bool IsRecommended => true;
public override Task<bool> CheckFeature()
{
return Task.FromResult(Utils.IntEquals(keyName, valueName, recommendedValue));
}
public override Task<bool> DoFeature()
{
try
{
Registry.SetValue(keyName, valueName, 0, Microsoft.Win32.RegistryValueKind.DWord);
return Task.FromResult(true);
}
catch (Exception ex)
{
Logger.Log("Code red in " + ex.Message, LogLevel.Error);
}
return Task.FromResult(false);
}
public override bool UndoFeature()
{
try
{
Registry.SetValue(keyName, valueName, 1, Microsoft.Win32.RegistryValueKind.DWord);
return true;
}
catch (Exception ex)
{
Logger.Log("Code red in " + ex.Message, LogLevel.Error);
}
return false;
}
}
}
+23
View File
@@ -0,0 +1,23 @@
using System.Threading.Tasks;
namespace Flyoobe
{
public abstract class FeatureBase
{
public abstract string ID();
public abstract string Info();
public abstract string GetFeatureDetails();
public abstract string SupportedOS();
public abstract Task<bool> CheckFeature();
public abstract Task<bool> DoFeature();
public abstract bool UndoFeature();
public abstract bool IsRecommended { get; }
}
}
+123
View File
@@ -0,0 +1,123 @@
using Flyoobe; // for FeatureNode
using Settings.Ads;
using Settings.Edge;
using Settings.Gaming;
using Settings.Issues;
using Settings.Personalization;
using Settings.Privacy;
using Settings.System;
using Settings.UI;
using System.Collections.Generic;
namespace Features
{
/// <summary>
/// Loads all available feature categories and their corresponding tweak nodes.
/// Each tweak inherits from FeatureBase and represents a system setting or cleanup action.
/// </summary>
public static class FeatureLoader
{
public static List<FeatureNode> Load()
{
return new List<FeatureNode>
{
new FeatureNode("Issues")
{
Children = new List<FeatureNode>
{
new FeatureNode(new BasicCleanup()),
new FeatureNode(new WingetUpgradeAll())
}
},
new FeatureNode("System")
{
Children = new List<FeatureNode>
{
new FeatureNode(new BSODDetails()),
new FeatureNode(new VerboseStatus()),
new FeatureNode(new SpeedUpShutdown()),
new FeatureNode(new NetworkThrottling()),
new FeatureNode(new SystemResponsiveness()),
new FeatureNode(new MenuShowDelay()),
new FeatureNode(new TaskbarEndTask()),
new FeatureNode(new DisableHibernation())
}
},
new FeatureNode("MS Edge")
{
Children = new List<FeatureNode>
{
new FeatureNode(new BrowserSignin()),
new FeatureNode(new DefaultTopSites()),
new FeatureNode(new DefautBrowserSetting()),
new FeatureNode(new EdgeCollections()),
new FeatureNode(new EdgeShoppingAssistant()),
new FeatureNode(new FirstRunExperience()),
new FeatureNode(new GamerMode()),
new FeatureNode(new HubsSidebar()),
new FeatureNode(new ImportOnEachLaunch()),
new FeatureNode(new StartupBoost()),
new FeatureNode(new TabPageQuickLinks()),
new FeatureNode(new UserFeedback())
}
},
new FeatureNode("UI")
{
Children = new List<FeatureNode>
{
new FeatureNode(new FullContextMenus()),
new FeatureNode(new WLockScreen()),
new FeatureNode(new SearchboxTaskbarMode()),
new FeatureNode(new ShowOrHideMostUsedApps()),
new FeatureNode(new ShowTaskViewButton()),
new FeatureNode(new DisableSearchBoxSuggestions()),
new FeatureNode(new DisableBingSearch()),
new FeatureNode(new StartLayout()),
new FeatureNode(new Transparency()),
new FeatureNode(new DisableSnapAssistFlyout())
}
},
new FeatureNode("Gaming")
{
Children = new List<FeatureNode>
{
new FeatureNode(new GameDVR()),
new FeatureNode(new PowerThrottling()),
new FeatureNode(new VisualFX())
}
},
new FeatureNode("Privacy")
{
Children = new List<FeatureNode>
{
new FeatureNode(new ActivityHistory()),
new FeatureNode(new LocationTracking()),
new FeatureNode(new PrivacyExperience()),
new FeatureNode(new Telemetry())
}
},
new FeatureNode("Ads")
{
Children = new List<FeatureNode>
{
new FeatureNode(new FileExplorerAds()),
new FeatureNode(new FinishSetupAds()),
new FeatureNode(new LockScreenAds()),
new FeatureNode(new PersonalizedAds()),
new FeatureNode(new SettingsAds()),
new FeatureNode(new StartmenuAds()),
new FeatureNode(new TailoredExperiences()),
new FeatureNode(new TipsAndSuggestions()),
new FeatureNode(new WelcomeExperienceAds())
}
},
};
}
}
}
+94
View File
@@ -0,0 +1,94 @@
using Features;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Flyoobe
{
/// <summary>
/// Manages all available features and categories.
/// Provides methods to query, apply, and undo tweaks.
/// </summary>
public class FeatureManager
{
// List of all loaded features (root nodes with category and children)
public List<FeatureNode> AllFeatures { get; private set; }
public FeatureManager()
{
// Load features from loader once during construction
AllFeatures = FeatureLoader.Load();
}
/// <summary>
/// Returns all available top-level categories.
/// </summary>
public List<string> GetCategories()
{
return AllFeatures.Select(f => f.Category).ToList();
}
/// <summary>
/// Returns all tweaks under a specific category.
/// </summary>
public List<FeatureNode> GetFeaturesByCategory(string category)
{
return AllFeatures.FirstOrDefault(f => f.Category == category)?.Children ?? new List<FeatureNode>();
}
/// <summary>
/// Applies (executes) a selected tweak asynchronously.
/// </summary>
public async Task<bool> ApplyFeature(FeatureNode node)
{
return await node.Feature.DoFeature();
}
/// <summary>
/// Undoes a tweak if supported.
/// </summary>
public bool UndoFeature(FeatureNode node)
{
return node.Feature.UndoFeature();
}
/// <summary>
/// Returns the short informational description of the feature.
/// </summary>
public string GetFeatureInfo(FeatureNode node)
{
return node.Feature?.Info() ?? "";
}
/// <summary>
/// Checks if the tweak is currently enabled (active).
/// </summary>
public async Task<bool> IsEnabled(FeatureNode node)
{
return await node.Feature.CheckFeature();
}
/// <summary>
/// Collects all features from all categories that are marked as "Recommended"
/// Use quick settings option.
/// </summary>
public List<FeatureNode> GetAllRecommendedFeatures()
{
var recommended = new List<FeatureNode>();
foreach (var categoryNode in AllFeatures)
{
foreach (var featureNode in categoryNode.Children)
{
if (featureNode.Feature.IsRecommended)
{
recommended.Add(featureNode);
}
}
}
return recommended;
}
}
}
+26
View File
@@ -0,0 +1,26 @@
using System.Collections.Generic;
namespace Flyoobe
{
public class FeatureNode
{
public string Category { get; set; }
public FeatureBase Feature { get; set; }
public List<FeatureNode> Children { get; set; } = new List<FeatureNode>();
public FeatureNode(string category)
{
Category = category;
}
public FeatureNode(FeatureBase feature)
{
Feature = feature;
}
public override string ToString()
{
return Feature?.ID() ?? Category;
}
}
}
+80
View File
@@ -0,0 +1,80 @@
using Microsoft.Win32;
using Flyoobe;
using System;
using System.Threading.Tasks;
namespace Settings.Gaming
{
internal class GameDVR : FeatureBase
{
private const string keyName = @"HKEY_CURRENT_USER\System\GameConfigStore";
// 0 = Enabled, 2 = Disabled
private const string keyName2 = @"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PolicyManager\default\ApplicationManagement\AllowGameDVR";
private const string valueName = "GameDVR_Enabled";
private const string valueName2 = "GameDVR_FSEBehaviorMode";
private const string valueName3 = "value";
public override string GetFeatureDetails()
{
return $"{keyName} |Value: {valueName} | {valueName2} | {keyName2} | {valueName3} ";
}
public override string ID()
{
return "Disable Game DVR";
}
public override string Info()
{
return "This feature will disable Game DVR.";
}
public override string SupportedOS() => "Windows 10, Windows 11";
public override bool IsRecommended => false;
public override Task<bool> CheckFeature()
{
return Task.FromResult(Utils.IntEquals(keyName, valueName, 0) &&
Utils.IntEquals(keyName, valueName2, 2) &&
Utils.IntEquals(keyName2, valueName3, 0));
}
public override Task<bool> DoFeature()
{
try
{
Registry.SetValue(keyName, valueName, 0, RegistryValueKind.DWord);
Registry.SetValue(keyName, valueName2, 2, RegistryValueKind.DWord);
Registry.SetValue(keyName2, valueName3, 0, RegistryValueKind.DWord);
return Task.FromResult(true);
}
catch (Exception ex)
{
Logger.Log("Code red in " + ex.Message, LogLevel.Error);
}
return Task.FromResult(false);
}
public override bool UndoFeature()
{
try
{
Registry.SetValue(keyName, valueName, 1, RegistryValueKind.DWord);
Registry.SetValue(keyName, valueName2, 0, RegistryValueKind.DWord);
Registry.SetValue(keyName2, valueName3, 1, RegistryValueKind.DWord);
return true;
}
catch (Exception ex)
{
Logger.Log("Code red in " + ex.Message, LogLevel.Error);
}
return false;
}
}
}
@@ -0,0 +1,69 @@
using Microsoft.Win32;
using Flyoobe;
using System;
using System.Threading.Tasks;
namespace Settings.Gaming
{
internal class PowerThrottling : FeatureBase
{
private const string keyName = @"HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Power\PowerThrottling";
private const string valueName = "PowerThrottlingOff";
private const int recommendedValue = 1;
public override string GetFeatureDetails()
{
return $"{keyName} | Value: {valueName} | Recommended Value: {recommendedValue}";
}
public override string ID()
{
return "Disable Power Throttling";
}
public override string Info()
{
return "This feature will disable Power Throttling.";
}
public override string SupportedOS() => "Windows 10, Windows 11";
public override bool IsRecommended => false;
public override Task<bool> CheckFeature()
{
return Task.FromResult(Utils.IntEquals(keyName, valueName, recommendedValue));
}
public override Task<bool> DoFeature()
{
try
{
Registry.SetValue(keyName, valueName, recommendedValue, Microsoft.Win32.RegistryValueKind.DWord);
return Task.FromResult(true);
}
catch (Exception ex)
{
Logger.Log("Code red in " + ex.Message, LogLevel.Error);
}
return Task.FromResult(false);
}
public override bool UndoFeature()
{
try
{
Registry.SetValue(keyName, valueName, 0, Microsoft.Win32.RegistryValueKind.DWord);
return true;
}
catch (Exception ex)
{
Logger.Log("Code red in " + ex.Message, LogLevel.Error);
}
return false;
}
}
}
+69
View File
@@ -0,0 +1,69 @@
using Microsoft.Win32;
using Flyoobe;
using System;
using System.Threading.Tasks;
namespace Settings.Gaming
{
internal class VisualFX : FeatureBase
{
private const string keyName = @"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\VisualEffects";
private const string valueName = "VisualFXSetting";
private const int recommendedValue = 2;
public override string GetFeatureDetails()
{
return $"{keyName} | Value: {valueName} | Recommended Value: {recommendedValue}";
}
public override string ID()
{
return "Disable Visual Effects";
}
public override string Info()
{
return "Turns off visual effects like animations and shadows in Windows to boost performance.";
}
public override string SupportedOS() => "Windows 10, Windows 11";
public override bool IsRecommended => true;
public override Task<bool> CheckFeature()
{
return Task.FromResult(Utils.IntEquals(keyName, valueName, 0));
}
public override Task<bool> DoFeature()
{
try
{
Registry.SetValue(keyName, valueName, 0, Microsoft.Win32.RegistryValueKind.DWord);
return Task.FromResult(true);
}
catch (Exception ex)
{
Logger.Log("Code red in " + ex.Message, LogLevel.Error);
}
return Task.FromResult(false);
}
public override bool UndoFeature()
{
try
{
Registry.SetValue(keyName, valueName, 2, Microsoft.Win32.RegistryValueKind.DWord);
return true;
}
catch (Exception ex)
{
Logger.Log("Code red in " + ex.Message, LogLevel.Error);
}
return false;
}
}
}
+163
View File
@@ -0,0 +1,163 @@
using Flyoobe;
using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
namespace Settings.Issues
{
internal class BasicCleanup : FeatureBase
{
private readonly string tempPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Temp");
private const int cleanupSetNumber = 1;
public override string ID() => "Basic Disk Cleanup";
public override string Info() => "Deletes all temporary files from the user's Temp folder. Then, the built-in Disk Cleanup utility (cleanmgr) is run.";
public override string SupportedOS() => "Windows 10, Windows 11";
public override bool IsRecommended => false;
public override Task<bool> CheckFeature()
{
try
{
var totalSize = GetDirectorySize(tempPath);
bool isOk = totalSize <= 50;
return Task.FromResult(isOk);
}
catch (Exception ex)
{
Logger.Log($"Error checking Temp folder: {ex.Message}", LogLevel.Error);
return Task.FromResult(false);
}
}
public override string GetFeatureDetails()
{
try
{
var totalSize = GetDirectorySize(tempPath);
return $"Temp folder size: {totalSize} MB (including cleanmgr /sagerun:1 in the next run)";
}
catch (Exception ex)
{
Logger.Log($"Error accessing Temp folder: {ex.Message}", LogLevel.Error);
return $"Temp folder not accessible: {tempPath}";
}
}
public override async Task<bool> DoFeature()
{
try
{
await CleanTempFolderAsync();
await RunDiskCleanup();
Logger.Log("Basic Cleanup completed successfully.", LogLevel.Info);
return true;
}
catch (Exception ex)
{
Logger.Log($"Error cleaning Temp folder: {ex.Message}", LogLevel.Warning);
return false;
}
}
private async Task CleanTempFolderAsync()
{
var files = await Task.Run(() => Directory.GetFiles(tempPath, "*", SearchOption.AllDirectories));
var dirs = await Task.Run(() => Directory.GetDirectories(tempPath, "*", SearchOption.AllDirectories));
foreach (var file in files)
{
try
{
await Task.Run(() => File.Delete(file));
Logger.Log($"Deleted file: {file}", LogLevel.Info);
}
catch (Exception ex)
{
Logger.Log($"Error deleting file {file}: {ex.Message}", LogLevel.Warning);
}
}
foreach (var dir in dirs)
{
try
{
await Task.Run(() => Directory.Delete(dir, true));
Logger.Log($"Deleted directory: {dir}", LogLevel.Info);
}
catch (Exception ex)
{
Logger.Log($"Error deleting directory {dir}: {ex.Message}", LogLevel.Warning);
}
}
}
// calculate the size of the directory in MB
private long GetDirectorySize(string directory)
{
try
{
var directoryInfo = new DirectoryInfo(directory);
long size = 0;
// Calculate size of all files
size += directoryInfo.GetFiles("*", SearchOption.AllDirectories).Sum(file => file.Length);
return size / (1024 * 1024); // return size in MB
}
catch (Exception ex)
{
Logger.Log($"Error calculating directory size: {ex.Message}", LogLevel.Warning);
return 0;
}
}
private async Task RunDiskCleanup()
{
try
{
Logger.Log("Running Disk Cleanup utility (cleanmgr)...", LogLevel.Info);
var sageSetCmd = $"cleanmgr.exe /sageset:{cleanupSetNumber}";
var startInfo1 = new ProcessStartInfo("cmd", $"/c {sageSetCmd}")
{
CreateNoWindow = true,
UseShellExecute = false
};
var sageRunCmd = $"cleanmgr.exe /sagerun:{cleanupSetNumber}";
var veryLowDiskCmd = $"cleanmgr.exe /verylowdisk";
var startInfo2 = new ProcessStartInfo("cmd", $"/c {sageRunCmd} {veryLowDiskCmd}")
{
CreateNoWindow = true,
UseShellExecute = false
};
using (var process1 = Process.Start(startInfo1))
{
if (process1 != null)
await Task.Run(() => process1.WaitForExit());
}
using (var process2 = Process.Start(startInfo2))
{
if (process2 != null)
await Task.Run(() => process2.WaitForExit());
}
}
catch (Exception ex)
{
Logger.Log($"Error running Disk Cleanup: {ex.Message}", LogLevel.Warning);
}
}
// Undo method: Cleanup cannot be undone, so return false
public override bool UndoFeature() => false;
}
}
+128
View File
@@ -0,0 +1,128 @@
using Flyoobe;
using System;
using System.Diagnostics;
using System.Threading.Tasks;
namespace Settings.System
{
internal class WingetUpgradeAll : FeatureBase
{
public override string GetFeatureDetails()
{
return "winget upgrade --include-unknown";
}
public override string ID()
{
return "Winget App Updates";
}
public override string SupportedOS() => "Windows 10, Windows 11";
public override bool IsRecommended => false;
public override string Info()
{
return "Automatically searches for available app updates using the Windows package manager 'winget' and installs them in a new Windows Terminal window. It runs 'winget upgrade --include-unknown' to list all available updates, including manually installed apps, and then 'winget upgrade --all --include-unknown' to install them. No manual interaction is required.";
}
public override async Task<bool> CheckFeature()
{
Logger.Log("📦 Checking all available updates via winget...", LogLevel.Warning);
Logger.Log("This may take a while, please be patient.", LogLevel.Warning);
try
{
string output = await ExecuteCommand("winget upgrade --include-unknown");
Logger.Log("Winget upgrade check:\n" + output, LogLevel.Info);
return output.ToLower().Contains("available");
}
catch (Exception ex)
{
Logger.Log("Winget check failed: " + ex.Message, LogLevel.Error);
return false;
}
}
public override Task<bool> DoFeature()
{
return Task.Factory.StartNew(() =>
{
try
{
LaunchInTerminal("winget upgrade --all --include-unknown");
return true;
}
catch (Exception ex)
{
Logger.Log("Failed to run winget upgrade: " + ex.Message, LogLevel.Error);
return false;
}
});
}
public override bool UndoFeature()
{
Logger.Log("Winget upgrades cannot be undone.", LogLevel.Warning);
return false;
}
private void LaunchInTerminal(string command)
{
var startInfo = new ProcessStartInfo
{
FileName = "wt.exe",
Arguments = "-w 0 nt -p \"Windows PowerShell\" powershell -NoExit -Command \"" + command + "\"",
UseShellExecute = true
};
Process.Start(startInfo);
}
private Task<string> ExecuteCommand(string command)
{
var tcs = new TaskCompletionSource<string>();
try
{
var startInfo = new ProcessStartInfo
{
FileName = "cmd.exe",
Arguments = "/c " + command,
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = true,
CreateNoWindow = true
};
var process = new Process();
process.StartInfo = startInfo;
string output = "";
process.OutputDataReceived += (sender, args) =>
{
if (args.Data != null)
output += args.Data + Environment.NewLine;
};
process.EnableRaisingEvents = true;
process.Exited += (sender, args) =>
{
tcs.TrySetResult(output);
process.Dispose();
};
process.Start();
process.BeginOutputReadLine();
}
catch (Exception ex)
{
tcs.TrySetException(ex);
}
return tcs.Task;
}
}
}
@@ -0,0 +1,70 @@
using Microsoft.Win32;
using Flyoobe;
using System;
using System.Threading.Tasks;
namespace Settings.Privacy
{
internal class ActivityHistory : FeatureBase
{
private const string keyName = @"HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System";
private const string valueName = "PublishUserActivities";
private const int recommendedValue = 0;
public override string GetFeatureDetails()
{
return $"{keyName} | Value: {valueName} | Recommended Value: {recommendedValue}";
}
public override string ID()
{
return "Disable activity history";
}
public override string SupportedOS() => "Windows 11";
public override bool IsRecommended => false;
public override string Info()
{
return "Disable activity history (prevents Windows from tracking and storing your activity)";
}
public override Task<bool> CheckFeature()
{
return Task.FromResult(
Utils.IntEquals(keyName, valueName, recommendedValue)
);
}
public override Task<bool> DoFeature()
{
try
{
Registry.SetValue(keyName, valueName, 0, RegistryValueKind.DWord);
return Task.FromResult(true);
}
catch (Exception ex)
{
Logger.Log("Code red in " + ex.Message, LogLevel.Error);
}
return Task.FromResult(false);
}
public override bool UndoFeature()
{
try
{
Registry.SetValue(keyName, valueName, 1, RegistryValueKind.DWord);
return true;
}
catch (Exception ex)
{
Logger.Log("Code red in " + ex.Message, LogLevel.Error);
}
return false;
}
}
}
@@ -0,0 +1,68 @@
using Microsoft.Win32;
using Flyoobe;
using System;
using System.Threading.Tasks;
namespace Settings.Privacy
{
internal class LocationTracking : FeatureBase
{
private const string keyName = @"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\LocationAndSensors";
private const string valueName = "LocationEnabled";
private const int recommendedValue = 0;
public override string GetFeatureDetails()
{
return $"{keyName} | Value: {valueName} | Recommended Value: {recommendedValue}";
}
public override string ID()
{
return "Disable location tracking";
}
public override string SupportedOS() => "Windows 11";
public override bool IsRecommended => true;
public override string Info()
{
return "Disable location tracking (prevents Windows from accessing your location)";
}
public override Task<bool> CheckFeature()
{
return Task.FromResult(Utils.IntEquals(keyName, valueName, recommendedValue));
}
public override Task<bool> DoFeature()
{
try
{
Registry.SetValue(keyName, valueName, 0, RegistryValueKind.DWord);
return Task.FromResult(true);
}
catch (Exception ex)
{
Logger.Log("Code red in " + ex.Message, LogLevel.Error);
}
return Task.FromResult(false);
}
public override bool UndoFeature()
{
try
{
Registry.SetValue(keyName, valueName, 1, RegistryValueKind.DWord);
return true;
}
catch (Exception ex)
{
Logger.Log("Code red in " + ex.Message, LogLevel.Error);
}
return false;
}
}
}
@@ -0,0 +1,64 @@
using Microsoft.Win32;
using Flyoobe;
using System;
using System.Threading.Tasks;
namespace Settings.Privacy
{
public class PrivacyExperience : FeatureBase
{
private const string keyName = @"HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\OOBE";
private const string valueName = "DisablePrivacyExperience";
private const int recommendedValue = 0;
public override string ID() => "Disable Privacy Settings Experience at sign-in";
public override string Info() => "This feature will disable Privacy Settings Experience at sign-in.";
public override string SupportedOS() => "Windows 11";
public override bool IsRecommended => true;
public override string GetFeatureDetails()
{
return $"{keyName} | Value: {valueName} | Recommended Value: {recommendedValue}";
}
public override Task<bool> CheckFeature()
{
bool result = !Utils.IntEquals(keyName, valueName, recommendedValue);
return Task.FromResult(result);
}
public override Task<bool> DoFeature()
{
try
{
Registry.SetValue(keyName, valueName, 1, Microsoft.Win32.RegistryValueKind.DWord);
return Task.FromResult(true);
}
catch (Exception ex)
{
Logger.Log("Code red in " + ex.Message, LogLevel.Error);
}
return Task.FromResult(false);
}
public override bool UndoFeature()
{
try
{
Registry.SetValue(keyName, valueName, 0, Microsoft.Win32.RegistryValueKind.DWord);
return true;
}
catch (Exception ex)
{
Logger.Log("Code red in " + ex.Message, LogLevel.Error);
}
return false;
}
}
}
+67
View File
@@ -0,0 +1,67 @@
using Microsoft.Win32;
using Flyoobe;
using System;
using System.Threading.Tasks;
namespace Settings.Privacy
{
public class Telemetry : FeatureBase
{
private const string dataCollection = @"HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\DataCollection";
private const string diagTrack = @"HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\DiagTrack";
public override string ID() => "Turn off Telemetry data collection";
public override string Info() => "This feature will turn off telemetry data collection and prevent the data from being sent to Microsoft.";
public override string SupportedOS() => "Windows 10, Windows 11";
public override bool IsRecommended => true;
public override string GetFeatureDetails()
{
return $"{dataCollection} | {diagTrack}";
}
public override Task<bool> CheckFeature()
{
return Task.FromResult(
Utils.IntEquals(dataCollection, "AllowTelemetry", 0) &&
Utils.IntEquals(diagTrack, "Start", 4)
);
}
public override Task<bool> DoFeature()
{
try
{
Registry.SetValue(dataCollection, "AllowTelemetry", 0, RegistryValueKind.DWord);
Registry.SetValue(diagTrack, "Start", 4, RegistryValueKind.DWord);
return Task.FromResult(true);
}
catch (Exception ex)
{
Logger.Log("Code red in " + ex.Message, LogLevel.Error);
}
return Task.FromResult(false);
}
public override bool UndoFeature()
{
try
{
Registry.SetValue(dataCollection, "AllowTelemetry", 1, RegistryValueKind.DWord);
Registry.SetValue(diagTrack, "Start", 2, RegistryValueKind.DWord);
return true;
}
catch (Exception ex)
{
Logger.Log("Code red in " + ex.Message, LogLevel.Error);
}
return false;
}
}
}
+73
View File
@@ -0,0 +1,73 @@
using Microsoft.Win32;
using Flyoobe;
using System;
using System.Threading.Tasks;
namespace Settings.System
{
internal class BSODDetails : FeatureBase
{
private const string keyName = @"HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\CrashControl";
private const string valueName1 = "DisplayParameters";
private const string valueName2 = "DisableEmoticon";
private const int recommendedValue = 1;
public override string GetFeatureDetails()
{
return $"{keyName} | Values: {valueName1}, {valueName2} | Recommended Value: {recommendedValue}";
}
public override string ID()
{
return "Show BSOD details instead of sad smiley";
}
public override string SupportedOS() => "Windows 10, Windows 11";
public override bool IsRecommended => false;
public override string Info()
{
return "This method displays the full classic BSOD with technical error details instead of the simplified sad face version.";
}
public override Task<bool> CheckFeature()
{
return Task.FromResult(
Utils.IntEquals(keyName, valueName1, recommendedValue) &&
Utils.IntEquals(keyName, valueName2, recommendedValue)
);
}
public override Task<bool> DoFeature()
{
try
{
Registry.SetValue(keyName, valueName1, recommendedValue, RegistryValueKind.DWord);
Registry.SetValue(keyName, valueName2, recommendedValue, RegistryValueKind.DWord);
return Task.FromResult(true);
}
catch (Exception ex)
{
Logger.Log("Code red in " + ex.Message, LogLevel.Error);
}
return Task.FromResult(false);
}
public override bool UndoFeature()
{
try
{
Registry.SetValue(keyName, valueName1, 0, RegistryValueKind.DWord);
Registry.SetValue(keyName, valueName2, 0, RegistryValueKind.DWord);
return true;
}
catch (Exception ex)
{
Logger.Log("Code red in " + ex.Message, LogLevel.Error);
}
return false;
}
}
}
+93
View File
@@ -0,0 +1,93 @@
using Microsoft.Win32;
using Flyoobe;
using System;
using System.Diagnostics;
using System.Threading.Tasks;
namespace Settings.System
{
internal class DisableHibernation : FeatureBase
{
private const string powerKey = @"HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Power";
private const string hibernateValueName = "HibernateEnabled";
private const int disabledValue = 0;
private const int enabledValue = 1;
// Key to hide/show the Hibernate option in the power menu Alt+F4 dialog
private const string flyoutMenuKey = @"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\FlyoutMenuSettings";
private const string showHibernateOptionName = "ShowHibernateOption";
public override string GetFeatureDetails()
{
return "Disables hibernation by setting registry values and running powercfg, and hides/shows the Hibernate option in the power menu.";
}
public override string ID()
{
return "Disable Hibernation";
}
public override string Info()
{
return "Hibernation is mostly useful for laptops to save battery by storing your session before shutdown. On desktops, it is rarely needed and uses disk space. Disabling it frees resources and avoids confusion by hiding the Hibernate option in the power menu.";
}
public override string SupportedOS() => "Windows 10, Windows 11";
public override bool IsRecommended => false;
public override Task<bool> CheckFeature()
{
bool hibernateDisabled = Utils.IntEquals(powerKey, hibernateValueName, disabledValue);
bool optionHidden = Utils.IntEquals(flyoutMenuKey, showHibernateOptionName, 0);
return Task.FromResult(hibernateDisabled && optionHidden);
}
public override Task<bool> DoFeature()
{
try
{
Registry.SetValue(powerKey, hibernateValueName, disabledValue, RegistryValueKind.DWord);
Registry.SetValue(flyoutMenuKey, showHibernateOptionName, 0, RegistryValueKind.DWord);
RunCommand("powercfg", "/hibernate off");
return Task.FromResult(true);
}
catch (Exception ex)
{
Logger.Log("Error disabling hibernation: " + ex.Message, LogLevel.Error);
return Task.FromResult(false);
}
}
public override bool UndoFeature()
{
try
{
Registry.SetValue(powerKey, hibernateValueName, enabledValue, RegistryValueKind.DWord);
Registry.SetValue(flyoutMenuKey, showHibernateOptionName, 1, RegistryValueKind.DWord);
RunCommand("powercfg", "/hibernate on");
bool hibernateEnabled = Utils.IntEquals(powerKey, hibernateValueName, enabledValue);
bool optionShown = Utils.IntEquals(flyoutMenuKey, showHibernateOptionName, 1);
return hibernateEnabled && optionShown;
}
catch (Exception ex)
{
Logger.Log("Error enabling hibernation: " + ex.Message, LogLevel.Error);
return false;
}
}
private void RunCommand(string fileName, string arguments)
{
using (var process = new Process())
{
process.StartInfo.FileName = fileName;
process.StartInfo.Arguments = arguments;
process.StartInfo.CreateNoWindow = true;
process.StartInfo.UseShellExecute = false;
process.Start();
process.WaitForExit();
}
}
}
}
+67
View File
@@ -0,0 +1,67 @@
using Microsoft.Win32;
using Flyoobe;
using System;
using System.Threading.Tasks;
namespace Settings.System
{
internal class MenuShowDelay : FeatureBase
{
private const string keyName = @"HKEY_CURRENT_USER\Control Panel\Desktop";
private const string valueName = "MenuShowDelay";
private const string recommendedValue = "10";
public override string GetFeatureDetails()
{
return $"{keyName} | Value: {valueName} | Recommended Value: \"{recommendedValue}\" (faster menu response)";
}
public override string ID()
{
return "Speed Up Menu Show Delay";
}
public override string Info()
{
return "Speeds up the appearance of menus and submenus by lowering the default delay. This improves the perceived responsiveness of the UI.";
}
public override string SupportedOS() => "Windows 10, Windows 11";
public override bool IsRecommended => false;
public override Task<bool> CheckFeature()
{
return Task.FromResult(Utils.StringEquals(keyName, valueName, recommendedValue));
}
public override Task<bool> DoFeature()
{
try
{
Registry.SetValue(keyName, valueName, recommendedValue, RegistryValueKind.String);
return Task.FromResult(true);
}
catch (Exception ex)
{
Logger.Log("Code red in " + ex.Message, LogLevel.Error);
}
return Task.FromResult(false);
}
public override bool UndoFeature()
{
try
{
Registry.SetValue(keyName, valueName, "400", RegistryValueKind.String); // Default is 400 on Windows 11
return true;
}
catch (Exception ex)
{
Logger.Log("Code red in " + ex.Message, LogLevel.Error);
}
return false;
}
}
}
@@ -0,0 +1,67 @@
using Microsoft.Win32;
using Flyoobe;
using System;
using System.Threading.Tasks;
namespace Settings.System
{
internal class NetworkThrottling : FeatureBase
{
private const string keyName = @"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Multimedia\SystemProfile";
private const string valueName = "NetworkThrottlingIndex";
private const int recommendedValue = -1; // 0xFFFFFFFF
public override string GetFeatureDetails()
{
return $"{keyName} | Value: {valueName} | Recommended Value: 0xFFFFFFFF (decimal: {uint.MaxValue})";
}
public override string ID()
{
return "Disable Network Throttling";
}
public override string Info()
{
return "Disables the Windows network throttling mechanism to potentially improve performance for streaming, gaming, or real-time applications.";
}
public override string SupportedOS() => "Windows 10, Windows 11";
public override bool IsRecommended => false;
public override Task<bool> CheckFeature()
{
return Task.FromResult(Utils.IntEquals(keyName, valueName, unchecked((int)0xFFFFFFFF)));
}
public override Task<bool> DoFeature()
{
try
{
Registry.SetValue(keyName, valueName, unchecked((int)0xFFFFFFFF), RegistryValueKind.DWord);
return Task.FromResult(true);
}
catch (Exception ex)
{
Logger.Log("Code red in " + ex.Message, LogLevel.Error);
}
return Task.FromResult(false);
}
public override bool UndoFeature()
{
try
{
Registry.SetValue(keyName, valueName, 10, RegistryValueKind.DWord); // Default is 10
return true;
}
catch (Exception ex)
{
Logger.Log("Code red in " + ex.Message, LogLevel.Error);
}
return false;
}
}
}
@@ -0,0 +1,69 @@
using Microsoft.Win32;
using Flyoobe;
using System;
using System.Threading.Tasks;
namespace Settings.System
{
internal class SpeedUpShutdown : FeatureBase
{
private const string keyName = @"HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control";
private const string valueName = "WaitToKillServiceTimeout";
private const string recommendedValue = "1000"; // Set to 1000 ms (1 second)
public override string GetFeatureDetails()
{
return $"{keyName} | Value: {valueName} | Recommended Value: {recommendedValue} ms";
}
public override string ID()
{
return "Speed Up Shutdown Time";
}
public override string Info()
{
return "This feature reduces the WaitToKillServiceTimeout value, which speeds up the shutdown process by reducing the time Windows waits for services to stop.";
}
public override string SupportedOS() => "Windows 10, Windows 11";
public override bool IsRecommended => false;
public override Task<bool> CheckFeature()
{
return Task.FromResult(
Utils.StringEquals(keyName, valueName, recommendedValue)
);
}
public override Task<bool> DoFeature()
{
try
{
Registry.SetValue(keyName, valueName, recommendedValue, RegistryValueKind.String);
return Task.FromResult(true);
}
catch (Exception ex)
{
Logger.Log("Error in SpeedUpShutdown: " + ex.Message, LogLevel.Error);
}
return Task.FromResult(false);
}
public override bool UndoFeature()
{
try
{
Registry.SetValue(keyName, valueName, "5000", RegistryValueKind.String); // Default value
return true;
}
catch (Exception ex)
{
Logger.Log("Error in SpeedUpShutdown (Undo): " + ex.Message, LogLevel.Error);
}
return false;
}
}
}
@@ -0,0 +1,67 @@
using Microsoft.Win32;
using Flyoobe;
using System;
using System.Threading.Tasks;
namespace Settings.System
{
internal class SystemResponsiveness : FeatureBase
{
private const string keyName = @"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Multimedia\SystemProfile";
private const string valueName = "SystemResponsiveness";
private const int recommendedValue = 10;
public override string GetFeatureDetails()
{
return $"{keyName} | Value: {valueName} | Recommended Value: {recommendedValue}";
}
public override string ID()
{
return "Optimize System Responsiveness";
}
public override string Info()
{
return "Enhances system responsiveness by prioritizing CPU resources for foreground tasks, improving performance during active use.";
}
public override string SupportedOS() => "Windows 10, Windows 11";
public override bool IsRecommended => false;
public override Task<bool> CheckFeature()
{
return Task.FromResult(Utils.IntEquals(keyName, valueName, recommendedValue));
}
public override Task<bool> DoFeature()
{
try
{
Registry.SetValue(keyName, valueName, recommendedValue, RegistryValueKind.DWord);
return Task.FromResult(true);
}
catch (Exception ex)
{
Logger.Log("Code red in " + ex.Message, LogLevel.Error);
}
return Task.FromResult(false);
}
public override bool UndoFeature()
{
try
{
Registry.SetValue(keyName, valueName, 20, RegistryValueKind.DWord); // Default is typically 20 on Windows 11
return true;
}
catch (Exception ex)
{
Logger.Log("Code red in " + ex.Message, LogLevel.Error);
}
return false;
}
}
}
+67
View File
@@ -0,0 +1,67 @@
using Microsoft.Win32;
using Flyoobe;
using System;
using System.Threading.Tasks;
namespace Settings.System
{
internal class TaskbarEndTask : FeatureBase
{
private const string keyName = @"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced\TaskbarDeveloperSettings";
private const string valueName = "TaskbarEndTask";
private const int recommendedValue = 1;
public override string GetFeatureDetails()
{
return $"{keyName} | Value: {valueName} | Recommended Value: {recommendedValue}";
}
public override string ID()
{
return "Enable End Task";
}
public override string Info()
{
return "Adds 'End Task' to the Windows 11 taskbar context menu, allowing you to directly kill unresponsive apps.";
}
public override string SupportedOS() => "Windows 11";
public override bool IsRecommended => true;
public override Task<bool> CheckFeature()
{
return Task.FromResult(Utils.IntEquals(keyName, valueName, recommendedValue));
}
public override Task<bool> DoFeature()
{
try
{
Registry.SetValue(keyName, valueName, recommendedValue, RegistryValueKind.DWord);
return Task.FromResult(true);
}
catch (Exception ex)
{
Logger.Log("Failed to enable End Task: " + ex.Message, LogLevel.Error);
}
return Task.FromResult(false);
}
public override bool UndoFeature()
{
try
{
Registry.SetValue(keyName, valueName, 0, RegistryValueKind.DWord);
return true;
}
catch (Exception ex)
{
Logger.Log("Failed to disable End Task: " + ex.Message, LogLevel.Error);
}
return false;
}
}
}
+70
View File
@@ -0,0 +1,70 @@
using Microsoft.Win32;
using Flyoobe;
using System;
using System.Threading.Tasks;
namespace Settings.System
{
internal class VerboseStatus : FeatureBase
{
private const string keyName = @"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System";
private const string valueName = "VerboseStatus";
private const int recommendedValue = 1;
public override string GetFeatureDetails()
{
return $"{keyName} | Value: {valueName} | Recommended Value: {recommendedValue}";
}
public override string ID()
{
return "Enable Verbose Logon status messages";
}
public override string Info()
{
return "This method allows you to see what processes are hanging when shutting down and turning on the machine.";
}
public override string SupportedOS() => "Windows 10, Windows 11";
public override bool IsRecommended => false;
public override Task<bool> CheckFeature()
{
return Task.FromResult(
Utils.IntEquals(keyName, valueName, recommendedValue)
);
}
public override Task<bool> DoFeature()
{
try
{
Registry.SetValue(keyName, valueName, recommendedValue, RegistryValueKind.DWord);
return Task.FromResult(true);
}
catch (Exception ex)
{
Logger.Log("Code red in " + ex.Message, LogLevel.Error);
}
return Task.FromResult(false);
}
public override bool UndoFeature()
{
try
{
Registry.SetValue(keyName, valueName, 0, RegistryValueKind.DWord);
return true;
}
catch (Exception ex)
{
Logger.Log("Code red in " + ex.Message, LogLevel.Error);
}
return false;
}
}
}
+65
View File
@@ -0,0 +1,65 @@
using Microsoft.Win32;
using Flyoobe;
using System;
using System.Threading.Tasks;
namespace Settings.UI
{
internal class DisableBingSearch : FeatureBase
{
private const string keyName = @"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Search";
private const string valueName = "BingSearchEnabled";
private const int recommendedValue = 0;
public override string GetFeatureDetails()
{
return $"{keyName} | Value: {valueName} | Recommended Value: {recommendedValue}";
}
public override string ID()
{
return "Disable Bing Search";
}
public override string Info()
{
return "This feature disables Bing integration in Windows Search.";
}
public override string SupportedOS() => "Windows 10, Windows 11";
public override bool IsRecommended => true;
public override Task<bool> CheckFeature()
{
return Task.FromResult(Utils.IntEquals(keyName, valueName, recommendedValue));
}
public override Task<bool> DoFeature()
{
try
{
Registry.SetValue(keyName, valueName, recommendedValue, RegistryValueKind.DWord);
return Task.FromResult(true);
}
catch (Exception ex)
{
Logger.Log("Error in DisableBingSearch: " + ex.Message, LogLevel.Error);
return Task.FromResult(false);
}
}
public override bool UndoFeature()
{
try
{
Registry.SetValue(keyName, valueName, 1, RegistryValueKind.DWord);
return true;
}
catch (Exception ex)
{
Logger.Log("Error undoing DisableBingSearch: " + ex.Message, LogLevel.Error);
return false;
}
}
}
}
+72
View File
@@ -0,0 +1,72 @@
using Microsoft.Win32;
using Flyoobe;
using System;
using System.Threading.Tasks;
namespace Settings.Personalization
{
internal class FullContextMenus : FeatureBase
{
private const string keyName = @"HKEY_CURRENT_USER\SOFTWARE\CLASSES\CLSID\{86ca1aa0-34aa-4e8b-a509-50c905bae2a2}\InprocServer32";
public override string GetFeatureDetails()
{
return $"{keyName}";
}
public override string ID()
{
return "Show Full context menus in Windows 11";
}
public override string Info()
{
return "This feature will enable full context menus";
}
public override string SupportedOS() => "Windows 11";
public override bool IsRecommended => false;
public override Task<bool> CheckFeature()
{
try
{
object value = Registry.GetValue(keyName, "", null);
return Task.FromResult(value != null); // Return true if value is not null
}
catch (Exception ex)
{
Logger.Log("Error occurred while checking: " + ex.Message, LogLevel.Error);
return Task.FromResult(false);
}
}
public override Task<bool> DoFeature()
{
try
{
Registry.SetValue(keyName, "", "", RegistryValueKind.String);
return Task.FromResult(true);
}
catch (Exception ex)
{
Logger.Log("Error occurred while enabling: " + ex.Message, LogLevel.Error);
return Task.FromResult(false);
}
}
public override bool UndoFeature()
{
try
{
Registry.CurrentUser.DeleteSubKeyTree(@"Software\Classes\CLSID\{86ca1aa0-34aa-4e8b-a509-50c905bae2a2}", false);
return true;
}
catch (Exception ex)
{
Logger.Log("Error occurred while disabling: " + ex.Message, LogLevel.Error);
return false;
}
}
}
}
@@ -0,0 +1,65 @@
using Microsoft.Win32;
using Flyoobe;
using System;
using System.Threading.Tasks;
namespace Settings.UI
{
internal class DisableSearchBoxSuggestions : FeatureBase
{
private const string keyName = @"HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\Explorer";
private const string valueName = "DisableSearchBoxSuggestions";
private const int recommendedValue = 1;
public override string GetFeatureDetails()
{
return $"{keyName} | Value: {valueName} | Recommended Value: {recommendedValue}";
}
public override string ID()
{
return "Disable Search Box Suggestions";
}
public override string Info()
{
return "This feature disables Bing search and web suggestions in the Windows Start Menu.";
}
public override string SupportedOS() => "Windows 11";
public override bool IsRecommended => true;
public override Task<bool> CheckFeature()
{
return Task.FromResult(Utils.IntEquals(keyName, valueName, recommendedValue));
}
public override Task<bool> DoFeature()
{
try
{
Registry.SetValue(keyName, valueName, recommendedValue, RegistryValueKind.DWord);
return Task.FromResult(true);
}
catch (Exception ex)
{
Logger.Log("Error in DisableSearchBoxSuggestions: " + ex.Message, LogLevel.Error);
return Task.FromResult(false);
}
}
public override bool UndoFeature()
{
try
{
Registry.SetValue(keyName, valueName, 0, RegistryValueKind.DWord); // 0 = Enable suggestions
return true;
}
catch (Exception ex)
{
Logger.Log("Error undoing DisableSearchBoxSuggestions: " + ex.Message, LogLevel.Error);
return false;
}
}
}
}
@@ -0,0 +1,69 @@
using Microsoft.Win32;
using Flyoobe;
using System;
using System.Threading.Tasks;
namespace Settings.Personalization
{
internal class SearchboxTaskbarMode : FeatureBase
{
private const string keyName = @"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Search";
private const string valueName = "SearchboxTaskbarMode";
private const int recommendedValue = 0;
public override string GetFeatureDetails()
{
return $"{keyName} | Value: {valueName} | Recommended Value: {recommendedValue}";
}
public override string ID()
{
return "Hide search box on taskbar";
}
public override string Info()
{
return "This feature will hide search box on taskbar";
}
public override string SupportedOS() => "Windows 11";
public override bool IsRecommended => false;
public override Task<bool> CheckFeature()
{
return Task.FromResult(
Utils.IntEquals(keyName, valueName, recommendedValue)
);
}
public override Task<bool> DoFeature()
{
try
{
Registry.SetValue(keyName, valueName, 0, RegistryValueKind.DWord);
return Task.FromResult(true);
}
catch (Exception ex)
{
Logger.Log("Code red in " + ex.Message, LogLevel.Error);
}
return Task.FromResult(false);
}
public override bool UndoFeature()
{
try
{
Registry.SetValue(keyName, valueName, 2, RegistryValueKind.DWord);
return true;
}
catch (Exception ex)
{
Logger.Log("Code red in " + ex.Message, LogLevel.Error);
}
return false;
}
}
}
@@ -0,0 +1,69 @@
using Microsoft.Win32;
using Flyoobe;
using System;
using System.Threading.Tasks;
namespace Settings.Personalization
{
internal class ShowOrHideMostUsedApps : FeatureBase
{
private const string keyName = @"HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Explorer";
private const string valueName = "ShowOrHideMostUsedApps";
private const int recommendedValue = 2;
public override string GetFeatureDetails()
{
return $"{keyName} | Value: {valueName} | Recommended Value: {recommendedValue}";
}
public override string ID()
{
return "Hide Most used apps in start menu";
}
public override string Info()
{
return "This feature will hide Most used apps in start menu for all users";
}
public override string SupportedOS() => "Windows 11";
public override bool IsRecommended => false;
public override Task<bool> CheckFeature()
{
return Task.FromResult(
Utils.IntEquals(keyName, valueName, recommendedValue)
);
}
public override Task<bool> DoFeature()
{
try
{
Registry.SetValue(keyName, valueName, recommendedValue, RegistryValueKind.DWord);
return Task.FromResult(true);
}
catch (Exception ex)
{
Logger.Log("Code red in " + ex.Message, LogLevel.Error);
}
return Task.FromResult(false);
}
public override bool UndoFeature()
{
try
{
Registry.SetValue(keyName, valueName, 1, RegistryValueKind.DWord);
return true;
}
catch (Exception ex)
{
Logger.Log("Code red in " + ex.Message, LogLevel.Error);
}
return false;
}
}
}
+69
View File
@@ -0,0 +1,69 @@
using Microsoft.Win32;
using Flyoobe;
using System;
using System.Threading.Tasks;
namespace Settings.Personalization
{
internal class ShowTaskViewButton : FeatureBase
{
private const string keyName = @"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced";
private const string valueName = "ShowTaskViewButton";
private const int recommendedValue = 0;
public override string GetFeatureDetails()
{
return $"{keyName} | Value: {valueName} | Recommended: {recommendedValue} (Task View off – cleaner taskbar, unless you use it often)";
}
public override string ID()
{
return "Hide Task view button on taskbar";
}
public override string Info()
{
return "This feature will hide the Task view button on taskbar";
}
public override string SupportedOS() => "Windows 11";
public override bool IsRecommended => false;
public override Task<bool> CheckFeature()
{
return Task.FromResult(
Utils.IntEquals(keyName, valueName, recommendedValue)
);
}
public override Task<bool> DoFeature()
{
try
{
Registry.SetValue(keyName, valueName, 0, RegistryValueKind.DWord);
return Task.FromResult(true);
}
catch (Exception ex)
{
Logger.Log("Code red in " + ex.Message, LogLevel.Error);
}
return Task.FromResult(false);
}
public override bool UndoFeature()
{
try
{
Registry.SetValue(keyName, valueName, 1, RegistryValueKind.DWord);
return true;
}
catch (Exception ex)
{
Logger.Log("Code red in " + ex.Message, LogLevel.Error);
}
return false;
}
}
}
+69
View File
@@ -0,0 +1,69 @@
using Microsoft.Win32;
using Flyoobe;
using System;
using System.Threading.Tasks;
namespace Settings.Personalization
{
internal class DisableSnapAssistFlyout : FeatureBase
{
private const string keyName = @"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced";
private const string valueName = "EnableSnapAssistFlyout";
private const int recommendedValue = 0;
public override string GetFeatureDetails()
{
return $"{keyName} | Value: {valueName} | Recommended Value: {recommendedValue}";
}
public override string ID()
{
return "Disable Snap Assist Flyout";
}
public override string Info()
{
return "This feature disables the Snap Assist flyout, which appears when you snap a window.";
}
public override string SupportedOS() => "Windows 11";
public override bool IsRecommended => false;
public override Task<bool> CheckFeature()
{
return Task.FromResult(
Utils.IntEquals(keyName, valueName, recommendedValue)
);
}
public override Task<bool> DoFeature()
{
try
{
Registry.SetValue(keyName, valueName, 0, RegistryValueKind.DWord);
return Task.FromResult(true);
}
catch (Exception ex)
{
Logger.Log("Error in DisableSnapAssistFlyout: " + ex.Message, LogLevel.Error);
}
return Task.FromResult(false);
}
public override bool UndoFeature()
{
try
{
Registry.SetValue(keyName, valueName, 1, RegistryValueKind.DWord);
return true;
}
catch (Exception ex)
{
Logger.Log("Error in DisableSnapAssistFlyout (Undo): " + ex.Message, LogLevel.Error);
}
return false;
}
}
}
+69
View File
@@ -0,0 +1,69 @@
using Microsoft.Win32;
using Flyoobe;
using System;
using System.Threading.Tasks;
namespace Settings.Personalization
{
internal class StartLayout : FeatureBase
{
private const string keyName = @"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced";
private const string valueName = "Start_Layout";
private const int recommendedValue = 1;
public override string GetFeatureDetails()
{
return $"{keyName} | Value: {valueName} | Recommended Value: {recommendedValue}";
}
public override string ID()
{
return "Pin more Apps on start menu";
}
public override string Info()
{
return "This feature will allow pinning more Apps on start menu";
}
public override string SupportedOS() => "Windows 11";
public override bool IsRecommended => false;
public override Task<bool> CheckFeature()
{
return Task.FromResult(
Utils.IntEquals(keyName, valueName, recommendedValue)
);
}
public override Task<bool> DoFeature()
{
try
{
Registry.SetValue(keyName, valueName, 1, RegistryValueKind.DWord);
return Task.FromResult(true);
}
catch (Exception ex)
{
Logger.Log("Code red in " + ex.Message, LogLevel.Error);
}
return Task.FromResult(false);
}
public override bool UndoFeature()
{
try
{
Registry.SetValue(keyName, valueName, 0, RegistryValueKind.DWord);
return true;
}
catch (Exception ex)
{
Logger.Log("Code red in " + ex.Message, LogLevel.Error);
}
return false;
}
}
}
+69
View File
@@ -0,0 +1,69 @@
using Microsoft.Win32;
using Flyoobe;
using System;
using System.Threading.Tasks;
namespace Settings.Personalization
{
internal class Transparency : FeatureBase
{
private const string keyName = @"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Themes\Personalize";
private const string valueName = "EnableTransparency";
private const int recommendedValue = 0;
public override string GetFeatureDetails()
{
return $"{keyName} | Value: {valueName} | Suggestion: {recommendedValue} (No transparency – smoother performance, still stylish)";
}
public override string ID()
{
return "Disable Transparency Effects";
}
public override string Info()
{
return "This feature disables transparency effects for Start menu, taskbar, and other surfaces.";
}
public override string SupportedOS() => "Windows 11";
public override bool IsRecommended => false;
public override Task<bool> CheckFeature()
{
return Task.FromResult(
Utils.IntEquals(keyName, valueName, recommendedValue)
);
}
public override Task<bool> DoFeature()
{
try
{
Registry.SetValue(keyName, valueName, 0, RegistryValueKind.DWord);
return Task.FromResult(true);
}
catch (Exception ex)
{
Logger.Log("Error in DisableTransparency: " + ex.Message, LogLevel.Error);
}
return Task.FromResult(false);
}
public override bool UndoFeature()
{
try
{
Registry.SetValue(keyName, valueName, 1, RegistryValueKind.DWord);
return true;
}
catch (Exception ex)
{
Logger.Log("Error in DisableTransparency (Undo): " + ex.Message, LogLevel.Error);
}
return false;
}
}
}
+68
View File
@@ -0,0 +1,68 @@
using Microsoft.Win32;
using Flyoobe;
using System;
using System.Threading.Tasks;
namespace Settings.Personalization
{
internal class WLockScreen : FeatureBase
{
private const string keyName = @"HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Personalization";
private const string valueName = "NoLockScreen";
private const int recommendedValue = 0;
public override string GetFeatureDetails()
{
return $"{keyName} | Value: {valueName} | Recommended Value: {recommendedValue}";
}
public override string ID()
{
return "Don't use personalized lock screen";
}
public override string Info()
{
return "This feature will disable the personalized lock screen.";
}
public override string SupportedOS() => "Windows 10, Windows 11";
public override bool IsRecommended => false;
public override Task<bool> CheckFeature()
{
bool result = !Utils.IntEquals(keyName, valueName, recommendedValue);
return Task.FromResult(result);
}
public override Task<bool> DoFeature()
{
try
{
Registry.SetValue(keyName, valueName, 1, RegistryValueKind.DWord);
return Task.FromResult(true);
}
catch (Exception ex)
{
Logger.Log("Code red in " + ex.Message, LogLevel.Error);
}
return Task.FromResult(false);
}
public override bool UndoFeature()
{
try
{
Registry.SetValue(keyName, valueName, 0, RegistryValueKind.DWord);
return true;
}
catch (Exception ex)
{
Logger.Log("Code red in " + ex.Message, LogLevel.Error);
}
return false;
}
}
}
+326
View File
@@ -0,0 +1,326 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{50CA0D4D-45AD-4E03-BFC5-64FFF4CDA36C}</ProjectGuid>
<OutputType>WinExe</OutputType>
<RootNamespace>Flyoobe</RootNamespace>
<AssemblyName>Flyo</AssemblyName>
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<Deterministic>true</Deterministic>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>x64</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup>
<ApplicationManifest>app.manifest</ApplicationManifest>
</PropertyGroup>
<PropertyGroup>
<ApplicationIcon>AppIcon.ico</ApplicationIcon>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Management" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Deployment" />
<Reference Include="System.Drawing" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
<Reference Include="Windows">
<HintPath>..\..\..\..\..\..\Program Files (x86)\Windows Kits\8.1\References\CommonConfiguration\Neutral\Annotated\Windows.winmd</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="AboutForm.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="AboutForm.Designer.cs">
<DependentUpon>AboutForm.cs</DependentUpon>
</Compile>
<Compile Include="Helper\DonationHelper.cs" />
<Compile Include="Helper\CopilotHelper.cs" />
<Compile Include="InstallView\BackupDriversProvider.cs" />
<Compile Include="InstallView\BootMenuInfoProvider.cs" />
<Compile Include="InstallView\InPlaceRepairProvider.cs" />
<Compile Include="InstallView\InstallProviders.cs" />
<Compile Include="InstallView\MctProvider.cs" />
<Compile Include="InstallView\MountIsoProvider.cs" />
<Compile Include="InstallView\NativeResetProvider.cs" />
<Compile Include="InstallView\RebootToUefiProvider.cs" />
<Compile Include="InstallView\RufusProvider.cs" />
<Compile Include="InstallView\RunSetupFromIsoProvider.cs" />
<Compile Include="InstallView\ToolHelper.cs" />
<Compile Include="InstallView\VentoyProvider.cs" />
<Compile Include="UpgradeView\IsoHandler.cs" />
<Compile Include="LogForm.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="LogForm.Designer.cs">
<DependentUpon>LogForm.cs</DependentUpon>
</Compile>
<Compile Include="Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<Compile Include="ToolHubView\ToolDefinition.cs" />
<Compile Include="ToolHubView\ToolHubControlView.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="ToolHubView\ToolHubControlView.Designer.cs">
<DependentUpon>ToolHubControlView.cs</DependentUpon>
</Compile>
<Compile Include="ToolHubView\ToolItemControl.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="ToolHubView\ToolItemControl.Designer.cs">
<DependentUpon>ToolItemControl.cs</DependentUpon>
</Compile>
<Compile Include="Views\AccountControlView.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="Views\AccountControlView.Designer.cs">
<DependentUpon>AccountControlView.cs</DependentUpon>
</Compile>
<Compile Include="Views\AppsControlView.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="Views\AppsControlView.Designer.cs">
<DependentUpon>AppsControlView.cs</DependentUpon>
</Compile>
<Compile Include="Features\FeatureBase.cs" />
<Compile Include="Features\FeatureLoader.cs" />
<Compile Include="Features\FeatureManager.cs" />
<Compile Include="Features\FeatureNode.cs" />
<Compile Include="Features\Ads\FileExlorerAds.cs" />
<Compile Include="Features\Ads\FinishSetupAds.cs" />
<Compile Include="Features\Ads\LockScreenAds.cs" />
<Compile Include="Features\Ads\PersonalizedAds.cs" />
<Compile Include="Features\Ads\SettingsAds.cs" />
<Compile Include="Features\Ads\StartmenuAds.cs" />
<Compile Include="Features\Ads\TailoredExperiences.cs" />
<Compile Include="Features\Ads\TipsAndSuggestions.cs" />
<Compile Include="Features\Ads\WelcomeExperienceAds.cs" />
<Compile Include="Features\AI\ClickToDo.cs" />
<Compile Include="Features\AI\CopilotTaskbar.cs" />
<Compile Include="Features\AI\Recall.cs" />
<Compile Include="Features\Edge\BrowserSignin.cs" />
<Compile Include="Features\Edge\DefaultTopSites.cs" />
<Compile Include="Features\Edge\DefautBrowserSetting.cs" />
<Compile Include="Features\Edge\EdgeCollections.cs" />
<Compile Include="Features\Edge\EdgeShoppingAssistant.cs" />
<Compile Include="Features\Edge\FirstRunExperience.cs" />
<Compile Include="Features\Edge\GamerMode.cs" />
<Compile Include="Features\Edge\HubsSidebar.cs" />
<Compile Include="Features\Edge\ImportOnEachLaunch.cs" />
<Compile Include="Features\Edge\StartupBoost.cs" />
<Compile Include="Features\Edge\TabPageQuickLinks.cs" />
<Compile Include="Features\Edge\UserFeedback.cs" />
<Compile Include="Features\Gaming\GameDVR.cs" />
<Compile Include="Features\Gaming\PowerThrotteling.cs" />
<Compile Include="Features\Gaming\VisualFX.cs" />
<Compile Include="Features\Issues\BasicCleanup.cs" />
<Compile Include="Features\Issues\WingetUpgrade.cs" />
<Compile Include="Features\Privacy\ActivityHistory.cs" />
<Compile Include="Features\Privacy\LocationTracking.cs" />
<Compile Include="Features\Privacy\PrivacyExperience.cs" />
<Compile Include="Features\Privacy\Telemetry.cs" />
<Compile Include="Features\System\BSODDetails.cs" />
<Compile Include="Features\System\Hibernation.cs" />
<Compile Include="Features\System\MenuShowDelay.cs" />
<Compile Include="Features\System\NetworkThrottling.cs" />
<Compile Include="Features\System\SpeedUpShutdown.cs" />
<Compile Include="Features\System\SystemResponsiveness.cs" />
<Compile Include="Features\System\TaskbarEndTask.cs" />
<Compile Include="Features\System\VerboseStatus.cs" />
<Compile Include="Features\UI\BingSearch.cs" />
<Compile Include="Features\UI\FullContextMenus.cs" />
<Compile Include="Features\UI\WLockScreen.cs" />
<Compile Include="Features\UI\SearchBoxSuggestions.cs" />
<Compile Include="Features\UI\SearchboxTaskbarMode.cs" />
<Compile Include="Features\UI\ShowOrHideMostUsedApps.cs" />
<Compile Include="Features\UI\ShowTaskViewButton.cs" />
<Compile Include="Features\UI\SnapAssistFlyout.cs" />
<Compile Include="Features\UI\StartLayout.cs" />
<Compile Include="Features\UI\Transparency.cs" />
<Compile Include="Views\DefaultsControlView.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="Views\DefaultsControlView.Designer.cs">
<DependentUpon>DefaultsControlView.cs</DependentUpon>
</Compile>
<Compile Include="Views\ExperienceControlView.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="Views\ExperienceControlView.Designer.cs">
<DependentUpon>ExperienceControlView.cs</DependentUpon>
</Compile>
<Compile Include="Helper\Logger.cs" />
<Compile Include="Views\DeviceControlView.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="Views\DeviceControlView.Designer.cs">
<DependentUpon>DeviceControlView.cs</DependentUpon>
</Compile>
<Compile Include="IView.cs" />
<Compile Include="MainForm.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="MainForm.Designer.cs">
<DependentUpon>MainForm.cs</DependentUpon>
</Compile>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Helper\Utils.cs" />
<Compile Include="ViewNavigator.cs" />
<Compile Include="Views\HomeControlView.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="Views\InstallerControlView.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="Views\InstallerControlView.Designer.cs">
<DependentUpon>InstallerControlView.cs</DependentUpon>
</Compile>
<Compile Include="Views\NetworkControlView.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="Views\NetworkControlView.Designer.cs">
<DependentUpon>NetworkControlView.cs</DependentUpon>
</Compile>
<Compile Include="Views\PersonalizationControlView.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="Views\PersonalizationControlView.Designer.cs">
<DependentUpon>PersonalizationControlView.cs</DependentUpon>
</Compile>
<Compile Include="InstallView\InstallControlView.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="InstallView\InstallControlView.Designer.cs">
<DependentUpon>InstallControlView.cs</DependentUpon>
</Compile>
<Compile Include="Views\UpdatesControlView.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="Views\UpdatesControlView.Designer.cs">
<DependentUpon>UpdatesControlView.cs</DependentUpon>
</Compile>
<Compile Include="UpgradeView\UpgradeControlView.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="UpgradeView\UpgradeControlView.Designer.cs">
<DependentUpon>UpgradeControlView.cs</DependentUpon>
</Compile>
<EmbeddedResource Include="AboutForm.resx">
<DependentUpon>AboutForm.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="LogForm.resx">
<DependentUpon>LogForm.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="ToolHubView\ToolHubControlView.resx">
<DependentUpon>ToolHubControlView.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="ToolHubView\ToolItemControl.resx">
<DependentUpon>ToolItemControl.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Views\AccountControlView.resx">
<DependentUpon>AccountControlView.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Views\AppsControlView.resx">
<DependentUpon>AppsControlView.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Views\DefaultsControlView.resx">
<DependentUpon>DefaultsControlView.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Views\ExperienceControlView.resx">
<DependentUpon>ExperienceControlView.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Views\DeviceControlView.resx">
<DependentUpon>DeviceControlView.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="MainForm.resx">
<DependentUpon>MainForm.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<SubType>Designer</SubType>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
<EmbeddedResource Include="Views\InstallerControlView.resx">
<DependentUpon>InstallerControlView.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Views\NetworkControlView.resx">
<DependentUpon>NetworkControlView.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Views\PersonalizationControlView.resx">
<DependentUpon>PersonalizationControlView.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="InstallView\InstallControlView.resx">
<DependentUpon>InstallControlView.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Views\UpdatesControlView.resx">
<DependentUpon>UpdatesControlView.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="UpgradeView\UpgradeControlView.resx">
<DependentUpon>UpgradeControlView.cs</DependentUpon>
</EmbeddedResource>
<None Include="app.manifest" />
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
<Compile Include="Properties\Settings.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Settings.settings</DependentUpon>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile>
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
</ItemGroup>
<ItemGroup>
<COMReference Include="WUApiLib">
<Guid>{B596CC9F-56E5-419E-A622-E01BB457431E}</Guid>
<VersionMajor>2</VersionMajor>
<VersionMinor>0</VersionMinor>
<Lcid>0</Lcid>
<WrapperTool>tlbimp</WrapperTool>
<Isolated>False</Isolated>
<EmbedInteropTypes>True</EmbedInteropTypes>
</COMReference>
</ItemGroup>
<ItemGroup>
<None Include="assetCopilot.png" />
</ItemGroup>
<ItemGroup>
<Content Include="AppIcon.ico" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
+92
View File
@@ -0,0 +1,92 @@
using System;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Windows.Forms;
public static class CopilotHelper
{
// Path to the Copilot icon file
private static readonly string IconPath = Path.Combine("app", "copilot.png");
// The Shell URI to launch the Copilot app
private const string CopilotAppUri = "shell:AppsFolder\\Microsoft.Copilot_8wekyb3d8bbwe!App";
/// <summary>
/// Loads and scales the Copilot icon if available.
/// </summary>
/// <param name="baseSize">Base size for the icon</param>
/// <returns>Scaled icon image or null if icon file missing</returns>
public static Image LoadScaledIcon(int baseSize)
{
if (!File.Exists(IconPath))
return null;
using (var img = Image.FromFile(IconPath))
{
int scaledSize = GetScaledIconSize(baseSize);
return new Bitmap(img, new Size(scaledSize, scaledSize));
}
}
/// <summary>
/// Calculates the scaled icon size based on current screen DPI.
/// </summary>
public static int GetScaledIconSize(int baseSize)
{
using (Graphics g = Graphics.FromHwnd(IntPtr.Zero))
return (int)(baseSize * (g.DpiX / 96f));
}
/// <summary>
/// Attempts to launch the Copilot app.
/// </summary>
public static void LaunchCopilot()
{
string appFolder = Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
"Packages",
"Microsoft.Copilot_8wekyb3d8bbwe"
);
if (!Directory.Exists(appFolder))
{
MessageBox.Show(
"Copilot is currently unavailable. You're the captain now...",
"Copilot Launch Failed",
MessageBoxButtons.OK,
MessageBoxIcon.Warning
);
return;
}
Process.Start(new ProcessStartInfo
{
FileName = "explorer.exe",
Arguments = CopilotAppUri,
UseShellExecute = true
});
}
/// <summary>
/// Sets up the Copilot button with the icon and tooltip.
/// </summary>
/// <param name="btn"></param>
/// <param name="iconBaseSize"></param>
public static void SetupCopilotButton(Button btn, int iconBaseSize)
{
if (File.Exists(IconPath))
{
btn.Visible = true;
btn.Image = LoadScaledIcon(iconBaseSize);
var tooltip = new ToolTip();
tooltip.SetToolTip(btn, "Ask Copilot");
}
else
{
btn.Visible = false;
}
}
}
+68
View File
@@ -0,0 +1,68 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
namespace Flyoobe
{
public enum LogLevel
{
Info,
Warning,
Error
}
public static class Logger
{
// Event raised when a warning or error is logged
public static event Action<string, LogLevel> OnNotificationLogged;
private static readonly List<string> _logBuffer = new List<string>();
private static readonly string _logFilePath;
// Static constructor initializes the log file path
static Logger()
{
string exeDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
string appDirectory = Path.Combine(exeDirectory, "app");
_logFilePath = Path.Combine(appDirectory, "log.txt");
}
/// <summary>
/// Logs a message with timestamp and log level.
/// Also appends the message to the log file.
/// </summary>
public static void Log(string message, LogLevel level = LogLevel.Info)
{
var timestamp = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
var levelStr = level.ToString().ToUpper();
var logLine = $"[{timestamp}] [{levelStr}] {message}";
_logBuffer.Add(logLine);
try
{
File.AppendAllText(_logFilePath, logLine + Environment.NewLine);
}
catch (Exception ex)
{
Debug.WriteLine($"Failed to write to log file: {ex.Message}");
}
// Fire event if level is Warning or Error
if (level == LogLevel.Warning || level == LogLevel.Error)
{
OnNotificationLogged?.Invoke(message, level);
}
}
/// <summary>
/// Returns the full log history stored in memory.
/// </summary>
public static string GetLog()
{
return string.Join(Environment.NewLine, _logBuffer);
}
}
}
+92
View File
@@ -0,0 +1,92 @@
using Microsoft.Win32;
using System;
using System.Diagnostics;
using System.Security.Principal;
namespace Flyoobe
{
internal static class Utils
{
private const string GitHubUrl = "https://github.com/builtbybel/Flyoobe";
/// <summary>
/// Checks if a registry value equals a specified integer.
/// </summary>
public static bool IntEquals(string keyName, string valueName, int expectedValue)
{
try
{
object value = Registry.GetValue(keyName, valueName, null);
return value is int intValue && intValue == expectedValue;
}
catch (Exception ex)
{
Logger.Log($"Registry check failed for {keyName}\\{valueName}: {ex.Message}", LogLevel.Error);
return false;
}
}
/// <summary>
/// Checks if a registry value equals a specified string.
/// </summary>
public static bool StringEquals(string keyName, string valueName, string expectedValue)
{
try
{
object value = Registry.GetValue(keyName, valueName, null);
return value is string strValue && strValue == expectedValue;
}
catch (Exception ex)
{
Logger.Log($"Registry check failed for {keyName}\\{valueName}: {ex.Message}", LogLevel.Error);
return false;
}
}
/// <summary>
/// Opens the GitHub project page in the default browser.
/// </summary>
public static void OpenGitHubPage(object sender, EventArgs e)
{
try
{
Process.Start(new ProcessStartInfo
{
FileName = GitHubUrl,
UseShellExecute = true
});
}
catch (Exception ex)
{
Logger.Log($"Failed to open GitHub page: {ex.Message}", LogLevel.Error);
}
}
/// <summary>
/// Checks if the application is running with administrative privileges.
/// </summary>
/// <returns></returns>
public static bool IsRunningAsAdmin()
{
using (var identity = WindowsIdentity.GetCurrent())
{
var principal = new WindowsPrincipal(identity);
return principal.IsInRole(WindowsBuiltInRole.Administrator);
}
}
/// <summary>
/// Detects if the current OS is Windows 11 or newer.
/// </summary>
public static bool DetectWindows11()
{
object buildObj = Registry.GetValue(@"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion", "CurrentBuildNumber", null);
if (buildObj != null && int.TryParse(buildObj.ToString(), out int build))
{
return build >= 22000; // Windows 11 starts at build 22000
}
return false; // If unable to detect, assume not Windows 11
}
}
}
+15
View File
@@ -0,0 +1,15 @@
/// <summary>
/// Represents a view that can be refreshed and provides a display title.
/// </summary>
public interface IView
{
/// <summary>
/// Refreshes the view to update its display or data.
/// </summary>
void RefreshView();
/// <summary>
/// Gets the title of the view for display in the UI.
/// </summary>
string ViewTitle { get; }
}
@@ -0,0 +1,138 @@
using System;
using System.Diagnostics;
using System.IO;
using System.Windows.Forms;
namespace Flyoobe
{
// Provider that exports all installed drivers into a fixed subfolder named "DriversBackup"
// INSIDE the parent folder chosen by the user, using:
// pnputil.exe /export-driver * <chosenParent>\DriversBackup
// Behavior:
// - Prompts user to choose a parent folder (defaults to C:\).
// - Always creates/uses "<chosenParent>\DriversBackup".
// - Runs pnputil elevated.
// - Shows a completion summary with INF package count.
public sealed class BackupDriversProvider : IInstallProvider
{
public string Id => "drivers-backup";
public string DisplayName => "Backup installed drivers (choose folder)";
public string HomepageUrl => null;
public string DirectDownloadUrl => null;
public string[] ExactExeNames => new[] { "pnputil.exe" };
public string[] WildcardExePatterns => Array.Empty<string>();
public bool TypicallyNeedsIso => false;
public bool IsExternalTool => false;
public string Hint =>
"Exports all currently installed device drivers (INF + binaries) to a folder you choose. " +
"After a clean install, point Device Manager to that folder to restore drivers even without internet.";
public string ShowOptionsAndBuildArgs(IWin32Window owner, LastSelections last)
{
// Default suggestion for the parent, the actual export target will be <parent>\DriversBackup
var defaultParent = @"C:\";
string parentPath;
// pick the PARENT folder where the 'DriversBackup' subfolder will be created
using (var fbd = new FolderBrowserDialog
{
Description = "Choose the PARENT folder. A 'DriversBackup' subfolder will be created inside it.",
ShowNewFolderButton = true,
SelectedPath = defaultParent
})
{
var dlgResult = fbd.ShowDialog(owner);
if (dlgResult != DialogResult.OK || string.IsNullOrWhiteSpace(fbd.SelectedPath))
return null; //user cancelled
parentPath = fbd.SelectedPath.Trim();
try
{
//Normalize parent path
parentPath = Path.GetFullPath(parentPath);
}
catch
{ //Keep raw selection if normalization fails (we'll error out later if invalid)
}
}
// Build the fixed subfolder path: <parent>\DriversBackup (always appended)
string target = Path.Combine(parentPath, "DriversBackup");
// Confirm before running the elevated export
if (!ToolHelpers.Confirm(owner,
"Export all installed drivers to:\r\n\r\n" + target +
"\r\n\r\nThis will run 'pnputil /export-driver *' with administrative rights."))
return null;
// Ensure the target DriversBackup folder exists
try
{
Directory.CreateDirectory(target);
}
catch (Exception ex)
{
MessageBox.Show(owner,
"Could not create target folder:\r\n" + target + "\r\n\r\n" + ex.Message,
"Folder error",
MessageBoxButtons.OK, MessageBoxIcon.Error);
return null;
}
try
{
// Start pnputil as an elevated process targeting the 'DriversBackup' subfolder
var psi = new ProcessStartInfo
{
FileName = "pnputil.exe",
Arguments = "/export-driver * \"" + target + "\"",
UseShellExecute = true,
Verb = "runas", // force elevation
CreateNoWindow = true
};
using (var proc = Process.Start(psi))
{
if (proc == null)
{
MessageBox.Show(owner, "Could not start pnputil.exe", "Error",
MessageBoxButtons.OK, MessageBoxIcon.Error);
return null;
}
proc.WaitForExit();
}
// Count exported INF files to provide a quick summary
int infCount = 0;
try
{
infCount = Directory.GetFiles(target, "*.inf", SearchOption.AllDirectories).Length;
}
catch
{ // Ignore counting errors; we can still show success without the count
}
MessageBox.Show(owner,
"Driver export completed.\r\n\r\n" +
$"Target: {target}\r\n" +
$"Exported driver packages: {infCount}\r\n\r\n" +
"Tip: After reinstall, in Device Manager choose 'Update driver' → 'Browse my computer' " +
"and select this folder to restore drivers.",
"Export complete",
MessageBoxButtons.OK, MessageBoxIcon.Information);
}
catch (Exception ex)
{
MessageBox.Show(owner,
"Failed to run pnputil:\r\n" + ex.Message,
"Error",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
return null; // returning null indicates no further action needed
}
}
}
+180
View File
@@ -0,0 +1,180 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Management; //HATING WMI NEEDS IMPROVEMENT!
namespace Flyoobe
{
// Just Pure info provider: shows common Boot Menu / BIOS keys by vendor.
// No tool launch; the provider only displays a small dialog with helpful hints.
public sealed class BootMenuInfoProvider : IInstallProvider
{
public string Id => "bootmenu-info";
public string DisplayName => "Boot Menu keys (info)";
public string HomepageUrl => null;
public string DirectDownloadUrl => null;
public string[] ExactExeNames => Array.Empty<string>();
public string[] WildcardExePatterns => Array.Empty<string>();
public bool TypicallyNeedsIso => false;
public bool IsExternalTool => false;
public string Hint =>
"Shows common Boot Menu and BIOS/UEFI keys for popular manufacturers. " +
"Helpful when you want to boot from a USB installer.";
public string ShowOptionsAndBuildArgs(IWin32Window owner, LastSelections last)
{
// Build and show info dialog; nothing to run afterwards.
using (var dlg = new BootMenuInfoDialog())
{
dlg.ShowDialog(owner);
}
return null;
}
// ------------------ self-contained dialog (no designer) ------------------
private sealed class BootMenuInfoDialog : Form
{
private readonly TextBox _txt;
private readonly Button _btnCopy;
private readonly Button _btnRecovery;
private readonly Button _btnClose;
public BootMenuInfoDialog()
{
Text = "Boot Menu keys (info)";
StartPosition = FormStartPosition.CenterParent;
FormBorderStyle = FormBorderStyle.FixedDialog;
MaximizeBox = false;
MinimizeBox = false;
ShowInTaskbar = false;
AutoSize = true;
AutoSizeMode = AutoSizeMode.GrowAndShrink;
Padding = new Padding(12);
// Main multiline textbox (read-only)
_txt = new TextBox
{
Multiline = true,
ReadOnly = true,
ScrollBars = ScrollBars.Vertical,
WordWrap = false,
Width = 520,
Height = 360
};
// Buttons
_btnCopy = new Button { Text = "Copy to clipboard", AutoSize = true };
_btnRecovery = new Button { Text = "Open Recovery settings", AutoSize = true };
_btnClose = new Button { Text = "Close", AutoSize = true, DialogResult = DialogResult.OK };
_btnCopy.Click += (s, e) => { try { Clipboard.SetText(_txt.Text); } catch { } };
_btnRecovery.Click += (s, e) => { ToolHelpers.OpenUri("ms-settings:recovery"); };
var btnPanel = new FlowLayoutPanel { FlowDirection = FlowDirection.RightToLeft, AutoSize = true, Dock = DockStyle.Fill, Margin = new Padding(0, 8, 0, 0) };
btnPanel.Controls.Add(_btnClose);
btnPanel.Controls.Add(_btnRecovery);
btnPanel.Controls.Add(_btnCopy);
var root = new TableLayoutPanel { ColumnCount = 1, AutoSize = true, Dock = DockStyle.Fill };
root.Controls.Add(_txt);
root.Controls.Add(btnPanel);
Controls.Add(root);
AcceptButton = _btnClose;
CancelButton = _btnClose;
// Populate content
_txt.Text = BuildContent();
}
// Returns vendor + model (if available) and a table of common keys.
private string BuildContent()
{
// Known keys by vendor (not exhaustive, but practical)
var map = new List<(string Vendor, string BootMenu, string BiosSetup)>
{
("Acer", "F12", "F2"),
("ASUS", "Esc or F8", "Del or F2"),
("Dell", "F12", "F2"),
("HP", "Esc or F9", "Esc or F10"),
("Lenovo", "F12 (Fn+F12)", "F1 or F2"),
("MSI", "F11", "Del"),
("Gigabyte", "F12", "Del"),
("ASRock", "F11", "F2 or Del"),
("Toshiba", "F12", "F2"),
("Sony", "F11 or Assist", "F2"),
("Samsung", "Esc or F12", "F2"),
("Microsoft", "Vol-Down + Power (Surface)", "Vol-Up + Power (UEFI)")
};
// Try to read Manufacturer/Model (WMI)
var (manufacturer, model) = GetSystemVendor();
var sb = new StringBuilder();
// Header
sb.AppendLine("Boot Menu & BIOS/UEFI keys");
sb.AppendLine("---------------------------");
if (!string.IsNullOrWhiteSpace(manufacturer) || !string.IsNullOrWhiteSpace(model))
{
sb.AppendLine($"Detected: {TrimOrUnknown(manufacturer)} {TrimOrUnknown(model)}");
}
else
{
sb.AppendLine("Detected: (unknown manufacturer/model)");
}
sb.AppendLine();
// If we have a known vendor, show it first
var primary = map.FirstOrDefault(x => manufacturer != null && manufacturer.IndexOf(x.Vendor, StringComparison.OrdinalIgnoreCase) >= 0);
if (!string.IsNullOrEmpty(primary.Vendor))
{
sb.AppendLine($"★ Recommended for your device ({primary.Vendor}):");
sb.AppendLine($" Boot Menu: {primary.BootMenu}");
sb.AppendLine($" BIOS/UEFI: {primary.BiosSetup}");
sb.AppendLine();
}
// Table of common keys
sb.AppendLine("Common keys by vendor:");
sb.AppendLine("Vendor | Boot Menu | BIOS/UEFI");
sb.AppendLine("--------------+-------------------+----------------");
foreach (var entry in map)
{
sb.AppendLine(
$"{entry.Vendor.PadRight(12)}| {entry.BootMenu.PadRight(18)}| {entry.BiosSetup}");
}
sb.AppendLine();
sb.AppendLine("Tips:");
sb.AppendLine("- Press and hold the key right after power-on, before the Windows logo.");
sb.AppendLine("- On some laptops you may need to hold Fn with the function key (e.g., Fn+F12).");
sb.AppendLine("- If you cannot reach the menu, use 'Open Recovery settings' and choose Advanced startup → UEFI Firmware Settings.");
return sb.ToString();
}
private static (string Manufacturer, string Model) GetSystemVendor()
{
try
{
using (var searcher = new ManagementObjectSearcher("SELECT Manufacturer, Model FROM Win32_ComputerSystem"))
{
foreach (ManagementObject mo in searcher.Get())
{
var m = (mo["Manufacturer"] as string) ?? "";
var model = (mo["Model"] as string) ?? "";
return (m.Trim(), model.Trim());
}
}
}
catch { /* WMI not available or permission issue */ }
return (null, null);
}
private static string TrimOrUnknown(string s) => string.IsNullOrWhiteSpace(s) ? "(unknown)" : s.Trim();
}
}
}
@@ -0,0 +1,57 @@
using System.IO;
using System.Windows.Forms;
namespace Flyoobe
{
// Runs setup.exe from a mounted Windows ISO with upgrade parameters.
public sealed class InPlaceRepairProvider : IInstallProvider
{
public string Id => "inplace";
public string DisplayName => "Repair upgrade (keeps apps & files)";
public string HomepageUrl => null;
public string DirectDownloadUrl => null;
public string[] ExactExeNames => new[] { "setup.exe" }; // for documentation only
public string[] WildcardExePatterns => System.Array.Empty<string>();
public bool TypicallyNeedsIso => true;
public bool IsExternalTool => false;
public string Hint =>
"Starts Windows Setup from a mounted ISO in automatic repair mode. " +
"This reinstalls Windows while keeping your apps, settings, and personal files. " +
"Recommended if your system is broken but you want to keep everything.";
public string ShowOptionsAndBuildArgs(IWin32Window owner, LastSelections last)
{
var setupPath = FindSetupExeOnMountedDrives();
if (setupPath == null)
{
MessageBox.Show(owner, "No 'setup.exe' found. Please mount a Windows ISO first.",
"Setup not found", MessageBoxButtons.OK, MessageBoxIcon.Information);
return null;
}
if (!ToolHelpers.Confirm(owner, "Start repair upgrade via setup.exe? The PC will restart during the process."))
return null;
// Start directly and handle here
ToolHelpers.Run(setupPath, "/auto upgrade /dynamicupdate enable", asAdmin: true);
return null; // handled > host should not run anything else
}
private static string FindSetupExeOnMountedDrives()
{
try
{
foreach (var di in DriveInfo.GetDrives())
{
if (di.DriveType == DriveType.CDRom || di.DriveType == DriveType.Removable || di.DriveType == DriveType.Fixed)
{
var p = Path.Combine(di.Name, "setup.exe");
if (File.Exists(p)) return p;
}
}
}
catch { }
return null;
}
}
}
+316
View File
@@ -0,0 +1,316 @@
namespace Flyoobe
{
partial class InstallControlView
{
/// <summary>
/// Erforderliche Designervariable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Verwendete Ressourcen bereinigen.
/// </summary>
/// <param name="disposing">True, wenn verwaltete Ressourcen gelöscht werden sollen; andernfalls False.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Vom Komponenten-Designer generierter Code
/// <summary>
/// Erforderliche Methode für die Designerunterstützung.
/// Der Inhalt der Methode darf nicht mit dem Code-Editor geändert werden.
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.panel1 = new System.Windows.Forms.Panel();
this.textProviderSearch = new System.Windows.Forms.TextBox();
this.btnQuickRepair = new System.Windows.Forms.Button();
this.btnCreateUsb = new System.Windows.Forms.Button();
this.lblOneClick = new System.Windows.Forms.Label();
this.panelInstall = new System.Windows.Forms.Panel();
this.lblBadgeDl = new System.Windows.Forms.Label();
this.lblBadgeIso = new System.Windows.Forms.Label();
this.cboSource = new System.Windows.Forms.ComboBox();
this.btnHomepage = new System.Windows.Forms.Button();
this.lblBadgeExternal = new System.Windows.Forms.Label();
this.btnDownload = new System.Windows.Forms.Button();
this.btnRun = new System.Windows.Forms.Button();
this.lblBadgeNative = new System.Windows.Forms.Label();
this.lblHint = new System.Windows.Forms.Label();
this.toolTip1 = new System.Windows.Forms.ToolTip(this.components);
this.panel1.SuspendLayout();
this.panelInstall.SuspendLayout();
this.SuspendLayout();
//
// panel1
//
this.panel1.AutoScroll = true;
this.panel1.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(242)))), ((int)(((byte)(244)))), ((int)(((byte)(244)))));
this.panel1.Controls.Add(this.textProviderSearch);
this.panel1.Controls.Add(this.btnQuickRepair);
this.panel1.Controls.Add(this.btnCreateUsb);
this.panel1.Controls.Add(this.lblOneClick);
this.panel1.Controls.Add(this.panelInstall);
this.panel1.Controls.Add(this.lblHint);
this.panel1.Dock = System.Windows.Forms.DockStyle.Fill;
this.panel1.Location = new System.Drawing.Point(0, 0);
this.panel1.Name = "panel1";
this.panel1.Size = new System.Drawing.Size(835, 457);
this.panel1.TabIndex = 11;
//
// textProviderSearch
//
this.textProviderSearch.AccessibleRole = System.Windows.Forms.AccessibleRole.SplitButton;
this.textProviderSearch.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.textProviderSearch.Font = new System.Drawing.Font("Segoe UI Variable Small", 9.75F);
this.textProviderSearch.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64)))));
this.textProviderSearch.Location = new System.Drawing.Point(196, 18);
this.textProviderSearch.Name = "textProviderSearch";
this.textProviderSearch.Size = new System.Drawing.Size(473, 25);
this.textProviderSearch.TabIndex = 339;
this.textProviderSearch.Text = "Search";
this.textProviderSearch.Click += new System.EventHandler(this.textProviderSearch_Click);
//
// btnQuickRepair
//
this.btnQuickRepair.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.btnQuickRepair.BackColor = System.Drawing.Color.Transparent;
this.btnQuickRepair.FlatAppearance.BorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(32)))), ((int)(((byte)(138)))), ((int)(((byte)(211)))));
this.btnQuickRepair.FlatAppearance.BorderSize = 2;
this.btnQuickRepair.FlatAppearance.MouseDownBackColor = System.Drawing.Color.LightGray;
this.btnQuickRepair.FlatAppearance.MouseOverBackColor = System.Drawing.Color.LightGray;
this.btnQuickRepair.Font = new System.Drawing.Font("Segoe UI Variable Small", 8.25F);
this.btnQuickRepair.ForeColor = System.Drawing.Color.Black;
this.btnQuickRepair.Location = new System.Drawing.Point(101, 422);
this.btnQuickRepair.Name = "btnQuickRepair";
this.btnQuickRepair.Size = new System.Drawing.Size(138, 27);
this.btnQuickRepair.TabIndex = 337;
this.btnQuickRepair.Text = "🪟 Quick Repair";
this.btnQuickRepair.UseVisualStyleBackColor = false;
//
// btnCreateUsb
//
this.btnCreateUsb.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.btnCreateUsb.BackColor = System.Drawing.Color.Transparent;
this.btnCreateUsb.FlatAppearance.BorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(32)))), ((int)(((byte)(138)))), ((int)(((byte)(211)))));
this.btnCreateUsb.FlatAppearance.BorderSize = 2;
this.btnCreateUsb.FlatAppearance.MouseDownBackColor = System.Drawing.Color.LightGray;
this.btnCreateUsb.FlatAppearance.MouseOverBackColor = System.Drawing.Color.LightGray;
this.btnCreateUsb.Font = new System.Drawing.Font("Segoe UI Variable Small", 8.25F);
this.btnCreateUsb.ForeColor = System.Drawing.Color.Black;
this.btnCreateUsb.Location = new System.Drawing.Point(245, 422);
this.btnCreateUsb.Name = "btnCreateUsb";
this.btnCreateUsb.Size = new System.Drawing.Size(138, 27);
this.btnCreateUsb.TabIndex = 338;
this.btnCreateUsb.Text = " 💿 Create Install USB";
this.btnCreateUsb.UseVisualStyleBackColor = false;
//
// lblOneClick
//
this.lblOneClick.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.lblOneClick.AutoEllipsis = true;
this.lblOneClick.Font = new System.Drawing.Font("Segoe UI Variable Small Semilig", 10.25F);
this.lblOneClick.ForeColor = System.Drawing.Color.Black;
this.lblOneClick.Location = new System.Drawing.Point(7, 425);
this.lblOneClick.Name = "lblOneClick";
this.lblOneClick.Size = new System.Drawing.Size(89, 27);
this.lblOneClick.TabIndex = 336;
this.lblOneClick.Text = "One-click:";
this.lblOneClick.UseCompatibleTextRendering = true;
//
// panelInstall
//
this.panelInstall.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.panelInstall.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(249)))), ((int)(((byte)(243)))), ((int)(((byte)(240)))));
this.panelInstall.Controls.Add(this.lblBadgeDl);
this.panelInstall.Controls.Add(this.lblBadgeIso);
this.panelInstall.Controls.Add(this.cboSource);
this.panelInstall.Controls.Add(this.btnHomepage);
this.panelInstall.Controls.Add(this.lblBadgeExternal);
this.panelInstall.Controls.Add(this.btnDownload);
this.panelInstall.Controls.Add(this.btnRun);
this.panelInstall.Controls.Add(this.lblBadgeNative);
this.panelInstall.Location = new System.Drawing.Point(42, 169);
this.panelInstall.Name = "panelInstall";
this.panelInstall.Size = new System.Drawing.Size(752, 173);
this.panelInstall.TabIndex = 335;
//
// lblBadgeDl
//
this.lblBadgeDl.AutoEllipsis = true;
this.lblBadgeDl.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(249)))), ((int)(((byte)(243)))), ((int)(((byte)(240)))));
this.lblBadgeDl.Font = new System.Drawing.Font("Segoe UI Variable Small Semilig", 9.25F);
this.lblBadgeDl.ForeColor = System.Drawing.Color.Black;
this.lblBadgeDl.Location = new System.Drawing.Point(306, 13);
this.lblBadgeDl.Name = "lblBadgeDl";
this.lblBadgeDl.Size = new System.Drawing.Size(130, 26);
this.lblBadgeDl.TabIndex = 338;
this.lblBadgeDl.Text = "⬇️ Direct download";
this.lblBadgeDl.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// lblBadgeIso
//
this.lblBadgeIso.AutoEllipsis = true;
this.lblBadgeIso.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(249)))), ((int)(((byte)(243)))), ((int)(((byte)(240)))));
this.lblBadgeIso.Font = new System.Drawing.Font("Segoe UI Variable Small Semilig", 9.25F);
this.lblBadgeIso.ForeColor = System.Drawing.Color.Black;
this.lblBadgeIso.Location = new System.Drawing.Point(194, 13);
this.lblBadgeIso.Name = "lblBadgeIso";
this.lblBadgeIso.Size = new System.Drawing.Size(106, 26);
this.lblBadgeIso.TabIndex = 337;
this.lblBadgeIso.Text = "💿 Needs ISO";
this.lblBadgeIso.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// cboSource
//
this.cboSource.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.cboSource.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.cboSource.FlatStyle = System.Windows.Forms.FlatStyle.System;
this.cboSource.Font = new System.Drawing.Font("Segoe UI Variable Small Semilig", 11.25F);
this.cboSource.FormattingEnabled = true;
this.cboSource.Location = new System.Drawing.Point(11, 61);
this.cboSource.Name = "cboSource";
this.cboSource.Size = new System.Drawing.Size(733, 28);
this.cboSource.TabIndex = 334;
//
// btnHomepage
//
this.btnHomepage.BackColor = System.Drawing.Color.Transparent;
this.btnHomepage.FlatAppearance.BorderColor = System.Drawing.Color.Silver;
this.btnHomepage.FlatAppearance.BorderSize = 2;
this.btnHomepage.FlatAppearance.MouseDownBackColor = System.Drawing.Color.LightGray;
this.btnHomepage.FlatAppearance.MouseOverBackColor = System.Drawing.Color.LightGray;
this.btnHomepage.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.btnHomepage.Font = new System.Drawing.Font("Segoe UI Variable Text Semiligh", 10.25F);
this.btnHomepage.ForeColor = System.Drawing.Color.Black;
this.btnHomepage.Location = new System.Drawing.Point(11, 116);
this.btnHomepage.Name = "btnHomepage";
this.btnHomepage.Size = new System.Drawing.Size(122, 31);
this.btnHomepage.TabIndex = 6;
this.btnHomepage.Text = "Web";
this.btnHomepage.UseCompatibleTextRendering = true;
this.btnHomepage.UseVisualStyleBackColor = false;
//
// lblBadgeExternal
//
this.lblBadgeExternal.AutoEllipsis = true;
this.lblBadgeExternal.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(249)))), ((int)(((byte)(243)))), ((int)(((byte)(240)))));
this.lblBadgeExternal.Font = new System.Drawing.Font("Segoe UI Variable Small Semilig", 9.25F);
this.lblBadgeExternal.ForeColor = System.Drawing.Color.Black;
this.lblBadgeExternal.Location = new System.Drawing.Point(97, 13);
this.lblBadgeExternal.Name = "lblBadgeExternal";
this.lblBadgeExternal.Size = new System.Drawing.Size(91, 26);
this.lblBadgeExternal.TabIndex = 336;
this.lblBadgeExternal.Text = "🧰 External";
this.lblBadgeExternal.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// btnDownload
//
this.btnDownload.BackColor = System.Drawing.Color.Transparent;
this.btnDownload.FlatAppearance.BorderColor = System.Drawing.Color.Silver;
this.btnDownload.FlatAppearance.BorderSize = 2;
this.btnDownload.FlatAppearance.MouseDownBackColor = System.Drawing.Color.LightGray;
this.btnDownload.FlatAppearance.MouseOverBackColor = System.Drawing.Color.LightGray;
this.btnDownload.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.btnDownload.Font = new System.Drawing.Font("Segoe UI Variable Text Semiligh", 10.25F);
this.btnDownload.ForeColor = System.Drawing.Color.Black;
this.btnDownload.Location = new System.Drawing.Point(139, 116);
this.btnDownload.Name = "btnDownload";
this.btnDownload.Size = new System.Drawing.Size(122, 31);
this.btnDownload.TabIndex = 11;
this.btnDownload.Text = "Download";
this.btnDownload.UseCompatibleTextRendering = true;
this.btnDownload.UseVisualStyleBackColor = false;
//
// btnRun
//
this.btnRun.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.btnRun.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(255)))), ((int)(((byte)(183)))), ((int)(((byte)(135)))));
this.btnRun.FlatAppearance.BorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(255)))), ((int)(((byte)(183)))), ((int)(((byte)(135)))));
this.btnRun.FlatAppearance.BorderSize = 2;
this.btnRun.FlatAppearance.MouseDownBackColor = System.Drawing.Color.LightGray;
this.btnRun.FlatAppearance.MouseOverBackColor = System.Drawing.Color.LightGray;
this.btnRun.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.btnRun.Font = new System.Drawing.Font("Segoe UI Variable Display Semib", 10.25F, System.Drawing.FontStyle.Bold);
this.btnRun.ForeColor = System.Drawing.Color.Black;
this.btnRun.Location = new System.Drawing.Point(530, 115);
this.btnRun.Name = "btnRun";
this.btnRun.Size = new System.Drawing.Size(214, 31);
this.btnRun.TabIndex = 10;
this.btnRun.Text = "Run";
this.btnRun.UseCompatibleTextRendering = true;
this.btnRun.UseVisualStyleBackColor = false;
//
// lblBadgeNative
//
this.lblBadgeNative.AutoEllipsis = true;
this.lblBadgeNative.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(249)))), ((int)(((byte)(243)))), ((int)(((byte)(240)))));
this.lblBadgeNative.Font = new System.Drawing.Font("Segoe UI Variable Small Semilig", 9.25F);
this.lblBadgeNative.ForeColor = System.Drawing.Color.Black;
this.lblBadgeNative.Location = new System.Drawing.Point(10, 13);
this.lblBadgeNative.Name = "lblBadgeNative";
this.lblBadgeNative.Size = new System.Drawing.Size(81, 26);
this.lblBadgeNative.TabIndex = 335;
this.lblBadgeNative.Text = "🪟 Native";
this.lblBadgeNative.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// lblHint
//
this.lblHint.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.lblHint.AutoEllipsis = true;
this.lblHint.Font = new System.Drawing.Font("Segoe UI Variable Small Semilig", 10.25F);
this.lblHint.ForeColor = System.Drawing.Color.Black;
this.lblHint.Location = new System.Drawing.Point(42, 66);
this.lblHint.Name = "lblHint";
this.lblHint.Size = new System.Drawing.Size(744, 87);
this.lblHint.TabIndex = 9;
this.lblHint.Text = "Info";
this.lblHint.UseCompatibleTextRendering = true;
//
// InstallControlView
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.AutoScroll = true;
this.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(247)))), ((int)(((byte)(244)))), ((int)(((byte)(242)))));
this.Controls.Add(this.panel1);
this.Name = "InstallControlView";
this.Size = new System.Drawing.Size(835, 457);
this.panel1.ResumeLayout(false);
this.panel1.PerformLayout();
this.panelInstall.ResumeLayout(false);
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.Panel panel1;
private System.Windows.Forms.Button btnHomepage;
private System.Windows.Forms.Button btnDownload;
private System.Windows.Forms.Button btnRun;
private System.Windows.Forms.Label lblHint;
private System.Windows.Forms.ToolTip toolTip1;
private System.Windows.Forms.ComboBox cboSource;
private System.Windows.Forms.Panel panelInstall;
private System.Windows.Forms.Label lblBadgeNative;
private System.Windows.Forms.Label lblBadgeDl;
private System.Windows.Forms.Label lblBadgeIso;
private System.Windows.Forms.Label lblBadgeExternal;
private System.Windows.Forms.TextBox textProviderSearch;
private System.Windows.Forms.Button btnQuickRepair;
private System.Windows.Forms.Button btnCreateUsb;
private System.Windows.Forms.Label lblOneClick;
}
}
+345
View File
@@ -0,0 +1,345 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Flyoobe
{
public partial class InstallControlView : UserControl, IView
{
public string ViewTitle => "Custom: Install && Repair";
// Providers & per-provider last selections
private readonly List<IInstallProvider> _providers = new List<IInstallProvider>();
// Store last selections (ISO/exe) per provider ID
private readonly Dictionary<string, LastSelections> _lastByProvider =
new Dictionary<string, LastSelections>(StringComparer.OrdinalIgnoreCase);
public InstallControlView()
{
InitializeComponent();
InitProviderCombo();
WireUpTooltips();
HookUpEvents();
HookSearchBox();
UpdateHint();
}
private void InitProviderCombo()
{
// Register install sources
_providers.Add(new NativeResetProvider());
_providers.Add(new RufusProvider());
_providers.Add(new MctProvider());
_providers.Add(new VentoyProvider());
_providers.Add(new InPlaceRepairProvider());
_providers.Add(new RunSetupFromIsoProvider());
_providers.Add(new MountIsoProvider());
_providers.Add(new RebootToUefiProvider());
_providers.Add(new BootMenuInfoProvider());
_providers.Add(new BackupDriversProvider());
// Bind providers to dropdown
if (cboSource != null)
{
cboSource.DropDownStyle = ComboBoxStyle.DropDownList;
cboSource.DisplayMember = nameof(IInstallProvider.DisplayName);
cboSource.DataSource = _providers;
cboSource.FormattingEnabled = true;
cboSource.Format += (s, e) =>
{
var p = e.ListItem as IInstallProvider;
if (p == null) { e.Value = e.ListItem?.ToString(); return; }
var badgeTool = p.IsExternalTool ? "🧰" : "🪟";
var badgeIso = p.TypicallyNeedsIso ? " 💿" : string.Empty;
var badgeDl = !string.IsNullOrEmpty(p.DirectDownloadUrl) ? " ⬇️" : string.Empty;
e.Value = $"{badgeTool}{badgeIso}{badgeDl} {p.DisplayName}";
};
// In InitProviderCombo(): nur EIN Aufruf statt zweier
cboSource.SelectedIndexChanged += (s, e) =>
{
UpdateHint();
UpdateBadgeLegend(SelectedProvider); // update badges
};
if (cboSource.Items.Count > 0) cboSource.SelectedIndex = 0;
// Initial legend
UpdateBadgeLegend(SelectedProvider);
}
}
// Reset all badges and highlight active ones.
private void UpdateBadgeLegend(IInstallProvider p)
{
// local helper to style a "badge" label
void Style(Label lbl, System.Drawing.Color back, System.Drawing.Color fore)
{
if (lbl == null) return;
lbl.BackColor = back;
lbl.ForeColor = fore;
lbl.Padding = new Padding(6, 2, 6, 2);
}
// base (dim) + highlight colors
var dimBack = System.Drawing.Color.FromArgb(240, 240, 240);
var dimFore = System.Drawing.Color.Black;
var hiBack = System.Drawing.Color.FromArgb(204, 222, 246); // blue badge
var hiFore = System.Drawing.Color.Black;
// reset all badges
Style(lblBadgeNative, dimBack, dimFore);
Style(lblBadgeExternal, dimBack, dimFore);
Style(lblBadgeIso, dimBack, dimFore);
Style(lblBadgeDl, dimBack, dimFore);
if (p == null) return;
// highlight active badges
if (p.IsExternalTool) Style(lblBadgeExternal, hiBack, hiFore);
else Style(lblBadgeNative, hiBack, hiFore);
if (p.TypicallyNeedsIso) Style(lblBadgeIso, hiBack, hiFore);
if (!string.IsNullOrEmpty(p.DirectDownloadUrl)) Style(lblBadgeDl, hiBack, hiFore);
}
public void RefreshView()
{
// Reserved for future state refresh (e.g., detect admin etc.)
}
// --------------------------------------------------------------------------------
// Event wiring
// --------------------------------------------------------------------------------
private void HookUpEvents()
{
// Install section
if (btnRun != null) btnRun.Click += async (s, e) => await RunSelectedAsync();
if (btnHomepage != null) btnHomepage.Click += (s, e) => OpenHomepage();
if (btnDownload != null) btnDownload.Click += async (s, e) => await DownloadProviderAsync();
// One-click actions
if (btnQuickRepair != null)
btnQuickRepair.Click += async (s, e) => await RunQuickAsync("winreset"); // NativeResetProvider.Id
if (btnCreateUsb != null)
btnCreateUsb.Click += async (s, e) => await RunQuickAsync("mct"); // MctProvider.Id
}
private void WireUpTooltips()
{
if (toolTip1 == null) return;
// Install
toolTip1.SetToolTip(cboSource, "Choose the install source (Rufus, MCT, Ventoy, ...).");
toolTip1.SetToolTip(btnRun, "Open provider options (if any) and run the selected tool.");
toolTip1.SetToolTip(btnHomepage, "Open the provider's official website.");
toolTip1.SetToolTip(btnDownload, "Download the provider binary if a direct URL is available.");
}
private void UpdateHint()
{
if (lblHint == null) return;
var p = SelectedProvider;
lblHint.Text = p?.Hint ?? string.Empty;
}
// --------------------------------------------------------------------------------
// Provider selection helpers
// --------------------------------------------------------------------------------
private IInstallProvider SelectedProvider
=> cboSource?.SelectedItem as IInstallProvider;
private LastSelections GetLast(IInstallProvider p)
{
if (p == null) return null;
if (!_lastByProvider.TryGetValue(p.Id, out var last))
{
last = new LastSelections();
_lastByProvider[p.Id] = last;
}
return last;
}
// --------------------------------------------------------------------------------
// Install: run selected provider
// --------------------------------------------------------------------------------
private async System.Threading.Tasks.Task RunSelectedAsync()
{
var p = SelectedProvider;
if (p == null) return;
var last = GetLast(p);
// Let provider collect options / handle itself.
var args = p.ShowOptionsAndBuildArgs(this, last);
if (args == null) return; // canceled or fully handled inside provider
if (p.IsExternalTool)
{
// External: resolve/browse EXE as before
var exePath = ToolHelpers.ResolveToolPath(last.LastExePath, p.ExactExeNames, p.WildcardExePatterns);
if (exePath == null)
{
using (var ofd = new OpenFileDialog
{
Title = $"Select {p.DisplayName} executable",
Filter = "Executables (*.exe)|*.exe|All files (*.*)|*.*"
})
{
try
{
var downloads = System.IO.Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), "Downloads");
if (System.IO.Directory.Exists(downloads)) ofd.InitialDirectory = downloads;
}
catch { }
if (ofd.ShowDialog(this) != DialogResult.OK) return;
exePath = ofd.FileName;
last.LastExePath = exePath;
}
}
ToolHelpers.Run(exePath, args, asAdmin: true);
}
else
{
// Native/built-in: run by command name without file picker (UseShellExecute=true)
var cmd = (p.ExactExeNames != null && p.ExactExeNames.Length > 0)
? p.ExactExeNames[0] // e.g., "systemreset.exe"
: null;
if (string.IsNullOrEmpty(cmd))
{
MessageBox.Show(this, "No command specified for native provider.", "Error",
MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
ToolHelpers.Run(cmd, args, asAdmin: true);
}
}
private void OpenHomepage()
{
var p = SelectedProvider;
if (p == null)
return;
if (string.IsNullOrEmpty(p.HomepageUrl))
{
MessageBox.Show(this,
$"No homepage is defined for {p.DisplayName}.",
"Info",
MessageBoxButtons.OK,
MessageBoxIcon.Information);
return;
}
ToolHelpers.OpenUri(p.HomepageUrl);
}
private async Task DownloadProviderAsync()
{
var p = SelectedProvider;
if (p == null) return;
if (string.IsNullOrEmpty(p.DirectDownloadUrl))
{
MessageBox.Show(this,
$"Direct download is not available for {p.DisplayName}. Please visit the homepage instead.",
"Info",
MessageBoxButtons.OK,
MessageBoxIcon.Information);
return;
}
var fileName = p.Id + ".exe"; // simple default filename
await ToolHelpers.DownloadAsync(this, p.DirectDownloadUrl, fileName);
}
// --------------------------------------------------------------------------------
// Finds a provider by its Id in the already-registered _providers list (Quick-click)
// --------------------------------------------------------------------------------
private IInstallProvider FindProviderById(string id)
{
if (string.IsNullOrEmpty(id)) return null;
foreach (var p in _providers)
if (string.Equals(p.Id, id, StringComparison.OrdinalIgnoreCase))
return p;
return null;
}
// Selects the provider in the combo (for UI consistency) and runs it via existing pipeline
private async System.Threading.Tasks.Task RunQuickAsync(string providerId)
{
var p = FindProviderById(providerId);
if (p == null)
{
MessageBox.Show(this, $"Provider '{providerId}' not available.", "Info",
MessageBoxButtons.OK, MessageBoxIcon.Information);
return;
}
// Select in UI so hint/badges update
if (cboSource != null)
cboSource.SelectedItem = p;
// Reuse your normal execution path
await RunSelectedAsync();
}
// --------------------------------------------------------------------------------
// Wires the search box to filter the providers list on-the-fly
// --------------------------------------------------------------------------------
private void HookSearchBox()
{
if (textProviderSearch == null || cboSource == null) return;
textProviderSearch.TextChanged += (s, e) =>
{
var q = textProviderSearch.Text?.Trim() ?? string.Empty;
FilterProviders(q);
};
}
// Filters the combo by DisplayName/Id/Hint (case-insensitive).
private void FilterProviders(string query)
{
if (cboSource == null) return;
// filtered view on the fly
var list = string.IsNullOrEmpty(query)
? _providers
: _providers.FindAll(p =>
(p.DisplayName ?? "").IndexOf(query, StringComparison.OrdinalIgnoreCase) >= 0
|| (p.Id ?? "").IndexOf(query, StringComparison.OrdinalIgnoreCase) >= 0
|| (p.Hint ?? "").IndexOf(query, StringComparison.OrdinalIgnoreCase) >= 0);
// Rebind
cboSource.DataSource = null;
cboSource.DataSource = list;
cboSource.DisplayMember = nameof(IInstallProvider.DisplayName);
if (cboSource.Items.Count > 0) cboSource.SelectedIndex = 0;
}
private void textProviderSearch_Click(object sender, EventArgs e)
{
textProviderSearch.Clear();
}
}
}
+123
View File
@@ -0,0 +1,123 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="toolTip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
</root>
+39
View File
@@ -0,0 +1,39 @@
using System.Windows.Forms;
namespace Flyoobe
{
/// <summary>
/// Shared "last selection" holder reused by providers (ISO/exe).
/// </summary>
public sealed class LastSelections
{
public string LastIsoPath { get; set; }
public string LastExePath { get; set; }
}
/// <summary>
/// Contract for install sources like Rufus, MCT, Ventoy, ...
/// </summary>
public interface IInstallProvider
{
string Id { get; }
string DisplayName { get; }
string HomepageUrl { get; } // may be null
string DirectDownloadUrl { get; } // may be null
string[] ExactExeNames { get; } // e.g. "rufus.exe"
string[] WildcardExePatterns { get; } // e.g. "rufus*.exe"
bool TypicallyNeedsIso { get; } // hint for UI
bool IsExternalTool { get; } // if true > resolve/browse EXE; if false > launch by command name (no file picker)
/// <summary>
/// Short hint shown in the UI.
/// </summary>
string Hint { get; }
/// <summary>
/// Show provider-specific options dialog (if any) and build CLI args.
/// Return null if user cancelled.
/// </summary>
string ShowOptionsAndBuildArgs(IWin32Window owner, LastSelections last);
}
}
+113
View File
@@ -0,0 +1,113 @@
using System.Text;
using System.Windows.Forms;
namespace Flyoobe
{
public sealed class MctProvider : IInstallProvider
{
public string Id => "mct";
public string DisplayName => "Media Creation Tool (Windows 11 Version 24H2)";
public string HomepageUrl => "https://www.microsoft.com/software-download/windows11";
public string DirectDownloadUrl => "https://go.microsoft.com/fwlink/?linkid=2156295";
public string[] ExactExeNames => new[] { "MediaCreationTool_Win11.exe" };
public string[] WildcardExePatterns => new[] { "MediaCreationTool*.exe" };
public bool IsExternalTool => true; // needs browsing/resolving
public bool TypicallyNeedsIso => false;
public string Hint => "The Media Creation Tool can download and create media itself. ISO is not mandatory.";
public string ShowOptionsAndBuildArgs(IWin32Window owner, LastSelections last)
{
using (var dlg = new MctOptionsDialog())
{
if (dlg.ShowDialog(owner) != DialogResult.OK) return null;
// Keep GUI visible: only partial switches
var sb = new StringBuilder();
if (dlg.AcceptEula) sb.Append("/Eula Accept ");
if (!string.IsNullOrWhiteSpace(dlg.SelectedArchitecture)) sb.Append("/MediaArch ").Append(dlg.SelectedArchitecture).Append(' ');
if (!string.IsNullOrWhiteSpace(dlg.LanguageCode)) sb.Append("/MediaLangCode ").Append(dlg.LanguageCode.ToLowerInvariant()).Append(' ');
if (dlg.RetailMode) sb.Append("/Retail ");
if (dlg.Selfhost) sb.Append("/Selfhost ");
return sb.ToString().Trim();
}
}
// --- Provider-local dialog (no designer) ------------------------------------------------------
private sealed class MctOptionsDialog : Form
{
private ComboBox cmbArch;
private TextBox txtLang;
private CheckBox chkEula;
private CheckBox chkRetail;
private CheckBox chkSelfhost;
private Button btnOk;
private Button btnCancel;
public string SelectedArchitecture => (cmbArch.SelectedItem as string) ?? "x64";
public string LanguageCode => string.IsNullOrWhiteSpace(txtLang.Text) ? "en-us" : txtLang.Text.Trim().ToLowerInvariant();
public bool AcceptEula => chkEula.Checked;
public bool RetailMode => chkRetail.Checked;
public bool Selfhost => chkSelfhost.Checked;
public MctOptionsDialog()
{
Text = "Media Creation Tool – Preset Options";
StartPosition = FormStartPosition.CenterParent;
FormBorderStyle = FormBorderStyle.FixedDialog;
MaximizeBox = false;
MinimizeBox = false;
ShowInTaskbar = false;
AutoSize = true;
AutoSizeMode = AutoSizeMode.GrowAndShrink;
Padding = new Padding(12);
var layout = new TableLayoutPanel
{
ColumnCount = 2,
AutoSize = true,
Dock = DockStyle.Fill
};
layout.ColumnStyles.Add(new ColumnStyle(SizeType.AutoSize));
layout.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100));
// Architecture
layout.Controls.Add(new Label { Text = "Architecture:", AutoSize = true, Margin = new Padding(0, 6, 8, 6) }, 0, 0);
cmbArch = new ComboBox { DropDownStyle = ComboBoxStyle.DropDownList, Width = 160 };
cmbArch.Items.AddRange(new object[] { "x64", "x86", "Both" });
cmbArch.SelectedIndex = 0;
layout.Controls.Add(cmbArch, 1, 0);
// Language
layout.Controls.Add(new Label { Text = "Language code:", AutoSize = true, Margin = new Padding(0, 6, 8, 6) }, 0, 1);
var defLang = System.Globalization.CultureInfo.CurrentUICulture?.Name?.ToLowerInvariant() ?? "en-us";
txtLang = new TextBox { Width = 200, Text = defLang };
layout.Controls.Add(txtLang, 1, 1);
// Options
chkEula = new CheckBox { Text = "Accept EULA", Checked = true, AutoSize = true };
chkRetail = new CheckBox { Text = "Retail mode", Checked = false, AutoSize = true };
chkSelfhost = new CheckBox { Text = "Selfhost", Checked = false, AutoSize = true };
var opts = new FlowLayoutPanel { FlowDirection = FlowDirection.LeftToRight, AutoSize = true };
opts.Controls.Add(chkEula);
opts.Controls.Add(chkRetail);
opts.Controls.Add(chkSelfhost);
layout.Controls.Add(new Label { Text = "Options:", AutoSize = true, Margin = new Padding(0, 6, 8, 6) }, 0, 2);
layout.Controls.Add(opts, 1, 2);
// Buttons
var pnlButtons = new FlowLayoutPanel { FlowDirection = FlowDirection.RightToLeft, AutoSize = true, Margin = new Padding(0, 12, 0, 0) };
btnOk = new Button { Text = "OK", DialogResult = DialogResult.OK, AutoSize = true };
btnCancel = new Button { Text = "Cancel", DialogResult = DialogResult.Cancel, AutoSize = true, Margin = new Padding(6, 0, 0, 0) };
pnlButtons.Controls.Add(btnOk);
pnlButtons.Controls.Add(btnCancel);
layout.Controls.Add(pnlButtons, 0, 3);
layout.SetColumnSpan(pnlButtons, 2);
Controls.Add(layout);
AcceptButton = btnOk;
CancelButton = btnCancel;
}
}
}
}
+38
View File
@@ -0,0 +1,38 @@
using System.Windows.Forms;
namespace Flyoobe
{
// Lets the user pick an ISO and mounts it via PowerShell (Mount-DiskImage).
public sealed class MountIsoProvider : IInstallProvider
{
public string Id => "mountiso";
public string DisplayName => "Mount ISO… (built-in)";
public string HomepageUrl => null;
public string DirectDownloadUrl => null;
public string[] ExactExeNames => System.Array.Empty<string>();
public string[] WildcardExePatterns => System.Array.Empty<string>();
public bool TypicallyNeedsIso => false;
public bool IsExternalTool => false;
public string Hint => "Pick a Windows ISO and mount it using PowerShell.";
public string ShowOptionsAndBuildArgs(IWin32Window owner, LastSelections last)
{
using (var ofd = new OpenFileDialog { Filter = "ISO files (*.iso)|*.iso|All files (*.*)|*.*" })
{
if (ofd.ShowDialog(owner) != DialogResult.OK) return null;
var isoPath = ofd.FileName;
var ps = "-NoProfile -Command \"Mount-DiskImage -ImagePath '" + isoPath + "' -PassThru | Out-Null\"";
if (!ToolHelpers.Run("powershell.exe", ps, asAdmin: true))
{
MessageBox.Show(owner, "Could not mount ISO. Try manual mount via Explorer (Right-click → Mount).",
"Mount failed", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
// remember last ISO for other providers (just optional)
if (last != null) last.LastIsoPath = isoPath;
}
return null; // handled
}
}
}
+104
View File
@@ -0,0 +1,104 @@
using Flyoobe;
using System;
using System.Windows.Forms;
using static System.Net.Mime.MediaTypeNames;
public sealed class NativeResetProvider : IInstallProvider
{
public string Id => "winreset";
public string DisplayName => "Windows Reset (built-in)";
public string HomepageUrl => "ms-settings:recovery";
public string DirectDownloadUrl => null;
public string[] ExactExeNames => new[] { "systemreset.exe" }; // only Doku
public string[] WildcardExePatterns => Array.Empty<string>();
public bool TypicallyNeedsIso => false;
public bool IsExternalTool => false;
public string Hint =>
"Built-in Windows reset. Inside the wizard choose 'Keep my files' or 'Remove everything' and optionally 'Cloud download'.";
public string ShowOptionsAndBuildArgs(IWin32Window owner, LastSelections last)
{
using (var dlg = new ResetOptionsDialog())
{
if (dlg.ShowDialog(owner) != DialogResult.OK)
return null; // canceled > host does not do anything
switch (dlg.SelectedMode)
{
case ResetMode.ResetWizard:
if (!ToolHelpers.Confirm(owner,
"Start 'Reset this PC'? This may remove apps/data depending on your selection."))
return null;
if (!ToolHelpers.Run("systemreset.exe", "-factoryreset", true))
ToolHelpers.Run("systemreset.exe", "", true);
return null; //RunSelectedAsync() should not start anything else
case ResetMode.RebootToWinRE:
ToolHelpers.Run("shutdown.exe", "/r /o /t 0 /f", true);
return null;
case ResetMode.OpenSettings:
ToolHelpers.OpenUri("ms-settings:recovery");
return null;
default:
return null;
}
}
}
private enum ResetMode { ResetWizard, RebootToWinRE, OpenSettings }
private sealed class ResetOptionsDialog : Form
{
private RadioButton rbWizard, rbWinre, rbSettings;
private Button btnOk, btnCancel;
public ResetMode SelectedMode =>
rbWizard.Checked ? ResetMode.ResetWizard :
rbWinre.Checked ? ResetMode.RebootToWinRE :
ResetMode.OpenSettings;
public ResetOptionsDialog()
{
Text = "Windows Reset options";
StartPosition = FormStartPosition.CenterParent;
FormBorderStyle = FormBorderStyle.FixedDialog;
MaximizeBox = false; MinimizeBox = false;
ShowInTaskbar = false;
AutoSize = true; AutoSizeMode = AutoSizeMode.GrowAndShrink;
Padding = new Padding(12);
var root = new TableLayoutPanel { ColumnCount = 1, AutoSize = true, Dock = DockStyle.Fill };
rbWizard = new RadioButton { Text = "Open Reset wizard (systemreset.exe -factoryreset)", Checked = true, AutoSize = true };
rbWinre = new RadioButton { Text = "Reboot into Advanced Startup (WinRE)", AutoSize = true };
rbSettings = new RadioButton { Text = "Open Recovery Settings", AutoSize = true };
root.Controls.Add(rbWizard);
root.Controls.Add(rbWinre);
root.Controls.Add(rbSettings);
root.Controls.Add(new Label
{
AutoSize = true,
MaximumSize = new System.Drawing.Size(520, 0),
Margin = new Padding(0, 8, 0, 0),
Text = "Note: Windows does not provide supported CLI switches to pre-select 'Keep my files', 'Remove everything' or 'Cloud download'. Choose them in the wizard."
});
var pnlButtons = new FlowLayoutPanel { FlowDirection = FlowDirection.RightToLeft, AutoSize = true, Margin = new Padding(0, 12, 0, 0) };
btnOk = new Button { Text = "OK", DialogResult = DialogResult.OK, AutoSize = true };
btnCancel = new Button { Text = "Cancel", DialogResult = DialogResult.Cancel, AutoSize = true, Margin = new Padding(6, 0, 0, 0) };
pnlButtons.Controls.Add(btnOk);
pnlButtons.Controls.Add(btnCancel);
root.Controls.Add(pnlButtons);
Controls.Add(root);
AcceptButton = btnOk;
CancelButton = btnCancel;
}
}
}
@@ -0,0 +1,56 @@
using System;
using System.Windows.Forms;
namespace Flyoobe
{
// Native provider to reboot directly into UEFI/BIOS setup using "shutdown.exe /r /fw /t 0".
// If /fw is not supported on the machine, we offer a fallback to Recovery Settings (WinRE path to UEFI Firmware Settings).
public sealed class RebootToUefiProvider : IInstallProvider
{
public string Id => "uefi-reboot";
public string DisplayName => "Reboot into UEFI firmware (BIOS)";
public string HomepageUrl => null;
public string DirectDownloadUrl => null;
public string[] ExactExeNames => new[] { "shutdown.exe" }; // informational
public string[] WildcardExePatterns => Array.Empty<string>();
public bool TypicallyNeedsIso => false;
public bool IsExternalTool => false;
public string Hint =>
"Restarts the PC straight into UEFI/BIOS setup (if supported by the firmware). " +
"Useful to change boot order before a clean install.";
public string ShowOptionsAndBuildArgs(IWin32Window owner, LastSelections last)
{
// Confirm with the user (explicit reboot).
if (!ToolHelpers.Confirm(owner,
"Reboot into UEFI/BIOS now? The PC will restart immediately."))
{
return null; // canceled
}
// Try the native fast path first: /r /fw /t 0
var ok = ToolHelpers.Run("shutdown.exe", "/r /fw /t 0", asAdmin: true);
if (!ok)
{
// Not supported or blocked on this device > offer a fallback....
var choice = MessageBox.Show(owner,
"Direct firmware reboot was not supported on this device.\r\n\r\n" +
"Open Recovery settings so you can choose 'UEFI Firmware Settings' after a restart?",
"UEFI reboot fallback",
MessageBoxButtons.OKCancel,
MessageBoxIcon.Information);
if (choice == DialogResult.OK)
{
// Settings > System > Recovery (so we can go to Advanced startup > UEFI Firmware Settings)
ToolHelpers.OpenUri("ms-settings:recovery");
}
}
// We handled everything here; host should not try to launch an external EXE.
return null;
}
}
}
+147
View File
@@ -0,0 +1,147 @@
using System.IO;
using System.Text;
using System.Windows.Forms;
namespace Flyoobe
{
public sealed class RufusProvider : IInstallProvider
{
public string Id => "rufus";
public string DisplayName => "Rufus (Version 4.9)";
public string HomepageUrl => "https://rufus.ie";
public string DirectDownloadUrl => "https://github.com/pbatard/rufus/releases/download/v4.9/rufus-4.9.exe"; // keep homepage
public string[] ExactExeNames => new[] { "rufus.exe" };
public string[] WildcardExePatterns => new[] { "rufus*.exe" };
public bool IsExternalTool => true; // needs browsing/resolving
public bool TypicallyNeedsIso => true;
public string Hint => "Rufus requires you to provide a Windows ISO file. It will create a bootable USB stick.";
public string ShowOptionsAndBuildArgs(IWin32Window owner, LastSelections last)
{
// Ask / ensure ISO first
var isoPath = EnsureIso(owner, last);
if (isoPath == null) return null; // user cancelled
// Show provider-local dialog and build CLI args
using (var dlg = new RufusOptionsDialog(System.Globalization.CultureInfo.CurrentUICulture?.Name ?? "en-US"))
{
if (dlg.ShowDialog(owner) != DialogResult.OK) return null;
// Build CLI: -g -i -l -f -x -w
var sb = new StringBuilder();
sb.Append("-g ");
sb.Append("-i \"").Append(isoPath).Append("\" ");
if (!string.IsNullOrWhiteSpace(dlg.SelectedLocale)) sb.Append("-l ").Append(dlg.SelectedLocale).Append(' ');
if (!string.IsNullOrWhiteSpace(dlg.SelectedFilesystem)) sb.Append("-f ").Append(dlg.SelectedFilesystem).Append(' ');
if (dlg.ExtraDevices) sb.Append("-x ");
if (dlg.WaitTensOfSeconds > 0) sb.Append("-w ").Append(dlg.WaitTensOfSeconds).Append(' ');
return sb.ToString().Trim();
}
}
private static string EnsureIso(IWin32Window owner, LastSelections last)
{
// Reuse last ISO if available
if (!string.IsNullOrEmpty(last.LastIsoPath) && File.Exists(last.LastIsoPath))
{
var res = MessageBox.Show(owner, "Use last selected ISO?\n\n" + last.LastIsoPath,
"Rufus", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question);
if (res == DialogResult.Cancel) return null;
if (res == DialogResult.Yes) return last.LastIsoPath;
}
// Ask for ISO
using (var ofd = new OpenFileDialog
{
Title = "Select Windows ISO",
Filter = "ISO (*.iso)|*.iso|All files (*.*)|*.*"
})
{
if (ofd.ShowDialog(owner) != DialogResult.OK) return null;
last.LastIsoPath = ofd.FileName;
return ofd.FileName;
}
}
// --- Provider-local dialog (no Designer needed) --------------------------------
// Keeping this dialog private to avoid leaking UI details outside the provider.
private sealed class RufusOptionsDialog : Form
{
private ComboBox cmbFilesystem;
private ComboBox cmbLocale;
private CheckBox chkExtra;
private NumericUpDown numWait;
private Button btnOk;
private Button btnCancel;
public string SelectedFilesystem => (cmbFilesystem.SelectedItem as string) ?? "ntfs";
public string SelectedLocale => string.IsNullOrWhiteSpace(cmbLocale.Text) ? "en-US" : cmbLocale.Text.Trim();
public bool ExtraDevices => chkExtra.Checked;
public int WaitTensOfSeconds => (int)numWait.Value;
public RufusOptionsDialog(string defaultLocale)
{
// Minimal, self-contained WinForms dialog
Text = "Rufus options";
StartPosition = FormStartPosition.CenterParent;
FormBorderStyle = FormBorderStyle.FixedDialog;
MaximizeBox = false;
MinimizeBox = false;
ShowInTaskbar = false;
AutoSize = true;
AutoSizeMode = AutoSizeMode.GrowAndShrink;
Padding = new Padding(12);
var layout = new TableLayoutPanel
{
ColumnCount = 2,
RowCount = 5,
AutoSize = true,
Dock = DockStyle.Fill
};
layout.ColumnStyles.Add(new ColumnStyle(SizeType.AutoSize));
layout.ColumnStyles.Add(new ColumnStyle(SizeType.AutoSize));
// Filesystem
layout.Controls.Add(new Label { Text = "Filesystem:", AutoSize = true, Margin = new Padding(0, 6, 8, 6) }, 0, 0);
cmbFilesystem = new ComboBox { DropDownStyle = ComboBoxStyle.DropDownList, Width = 160 };
cmbFilesystem.Items.AddRange(new object[] { "ntfs", "fat32", "exfat" });
cmbFilesystem.SelectedIndex = 0;
layout.Controls.Add(cmbFilesystem, 1, 0);
// Locale
layout.Controls.Add(new Label { Text = "Locale:", AutoSize = true, Margin = new Padding(0, 6, 8, 6) }, 0, 1);
cmbLocale = new ComboBox { DropDownStyle = ComboBoxStyle.DropDown, Width = 160 };
cmbLocale.Items.AddRange(new object[] { "en-US", "de-DE", "fr-FR", "it-IT", "es-ES" });
if (!string.IsNullOrEmpty(defaultLocale) && !cmbLocale.Items.Contains(defaultLocale))
cmbLocale.Items.Insert(0, defaultLocale);
cmbLocale.Text = string.IsNullOrEmpty(defaultLocale) ? "en-US" : defaultLocale;
layout.Controls.Add(cmbLocale, 1, 1);
// Extra devices
layout.Controls.Add(new Label { Text = "List extra devices (-x):", AutoSize = true, Margin = new Padding(0, 6, 8, 6) }, 0, 2);
chkExtra = new CheckBox { Checked = false, AutoSize = true };
layout.Controls.Add(chkExtra, 1, 2);
// Wait
layout.Controls.Add(new Label { Text = "Wait (-w) (tens of seconds):", AutoSize = true, Margin = new Padding(0, 6, 8, 6) }, 0, 3);
numWait = new NumericUpDown { Minimum = 0, Maximum = 120, Value = 0, Width = 80 };
layout.Controls.Add(numWait, 1, 3);
// Buttons
var panelButtons = new FlowLayoutPanel { FlowDirection = FlowDirection.RightToLeft, AutoSize = true, Dock = DockStyle.Fill, Margin = new Padding(0, 12, 0, 0) };
btnOk = new Button { Text = "OK", DialogResult = DialogResult.OK, AutoSize = true };
btnCancel = new Button { Text = "Cancel", DialogResult = DialogResult.Cancel, AutoSize = true, Margin = new Padding(6, 0, 0, 0) };
panelButtons.Controls.Add(btnOk);
panelButtons.Controls.Add(btnCancel);
layout.Controls.Add(panelButtons, 0, 4);
layout.SetColumnSpan(panelButtons, 2);
Controls.Add(layout);
AcceptButton = btnOk;
CancelButton = btnCancel;
}
}
}
}
@@ -0,0 +1,56 @@
using System.IO;
using System.Windows.Forms;
namespace Flyoobe
{
// Launches setup.exe from mounted ISO without parameters.
public sealed class RunSetupFromIsoProvider : IInstallProvider
{
public string Id => "setupfromiso";
public string DisplayName => "Run Windows Setup from ISO (full wizard)";
public string HomepageUrl => null;
public string DirectDownloadUrl => null;
public string[] ExactExeNames => new[] { "setup.exe" };
public string[] WildcardExePatterns => System.Array.Empty<string>();
public bool TypicallyNeedsIso => true;
public bool IsExternalTool => false;
public string Hint =>
"Opens the full Windows Setup wizard from a mounted ISO. " +
"You can choose between Upgrade or Clean install and set partitions manually. " +
"Recommended if you want complete control over the installation process.";
public string ShowOptionsAndBuildArgs(IWin32Window owner, LastSelections last)
{
var setup = FindSetupExeOnMountedDrives();
if (setup == null)
{
MessageBox.Show(owner, "No mounted Windows ISO with 'setup.exe' found.",
"Setup missing", MessageBoxButtons.OK, MessageBoxIcon.Information);
return null;
}
if (!ToolHelpers.Confirm(owner, "Run setup.exe from the mounted ISO?"))
return null;
ToolHelpers.Run(setup, "", asAdmin: true);
return null;
}
private static string FindSetupExeOnMountedDrives()
{
try
{
foreach (var di in DriveInfo.GetDrives())
{
if (di.DriveType == DriveType.CDRom || di.DriveType == DriveType.Removable || di.DriveType == DriveType.Fixed)
{
var p = Path.Combine(di.Name, "setup.exe");
if (File.Exists(p)) return p;
}
}
}
catch { }
return null;
}
}
}
+121
View File
@@ -0,0 +1,121 @@
using System;
using System.Diagnostics;
using System.IO;
using System.Net;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Flyoobe
{
internal static class ToolHelpers
{
/// <summary>Try last path, app base, CWD, then PATH (wildcards allowed).</summary>
public static string ResolveToolPath(string lastPath, string[] exactFileNames, string[] patterns)
{
try
{
if (!string.IsNullOrEmpty(lastPath) && File.Exists(lastPath)) return lastPath;
var baseDir = AppDomain.CurrentDomain.BaseDirectory;
var cwd = Environment.CurrentDirectory;
// exact files in base/cwd
if (exactFileNames != null)
{
foreach (var f in exactFileNames)
{
var p1 = Path.Combine(baseDir, f); if (File.Exists(p1)) return p1;
var p2 = Path.Combine(cwd, f); if (File.Exists(p2)) return p2;
}
}
// wildcards in base/cwd
if (patterns != null)
{
foreach (var pat in patterns)
{
var m1 = SafeGetFiles(baseDir, pat); if (m1?.Length > 0) return m1[0];
var m2 = SafeGetFiles(cwd, pat); if (m2?.Length > 0) return m2[0];
}
}
// PATH dirs (wildcards)
var env = Environment.GetEnvironmentVariable("PATH");
if (!string.IsNullOrEmpty(env) && patterns != null)
{
foreach (var dir in env.Split(Path.PathSeparator))
{
foreach (var pat in patterns)
{
var m = SafeGetFiles(dir, pat); if (m?.Length > 0) return m[0];
}
}
}
}
catch { }
return null;
}
private static string[] SafeGetFiles(string dir, string pattern)
{
try { return Directory.GetFiles(dir, pattern); } catch { return null; }
}
public static bool Confirm(IWin32Window owner, string msg)
=> MessageBox.Show(owner, msg, "Confirm", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.OK;
public static bool Run(string file, string args, bool asAdmin)
{
try
{
var psi = new ProcessStartInfo
{
FileName = file,
Arguments = args ?? "",
UseShellExecute = true
};
if (asAdmin) psi.Verb = "runas";
Process.Start(psi);
return true;
}
catch (Exception ex)
{
MessageBox.Show("Start failed:\n" + file + " " + args + "\n\n" + ex.Message, "Error",
MessageBoxButtons.OK, MessageBoxIcon.Error);
return false;
}
}
public static void OpenUri(string uri)
{
try { Process.Start(new ProcessStartInfo(uri) { UseShellExecute = true }); }
catch (Exception ex) { MessageBox.Show("Could not open link: " + ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); }
}
public static async Task<bool> DownloadAsync(IWin32Window owner, string url, string defaultFileName)
{
using (var sfd = new SaveFileDialog { FileName = defaultFileName, Filter = "Programs (*.exe)|*.exe|All files (*.*)|*.*" })
{
if (sfd.ShowDialog(owner) != DialogResult.OK) return false;
try
{
try { ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls12; } catch { }
using (var wc = new WebClient())
{
Cursor.Current = Cursors.WaitCursor;
await wc.DownloadFileTaskAsync(new Uri(url), sfd.FileName);
}
MessageBox.Show("Download complete: " + sfd.FileName, "Done", MessageBoxButtons.OK, MessageBoxIcon.Information);
return true;
}
catch (Exception ex)
{
MessageBox.Show("Download failed: " + ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return false;
}
finally { Cursor.Current = Cursors.Default; }
}
}
}
}
+29
View File
@@ -0,0 +1,29 @@
using System.Windows.Forms;
namespace Flyoobe
{
public sealed class VentoyProvider : IInstallProvider
{
public string Id => "ventoy";
public string DisplayName => "Ventoy";
public string HomepageUrl => "https://www.ventoy.net/en/download.html";
public string DirectDownloadUrl => null; // Ventoy ships as ZIP/installer, no stable EXE direct link
public string[] ExactExeNames => new[] { "Ventoy2Disk.exe" };
public string[] WildcardExePatterns => new[] { "Ventoy*Disk*.exe" };
public bool IsExternalTool => true; // needs browsing/resolving
public bool TypicallyNeedsIso => false;
// Custom hint for the UI
public string Hint =>
"Ventoy creates a USB drive where you can later copy multiple ISO files. " +
"You don't need to select an ISO during setup.";
// Add advanced CLI support!?
public string ShowOptionsAndBuildArgs(IWin32Window owner, LastSelections last)
{
// Ventoy doesn't really use CLI args for normal installation.
// Just launch the GUI and let the user configure inside.
return string.Empty;
}
}
}
+85
View File
@@ -0,0 +1,85 @@
namespace Flyoobe
{
partial class LogForm
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.richLog = new System.Windows.Forms.RichTextBox();
this.panelLogger = new System.Windows.Forms.Panel();
this.panelLogger.SuspendLayout();
this.SuspendLayout();
//
// richLog
//
this.richLog.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.richLog.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(248)))), ((int)(((byte)(248)))), ((int)(((byte)(248)))));
this.richLog.BorderStyle = System.Windows.Forms.BorderStyle.None;
this.richLog.Font = new System.Drawing.Font("Cascadia Code", 8.75F);
this.richLog.Location = new System.Drawing.Point(14, 14);
this.richLog.Name = "richLog";
this.richLog.Size = new System.Drawing.Size(608, 290);
this.richLog.TabIndex = 0;
this.richLog.Text = "";
//
// panelLogger
//
this.panelLogger.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.panelLogger.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(252)))), ((int)(((byte)(247)))), ((int)(((byte)(242)))));
this.panelLogger.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.panelLogger.Controls.Add(this.richLog);
this.panelLogger.Location = new System.Drawing.Point(12, 12);
this.panelLogger.Name = "panelLogger";
this.panelLogger.Size = new System.Drawing.Size(637, 319);
this.panelLogger.TabIndex = 1;
//
// LogForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(232)))), ((int)(((byte)(232)))), ((int)(((byte)(232)))));
this.ClientSize = new System.Drawing.Size(661, 343);
this.Controls.Add(this.panelLogger);
this.Name = "LogForm";
this.ShowIcon = false;
this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Show;
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "Notifications";
this.panelLogger.ResumeLayout(false);
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.RichTextBox richLog;
private System.Windows.Forms.Panel panelLogger;
}
}
+14
View File
@@ -0,0 +1,14 @@
using System.Windows.Forms;
namespace Flyoobe
{
public partial class LogForm : Form
{
public LogForm(string logText)
{
InitializeComponent();
richLog.Text = logText;
richLog.SelectionStart = richLog.Text.Length; // Scroll to the end of the log
}
}
}
+120
View File
@@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>
Loaded 100 of 121 files, more files were not shown because too many files have changed in this diff. Show more