Update Control Panel

The Control Panel now also includes third party panel items.
This commit is contained in:
Coenraad Stijne 2014-07-18 20:15:35 +02:00
parent 2a86b06e0c
commit 102d5fdd7f
4 changed files with 221 additions and 157 deletions

View File

@ -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

View File

@ -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;
}
}
}

View File

@ -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)

View File

@ -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}"