Add wox plugin installer.

This commit is contained in:
qianlifeng
2014-03-02 11:04:30 +08:00
parent fce020f4dd
commit 13ed55ac10
6 changed files with 83 additions and 70 deletions

View File

@@ -1,33 +1,33 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace Wox.UAC
{
public partial class MainWindow : Window
{
PluginInstaller installer = new PluginInstaller();
public MainWindow()
{
InitializeComponent();
string[] param = Environment.GetCommandLineArgs();
if (param.Length > 2)
if (param.Length > 1)
{
switch (param[1])
{
case "UAC":
Invoke(param[2], param[3], param[4]);
break;
case "AssociatePluginInstaller":
installer.RegisterInstaller();
break;
case "InstallPlugin":
var path = param[2];
installer.Install(path);
break;
}
}
Application.Current.Shutdown(0);

261
Wox.UAC/PluginInstaller.cs Normal file
View File

@@ -0,0 +1,261 @@
using System;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
using System.Windows;
using ICSharpCode.SharpZipLib.Zip;
using Microsoft.Win32;
using Newtonsoft.Json;
using Wox.Plugin;
namespace Wox.UAC
{
public class PluginInstaller
{
[DllImport("shell32.dll")]
private static extern void SHChangeNotify(uint wEventId, uint uFlags, IntPtr dwItem1, IntPtr dwItem2);
/// <summary>
/// associate filetype with specified program
/// </summary>
/// <param name="filePath"></param>
/// <param name="fileType"></param>
/// <param name="iconPath"></param>
/// <param name="overrides"></param>
private static void SaveReg(string filePath, string fileType, string iconPath, bool overrides)
{
RegistryKey classRootKey = Registry.ClassesRoot.OpenSubKey("", true);
RegistryKey woxKey = classRootKey.OpenSubKey(fileType, true);
if (woxKey != null)
{
if (!overrides)
{
return;
}
classRootKey.DeleteSubKeyTree(fileType);
}
classRootKey.CreateSubKey(fileType);
woxKey = classRootKey.OpenSubKey(fileType, true);
woxKey.SetValue("", "wox.wox");
woxKey.SetValue("Content Type", "application/wox");
RegistryKey iconKey = woxKey.CreateSubKey("DefaultIcon");
iconKey.SetValue("", iconPath);
woxKey.CreateSubKey("shell");
RegistryKey shellKey = woxKey.OpenSubKey("shell", true);
shellKey.SetValue("", "Open");
RegistryKey openKey = shellKey.CreateSubKey("open");
openKey.SetValue("", "Open with wox");
openKey = shellKey.OpenSubKey("open", true);
openKey.CreateSubKey("command");
RegistryKey commandKey = openKey.OpenSubKey("command", true);
string pathString = "\"" + filePath + "\" \"installPlugin\" \"%1\"";
commandKey.SetValue("", pathString);
//refresh cache
SHChangeNotify(0x8000000, 0, IntPtr.Zero, IntPtr.Zero);
}
public void RegisterInstaller()
{
string filePath = Directory.GetCurrentDirectory() + "\\Wox.UAC.exe";
string iconPath = Directory.GetCurrentDirectory() + "\\app.ico";
SaveReg(filePath, ".wox", iconPath, true);
}
public void Install(string path)
{
if (File.Exists(path))
{
string tempFoler = System.IO.Path.GetTempPath() + "\\wox\\plugins";
if (Directory.Exists(tempFoler))
{
Directory.Delete(tempFoler, true);
}
UnZip(path, tempFoler, true);
string iniPath = tempFoler + "\\plugin.json";
if (!File.Exists(iniPath))
{
MessageBox.Show("Install failed: config is missing");
return;
}
PluginMetadata plugin = GetMetadataFromJson(tempFoler);
if (plugin == null || plugin.Name == null)
{
MessageBox.Show("Install failed: config of this plugin is invalid");
return;
}
string pluginFolerPath = AppDomain.CurrentDomain.BaseDirectory + "Plugins";
if (!Directory.Exists(pluginFolerPath))
{
MessageBox.Show("Install failed: cound't find plugin directory");
return;
}
string newPluginPath = pluginFolerPath + "\\" + plugin.Name;
string content = string.Format(
"Do you want to install following plugin?\r\nName: {0}\r\nVersion: {1}\r\nAuthor: {2}",
plugin.Name, plugin.Version, plugin.Author);
if (Directory.Exists(newPluginPath))
{
PluginMetadata existingPlugin = GetMetadataFromJson(newPluginPath);
if (existingPlugin == null || existingPlugin.Name == null)
{
//maybe broken plugin, just delete it
Directory.Delete(newPluginPath, true);
}
else
{
content = string.Format(
"Do you want to update following plugin?\r\nName: {0}\r\nOld Version: {1}\r\nNew Version: {2}\r\nAuthor: {3}",
plugin.Name, existingPlugin.Version, plugin.Version, plugin.Author);
}
}
MessageBoxResult result = MessageBox.Show(content, "Install plugin",
MessageBoxButton.YesNo, MessageBoxImage.Question);
if (result == MessageBoxResult.Yes)
{
if (Directory.Exists(newPluginPath))
{
Directory.Delete(newPluginPath, true);
}
UnZip(path, newPluginPath, true);
Directory.Delete(tempFoler, true);
string wox = AppDomain.CurrentDomain.BaseDirectory + "Wox.exe";
if (File.Exists(wox))
{
ProcessStartInfo info = new ProcessStartInfo(wox, "reloadplugin")
{
UseShellExecute = true
};
Process.Start(info);
MessageBox.Show("You have installed plugin " + plugin.Name + " successfully.");
}
else
{
MessageBox.Show("You have installed plugin " + plugin.Name + " successfully. Please restart your wox to use new plugin.");
}
}
}
}
private static PluginMetadata GetMetadataFromJson(string pluginDirectory)
{
string configPath = Path.Combine(pluginDirectory, "plugin.json");
PluginMetadata metadata;
if (!File.Exists(configPath))
{
return null;
}
try
{
metadata = JsonConvert.DeserializeObject<PluginMetadata>(File.ReadAllText(configPath));
metadata.PluginType = PluginType.ThirdParty;
metadata.PluginDirecotry = pluginDirectory;
}
catch (Exception)
{
string error = string.Format("Parse plugin config {0} failed: json format is not valid", configPath);
#if (DEBUG)
{
throw new Exception(error);
}
#endif
return null;
}
if (!AllowedLanguage.IsAllowed(metadata.Language))
{
string error = string.Format("Parse plugin config {0} failed: invalid language {1}", configPath,
metadata.Language);
#if (DEBUG)
{
throw new Exception(error);
}
#endif
return null;
}
if (!File.Exists(metadata.ExecuteFilePath))
{
string error = string.Format("Parse plugin config {0} failed: ExecuteFile {1} didn't exist", configPath,
metadata.ExecuteFilePath);
#if (DEBUG)
{
throw new Exception(error);
}
#endif
return null;
}
return metadata;
}
/// <summary>
/// unzip
/// </summary>
/// <param name="zipedFile">The ziped file.</param>
/// <param name="strDirectory">The STR directory.</param>
/// <param name="overWrite">overwirte</param>
private void UnZip(string zipedFile, string strDirectory, bool overWrite)
{
if (strDirectory == "")
strDirectory = Directory.GetCurrentDirectory();
if (!strDirectory.EndsWith("\\"))
strDirectory = strDirectory + "\\";
using (ZipInputStream s = new ZipInputStream(File.OpenRead(zipedFile)))
{
ZipEntry theEntry;
while ((theEntry = s.GetNextEntry()) != null)
{
string directoryName = "";
string pathToZip = "";
pathToZip = theEntry.Name;
if (pathToZip != "")
directoryName = Path.GetDirectoryName(pathToZip) + "\\";
string fileName = Path.GetFileName(pathToZip);
Directory.CreateDirectory(strDirectory + directoryName);
if (fileName != "")
{
if ((File.Exists(strDirectory + directoryName + fileName) && overWrite) || (!File.Exists(strDirectory + directoryName + fileName)))
{
using (FileStream streamWriter = File.Create(strDirectory + directoryName + fileName))
{
byte[] data = new byte[2048];
while (true)
{
int size = s.Read(data, 0, data.Length);
if (size > 0)
streamWriter.Write(data, 0, size);
else
break;
}
streamWriter.Close();
}
}
}
}
s.Close();
}
}
}
}

View File

@@ -42,9 +42,17 @@
<ApplicationManifest>app.manifest</ApplicationManifest>
</PropertyGroup>
<ItemGroup>
<Reference Include="ICSharpCode.SharpZipLib, Version=0.86.0.518, Culture=neutral, PublicKeyToken=1b03e6acf1164f73, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\SharpZipLib.0.86.0\lib\20\ICSharpCode.SharpZipLib.dll</HintPath>
</Reference>
<Reference Include="log4net">
<HintPath>..\packages\log4net.2.0.3\lib\net35-full\log4net.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json, Version=4.5.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Newtonsoft.Json.6.0.1\lib\net35\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
@@ -74,6 +82,7 @@
</Compile>
</ItemGroup>
<ItemGroup>
<Compile Include="PluginInstaller.cs" />
<Compile Include="Properties\AssemblyInfo.cs">
<SubType>Code</SubType>
</Compile>
@@ -104,18 +113,10 @@
<Project>{4fd29318-a8ab-4d8f-aa47-60bc241b8da3}</Project>
<Name>Wox.Infrastructure</Name>
</ProjectReference>
<ProjectReference Include="..\Wox.Plugin.System\Wox.Plugin.System.csproj">
<Project>{69ce0206-cb41-453d-88af-df86092ef9b8}</Project>
<Name>Wox.Plugin.System</Name>
</ProjectReference>
<ProjectReference Include="..\Wox.Plugin\Wox.Plugin.csproj">
<Project>{8451ecdd-2ea4-4966-bb0a-7bbc40138e80}</Project>
<Name>Wox.Plugin</Name>
</ProjectReference>
<ProjectReference Include="..\Wox\Wox.csproj">
<Project>{DB90F671-D861-46BB-93A3-F1304F5BA1C5}</Project>
<Name>Wox</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Resource Include="app.ico" />