mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-04-09 04:37:30 +02:00
Fix issues in ControlPanel plugin.
This commit is contained in:
@@ -1,12 +1,9 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using Wox.Infrastructure;
|
|
||||||
using Wox.Infrastructure.Storage.UserSettings;
|
|
||||||
using WindowsControlPanelItems;
|
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using Wox.Infrastructure;
|
||||||
|
|
||||||
namespace Wox.Plugin.SystemPlugins.ControlPanel
|
namespace Wox.Plugin.SystemPlugins.ControlPanel
|
||||||
{
|
{
|
||||||
@@ -42,10 +39,16 @@ namespace Wox.Plugin.SystemPlugins.ControlPanel
|
|||||||
protected override void InitInternal(PluginInitContext context)
|
protected override void InitInternal(PluginInitContext context)
|
||||||
{
|
{
|
||||||
this.context = context;
|
this.context = context;
|
||||||
controlPanelItems = WindowsControlPanelItems.List.Create(48);
|
controlPanelItems = ControlPanelList.Create(48);
|
||||||
iconFolder = @"Images\ControlPanelIcons\";
|
iconFolder = @"Images\ControlPanelIcons\";
|
||||||
fileType = ".bmp";
|
fileType = ".bmp";
|
||||||
|
|
||||||
|
if (!Directory.Exists(iconFolder))
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(iconFolder);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
foreach (ControlPanelItem item in controlPanelItems)
|
foreach (ControlPanelItem item in controlPanelItems)
|
||||||
{
|
{
|
||||||
if (!File.Exists(iconFolder + item.ApplicationName + fileType))
|
if (!File.Exists(iconFolder + item.ApplicationName + fileType))
|
||||||
@@ -61,37 +64,17 @@ namespace Wox.Plugin.SystemPlugins.ControlPanel
|
|||||||
string myQuery = query.RawQuery.Trim();
|
string myQuery = query.RawQuery.Trim();
|
||||||
|
|
||||||
List<Result> results = new List<Result>();
|
List<Result> results = new List<Result>();
|
||||||
List<Result> filteredResults = new List<Result>();
|
|
||||||
|
|
||||||
foreach (var item in controlPanelItems)
|
foreach (var item in controlPanelItems)
|
||||||
{
|
{
|
||||||
if (item.LocalizedString.IndexOf(myQuery, StringComparison.OrdinalIgnoreCase) >= 0)
|
var fuzzyMather = FuzzyMatcher.Create(myQuery);
|
||||||
{
|
if (MatchProgram(item, fuzzyMather))
|
||||||
results.Insert(0, new Result()
|
|
||||||
{
|
|
||||||
Title = item.LocalizedString,
|
|
||||||
SubTitle = item.InfoTip,
|
|
||||||
IcoPath = "Images\\ControlPanelIcons\\" + item.ApplicationName + fileType,
|
|
||||||
Action = e =>
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Process.Start(item.ExecutablePath);
|
|
||||||
}
|
|
||||||
catch (Exception)
|
|
||||||
{
|
|
||||||
//Silently Fail for now..
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
else if (item.InfoTip.IndexOf(myQuery, StringComparison.OrdinalIgnoreCase) >= 0)
|
|
||||||
{
|
{
|
||||||
results.Add(new Result()
|
results.Add(new Result()
|
||||||
{
|
{
|
||||||
Title = item.LocalizedString,
|
Title = item.LocalizedString,
|
||||||
SubTitle = item.InfoTip,
|
SubTitle = item.InfoTip,
|
||||||
|
Score = item.Score,
|
||||||
IcoPath = "Images\\ControlPanelIcons\\" + item.ApplicationName + fileType,
|
IcoPath = "Images\\ControlPanelIcons\\" + item.ApplicationName + fileType,
|
||||||
Action = e =>
|
Action = e =>
|
||||||
{
|
{
|
||||||
@@ -108,12 +91,18 @@ namespace Wox.Plugin.SystemPlugins.ControlPanel
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (int i = 0; i < 2 && i < results.Count; i++)
|
|
||||||
{
|
|
||||||
filteredResults.Add(results[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return filteredResults;
|
return results.OrderByDescending(o => o.Score).Take(5).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool MatchProgram(ControlPanelItem item, FuzzyMatcher matcher)
|
||||||
|
{
|
||||||
|
if (item.LocalizedString != null && (item.Score = matcher.Evaluate(item.LocalizedString).Score) > 0) return true;
|
||||||
|
if (item.InfoTip != null && (item.Score = matcher.Evaluate(item.InfoTip).Score) > 0) return true;
|
||||||
|
|
||||||
|
if (item.LocalizedString != null && (item.Score = matcher.Evaluate(item.LocalizedString.Unidecode()).Score) > 0) return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
25
Wox.Plugin.SystemPlugins/ControlPanel/ControlPanelItem.cs
Normal file
25
Wox.Plugin.SystemPlugins/ControlPanel/ControlPanelItem.cs
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
using System.Diagnostics;
|
||||||
|
using System.Drawing;
|
||||||
|
|
||||||
|
namespace Wox.Plugin.SystemPlugins.ControlPanel
|
||||||
|
{
|
||||||
|
//from:https://raw.githubusercontent.com/CoenraadS/Windows-Control-Panel-Items
|
||||||
|
public class ControlPanelItem
|
||||||
|
{
|
||||||
|
public string LocalizedString { get; private set; }
|
||||||
|
public string InfoTip { get; private set; }
|
||||||
|
public string ApplicationName { get; private set; }
|
||||||
|
public ProcessStartInfo ExecutablePath { get; private set; }
|
||||||
|
public Icon Icon { get; private set; }
|
||||||
|
public int Score { get; set; }
|
||||||
|
|
||||||
|
public ControlPanelItem(string newLocalizedString, string newInfoTip, string newApplicationName, ProcessStartInfo newExecutablePath, Icon newLargeIcon)
|
||||||
|
{
|
||||||
|
LocalizedString = newLocalizedString;
|
||||||
|
InfoTip = newInfoTip;
|
||||||
|
ApplicationName = newApplicationName;
|
||||||
|
ExecutablePath = newExecutablePath;
|
||||||
|
Icon = (Icon)newLargeIcon.Clone();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
265
Wox.Plugin.SystemPlugins/ControlPanel/ControlPanelList.cs
Normal file
265
Wox.Plugin.SystemPlugins/ControlPanel/ControlPanelList.cs
Normal file
@@ -0,0 +1,265 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
using Microsoft.Win32;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Drawing;
|
||||||
|
|
||||||
|
namespace Wox.Plugin.SystemPlugins.ControlPanel
|
||||||
|
{
|
||||||
|
//from:https://raw.githubusercontent.com/CoenraadS/Windows-Control-Panel-Items
|
||||||
|
public static class ControlPanelList
|
||||||
|
{
|
||||||
|
private const uint GROUP_ICON = 14;
|
||||||
|
private const uint LOAD_LIBRARY_AS_DATAFILE = 0x00000002;
|
||||||
|
private const string CONTROL = @"%SystemRoot%\System32\control.exe";
|
||||||
|
|
||||||
|
private delegate bool EnumResNameDelegate(
|
||||||
|
IntPtr hModule,
|
||||||
|
IntPtr lpszType,
|
||||||
|
IntPtr lpszName,
|
||||||
|
IntPtr lParam);
|
||||||
|
|
||||||
|
[DllImport("kernel32.dll", EntryPoint = "EnumResourceNamesW", CharSet = CharSet.Unicode, SetLastError = true)]
|
||||||
|
static extern bool EnumResourceNamesWithID(IntPtr hModule, uint lpszType, EnumResNameDelegate lpEnumFunc, IntPtr lParam);
|
||||||
|
|
||||||
|
[DllImport("kernel32.dll", SetLastError = true)]
|
||||||
|
static extern IntPtr LoadLibraryEx(string lpFileName, IntPtr hFile, uint dwFlags);
|
||||||
|
|
||||||
|
[DllImport("kernel32.dll", SetLastError = true)]
|
||||||
|
static extern bool FreeLibrary(IntPtr hModule);
|
||||||
|
|
||||||
|
[DllImport("user32.dll", CharSet = CharSet.Auto)]
|
||||||
|
static extern int LoadString(IntPtr hInstance, uint uID, StringBuilder lpBuffer, int nBufferMax);
|
||||||
|
|
||||||
|
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
|
||||||
|
static extern IntPtr LoadImage(IntPtr hinst, IntPtr lpszName, uint uType,
|
||||||
|
int cxDesired, int cyDesired, uint fuLoad);
|
||||||
|
|
||||||
|
[DllImport("user32.dll", CharSet = CharSet.Auto)]
|
||||||
|
extern static bool DestroyIcon(IntPtr handle);
|
||||||
|
|
||||||
|
[DllImport("kernel32.dll")]
|
||||||
|
static extern IntPtr FindResource(IntPtr hModule, IntPtr lpName, IntPtr lpType);
|
||||||
|
|
||||||
|
static Queue<IntPtr> iconQueue;
|
||||||
|
|
||||||
|
public static List<ControlPanelItem> Create(int iconSize)
|
||||||
|
{
|
||||||
|
List<ControlPanelItem> controlPanelItems = new List<ControlPanelItem>();
|
||||||
|
string applicationName;
|
||||||
|
string[] localizedString;
|
||||||
|
string[] infoTip = new string[1];
|
||||||
|
List<string> iconString;
|
||||||
|
IntPtr dataFilePointer;
|
||||||
|
uint stringTableIndex;
|
||||||
|
IntPtr iconIndex;
|
||||||
|
StringBuilder resource;
|
||||||
|
ProcessStartInfo executablePath;
|
||||||
|
IntPtr iconPtr = IntPtr.Zero;
|
||||||
|
Icon myIcon;
|
||||||
|
|
||||||
|
RegistryKey nameSpace = Registry.LocalMachine.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ControlPanel\\NameSpace");
|
||||||
|
RegistryKey clsid = Registry.LocalMachine.OpenSubKey("SOFTWARE\\Classes\\CLSID");
|
||||||
|
RegistryKey currentKey;
|
||||||
|
|
||||||
|
foreach (string key in nameSpace.GetSubKeyNames())
|
||||||
|
{
|
||||||
|
//todo:throw exceptions in my computer, need to check this,Silently Fail for now.
|
||||||
|
try
|
||||||
|
{
|
||||||
|
currentKey = clsid.OpenSubKey(key);
|
||||||
|
if (currentKey != null)
|
||||||
|
{
|
||||||
|
if (currentKey.GetValue("System.ApplicationName") != null &&
|
||||||
|
currentKey.GetValue("LocalizedString") != null)
|
||||||
|
{
|
||||||
|
applicationName = currentKey.GetValue("System.ApplicationName").ToString();
|
||||||
|
//Debug.WriteLine(key.ToString() + " (" + applicationName + ")");
|
||||||
|
localizedString = currentKey.GetValue("LocalizedString")
|
||||||
|
.ToString()
|
||||||
|
.Split(new char[] {','}, 2);
|
||||||
|
if (localizedString[0][0] == '@')
|
||||||
|
{
|
||||||
|
localizedString[0] = localizedString[0].Substring(1);
|
||||||
|
}
|
||||||
|
localizedString[0] = Environment.ExpandEnvironmentVariables(localizedString[0]);
|
||||||
|
if (localizedString.Length > 1)
|
||||||
|
{
|
||||||
|
dataFilePointer = LoadLibraryEx(localizedString[0], IntPtr.Zero,
|
||||||
|
LOAD_LIBRARY_AS_DATAFILE);
|
||||||
|
|
||||||
|
stringTableIndex = sanitizeUint(localizedString[1]);
|
||||||
|
|
||||||
|
resource = new StringBuilder(255);
|
||||||
|
LoadString(dataFilePointer, stringTableIndex, resource, resource.Capacity + 1);
|
||||||
|
|
||||||
|
localizedString[0] = resource.ToString();
|
||||||
|
|
||||||
|
if (currentKey.GetValue("InfoTip") != null)
|
||||||
|
{
|
||||||
|
infoTip = currentKey.GetValue("InfoTip").ToString().Split(new char[] {','}, 2);
|
||||||
|
if (infoTip[0][0] == '@')
|
||||||
|
{
|
||||||
|
infoTip[0] = infoTip[0].Substring(1);
|
||||||
|
}
|
||||||
|
infoTip[0] = Environment.ExpandEnvironmentVariables(infoTip[0]);
|
||||||
|
|
||||||
|
dataFilePointer = LoadLibraryEx(infoTip[0], IntPtr.Zero, LOAD_LIBRARY_AS_DATAFILE);
|
||||||
|
|
||||||
|
stringTableIndex = sanitizeUint(infoTip[1]);
|
||||||
|
|
||||||
|
resource = new StringBuilder(255);
|
||||||
|
LoadString(dataFilePointer, stringTableIndex, resource, resource.Capacity + 1);
|
||||||
|
|
||||||
|
infoTip[0] = resource.ToString();
|
||||||
|
}
|
||||||
|
else if (currentKey.GetValue(null) != null)
|
||||||
|
{
|
||||||
|
infoTip[0] = currentKey.GetValue(null).ToString();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
infoTip[0] = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
FreeLibrary(dataFilePointer);
|
||||||
|
//We are finished with extracting strings. Prepare to load icon file.
|
||||||
|
dataFilePointer = IntPtr.Zero;
|
||||||
|
myIcon = null;
|
||||||
|
iconPtr = IntPtr.Zero;
|
||||||
|
|
||||||
|
if (currentKey.OpenSubKey("DefaultIcon") != null)
|
||||||
|
{
|
||||||
|
if (currentKey.OpenSubKey("DefaultIcon").GetValue(null) != null)
|
||||||
|
{
|
||||||
|
iconString =
|
||||||
|
new List<string>(
|
||||||
|
currentKey.OpenSubKey("DefaultIcon")
|
||||||
|
.GetValue(null)
|
||||||
|
.ToString()
|
||||||
|
.Split(new char[] {','}, 2));
|
||||||
|
if (iconString[0][0] == '@')
|
||||||
|
{
|
||||||
|
iconString[0] = iconString[0].Substring(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
dataFilePointer = LoadLibraryEx(iconString[0], IntPtr.Zero,
|
||||||
|
LOAD_LIBRARY_AS_DATAFILE);
|
||||||
|
|
||||||
|
if (iconString.Count < 2)
|
||||||
|
{
|
||||||
|
iconString.Add("0");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
iconIndex = (IntPtr) sanitizeUint(iconString[1]);
|
||||||
|
|
||||||
|
if (iconIndex == IntPtr.Zero)
|
||||||
|
{
|
||||||
|
iconQueue = new Queue<IntPtr>();
|
||||||
|
EnumResourceNamesWithID(dataFilePointer, GROUP_ICON,
|
||||||
|
new EnumResNameDelegate(EnumRes), IntPtr.Zero);
|
||||||
|
//Iterate through resources.
|
||||||
|
|
||||||
|
while (iconPtr == IntPtr.Zero && iconQueue.Count > 0)
|
||||||
|
{
|
||||||
|
iconPtr = LoadImage(dataFilePointer, iconQueue.Dequeue(), 1, iconSize,
|
||||||
|
iconSize, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
iconPtr = LoadImage(dataFilePointer, iconIndex, 1, iconSize, iconSize, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
myIcon = Icon.FromHandle(iconPtr);
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
//Silently fail for now.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
executablePath = new ProcessStartInfo();
|
||||||
|
executablePath.FileName = Environment.ExpandEnvironmentVariables(CONTROL);
|
||||||
|
executablePath.Arguments = "-name " + applicationName;
|
||||||
|
controlPanelItems.Add(new ControlPanelItem(localizedString[0], infoTip[0],
|
||||||
|
applicationName, executablePath, myIcon));
|
||||||
|
FreeLibrary(dataFilePointer);
|
||||||
|
if (iconPtr != IntPtr.Zero)
|
||||||
|
{
|
||||||
|
DestroyIcon(myIcon.Handle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Debug.Write(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return controlPanelItems;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static uint sanitizeUint(string args) //Remove all chars before and after first set of digits.
|
||||||
|
{
|
||||||
|
int x = 0;
|
||||||
|
|
||||||
|
while (x < args.Length && !Char.IsDigit(args[x]))
|
||||||
|
{
|
||||||
|
args = args.Substring(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
x = 0;
|
||||||
|
|
||||||
|
while (x < args.Length && Char.IsDigit(args[x]))
|
||||||
|
{
|
||||||
|
x++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (x < args.Length)
|
||||||
|
{
|
||||||
|
args = args.Remove(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Convert.ToUInt32(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool IS_INTRESOURCE(IntPtr value)
|
||||||
|
{
|
||||||
|
if (((uint)value) > ushort.MaxValue)
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
private static uint GET_RESOURCE_ID(IntPtr value)
|
||||||
|
{
|
||||||
|
if (IS_INTRESOURCE(value) == true)
|
||||||
|
return (uint)value;
|
||||||
|
throw new System.NotSupportedException("value is not an ID!");
|
||||||
|
}
|
||||||
|
private static string GET_RESOURCE_NAME(IntPtr value)
|
||||||
|
{
|
||||||
|
if (IS_INTRESOURCE(value) == true)
|
||||||
|
return value.ToString();
|
||||||
|
return Marshal.PtrToStringUni((IntPtr)value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool EnumRes(IntPtr hModule, IntPtr lpszType, IntPtr lpszName, IntPtr lParam)
|
||||||
|
{
|
||||||
|
//Debug.WriteLine("Type: " + GET_RESOURCE_NAME(lpszType));
|
||||||
|
//Debug.WriteLine("Name: " + GET_RESOURCE_NAME(lpszName));
|
||||||
|
iconQueue.Enqueue(lpszName);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -41,9 +41,6 @@
|
|||||||
<Reference Include="PresentationCore" />
|
<Reference Include="PresentationCore" />
|
||||||
<Reference Include="PresentationFramework" />
|
<Reference Include="PresentationFramework" />
|
||||||
<Reference Include="WindowsBase" />
|
<Reference Include="WindowsBase" />
|
||||||
<Reference Include="WindowsControlPanelItems">
|
|
||||||
<HintPath>..\packages\WindowsControlPanelItems.dll.1.0.0\lib\net35\WindowsControlPanelItems.dll</HintPath>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="YAMP">
|
<Reference Include="YAMP">
|
||||||
<HintPath>..\packages\YAMP.1.3.0\lib\net35\YAMP.dll</HintPath>
|
<HintPath>..\packages\YAMP.1.3.0\lib\net35\YAMP.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
@@ -63,6 +60,8 @@
|
|||||||
<Compile Include="CMD\CMDStorage.cs" />
|
<Compile Include="CMD\CMDStorage.cs" />
|
||||||
<Compile Include="ColorsPlugin.cs" />
|
<Compile Include="ColorsPlugin.cs" />
|
||||||
<Compile Include="ControlPanel\ControlPanel.cs" />
|
<Compile Include="ControlPanel\ControlPanel.cs" />
|
||||||
|
<Compile Include="ControlPanel\ControlPanelItem.cs" />
|
||||||
|
<Compile Include="ControlPanel\ControlPanelList.cs" />
|
||||||
<Compile Include="Folder\FolderPluginSettings.xaml.cs">
|
<Compile Include="Folder\FolderPluginSettings.xaml.cs">
|
||||||
<DependentUpon>FolderPluginSettings.xaml</DependentUpon>
|
<DependentUpon>FolderPluginSettings.xaml</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
|||||||
Reference in New Issue
Block a user