mirror of
https://github.com/microsoft/PowerToys.git
synced 2025-01-18 14:41:21 +08:00
Update Control Panel
The Control Panel now also includes third party panel items.
This commit is contained in:
parent
2a86b06e0c
commit
102d5fdd7f
@ -51,9 +51,9 @@ namespace Wox.Plugin.SystemPlugins.ControlPanel
|
||||
|
||||
foreach (ControlPanelItem item in controlPanelItems)
|
||||
{
|
||||
if (!File.Exists(iconFolder + item.ApplicationName + fileType))
|
||||
if (!File.Exists(iconFolder + item.LocalizedString + fileType))
|
||||
{
|
||||
item.Icon.ToBitmap().Save(iconFolder + item.ApplicationName + fileType);
|
||||
item.Icon.ToBitmap().Save(iconFolder + item.LocalizedString + fileType);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -75,7 +75,7 @@ namespace Wox.Plugin.SystemPlugins.ControlPanel
|
||||
Title = item.LocalizedString,
|
||||
SubTitle = item.InfoTip,
|
||||
Score = item.Score,
|
||||
IcoPath = "Images\\ControlPanelIcons\\" + item.ApplicationName + fileType,
|
||||
IcoPath = "Images\\ControlPanelIcons\\" + item.LocalizedString + fileType,
|
||||
Action = e =>
|
||||
{
|
||||
try
|
||||
|
@ -8,18 +8,16 @@ namespace Wox.Plugin.SystemPlugins.ControlPanel
|
||||
{
|
||||
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)
|
||||
public ControlPanelItem(string newLocalizedString, string newInfoTip, ProcessStartInfo newExecutablePath, Icon newIcon)
|
||||
{
|
||||
LocalizedString = newLocalizedString;
|
||||
InfoTip = newInfoTip;
|
||||
ApplicationName = newApplicationName;
|
||||
ExecutablePath = newExecutablePath;
|
||||
Icon = (Icon)newLargeIcon.Clone();
|
||||
Icon = newIcon;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -45,172 +45,238 @@ namespace Wox.Plugin.SystemPlugins.ControlPanel
|
||||
|
||||
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");
|
||||
static RegistryKey nameSpace = Registry.LocalMachine.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ControlPanel\\NameSpace");
|
||||
static RegistryKey clsid = Registry.ClassesRoot.OpenSubKey("CLSID");
|
||||
|
||||
public static List<ControlPanelItem> Create(uint iconSize)
|
||||
{
|
||||
int size = (int)iconSize;
|
||||
RegistryKey currentKey;
|
||||
ProcessStartInfo executablePath;
|
||||
List<ControlPanelItem> controlPanelItems = new List<ControlPanelItem>();
|
||||
string localizedString;
|
||||
string infoTip;
|
||||
Icon myIcon;
|
||||
|
||||
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)
|
||||
{
|
||||
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);
|
||||
executablePath = getExecutablePath(currentKey);
|
||||
|
||||
stringTableIndex = sanitizeUint(localizedString[1]);
|
||||
if (executablePath == null)
|
||||
continue; //Cannot have item without executable path
|
||||
|
||||
resource = new StringBuilder(255);
|
||||
LoadString(dataFilePointer, stringTableIndex, resource, resource.Capacity + 1);
|
||||
localizedString = getLocalizedString(currentKey);
|
||||
|
||||
localizedString[0] = resource.ToString();
|
||||
if (string.IsNullOrEmpty(localizedString))
|
||||
continue; //Cannot have item without Title
|
||||
|
||||
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]);
|
||||
infoTip = getInfoTip(currentKey);
|
||||
|
||||
dataFilePointer = LoadLibraryEx(infoTip[0], IntPtr.Zero, LOAD_LIBRARY_AS_DATAFILE);
|
||||
myIcon = getIcon(currentKey, size);
|
||||
|
||||
stringTableIndex = sanitizeUint(infoTip[1]);
|
||||
controlPanelItems.Add(new ControlPanelItem(localizedString, infoTip, executablePath, myIcon));
|
||||
|
||||
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 ProcessStartInfo getExecutablePath(RegistryKey currentKey)
|
||||
{
|
||||
ProcessStartInfo executablePath = new ProcessStartInfo();
|
||||
string applicationName;
|
||||
|
||||
if (currentKey.GetValue("System.ApplicationName") != null)
|
||||
{
|
||||
//CPL Files (usually native MS items)
|
||||
applicationName = currentKey.GetValue("System.ApplicationName").ToString();
|
||||
executablePath.FileName = Environment.ExpandEnvironmentVariables(CONTROL);
|
||||
executablePath.Arguments = "-name " + applicationName;
|
||||
}
|
||||
else if (currentKey.OpenSubKey("Shell\\Open\\Command") != null && currentKey.OpenSubKey("Shell\\Open\\Command").GetValue(null) != null)
|
||||
{
|
||||
//Other files (usually third party items)
|
||||
executablePath.FileName = Environment.ExpandEnvironmentVariables(currentKey.OpenSubKey("Shell\\Open\\Command").GetValue(null).ToString());
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return executablePath;
|
||||
}
|
||||
|
||||
private static string getLocalizedString(RegistryKey currentKey)
|
||||
{
|
||||
IntPtr dataFilePointer;
|
||||
string[] localizedStringRaw;
|
||||
uint stringTableIndex;
|
||||
StringBuilder resource;
|
||||
string localizedString;
|
||||
|
||||
if (currentKey.GetValue("LocalizedString") != null)
|
||||
{
|
||||
localizedStringRaw = currentKey.GetValue("LocalizedString").ToString().Split(new char[] { ',' }, 2);
|
||||
|
||||
if (localizedStringRaw.Length > 1)
|
||||
{
|
||||
if (localizedStringRaw[0][0] == '@')
|
||||
{
|
||||
localizedStringRaw[0] = localizedStringRaw[0].Substring(1);
|
||||
}
|
||||
|
||||
localizedStringRaw[0] = Environment.ExpandEnvironmentVariables(localizedStringRaw[0]);
|
||||
|
||||
dataFilePointer = LoadLibraryEx(localizedStringRaw[0], IntPtr.Zero, LOAD_LIBRARY_AS_DATAFILE); //Load file with strings
|
||||
|
||||
stringTableIndex = sanitizeUint(localizedStringRaw[1]);
|
||||
|
||||
resource = new StringBuilder(255);
|
||||
LoadString(dataFilePointer, stringTableIndex, resource, resource.Capacity + 1); //Extract needed string
|
||||
FreeLibrary(dataFilePointer);
|
||||
|
||||
localizedString = resource.ToString();
|
||||
|
||||
/*This shouldn't be necessary, but some apps (e.g. Bootcamp)
|
||||
* don't follow Microsoft's standard. Have to make a choice whether
|
||||
* empty string == failure, or use default name. I'm using default name */
|
||||
|
||||
if (String.IsNullOrEmpty(localizedString))
|
||||
{
|
||||
if (currentKey.GetValue(null) != null)
|
||||
{
|
||||
localizedString = currentKey.GetValue(null).ToString();
|
||||
}
|
||||
else
|
||||
{
|
||||
return null; //Cannot have item without title.
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
localizedString = localizedStringRaw[0];
|
||||
}
|
||||
}
|
||||
else if (currentKey.GetValue(null) != null)
|
||||
{
|
||||
localizedString = currentKey.GetValue(null).ToString();
|
||||
}
|
||||
else
|
||||
{
|
||||
return null; //Cannot have item without title.
|
||||
}
|
||||
return localizedString;
|
||||
}
|
||||
|
||||
private static string getInfoTip(RegistryKey currentKey)
|
||||
{
|
||||
IntPtr dataFilePointer;
|
||||
string[] infoTipRaw;
|
||||
uint stringTableIndex;
|
||||
StringBuilder resource;
|
||||
string infoTip = "";
|
||||
|
||||
if (currentKey.GetValue("InfoTip") != null)
|
||||
{
|
||||
infoTipRaw = currentKey.GetValue("InfoTip").ToString().Split(new char[] { ',' }, 2);
|
||||
|
||||
if (infoTipRaw.Length == 2)
|
||||
{
|
||||
if (infoTipRaw[0][0] == '@')
|
||||
{
|
||||
infoTipRaw[0] = infoTipRaw[0].Substring(1);
|
||||
}
|
||||
infoTipRaw[0] = Environment.ExpandEnvironmentVariables(infoTipRaw[0]);
|
||||
|
||||
dataFilePointer = LoadLibraryEx(infoTipRaw[0], IntPtr.Zero, LOAD_LIBRARY_AS_DATAFILE); //Load file with strings
|
||||
|
||||
stringTableIndex = sanitizeUint(infoTipRaw[1]);
|
||||
|
||||
resource = new StringBuilder(255);
|
||||
LoadString(dataFilePointer, stringTableIndex, resource, resource.Capacity + 1); //Extract needed string
|
||||
FreeLibrary(dataFilePointer);
|
||||
|
||||
infoTip = resource.ToString();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
infoTip = "";
|
||||
}
|
||||
|
||||
return infoTip;
|
||||
}
|
||||
|
||||
private static Icon getIcon(RegistryKey currentKey, int iconSize)
|
||||
{
|
||||
IntPtr iconPtr = IntPtr.Zero;
|
||||
List<string> iconString;
|
||||
IntPtr dataFilePointer;
|
||||
IntPtr iconIndex;
|
||||
Icon myIcon = null;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
FreeLibrary(dataFilePointer);
|
||||
|
||||
try
|
||||
{
|
||||
myIcon = Icon.FromHandle(iconPtr);
|
||||
myIcon = (Icon)myIcon.Clone(); //Remove pointer dependancy.
|
||||
}
|
||||
catch
|
||||
{
|
||||
//Silently fail for now..
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (iconPtr != IntPtr.Zero)
|
||||
{
|
||||
DestroyIcon(iconPtr);
|
||||
}
|
||||
return myIcon;
|
||||
}
|
||||
|
||||
private static uint sanitizeUint(string args) //Remove all chars before and after first set of digits.
|
||||
{
|
||||
int x = 0;
|
||||
@ -241,12 +307,14 @@ namespace Wox.Plugin.SystemPlugins.ControlPanel
|
||||
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)
|
||||
|
4
Wox.sln
4
Wox.sln
@ -1,8 +1,6 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 2013
|
||||
VisualStudioVersion = 12.0.30110.0
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
# Visual Studio 2012
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Wox.Test", "Wox.Test\Wox.Test.csproj", "{FF742965-9A80-41A5-B042-D6C7D3A21708}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Wox.Plugin", "Wox.Plugin\Wox.Plugin.csproj", "{8451ECDD-2EA4-4966-BB0A-7BBC40138E80}"
|
||||
|
Loading…
Reference in New Issue
Block a user