Commit InstallView, UpgradeView
This commit is contained in:
1 parent
cfed49d76d
commit
257d6cd6c3
21 files changed
+1159
-103
No files matched your search
@@ -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
@@ -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>
|
||||
@@ -180,7 +180,8 @@ namespace Flyoobe
|
||||
// Update label text
|
||||
linkAppVersion.Text = text;
|
||||
|
||||
// If clickable, show bold & underline and make cursor a hand
|
||||
// If clickable,
|
||||
// show bold ; underline ; make cursor a hand
|
||||
if (clickable)
|
||||
{
|
||||
linkAppVersion.Font = new Font(linkAppVersion.Font, FontStyle.Bold | FontStyle.Underline);
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
using Flyoobe; // for FeatureNode
|
||||
using Settings.Ads;
|
||||
using Settings.AI;
|
||||
using Settings.Edge;
|
||||
using Settings.Gaming;
|
||||
using Settings.Issues;
|
||||
@@ -118,16 +117,6 @@ namespace Features
|
||||
new FeatureNode(new WelcomeExperienceAds())
|
||||
}
|
||||
},
|
||||
|
||||
new FeatureNode("AI")
|
||||
{
|
||||
Children = new List<FeatureNode>
|
||||
{
|
||||
new FeatureNode(new CopilotTaskbar()),
|
||||
new FeatureNode(new Recall()),
|
||||
new FeatureNode(new ClickToDo())
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,13 +5,19 @@ using System.Windows.Forms;
|
||||
|
||||
namespace Flyoobe
|
||||
{
|
||||
// Native provider that exports all installed drivers to C:\DriversBackup using:
|
||||
// pnputil.exe /export-driver * C:\DriversBackup
|
||||
// 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 (exports to C:\\DriversBackup)";
|
||||
public string DisplayName => "Backup installed drivers (choose folder)";
|
||||
public string HomepageUrl => null;
|
||||
public string DirectDownloadUrl => null;
|
||||
public string[] ExactExeNames => new[] { "pnputil.exe" };
|
||||
@@ -20,18 +26,48 @@ namespace Flyoobe
|
||||
public bool IsExternalTool => false;
|
||||
|
||||
public string Hint =>
|
||||
"Exports all currently installed device drivers (INF + binaries) to C:\\DriversBackup. " +
|
||||
"After a clean install, point Device Manager to this folder to restore drivers even without internet.";
|
||||
"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)
|
||||
{
|
||||
const string target = @"C:\DriversBackup";
|
||||
// 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 runs 'pnputil /export-driver *' with administrative rights."))
|
||||
"\r\n\r\nThis will run 'pnputil /export-driver *' with administrative rights."))
|
||||
return null;
|
||||
|
||||
// Ensure the target DriversBackup folder exists
|
||||
try
|
||||
{
|
||||
Directory.CreateDirectory(target);
|
||||
@@ -47,7 +83,7 @@ namespace Flyoobe
|
||||
|
||||
try
|
||||
{
|
||||
// Start pnputil as elevated process
|
||||
// Start pnputil as an elevated process targeting the 'DriversBackup' subfolder
|
||||
var psi = new ProcessStartInfo
|
||||
{
|
||||
FileName = "pnputil.exe",
|
||||
@@ -69,15 +105,17 @@ namespace Flyoobe
|
||||
proc.WaitForExit();
|
||||
}
|
||||
|
||||
// Now export is complete > count drivers
|
||||
// Count exported INF files to provide a quick summary
|
||||
int infCount = 0;
|
||||
try
|
||||
{
|
||||
infCount = Directory.GetFiles(target, "*.inf", SearchOption.AllDirectories).Length;
|
||||
}
|
||||
catch { /* ignore */ }
|
||||
catch
|
||||
{ // Ignore counting errors; we can still show success without the count
|
||||
}
|
||||
|
||||
MessageBox.Show(owner,
|
||||
MessageBox.Show(owner,
|
||||
"Driver export completed.\r\n\r\n" +
|
||||
$"Target: {target}\r\n" +
|
||||
$"Exported driver packages: {infCount}\r\n\r\n" +
|
||||
@@ -94,7 +132,7 @@ namespace Flyoobe
|
||||
MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
}
|
||||
|
||||
return null;
|
||||
return null; // returning null indicates no further action needed
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -282,7 +282,7 @@ namespace Flyoobe
|
||||
return null;
|
||||
}
|
||||
|
||||
// Selects the provider in the combo (for UI consistency) and runs it via existing pipeline.
|
||||
// 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);
|
||||
|
||||
@@ -35,6 +35,7 @@ namespace Flyoobe
|
||||
_navigator.RegisterView("Device", () => new DeviceControlView());
|
||||
_navigator.RegisterView("Personalization", () => new PersonalizationControlView());
|
||||
_navigator.RegisterView("Browser", () => new DefaultsControlView());
|
||||
_navigator.RegisterView("AI", () => new AiControlView());
|
||||
_navigator.RegisterView("Network", () => new NetworkControlView());
|
||||
_navigator.RegisterView("Account", () => new AccountControlView());
|
||||
_navigator.RegisterView("Apps", () => new AppsControlView());
|
||||
|
||||
@@ -0,0 +1,200 @@
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
|
||||
public class EsuEnrollmentHandler
|
||||
{
|
||||
/// <summary>
|
||||
/// Keep Windows 10 secure until 2026 (Enroll in ESU) using abbodi1406's ConsumerESU scripts.
|
||||
/// Downloads from GitHub if missing and executes.
|
||||
/// </summary>
|
||||
///
|
||||
public static async Task HandleEnrollInESU()
|
||||
{
|
||||
string repoBase = "https://raw.githubusercontent.com/abbodi1406/ConsumerESU/master/";
|
||||
string cmdFile = "Consumer_ESU_Enrollment_run.cmd";
|
||||
string psFile = "Consumer_ESU_Enrollment.ps1";
|
||||
|
||||
string appDir = AppDomain.CurrentDomain.BaseDirectory;
|
||||
string cmdPath = Path.Combine(appDir, cmdFile);
|
||||
string psPath = Path.Combine(appDir, psFile);
|
||||
|
||||
// Ensure scripts exist (download if missing)
|
||||
if (!File.Exists(cmdPath) || !File.Exists(psPath))
|
||||
{
|
||||
var confirm = MessageBox.Show(
|
||||
"The ESU enrollment scripts are missing.\n\n" +
|
||||
"They will be downloaded directly from GitHub (abbodi1406/ConsumerESU).\n\n" +
|
||||
"Do you want to continue?",
|
||||
"Download Scripts",
|
||||
MessageBoxButtons.YesNo,
|
||||
MessageBoxIcon.Question);
|
||||
|
||||
if (confirm != DialogResult.Yes) return;
|
||||
|
||||
using (var wc = new WebClient())
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!File.Exists(cmdPath))
|
||||
await wc.DownloadFileTaskAsync(new Uri(repoBase + cmdFile), cmdPath);
|
||||
if (!File.Exists(psPath))
|
||||
await wc.DownloadFileTaskAsync(new Uri(repoBase + psFile), psPath);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show("Failed to download ESU scripts:\n" + ex.Message,
|
||||
"Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Show parameter selection dialog
|
||||
string esuArgs = "";
|
||||
using (var dlg = new EsuParamDialog())
|
||||
{
|
||||
if (dlg.ShowDialog() != DialogResult.OK)
|
||||
return;
|
||||
|
||||
esuArgs = dlg.SelectedParam;
|
||||
if (dlg.AddProceed) esuArgs += " -Proceed";
|
||||
}
|
||||
|
||||
// Confirm and run
|
||||
var result = MessageBox.Show(
|
||||
"This will launch the Consumer ESU Enrollment Tool with parameters:\n\n" +
|
||||
esuArgs + "\n\nContinue?",
|
||||
"Enroll in ESU",
|
||||
MessageBoxButtons.YesNo,
|
||||
MessageBoxIcon.Information);
|
||||
|
||||
if (result != DialogResult.Yes) return;
|
||||
|
||||
try
|
||||
{
|
||||
var psi = new ProcessStartInfo
|
||||
{
|
||||
FileName = "cmd.exe",
|
||||
Arguments = "/c \"" + cmdPath + "\" " + esuArgs,
|
||||
WorkingDirectory = appDir,
|
||||
UseShellExecute = true,
|
||||
Verb = "runas" // run as admin
|
||||
};
|
||||
Process.Start(psi);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show("Failed to run ESU enrollment script:\n" + ex.Message,
|
||||
"Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dialog form to select ESU enrollment parameter (no-designer)
|
||||
/// </summary>
|
||||
private class EsuParamDialog : Form
|
||||
{
|
||||
private ComboBox combo;
|
||||
private CheckBox chkProceed;
|
||||
private Button btnOk;
|
||||
private Button btnCancel;
|
||||
private LinkLabel link;
|
||||
|
||||
public string SelectedParam { get; private set; }
|
||||
public bool AddProceed { get; private set; }
|
||||
|
||||
public EsuParamDialog()
|
||||
{
|
||||
Text = "Select ESU Enrollment Parameter";
|
||||
Width = 550;
|
||||
Height = 250;
|
||||
StartPosition = FormStartPosition.CenterParent;
|
||||
FormBorderStyle = FormBorderStyle.FixedDialog;
|
||||
MaximizeBox = false;
|
||||
MinimizeBox = false;
|
||||
ShowIcon = false;
|
||||
ShowInTaskbar = false;
|
||||
|
||||
combo = new ComboBox
|
||||
{
|
||||
Left = 20,
|
||||
Top = 20,
|
||||
Width = 500,
|
||||
DropDownStyle = ComboBoxStyle.DropDownList
|
||||
};
|
||||
combo.Items.AddRange(new object[]
|
||||
{
|
||||
"-Online : Only enroll using Microsoft user account token (exit if failed)",
|
||||
"-Store : Only enroll using Microsoft store account token (exit if failed)",
|
||||
"-Local : Only enroll using Local user account token (exit if failed)",
|
||||
"-License : Force acquire Consumer ESU License regardless or without enrollment",
|
||||
"-Remove : Remove Consumer ESU License if exists"
|
||||
});
|
||||
combo.SelectedIndex = 0;
|
||||
|
||||
chkProceed = new CheckBox
|
||||
{
|
||||
Left = 20,
|
||||
Top = 60,
|
||||
Text = "Add -Proceed (force running enrollment even if already enrolled)",
|
||||
AutoSize = true
|
||||
};
|
||||
|
||||
btnOk = new Button
|
||||
{
|
||||
Text = "OK",
|
||||
Left = 340,
|
||||
Width = 80,
|
||||
Top = 150,
|
||||
DialogResult = DialogResult.OK
|
||||
};
|
||||
btnCancel = new Button
|
||||
{
|
||||
Text = "Cancel",
|
||||
Left = 430,
|
||||
Width = 80,
|
||||
Top = 150,
|
||||
DialogResult = DialogResult.Cancel
|
||||
};
|
||||
|
||||
link = new LinkLabel
|
||||
{
|
||||
Left = 20,
|
||||
Top = 100,
|
||||
AutoSize = true,
|
||||
Text = "Help && Credits: https://github.com/abbodi1406/ConsumerESU"
|
||||
};
|
||||
link.LinkClicked += (s, e) =>
|
||||
{
|
||||
try { Process.Start(new ProcessStartInfo { FileName = "https://github.com/abbodi1406/ConsumerESU", UseShellExecute = true }); }
|
||||
catch { }
|
||||
};
|
||||
|
||||
Controls.Add(combo);
|
||||
Controls.Add(chkProceed);
|
||||
Controls.Add(link);
|
||||
Controls.Add(btnOk);
|
||||
Controls.Add(btnCancel);
|
||||
|
||||
AcceptButton = btnOk;
|
||||
CancelButton = btnCancel;
|
||||
}
|
||||
|
||||
protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
|
||||
{
|
||||
if (DialogResult == DialogResult.OK)
|
||||
{
|
||||
// Extract only the switch (first word, e.g. "-Online")
|
||||
SelectedParam = combo.SelectedItem.ToString().Split(' ')[0];
|
||||
AddProceed = chkProceed.Checked;
|
||||
}
|
||||
base.OnClosing(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -403,81 +403,6 @@ try {{
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Keep Windows 10 secure until 2026 (Enroll in ESU) using abbodi1406's ConsumerESU scripts.
|
||||
/// Downloads from GitHub if missing and executes.
|
||||
/// </summary>
|
||||
public async void HandleEnrollInESU()
|
||||
{
|
||||
string repoBase = "https://raw.githubusercontent.com/abbodi1406/ConsumerESU/master/";
|
||||
string cmdFile = "Consumer_ESU_Enrollment_run.cmd";
|
||||
string psFile = "Consumer_ESU_Enrollment.ps1";
|
||||
|
||||
string appDir = AppDomain.CurrentDomain.BaseDirectory;
|
||||
string cmdPath = Path.Combine(appDir, cmdFile);
|
||||
string psPath = Path.Combine(appDir, psFile);
|
||||
|
||||
// Check if scripts exist, otherwise download
|
||||
if (!System.IO.File.Exists(cmdPath) || !System.IO.File.Exists(psPath))
|
||||
{
|
||||
var confirm = MessageBox.Show(
|
||||
"The ESU enrollment scripts are missing.\n\n" +
|
||||
"They will now be downloaded directly from GitHub (abbodi1406/ConsumerESU).\n\n" +
|
||||
"Do you want to continue?",
|
||||
"Download Scripts",
|
||||
MessageBoxButtons.YesNo,
|
||||
MessageBoxIcon.Question);
|
||||
|
||||
if (confirm != DialogResult.Yes)
|
||||
return;
|
||||
|
||||
using (var wc = new System.Net.WebClient())
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!System.IO.File.Exists(cmdPath))
|
||||
await wc.DownloadFileTaskAsync(new Uri(repoBase + cmdFile), cmdPath);
|
||||
|
||||
if (!System.IO.File.Exists(psPath))
|
||||
await wc.DownloadFileTaskAsync(new Uri(repoBase + psFile), psPath);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show("Failed to download ESU scripts:\n" + ex.Message,
|
||||
"Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
var result = MessageBox.Show(
|
||||
"📦 This will now launch the Consumer ESU Enrollment Tool by abbodi1406.\n\n" +
|
||||
"✔ Extends Windows 10 support until October 2026\n" +
|
||||
"✔ Requires Windows 10 22H2 with KB5039299+ (19045.4598+)\n" +
|
||||
"✔ Requires Microsoft Account + Internet access\n\n" +
|
||||
"Do you want to continue?",
|
||||
"Enroll in ESU",
|
||||
MessageBoxButtons.YesNo,
|
||||
MessageBoxIcon.Information);
|
||||
|
||||
if (result != DialogResult.Yes)
|
||||
return;
|
||||
|
||||
// Start the .cmd (which internally calls the PowerShell)
|
||||
try
|
||||
{
|
||||
Process.Start(new ProcessStartInfo
|
||||
{
|
||||
FileName = cmdPath,
|
||||
Verb = "runas",
|
||||
UseShellExecute = true
|
||||
});
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show("Failed to run ESU enrollment script:\n" + ex.Message,
|
||||
"Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handle unexpected exceptions by logging the error, updating the status, and optionally launching Copilot for help.
|
||||
@@ -508,6 +433,7 @@ try {{
|
||||
CopilotHelper.LaunchCopilot();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class ProcessExtensions
|
||||
@@ -520,4 +446,5 @@ try {{
|
||||
await tcs.Task;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ namespace Flyoobe
|
||||
var combo = sender as ComboBox;
|
||||
int selectedIndex = combo.SelectedIndex;
|
||||
|
||||
// Let user pick ISO from local disk (compatibility check is now in HandleIsoInput)
|
||||
// Pick ISO from local disk (compatibility check is now in HandleIsoInput)
|
||||
if (selectedIndex == 1)
|
||||
{
|
||||
await HandleIsoInput(sender, null);
|
||||
@@ -63,7 +63,7 @@ namespace Flyoobe
|
||||
break;
|
||||
|
||||
case 3:
|
||||
_isoHandler.HandleEnrollInESU();
|
||||
await EsuEnrollmentHandler.HandleEnrollInESU();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user