Refactoring. Move system plugins to seperate DLLs.

This commit is contained in:
qianlifeng
2015-01-03 15:20:34 +08:00
parent 203965043e
commit 4243843951
134 changed files with 2209 additions and 1158 deletions

View File

@@ -0,0 +1,176 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Control = System.Windows.Controls.Control;
namespace Wox.Plugin.CMD
{
public class CMD : IPlugin, ISettingProvider
{
private PluginInitContext context;
public List<Result> Query(Query query)
{
List<Result> results = new List<Result>();
List<Result> pushedResults = new List<Result>();
if (query.RawQuery == ">")
{
IEnumerable<Result> history = CMDStorage.Instance.CMDHistory.OrderByDescending(o => o.Value)
.Select(m => new Result
{
Title = m.Key,
SubTitle = "this command has been executed " + m.Value + " times",
IcoPath = "Images/cmd.png",
Action = (c) =>
{
ExecuteCmd(m.Key);
return true;
},
ContextMenu = GetContextMenus(m.Key)
}).Take(5);
results.AddRange(history);
}
if (query.RawQuery.StartsWith(">") && query.RawQuery.Length > 1)
{
string cmd = query.RawQuery.Substring(1);
Result result = new Result
{
Title = cmd,
Score = 5000,
SubTitle = "execute command through command shell",
IcoPath = "Images/cmd.png",
Action = (c) =>
{
ExecuteCmd(cmd);
return true;
},
ContextMenu = GetContextMenus(cmd)
};
try
{
if (File.Exists(cmd) || Directory.Exists(cmd))
{
result.IcoPath = cmd;
}
}
catch (Exception) { }
context.API.PushResults(query, context.CurrentPluginMetadata, new List<Result>() { result });
pushedResults.Add(result);
IEnumerable<Result> history = CMDStorage.Instance.CMDHistory.Where(o => o.Key.Contains(cmd))
.OrderByDescending(o => o.Value)
.Select(m =>
{
if (m.Key == cmd)
{
result.SubTitle = "this command has been executed " + m.Value + " times";
return null;
}
var ret = new Result
{
Title = m.Key,
SubTitle = "this command has been executed " + m.Value + " times",
IcoPath = "Images/cmd.png",
Action = (c) =>
{
ExecuteCmd(m.Key);
return true;
},
ContextMenu = GetContextMenus(m.Key)
};
try
{
if (File.Exists(m.Key) || Directory.Exists(m.Key))
{
ret.IcoPath = m.Key;
}
}
catch (Exception) { }
return ret;
}).Where(o => o != null).Take(4);
context.API.PushResults(query, context.CurrentPluginMetadata, history.ToList());
pushedResults.AddRange(history);
try
{
string basedir = null;
string dir = null;
string excmd = Environment.ExpandEnvironmentVariables(cmd);
if (Directory.Exists(excmd) && (cmd.EndsWith("/") || cmd.EndsWith(@"\")))
{
basedir = excmd;
dir = cmd;
}
else if (Directory.Exists(Path.GetDirectoryName(excmd)))
{
basedir = Path.GetDirectoryName(excmd);
var dirn = Path.GetDirectoryName(cmd);
dir = (dirn.EndsWith("/") || dirn.EndsWith(@"\")) ? dirn : cmd.Substring(0, dirn.Length + 1);
}
if (basedir != null)
{
List<string> autocomplete = Directory.GetFileSystemEntries(basedir).Select(o => dir + Path.GetFileName(o)).Where(o => o.StartsWith(cmd, StringComparison.OrdinalIgnoreCase) && !results.Any(p => o.Equals(p.Title, StringComparison.OrdinalIgnoreCase)) && !pushedResults.Any(p => o.Equals(p.Title, StringComparison.OrdinalIgnoreCase))).ToList();
autocomplete.Sort();
results.AddRange(autocomplete.ConvertAll(m => new Result()
{
Title = m,
SubTitle = "",
IcoPath = m,
Action = (c) =>
{
ExecuteCmd(m);
return true;
},
ContextMenu = GetContextMenus(m)
}));
}
}
catch (Exception) { }
}
return results;
}
private List<Result> GetContextMenus(string cmd)
{
return new List<Result>()
{
new Result()
{
Title = "Run As Administrator",
Action = c =>
{
context.API.HideApp();
ExecuteCmd(cmd, true);
return true;
},
IcoPath = "Images/cmd.png"
}
};
}
private void ExecuteCmd(string cmd, bool runAsAdministrator = false)
{
if (context.API.ShellRun(cmd, runAsAdministrator))
CMDStorage.Instance.AddCmdHistory(cmd);
}
public void Init(PluginInitContext context)
{
this.context = context;
}
public Control CreateSettingPanel()
{
return new CMDSetting();
}
}
}

View File

@@ -0,0 +1,25 @@
<UserControl x:Class="Wox.Plugin.CMD.CMDSetting"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
Loaded="CMDSetting_OnLoaded"
d:DesignHeight="300" d:DesignWidth="300">
<Border BorderBrush="Gray" Margin="10" BorderThickness="1">
<Grid Margin="10" VerticalAlignment="Top" >
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Orientation="Horizontal">
<CheckBox x:Name="cbReplaceWinR" >Replace Win+R</CheckBox>
</StackPanel>
<StackPanel Grid.Row="1" Orientation="Horizontal" Margin="0 10 0 0">
<CheckBox x:Name="cbLeaveCmdOpen" >
Do not close Command Prompt after command execution
</CheckBox>
</StackPanel>
</Grid>
</Border>
</UserControl>

View File

@@ -0,0 +1,43 @@
using System.Windows;
using System.Windows.Controls;
using Wox.Infrastructure.Storage.UserSettings;
namespace Wox.Plugin.CMD
{
public partial class CMDSetting : UserControl
{
public CMDSetting()
{
InitializeComponent();
}
private void CMDSetting_OnLoaded(object sender, RoutedEventArgs re)
{
cbReplaceWinR.IsChecked = UserSettingStorage.Instance.ReplaceWinR;
cbLeaveCmdOpen.IsChecked = UserSettingStorage.Instance.LeaveCmdOpen;
cbLeaveCmdOpen.Checked += (o, e) =>
{
UserSettingStorage.Instance.LeaveCmdOpen = true;
UserSettingStorage.Instance.Save();
};
cbLeaveCmdOpen.Unchecked += (o, e) =>
{
UserSettingStorage.Instance.LeaveCmdOpen = false;
UserSettingStorage.Instance.Save();
};
cbReplaceWinR.Checked += (o, e) =>
{
UserSettingStorage.Instance.ReplaceWinR = true;
UserSettingStorage.Instance.Save();
};
cbReplaceWinR.Unchecked += (o, e) =>
{
UserSettingStorage.Instance.ReplaceWinR = false;
UserSettingStorage.Instance.Save();
};
}
}
}

View File

@@ -0,0 +1,31 @@
using System.Collections.Generic;
using Newtonsoft.Json;
using Wox.Infrastructure.Storage;
namespace Wox.Plugin.CMD
{
public class CMDStorage : JsonStrorage<CMDStorage>
{
[JsonProperty]
public Dictionary<string, int> CMDHistory = new Dictionary<string, int>();
protected override string ConfigName
{
get { return "CMDHistory"; }
}
public void AddCmdHistory(string cmdName)
{
if (CMDHistory.ContainsKey(cmdName))
{
CMDHistory[cmdName] += 1;
}
else
{
CMDHistory.Add(cmdName, 1);
}
Save();
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// 有关程序集的常规信息通过以下
// 特性集控制。更改这些特性值可修改
// 与程序集关联的信息。
[assembly: AssemblyTitle("Wox.Plugin.CMD")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Wox.Plugin.CMD")]
[assembly: AssemblyCopyright("Copyright © 2015")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// 将 ComVisible 设置为 false 使此程序集中的类型
// 对 COM 组件不可见。 如果需要从 COM 访问此程序集中的类型,
// 则将该类型上的 ComVisible 特性设置为 true。
[assembly: ComVisible(false)]
// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
[assembly: Guid("9283a32d-5d3c-4231-96e0-2150ed4716b9")]
// 程序集的版本信息由下面四个值组成:
//
// 主版本
// 次版本
// 生成号
// 修订号
//
// 可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值,
// 方法是按如下所示使用“*”:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View File

@@ -0,0 +1,103 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" 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>{C21BFF9C-2C99-4B5F-B7C9-A5E6DDDB37B0}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Wox.Plugin.CMD</RootNamespace>
<AssemblyName>Wox.Plugin.CMD</AssemblyName>
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
<RestorePackages>true</RestorePackages>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>..\..\Output\Debug\Plugins\Wox.Plugin.CMD\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="log4net, Version=1.2.13.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\packages\log4net.2.0.3\lib\net35-full\log4net.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\packages\Newtonsoft.Json.6.0.7\lib\net35\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="PresentationCore" />
<Reference Include="PresentationFramework" />
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
<Reference Include="WindowsBase" />
</ItemGroup>
<ItemGroup>
<Compile Include="CMD.cs" />
<Compile Include="CMDSetting.xaml.cs">
<DependentUpon>CMDSetting.xaml</DependentUpon>
</Compile>
<Compile Include="CMDStorage.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<Page Include="CMDSetting.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Wox.Infrastructure\Wox.Infrastructure.csproj">
<Project>{4fd29318-a8ab-4d8f-aa47-60bc241b8da3}</Project>
<Name>Wox.Infrastructure</Name>
</ProjectReference>
<ProjectReference Include="..\..\Wox.Plugin\Wox.Plugin.csproj">
<Project>{8451ecdd-2ea4-4966-bb0a-7bbc40138e80}</Project>
<Name>Wox.Plugin</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
<None Include="plugin.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
<ItemGroup>
<None Include="Images\cmd.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>这台计算机上缺少此项目引用的 NuGet 程序包。启用“NuGet 程序包还原”可下载这些程序包。有关详细信息,请参阅 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('$(SolutionDir)\.nuget\NuGet.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\.nuget\NuGet.targets'))" />
</Target>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="log4net" version="2.0.3" targetFramework="net35" />
<package id="Newtonsoft.Json" version="6.0.7" targetFramework="net35" />
</packages>

View File

@@ -0,0 +1,12 @@
{
"ID":"D409510CD0D2481F853690A07E6DC426",
"ActionKeyword":"*",
"Name":"Shell",
"Description":"Provide executing commands from Wox. Commands should start with >",
"Author":"qianlifeng",
"Version":"1.0.0",
"Language":"csharp",
"Website":"http://www.getwox.com/plugin",
"ExecuteFileName":"Wox.Plugin.CMD.dll",
"IcoPath":"Images\\cmd.png"
}

View File

@@ -0,0 +1,96 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using System.Windows;
using YAMP;
namespace Wox.Plugin.SystemPlugins
{
public class Calculator : IPlugin
{
private static Regex regValidExpressChar = new Regex(
@"^(" +
@"sin|cos|ceil|floor|exp|pi|max|min|det|arccos|abs|" +
@"eigval|eigvec|eig|sum|polar|plot|round|sort|real|zeta|" +
@"bin2dec|hex2dec|oct2dec|" +
@"==|~=|&&|\|\||" +
@"[ei]|[0-9]|[\+\-\*\/\^\., ""]|[\(\)\|\!\[\]]" +
@")+$", RegexOptions.Compiled);
private static Regex regBrackets = new Regex(@"[\(\)\[\]]", RegexOptions.Compiled);
private static ParseContext yampContext = null;
private PluginInitContext context { get; set; }
static Calculator()
{
yampContext = Parser.PrimaryContext;
Parser.InteractiveMode = false;
Parser.UseScripting = false;
}
public List<Result> Query(Query query)
{
if (query.RawQuery.Length <= 2 // don't affect when user only input "e" or "i" keyword
|| !regValidExpressChar.IsMatch(query.RawQuery)
|| !IsBracketComplete(query.RawQuery)) return new List<Result>();
try
{
var result = yampContext.Run(query.RawQuery);
if (result.Output != null && !string.IsNullOrEmpty(result.Result))
{
return new List<Result>() { new Result() {
Title = result.Result,
IcoPath = "Images/calculator.png",
Score = 300,
SubTitle = "Copy this number to the clipboard",
Action = (c) =>
{
try
{
Clipboard.SetText(result.Result);
return true;
}
catch (System.Runtime.InteropServices.ExternalException e)
{
MessageBox.Show("Copy failed, please try later");
return false;
}
}
} };
}
}
catch
{}
return new List<Result>();
}
private bool IsBracketComplete(string query)
{
var matchs = regBrackets.Matches(query);
var leftBracketCount = 0;
foreach (Match match in matchs)
{
if (match.Value == "(" || match.Value == "[")
{
leftBracketCount++;
}
else
{
leftBracketCount--;
}
}
return leftBracketCount == 0;
}
public void Init(PluginInitContext context)
{
this.context = context;
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

View File

@@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// 有关程序集的常规信息通过以下
// 特性集控制。更改这些特性值可修改
// 与程序集关联的信息。
[assembly: AssemblyTitle("Wox.Plugin.Caculator")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Wox.Plugin.Caculator")]
[assembly: AssemblyCopyright("Copyright © 2015")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// 将 ComVisible 设置为 false 使此程序集中的类型
// 对 COM 组件不可见。 如果需要从 COM 访问此程序集中的类型,
// 则将该类型上的 ComVisible 特性设置为 true。
[assembly: ComVisible(false)]
// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
[assembly: Guid("ba698b90-59ed-4c2e-bce1-497eb2f9e76f")]
// 程序集的版本信息由下面四个值组成:
//
// 主版本
// 次版本
// 生成号
// 修订号
//
// 可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值,
// 方法是按如下所示使用“*”:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View File

@@ -0,0 +1,87 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" 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>{59BD9891-3837-438A-958D-ADC7F91F6F7E}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Wox.Plugin.Caculator</RootNamespace>
<AssemblyName>Wox.Plugin.Caculator</AssemblyName>
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
<RestorePackages>true</RestorePackages>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>..\..\Output\Debug\Plugins\Wox.Plugin.Caculator\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="PresentationCore" />
<Reference Include="PresentationFramework" />
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
<Reference Include="YAMP">
<HintPath>..\..\packages\YAMP.1.4.0\lib\net35\YAMP.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="Calculator.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
<None Include="plugin.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Wox.Infrastructure\Wox.Infrastructure.csproj">
<Project>{4fd29318-a8ab-4d8f-aa47-60bc241b8da3}</Project>
<Name>Wox.Infrastructure</Name>
</ProjectReference>
<ProjectReference Include="..\..\Wox.Plugin\Wox.Plugin.csproj">
<Project>{8451ecdd-2ea4-4966-bb0a-7bbc40138e80}</Project>
<Name>Wox.Plugin</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="Images\calculator.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>这台计算机上缺少此项目引用的 NuGet 程序包。启用“NuGet 程序包还原”可下载这些程序包。有关详细信息,请参阅 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('$(SolutionDir)\.nuget\NuGet.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\.nuget\NuGet.targets'))" />
</Target>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="YAMP" version="1.4.0" targetFramework="net35" />
</packages>

View File

@@ -0,0 +1,12 @@
{
"ID":"CEA0FDFC6D3B4085823D60DC76F28855",
"ActionKeyword":"*",
"Name":"Calculator",
"Description":"Provide mathematical calculations.(Try 5*3-2 in Wox)",
"Author":"qianlifeng",
"Version":"1.0.0",
"Language":"csharp",
"Website":"http://www.getwox.com/plugin",
"ExecuteFileName":"Wox.Plugin.Caculator.dll",
"IcoPath":"Images\\calculator.png"
}

View File

@@ -0,0 +1,108 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Windows;
namespace Wox.Plugin.Color
{
public sealed class ColorsPlugin : IPlugin
{
private string DIR_PATH = Path.Combine(Path.GetTempPath(), @"Plugins\Colors\");
private const int IMG_SIZE = 32;
private DirectoryInfo ColorsDirectory { get; set; }
public ColorsPlugin()
{
if (!Directory.Exists(DIR_PATH))
{
ColorsDirectory = Directory.CreateDirectory(DIR_PATH);
}
else
{
ColorsDirectory = new DirectoryInfo(DIR_PATH);
}
}
public List<Result> Query(Query query)
{
var raw = query.RawQuery;
if (!IsAvailable(raw)) return new List<Result>(0);
try
{
var cached = Find(raw);
if (cached.Length == 0)
{
var path = CreateImage(raw);
return new List<Result>
{
new Result
{
Title = raw,
IcoPath = path,
Action = _ =>
{
Clipboard.SetText(raw);
return true;
}
}
};
}
return cached.Select(x => new Result
{
Title = raw,
IcoPath = x.FullName,
Action = _ =>
{
Clipboard.SetText(raw);
return true;
}
}).ToList();
}
catch (Exception exception)
{
// todo: log
return new List<Result>(0);
}
}
private bool IsAvailable(string query)
{
// todo: rgb, names
var length = query.Length - 1; // minus `#` sign
return query.StartsWith("#") && (length == 3 || length == 6);
}
public FileInfo[] Find(string name)
{
var file = string.Format("{0}.png", name.Substring(1));
return ColorsDirectory.GetFiles(file, SearchOption.TopDirectoryOnly);
}
private string CreateImage(string name)
{
using (var bitmap = new Bitmap(IMG_SIZE, IMG_SIZE))
using (var graphics = Graphics.FromImage(bitmap))
{
var color = ColorTranslator.FromHtml(name);
graphics.Clear(color);
var path = CreateFileName(name);
bitmap.Save(path, ImageFormat.Png);
return path;
}
}
private string CreateFileName(string name)
{
return string.Format("{0}{1}.png", ColorsDirectory.FullName, name.Substring(1));
}
public void Init(PluginInitContext context)
{
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

View File

@@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// 有关程序集的常规信息通过以下
// 特性集控制。更改这些特性值可修改
// 与程序集关联的信息。
[assembly: AssemblyTitle("Wox.Plugin.Color")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Wox.Plugin.Color")]
[assembly: AssemblyCopyright("Copyright © 2015")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// 将 ComVisible 设置为 false 使此程序集中的类型
// 对 COM 组件不可见。 如果需要从 COM 访问此程序集中的类型,
// 则将该类型上的 ComVisible 特性设置为 true。
[assembly: ComVisible(false)]
// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
[assembly: Guid("46b03f84-5bf7-4ed4-a69b-f0274c8b3776")]
// 程序集的版本信息由下面四个值组成:
//
// 主版本
// 次版本
// 生成号
// 修订号
//
// 可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值,
// 方法是按如下所示使用“*”:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View File

@@ -0,0 +1,70 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" 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>{F35190AA-4758-4D9E-A193-E3BDF6AD3567}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Wox.Plugin.Color</RootNamespace>
<AssemblyName>Wox.Plugin.Color</AssemblyName>
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>..\..\Output\Debug\Plugins\Wox.Plugin.Color\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="PresentationCore" />
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Drawing" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Color.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Include="Images\color.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
<ItemGroup>
<None Include="plugin.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Wox.Plugin\Wox.Plugin.csproj">
<Project>{8451ecdd-2ea4-4966-bb0a-7bbc40138e80}</Project>
<Name>Wox.Plugin</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@@ -0,0 +1,12 @@
{
"ID":"9B36CE6181FC47FBB597AA2C29CD9B0A",
"ActionKeyword":"*",
"Name":"Colors",
"Description":"Provide hex color preview.(Try #000 in Wox)",
"Author":"qianlifeng",
"Version":"1.0.0",
"Language":"csharp",
"Website":"http://www.getwox.com/plugin",
"ExecuteFileName":"Wox.Plugin.Color.dll",
"IcoPath":"Images\\color.png"
}

View File

@@ -0,0 +1,87 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using Wox.Infrastructure;
namespace Wox.Plugin.ControlPanel
{
public class ControlPanel : IPlugin
{
private PluginInitContext context;
private List<ControlPanelItem> controlPanelItems = new List<ControlPanelItem>();
private string iconFolder;
private string fileType;
public void Init(PluginInitContext context)
{
this.context = context;
controlPanelItems = ControlPanelList.Create(48);
iconFolder = Path.Combine(context.CurrentPluginMetadata.PluginDirectory, @"Images\ControlPanelIcons\");
fileType = ".bmp";
if (!Directory.Exists(iconFolder))
{
Directory.CreateDirectory(iconFolder);
}
foreach (ControlPanelItem item in controlPanelItems)
{
if (!File.Exists(iconFolder + item.GUID + fileType) && item.Icon != null)
{
item.Icon.ToBitmap().Save(iconFolder + item.GUID + fileType);
}
}
}
public List<Result> Query(Query query)
{
if (query.RawQuery.EndsWith(" ") || query.RawQuery.Length <= 1) return new List<Result>();
string myQuery = query.RawQuery.Trim();
List<Result> results = new List<Result>();
foreach (var item in controlPanelItems)
{
var fuzzyMather = FuzzyMatcher.Create(myQuery);
if (MatchProgram(item, fuzzyMather))
{
results.Add(new Result()
{
Title = item.LocalizedString,
SubTitle = item.InfoTip,
Score = item.Score,
IcoPath = Path.Combine(context.CurrentPluginMetadata.PluginDirectory, @"Images\\ControlPanelIcons\\" + item.GUID + fileType),
Action = e =>
{
try
{
Process.Start(item.ExecutablePath);
}
catch (Exception)
{
//Silently Fail for now..
}
return true;
}
});
}
}
List<Result> panelItems = results.OrderByDescending(o => o.Score).Take(5).ToList();
return panelItems;
}
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;
}
}
}

View File

@@ -0,0 +1,25 @@
using System.Diagnostics;
using System.Drawing;
namespace Wox.Plugin.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 GUID { 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 newGUID, ProcessStartInfo newExecutablePath, Icon newIcon)
{
LocalizedString = newLocalizedString;
InfoTip = newInfoTip;
ExecutablePath = newExecutablePath;
Icon = newIcon;
GUID = newGUID;
}
}
}

View File

@@ -0,0 +1,335 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Text;
using Microsoft.Win32;
namespace Wox.Plugin.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 IntPtr defaultIconPtr;
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())
{
currentKey = clsid.OpenSubKey(key);
if (currentKey != null)
{
executablePath = getExecutablePath(currentKey);
if (!(executablePath == null)) //Cannot have item without executable path
{
localizedString = getLocalizedString(currentKey);
if (!string.IsNullOrEmpty(localizedString))//Cannot have item without Title
{
infoTip = getInfoTip(currentKey);
myIcon = getIcon(currentKey, size);
controlPanelItems.Add(new ControlPanelItem(localizedString, infoTip, key, executablePath, myIcon));
}
}
}
}
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)
string input = "\"" + Environment.ExpandEnvironmentVariables(currentKey.OpenSubKey("Shell\\Open\\Command").GetValue(null).ToString()) + "\"";
executablePath.FileName = "cmd.exe";
executablePath.Arguments = "/C " + input;
executablePath.WindowStyle = ProcessWindowStyle.Hidden;
}
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 string[] { ",-" }, StringSplitOptions.None);
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();
//Some apps don't return a string, although they do have a stringIndex. Use Default value.
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 string[] { ",-" }, StringSplitOptions.None);
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 = currentKey.GetValue("InfoTip").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)
{
iconIndex = (IntPtr)sanitizeUint(iconString[1]);
iconPtr = LoadImage(dataFilePointer, iconIndex, 1, iconSize, iconSize, 0);
}
if (iconPtr == IntPtr.Zero)
{
defaultIconPtr = IntPtr.Zero;
EnumResourceNamesWithID(dataFilePointer, GROUP_ICON, new EnumResNameDelegate(EnumRes), IntPtr.Zero); //Iterate through resources.
iconPtr = LoadImage(dataFilePointer, defaultIconPtr, 1, iconSize, iconSize, 0);
}
FreeLibrary(dataFilePointer);
if (iconPtr != IntPtr.Zero)
{
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;
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);
}
/*If the logic is correct, this should never through an exception.
* If there is an exception, then need to analyze what the input is.
* Returning the wrong number will cause more errors */
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));
defaultIconPtr = lpszName;
return false;
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

View File

@@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// 有关程序集的常规信息通过以下
// 特性集控制。更改这些特性值可修改
// 与程序集关联的信息。
[assembly: AssemblyTitle("Wox.Plugin.ControlPanel")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Wox.Plugin.ControlPanel")]
[assembly: AssemblyCopyright("Copyright © 2015")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// 将 ComVisible 设置为 false 使此程序集中的类型
// 对 COM 组件不可见。 如果需要从 COM 访问此程序集中的类型,
// 则将该类型上的 ComVisible 特性设置为 true。
[assembly: ComVisible(false)]
// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
[assembly: Guid("59141b10-8941-4e90-a0a6-bc9385a04cc6")]
// 程序集的版本信息由下面四个值组成:
//
// 主版本
// 次版本
// 生成号
// 修订号
//
// 可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值,
// 方法是按如下所示使用“*”:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View File

@@ -0,0 +1,75 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" 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>{1EE20B48-82FB-48A2-8086-675D6DDAB4F0}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Wox.Plugin.ControlPanel</RootNamespace>
<AssemblyName>Wox.Plugin.ControlPanel</AssemblyName>
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>..\..\Output\Debug\Plugins\Wox.Plugin.ControlPanel\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Drawing" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="ControlPanel.cs" />
<Compile Include="ControlPanelItem.cs" />
<Compile Include="ControlPanelList.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Include="plugin.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Wox.Infrastructure\Wox.Infrastructure.csproj">
<Project>{4fd29318-a8ab-4d8f-aa47-60bc241b8da3}</Project>
<Name>Wox.Infrastructure</Name>
</ProjectReference>
<ProjectReference Include="..\..\Wox.Plugin\Wox.Plugin.csproj">
<Project>{8451ecdd-2ea4-4966-bb0a-7bbc40138e80}</Project>
<Name>Wox.Plugin</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="Images\ControlPanel.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@@ -0,0 +1,12 @@
{
"ID":"209621585B9B4D81813913C507C058C6",
"ActionKeyword":"*",
"Name":"Control Panel",
"Description":"Search within the Control Panel.",
"Author":"CoenraadS",
"Version":"1.0.0",
"Language":"csharp",
"Website":"http://www.getwox.com/plugin",
"ExecuteFileName":"Wox.Plugin.ControlPanel.dll",
"IcoPath":"Images\\ControlPanel.png"
}

View File

@@ -0,0 +1,188 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Windows;
using Wox.Infrastructure.Storage.UserSettings;
using Control = System.Windows.Controls.Control;
namespace Wox.Plugin.Folder
{
public class FolderPlugin : IPlugin, ISettingProvider
{
private static List<string> driverNames;
private PluginInitContext context;
public Control CreateSettingPanel()
{
return new FileSystemSettings();
}
public void Init(PluginInitContext context)
{
this.context = context;
this.context.API.BackKeyDownEvent += ApiBackKeyDownEvent;
InitialDriverList();
if (UserSettingStorage.Instance.FolderLinks == null)
{
UserSettingStorage.Instance.FolderLinks = new List<FolderLink>();
UserSettingStorage.Instance.Save();
}
}
private void ApiBackKeyDownEvent(object sender, WoxKeyDownEventArgs e)
{
string query = e.Query;
if (Directory.Exists(query))
{
if (query.EndsWith("\\"))
{
query = query.Remove(query.Length - 1);
}
if (query.Contains("\\"))
{
int index = query.LastIndexOf("\\");
query = query.Remove(index) + "\\";
}
context.API.ChangeQuery(query);
}
}
public List<Result> Query(Query query)
{
if(string.IsNullOrEmpty(query.RawQuery)) return new List<Result>();
string input = query.RawQuery.ToLower();
List<FolderLink> userFolderLinks = UserSettingStorage.Instance.FolderLinks.Where(
x => x.Nickname.StartsWith(input, StringComparison.OrdinalIgnoreCase)).ToList();
List<Result> results =
userFolderLinks.Select(
item => new Result(item.Nickname, "Images/folder.png", "Ctrl + Enter to open the directory")
{
Action = c =>
{
if (c.SpecialKeyState.CtrlPressed)
{
try
{
Process.Start(item.Path);
return true;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Could not start " + item.Path);
return false;
}
}
context.API.ChangeQuery(item.Path);
return false;
}
}).ToList();
if (!driverNames.Any(input.StartsWith))
return results;
if (!input.EndsWith("\\"))
{
//"c:" means "the current directory on the C drive" whereas @"c:\" means "root of the C drive"
input = input + "\\";
}
results.AddRange(QueryInternal_Directory_Exists(input));
return results;
}
private void InitialDriverList()
{
if (driverNames == null)
{
driverNames = new List<string>();
DriveInfo[] allDrives = DriveInfo.GetDrives();
foreach (DriveInfo driver in allDrives)
{
driverNames.Add(driver.Name.ToLower().TrimEnd('\\'));
}
}
}
private List<Result> QueryInternal_Directory_Exists(string rawQuery)
{
var results = new List<Result>();
if (!Directory.Exists(rawQuery)) return results;
results.Add(new Result("Open current directory", "Images/folder.png")
{
Score = 10000,
Action = c =>
{
Process.Start(rawQuery);
return true;
}
});
//Add children directories
DirectoryInfo[] dirs = new DirectoryInfo(rawQuery).GetDirectories();
foreach (DirectoryInfo dir in dirs)
{
if ((dir.Attributes & FileAttributes.Hidden) == FileAttributes.Hidden) continue;
DirectoryInfo dirCopy = dir;
var result = new Result(dir.Name, "Images/folder.png", "Ctrl + Enter to open the directory")
{
Action = c =>
{
if (c.SpecialKeyState.CtrlPressed)
{
try
{
Process.Start(dirCopy.FullName);
return true;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Could not start " + dirCopy.FullName);
return false;
}
}
context.API.ChangeQuery(dirCopy.FullName + "\\");
return false;
}
};
results.Add(result);
}
//Add children files
FileInfo[] files = new DirectoryInfo(rawQuery).GetFiles();
foreach (FileInfo file in files)
{
if ((file.Attributes & FileAttributes.Hidden) == FileAttributes.Hidden) continue;
string filePath = file.FullName;
var result = new Result(Path.GetFileName(filePath), "Images/file.png")
{
Action = c =>
{
try
{
Process.Start(filePath);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Could not start " + filePath);
}
return true;
}
};
results.Add(result);
}
return results;
}
}
}

View File

@@ -0,0 +1,32 @@
<UserControl x:Class="Wox.Plugin.Folder.FileSystemSettings"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid Margin="10">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="50"/>
</Grid.RowDefinitions>
<ListView x:Name="lbxFolders" Grid.Row="0">
<ListView.View>
<GridView>
<GridViewColumn Header="Folder Path" Width="180">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
<StackPanel Grid.Row="1" HorizontalAlignment="Right" Orientation="Horizontal">
<Button x:Name="btnDelete" Click="btnDelete_Click" Width="100" Margin="10" Content="Delete"/>
<Button x:Name="btnEdit" Click="btnEdit_Click" Width="100" Margin="10" Content="Edit"/>
<Button x:Name="btnAdd" Click="btnAdd_Click" Width="100" Margin="10" Content="Add"/>
</StackPanel>
</Grid>
</UserControl>

View File

@@ -0,0 +1,74 @@
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Forms;
using Wox.Infrastructure.Storage.UserSettings;
using MessageBox = System.Windows.MessageBox;
using UserControl = System.Windows.Controls.UserControl;
namespace Wox.Plugin.Folder {
/// <summary>
/// Interaction logic for FileSystemSettings.xaml
/// </summary>
public partial class FileSystemSettings : UserControl {
public FileSystemSettings() {
InitializeComponent();
lbxFolders.ItemsSource = UserSettingStorage.Instance.FolderLinks;
}
private void btnDelete_Click(object sender, RoutedEventArgs e) {
var selectedFolder = lbxFolders.SelectedItem as FolderLink;
if (selectedFolder != null)
{
UserSettingStorage.Instance.FolderLinks.Remove(selectedFolder);
lbxFolders.Items.Refresh();
}
else
{
MessageBox.Show("Please select a folder link!");
}
}
private void btnEdit_Click(object sender, RoutedEventArgs e)
{
var selectedFolder = lbxFolders.SelectedItem as FolderLink;
if (selectedFolder != null)
{
var folderBrowserDialog = new FolderBrowserDialog();
folderBrowserDialog.SelectedPath = selectedFolder.Path;
if (folderBrowserDialog.ShowDialog() == DialogResult.OK)
{
var link = UserSettingStorage.Instance.FolderLinks.First(x => x.Path == selectedFolder.Path);
link.Path = folderBrowserDialog.SelectedPath;
UserSettingStorage.Instance.Save();
}
lbxFolders.Items.Refresh();
}
else
{
MessageBox.Show("Please select a folder link!");
}
}
private void btnAdd_Click(object sender, RoutedEventArgs e) {
var folderBrowserDialog = new System.Windows.Forms.FolderBrowserDialog();
if (folderBrowserDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK) {
var newFolder = new FolderLink() {
Path = folderBrowserDialog.SelectedPath
};
if (UserSettingStorage.Instance.FolderLinks == null) {
UserSettingStorage.Instance.FolderLinks = new List<FolderLink>();
}
UserSettingStorage.Instance.FolderLinks.Add(newFolder);
UserSettingStorage.Instance.Save();
}
lbxFolders.Items.Refresh();
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

View File

@@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// 有关程序集的常规信息通过以下
// 特性集控制。更改这些特性值可修改
// 与程序集关联的信息。
[assembly: AssemblyTitle("Wox.Plugin.Folder")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Wox.Plugin.Folder")]
[assembly: AssemblyCopyright("Copyright © 2015")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// 将 ComVisible 设置为 false 使此程序集中的类型
// 对 COM 组件不可见。 如果需要从 COM 访问此程序集中的类型,
// 则将该类型上的 ComVisible 特性设置为 true。
[assembly: ComVisible(false)]
// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
[assembly: Guid("e047418e-f7b0-4a3a-b855-0bef7178179f")]
// 程序集的版本信息由下面四个值组成:
//
// 主版本
// 次版本
// 生成号
// 修订号
//
// 可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值,
// 方法是按如下所示使用“*”:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View File

@@ -0,0 +1,99 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" 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>{787B8AA6-CA93-4C84-96FE-DF31110AD1C4}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Wox.Plugin.Folder</RootNamespace>
<AssemblyName>Wox.Plugin.Folder</AssemblyName>
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
<RestorePackages>true</RestorePackages>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>..\..\Output\Debug\Plugins\Wox.Plugin.Folder\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="log4net, Version=1.2.13.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\packages\log4net.2.0.3\lib\net35-full\log4net.dll</HintPath>
</Reference>
<Reference Include="PresentationCore" />
<Reference Include="PresentationFramework" />
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
<Reference Include="WindowsBase" />
</ItemGroup>
<ItemGroup>
<Compile Include="FolderPlugin.cs" />
<Compile Include="FolderPluginSettings.xaml.cs">
<DependentUpon>FolderPluginSettings.xaml</DependentUpon>
</Compile>
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
<None Include="plugin.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
<ItemGroup>
<Page Include="FolderPluginSettings.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Wox.Infrastructure\Wox.Infrastructure.csproj">
<Project>{4fd29318-a8ab-4d8f-aa47-60bc241b8da3}</Project>
<Name>Wox.Infrastructure</Name>
</ProjectReference>
<ProjectReference Include="..\..\Wox.Plugin\Wox.Plugin.csproj">
<Project>{8451ecdd-2ea4-4966-bb0a-7bbc40138e80}</Project>
<Name>Wox.Plugin</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="Images\folder.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>这台计算机上缺少此项目引用的 NuGet 程序包。启用“NuGet 程序包还原”可下载这些程序包。有关详细信息,请参阅 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('$(SolutionDir)\.nuget\NuGet.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\.nuget\NuGet.targets'))" />
</Target>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="log4net" version="2.0.3" targetFramework="net35" />
</packages>

View File

@@ -0,0 +1,12 @@
{
"ID":"B4D3B69656E14D44865C8D818EAE47C4",
"ActionKeyword":"*",
"Name":"Folder",
"Description":"Provide opening folder from wox directorily. You can add your favorite folders.",
"Author":"qianlifeng",
"Version":"1.0.0",
"Language":"csharp",
"Website":"http://www.getwox.com/plugin",
"ExecuteFileName":"Wox.Plugin.Folder.dll",
"IcoPath":"Images\\folder.png"
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

View File

@@ -0,0 +1,70 @@
using System.Collections.Generic;
using System.Linq;
using Wox.Infrastructure.Storage.UserSettings;
namespace Wox.Plugin.PluginIndicator
{
public class PluginIndicator : IPlugin
{
private List<PluginPair> allPlugins = new List<PluginPair>();
private PluginInitContext context;
public List<Result> Query(Query query)
{
List<Result> results = new List<Result>();
if (string.IsNullOrEmpty(query.RawQuery)) return results;
if (allPlugins.Count == 0)
{
allPlugins = context.API.GetAllPlugins().Where(o => o.Metadata.ActionKeyword != "*").ToList();
}
foreach (PluginMetadata metadata in allPlugins.Select(o => o.Metadata))
{
if (metadata.ActionKeyword.StartsWith(query.RawQuery))
{
PluginMetadata metadataCopy = metadata;
var customizedPluginConfig = UserSettingStorage.Instance.CustomizedPluginConfigs.FirstOrDefault(o => o.ID == metadataCopy.ID);
if (customizedPluginConfig != null && customizedPluginConfig.Disabled)
{
continue;
}
Result result = new Result
{
Title = metadata.ActionKeyword,
SubTitle = string.Format("Activate {0} plugin", metadata.Name),
Score = 100,
IcoPath = metadata.FullIcoPath,
Action = (c) =>
{
context.API.ChangeQuery(metadataCopy.ActionKeyword + " ");
return false;
},
};
results.Add(result);
}
}
results.AddRange(UserSettingStorage.Instance.WebSearches.Where(o => o.ActionWord.StartsWith(query.RawQuery) && o.Enabled).Select(n => new Result()
{
Title = n.ActionWord,
SubTitle = string.Format("Activate {0} web search", n.ActionWord),
Score = 100,
IcoPath = "Images/work.png",
Action = (c) =>
{
context.API.ChangeQuery(n.ActionWord + " ");
return false;
}
}));
return results;
}
public void Init(PluginInitContext context)
{
this.context = context;
}
}
}

View File

@@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// 有关程序集的常规信息通过以下
// 特性集控制。更改这些特性值可修改
// 与程序集关联的信息。
[assembly: AssemblyTitle("Wox.Plugin.PluginIndicator")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Wox.Plugin.PluginIndicator")]
[assembly: AssemblyCopyright("Copyright © 2015")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// 将 ComVisible 设置为 false 使此程序集中的类型
// 对 COM 组件不可见。 如果需要从 COM 访问此程序集中的类型,
// 则将该类型上的 ComVisible 特性设置为 true。
[assembly: ComVisible(false)]
// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
[assembly: Guid("27f6d9fc-340b-47be-90ea-2a86bfca7bad")]
// 程序集的版本信息由下面四个值组成:
//
// 主版本
// 次版本
// 生成号
// 修订号
//
// 可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值,
// 方法是按如下所示使用“*”:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View File

@@ -0,0 +1,72 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" 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>{FDED22C8-B637-42E8-824A-63B5B6E05A3A}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Wox.Plugin.PluginIndicator</RootNamespace>
<AssemblyName>Wox.Plugin.PluginIndicator</AssemblyName>
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>..\..\Output\Debug\Plugins\Wox.Plugin.PluginIndicator\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="PluginIndicator.cs" />
</ItemGroup>
<ItemGroup>
<None Include="plugin.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Wox.Infrastructure\Wox.Infrastructure.csproj">
<Project>{4fd29318-a8ab-4d8f-aa47-60bc241b8da3}</Project>
<Name>Wox.Infrastructure</Name>
</ProjectReference>
<ProjectReference Include="..\..\Wox.Plugin\Wox.Plugin.csproj">
<Project>{8451ecdd-2ea4-4966-bb0a-7bbc40138e80}</Project>
<Name>Wox.Plugin</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="Images\work.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@@ -0,0 +1,12 @@
{
"ID":"6A122269676E40EB86EB543B945932B9",
"ActionKeyword":"*",
"Name":"Plugin Indicator",
"Description":"Provide plugin actionword suggestion.",
"Author":"qianlifeng",
"Version":"1.0.0",
"Language":"csharp",
"Website":"http://www.getwox.com/plugin",
"ExecuteFileName":"Wox.Plugin.PluginIndicator.dll",
"IcoPath":"Images\\work.png"
}

View File

@@ -62,9 +62,9 @@
</None>
</ItemGroup>
<ItemGroup>
<Content Include="Images\plugin.png">
<None Include="Images\plugin.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</None>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup>

View File

@@ -0,0 +1,53 @@
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Threading;
using Wox.Infrastructure.Storage.UserSettings;
namespace Wox.Plugin.Program
{
internal class FileChangeWatcher
{
private static bool isIndexing = false;
private static List<string> watchedPath = new List<string>();
public static void AddWatch(string path, bool includingSubDirectory = true)
{
if (watchedPath.Contains(path)) return;
if (!Directory.Exists(path))
{
Debug.WriteLine(string.Format("FileChangeWatcher: {0} doesn't exist", path),"WoxDebug");
return;
}
watchedPath.Add(path);
foreach (string fileType in UserSettingStorage.Instance.ProgramSuffixes.Split(';'))
{
FileSystemWatcher watcher = new FileSystemWatcher
{
Path = path,
IncludeSubdirectories = includingSubDirectory,
Filter = string.Format("*.{0}", fileType),
EnableRaisingEvents = true
};
watcher.Changed += FileChanged;
watcher.Created += FileChanged;
watcher.Deleted += FileChanged;
watcher.Renamed += FileChanged;
}
}
private static void FileChanged(object source, FileSystemEventArgs e)
{
if (!isIndexing)
{
ThreadPool.QueueUserWorkItem(o =>
{
Programs.IndexPrograms();
isIndexing = false;
});
}
}
}
}

View File

@@ -0,0 +1,51 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
namespace Wox.Plugin.Program
{
public interface IProgramSource
{
List<Program> LoadPrograms();
int BonusPoints { get; set; }
}
[Serializable]
public abstract class AbstractProgramSource : IProgramSource
{
public abstract List<Program> LoadPrograms();
public int BonusPoints
{
get; set;
}
protected Program CreateEntry(string file)
{
var p = new Program()
{
Title = Path.GetFileNameWithoutExtension(file),
IcoPath = file,
ExecutePath = file
};
switch (Path.GetExtension(file).ToLower())
{
case ".exe":
p.ExecuteName = Path.GetFileName(file);
try
{
FileVersionInfo versionInfo = FileVersionInfo.GetVersionInfo(file);
if (!string.IsNullOrEmpty(versionInfo.FileDescription))
{
p.Title = versionInfo.FileDescription;
}
}
catch (Exception) { }
break;
}
return p;
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

View File

@@ -0,0 +1,6 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:system="clr-namespace:System;assembly=mscorlib">
</ResourceDictionary>

View File

@@ -0,0 +1,34 @@
using System;
using Wox.Infrastructure;
namespace Wox.Plugin.Program
{
[Serializable]
public class Program
{
private static readonly global::System.Text.RegularExpressions.Regex AbbrRegexp = new global::System.Text.RegularExpressions.Regex("[^A-Z0-9]", global::System.Text.RegularExpressions.RegexOptions.Compiled);
private string m_Title;
public string Title
{
get
{
return m_Title;
}
set
{
m_Title = value;
string pinyin = m_Title.Unidecode();
PinyinTitle = pinyin;
AbbrTitle = AbbrRegexp.Replace(global::System.Threading.Thread.CurrentThread.CurrentCulture.TextInfo.ToTitleCase(pinyin), "");
if (AbbrTitle.Length < 2) AbbrTitle = null;
}
}
public string PinyinTitle { get; private set; }
public string AbbrTitle { get; private set; }
public string IcoPath { get; set; }
public string ExecutePath { get; set; }
public string ExecuteName { get; set; }
public int Score { get; set; }
public IProgramSource Source { get; set; }
}
}

View File

@@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using Wox.Infrastructure.Storage;
namespace Wox.Plugin.Program
{
[Serializable]
public class ProgramCacheStorage : BinaryStorage<ProgramCacheStorage>
{
public List<Program> Programs = new List<Program>();
protected override string ConfigName
{
get { return "ProgramIndexCache"; }
}
}
}

View File

@@ -0,0 +1,49 @@
<UserControl x:Class="Wox.Plugin.Program.ProgramSetting"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:infrastructure="clr-namespace:Wox.Infrastructure;assembly=Wox.Infrastructure"
xmlns:program="clr-namespace:Wox.Plugin.Program"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="600">
<UserControl.Resources>
<BooleanToVisibilityConverter x:Key="BoolToVis" />
</UserControl.Resources>
<Grid Margin="10">
<Grid.RowDefinitions>
<RowDefinition Height="50"/>
<RowDefinition Height="*"/>
<RowDefinition Height="50"/>
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Orientation="Horizontal" HorizontalAlignment="Right">
<Button Height="30" HorizontalAlignment="Right" x:Name="btnProgramSuffixes" Width="130" Click="BtnProgramSuffixes_OnClick">Index file suffixes</Button>
<Button Height="30" HorizontalAlignment="Right" Margin="10 0 0 0" x:Name="btnReindex" Width="100" Click="btnReindex_Click">Re-Index</Button>
</StackPanel>
<ListView x:Name="programSourceView" Grid.Row="1">
<ListView.View>
<GridView>
<GridViewColumn Header="Location" Width="400">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Location, ConverterParameter=(null), Converter={program:StringEmptyConverter}}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
<DockPanel Grid.Row="2">
<StackPanel x:Name="indexingPanel" Visibility="Hidden" HorizontalAlignment="Left" Orientation="Horizontal">
<ProgressBar x:Name="progressBarIndexing" Height="20" Width="80" Minimum="0" Maximum="100" IsIndeterminate="True"></ProgressBar>
<TextBlock Margin="10 0 0 0" Height="20" HorizontalAlignment="Center">Indexing</TextBlock>
</StackPanel>
<StackPanel HorizontalAlignment="Right" Orientation="Horizontal">
<Button x:Name="btnDeleteProgramSource" Click="btnDeleteProgramSource_OnClick" Width="100" Margin="10" Content="Delete"/>
<Button x:Name="btnEditProgramSource" Click="btnEditProgramSource_OnClick" Width="100" Margin="10" Content="Edit"/>
<Button x:Name="btnAddProgramSource" Click="btnAddProgramSource_OnClick" Width="100" Margin="10" Content="Add"/>
</StackPanel>
</DockPanel>
</Grid>
</UserControl>

View File

@@ -0,0 +1,106 @@
using System;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using Wox.Infrastructure.Storage.UserSettings;
namespace Wox.Plugin.Program
{
/// <summary>
/// Interaction logic for ProgramSetting.xaml
/// </summary>
public partial class ProgramSetting : UserControl
{
public ProgramSetting()
{
InitializeComponent();
Loaded += Setting_Loaded;
}
private void Setting_Loaded(object sender, RoutedEventArgs e)
{
programSourceView.ItemsSource = UserSettingStorage.Instance.ProgramSources;
}
private void ReIndexing()
{
programSourceView.Items.Refresh();
ThreadPool.QueueUserWorkItem(t =>
{
Dispatcher.Invoke(new Action(() => { indexingPanel.Visibility = Visibility.Visible; }));
Programs.IndexPrograms();
Dispatcher.Invoke(new Action(() => { indexingPanel.Visibility = Visibility.Hidden; }));
});
}
private void btnAddProgramSource_OnClick(object sender, RoutedEventArgs e)
{
var folderBrowserDialog = new System.Windows.Forms.FolderBrowserDialog();
if (folderBrowserDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
string path = folderBrowserDialog.SelectedPath;
UserSettingStorage.Instance.ProgramSources.Add(new ProgramSource()
{
Location = path,
Type = "FileSystemProgramSource",
Enabled = true
});
UserSettingStorage.Instance.Save();
ReIndexing();
}
}
private void btnDeleteProgramSource_OnClick(object sender, RoutedEventArgs e)
{
ProgramSource selectedProgramSource = programSourceView.SelectedItem as ProgramSource;
if (selectedProgramSource != null)
{
if (MessageBox.Show("Are your sure to delete " + selectedProgramSource.Location, "Delete ProgramSource",
MessageBoxButton.YesNo) == MessageBoxResult.Yes)
{
UserSettingStorage.Instance.ProgramSources.Remove(selectedProgramSource);
UserSettingStorage.Instance.Save();
ReIndexing();
}
}
else
{
MessageBox.Show("Please select a program source");
}
}
private void btnEditProgramSource_OnClick(object sender, RoutedEventArgs e)
{
ProgramSource selectedProgramSource = programSourceView.SelectedItem as ProgramSource;
if (selectedProgramSource != null)
{
//todo: update
var folderBrowserDialog = new System.Windows.Forms.FolderBrowserDialog();
if (folderBrowserDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
string path = folderBrowserDialog.SelectedPath;
selectedProgramSource.Location = path;
UserSettingStorage.Instance.Save();
ReIndexing();
}
}
else
{
MessageBox.Show("Please select a program source");
}
}
private void btnReindex_Click(object sender, RoutedEventArgs e)
{
ReIndexing();
}
private void BtnProgramSuffixes_OnClick(object sender, RoutedEventArgs e)
{
ProgramSuffixes p = new ProgramSuffixes();
p.ShowDialog();
}
}
}

View File

@@ -0,0 +1,58 @@
using System;
using System.Collections.Generic;
using Wox.Infrastructure.Storage.UserSettings;
namespace Wox.Plugin.Program.ProgramSources
{
[Serializable]
[global::System.ComponentModel.Browsable(false)]
public class AppPathsProgramSource: AbstractProgramSource
{
public AppPathsProgramSource()
{
this.BonusPoints = -10;
}
public AppPathsProgramSource(ProgramSource source)
: this()
{
this.BonusPoints = source.BonusPoints;
}
public override List<Program> LoadPrograms()
{
var list = new List<Program>();
ReadAppPaths(@"SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths", list);
ReadAppPaths(@"SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\App Paths", list); //TODO: need test more on 64-bit
return list;
}
private void ReadAppPaths(string rootpath, List<Program> list)
{
using (var root = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(rootpath))
{
if (root == null) return;
foreach (var item in root.GetSubKeyNames())
{
using (var key = root.OpenSubKey(item))
{
object path = key.GetValue("");
if (path is string && global::System.IO.File.Exists((string)path))
{
var entry = CreateEntry((string)path);
entry.ExecuteName = item;
list.Add(entry);
}
key.Close();
}
}
}
}
public override string ToString()
{
return typeof(AppPathsProgramSource).Name;
}
}
}

View File

@@ -0,0 +1,40 @@
using System;
using System.Runtime.InteropServices;
using System.Text;
using Wox.Infrastructure.Storage.UserSettings;
namespace Wox.Plugin.Program.ProgramSources
{
[Serializable]
[global::System.ComponentModel.Browsable(false)]
public class CommonStartMenuProgramSource : FileSystemProgramSource
{
[DllImport("shell32.dll")]
static extern bool SHGetSpecialFolderPath(IntPtr hwndOwner, [Out] StringBuilder lpszPath, int nFolder, bool fCreate);
const int CSIDL_COMMON_PROGRAMS = 0x17;
private static string getPath()
{
StringBuilder commonStartMenuPath = new StringBuilder(560);
SHGetSpecialFolderPath(IntPtr.Zero, commonStartMenuPath, CSIDL_COMMON_PROGRAMS, false);
return commonStartMenuPath.ToString();
}
public CommonStartMenuProgramSource()
: base(getPath())
{
}
public CommonStartMenuProgramSource(ProgramSource source)
: this()
{
this.BonusPoints = source.BonusPoints;
}
public override string ToString()
{
return typeof(CommonStartMenuProgramSource).Name;
}
}
}

View File

@@ -0,0 +1,152 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Wox.Infrastructure.Storage.UserSettings;
namespace Wox.Plugin.SystemPlugins.Program.ProgramSources {
//TODO: Consider Removing
/// <summary>
///
/// </summary>
public class FileSystemFolderSourceShallow : FileSystemProgramSource {
//private static Dictionary<string, DirectoryInfo[]> parentDirectories = new Dictionary<string, DirectoryInfo[]>();
public FileSystemFolderSourceShallow(string baseDirectory)
: base(baseDirectory) { }
public FileSystemFolderSourceShallow(ProgramSource source)
: base(source) { }
public override List<Program> LoadPrograms() {
List<Program> list = new List<Program>();
foreach (var Folder in Directory.GetDirectories(BaseDirectory)) {
list.Add(CreateEntry(Folder));
}
foreach (string file in Directory.GetFiles(base.BaseDirectory)) {
if (Suffixes.Any(o => file.EndsWith("." + o))) {
list.Add(CreateEntry(file));
}
}
return list;
}
public override string ToString() {
return typeof(UserStartMenuProgramSource).Name;
}
/*
public class FolderSource : IProgramSource {
private PluginInitContext context;
public string Location { get; set; }
public int BonusPoints { get; set; }
public FolderSource(string Location) {
this.Location = Location;
}
public List<Program> LoadPrograms() {
List<Result> results = new List<Result>();
if (Directory.Exists(Location)) {
// show all child directory
if (Location.EndsWith("\\") || Location.EndsWith("/")) {
var dirInfo = new DirectoryInfo(Location);
var dirs = dirInfo.GetDirectories();
var parentDirKey = Location.TrimEnd('\\', '/');
if (!parentDirectories.ContainsKey(parentDirKey))
parentDirectories.Add(parentDirKey, dirs);
foreach (var dir in dirs) {
if ((dir.Attributes & FileAttributes.Hidden) == FileAttributes.Hidden)
continue;
var dirPath = dir.FullName;
Result result = new Result {
Title = dir.Name,
IcoPath = "Images/folder.png",
Action = (c) => {
context.ChangeQuery(dirPath);
return false;
}
};
results.Add(result);
}
if (results.Count == 0) {
Result result = new Result {
Title = "Open this directory",
SubTitle = "No files in this directory",
IcoPath = "Images/folder.png",
Action = (c) => {
Process.Start(Location);
return true;
}
};
results.Add(result);
}
}
else {
Result result = new Result {
Title = "Open this directory",
SubTitle = string.Format("path: {0}", Location),
Score = 50,
IcoPath = "Images/folder.png",
Action = (c) => {
Process.Start(Location);
return true;
}
};
results.Add(result);
}
}
// change to search in current directory
var parentDir = Path.GetDirectoryName(Location);
if (!string.IsNullOrEmpty(parentDir) && results.Count == 0) {
parentDir = parentDir.TrimEnd('\\', '/');
if (parentDirectories.ContainsKey(parentDir)) {
var dirs = parentDirectories[parentDir];
var queryFileName = Path.GetFileName(Location).ToLower();
var fuzzy = FuzzyMatcher.Create(queryFileName);
foreach (var dir in dirs) {
if ((dir.Attributes & FileAttributes.Hidden) == FileAttributes.Hidden)
continue;
var matchResult = fuzzy.Evaluate(dir.Name);
if (!matchResult.Success)
continue;
var dirPath = dir.FullName;
Result result = new Result {
Title = dir.Name,
IcoPath = "Images/folder.png",
Score = matchResult.Score,
Action = (c) => {
context.ChangeQuery(dirPath);
return false;
}
};
results.Add(result);
}
}
}
throw new Exception("Debug this!");
}
}
*/
}
}

View File

@@ -0,0 +1,73 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Wox.Infrastructure.Storage.UserSettings;
using Log = Wox.Infrastructure.Logger.Log;
namespace Wox.Plugin.Program.ProgramSources
{
[Serializable]
public class FileSystemProgramSource : AbstractProgramSource
{
private string baseDirectory;
public FileSystemProgramSource(string baseDirectory)
{
this.baseDirectory = baseDirectory;
}
public FileSystemProgramSource(ProgramSource source):this(source.Location)
{
this.BonusPoints = source.BonusPoints;
}
public override List<Program> LoadPrograms()
{
List<Program> list = new List<Program>();
if (Directory.Exists(baseDirectory))
{
GetAppFromDirectory(baseDirectory, list);
FileChangeWatcher.AddWatch(baseDirectory);
}
return list;
}
private void GetAppFromDirectory(string path, List<Program> list)
{
try
{
foreach (string file in Directory.GetFiles(path))
{
if (UserSettingStorage.Instance.ProgramSuffixes.Split(';').Any(o => file.EndsWith("." + o)))
{
Program p = CreateEntry(file);
list.Add(p);
}
}
foreach (var subDirectory in Directory.GetDirectories(path))
{
GetAppFromDirectory(subDirectory, list);
}
}
catch (UnauthorizedAccessException e)
{
Log.Warn(string.Format("Can't access to directory {0}", path));
}
catch (DirectoryNotFoundException e)
{
Log.Warn(string.Format("Directory {0} doesn't exist", path));
}
catch (PathTooLongException e)
{
Log.Warn(string.Format("File path too long: {0}", e.Message));
}
}
public override string ToString()
{
return typeof(FileSystemProgramSource).Name + ":" + this.baseDirectory;
}
}
}

View File

@@ -0,0 +1,26 @@
using System;
using Wox.Infrastructure.Storage.UserSettings;
namespace Wox.Plugin.Program.ProgramSources
{
[Serializable]
[global::System.ComponentModel.Browsable(false)]
public class UserStartMenuProgramSource : FileSystemProgramSource
{
public UserStartMenuProgramSource()
: base(Environment.GetFolderPath(Environment.SpecialFolder.Programs))
{
}
public UserStartMenuProgramSource(ProgramSource source)
: this()
{
this.BonusPoints = source.BonusPoints;
}
public override string ToString()
{
return typeof(UserStartMenuProgramSource).Name;
}
}
}

View File

@@ -0,0 +1,17 @@
<Window x:Class="Wox.Plugin.Program.ProgramSuffixes"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
Width="400"
Height="170"
WindowStartupLocation="CenterScreen"
d:DesignHeight="400" d:DesignWidth="300">
<StackPanel>
<TextBlock Margin="10 10 0 0" Foreground="Gray">Wox will only index files that end with following suffixes.</TextBlock>
<TextBlock Margin="10 0 0 0" Foreground="Gray">Each suffix should split by ;</TextBlock>
<TextBox x:Name="tbSuffixes" Margin="10"/>
<Button HorizontalAlignment="Right" Height="30" Width="80" Click="ButtonBase_OnClick" Margin="10">Update</Button>
</StackPanel>
</Window>

View File

@@ -0,0 +1,30 @@
using System.Windows;
using Wox.Infrastructure.Storage.UserSettings;
namespace Wox.Plugin.Program
{
/// <summary>
/// ProgramSuffixes.xaml 的交互逻辑
/// </summary>
public partial class ProgramSuffixes
{
public ProgramSuffixes()
{
InitializeComponent();
tbSuffixes.Text = UserSettingStorage.Instance.ProgramSuffixes;
}
private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
{
if (string.IsNullOrEmpty(tbSuffixes.Text))
{
MessageBox.Show("File suffixes can't be empty");
return;
}
UserSettingStorage.Instance.ProgramSuffixes = tbSuffixes.Text;
MessageBox.Show("Sucessfully update file suffixes");
}
}
}

View File

@@ -0,0 +1,180 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Wox.Infrastructure;
using Wox.Infrastructure.Storage.UserSettings;
using Wox.Plugin.Program.ProgramSources;
namespace Wox.Plugin.Program
{
public class Programs : ISettingProvider,IPlugin
{
private static object lockObject = new object();
private static List<Program> programs = new List<Program>();
private static List<IProgramSource> sources = new List<IProgramSource>();
private static Dictionary<string, Type> SourceTypes = new Dictionary<string, Type>() {
{"FileSystemProgramSource", typeof(FileSystemProgramSource)},
{"CommonStartMenuProgramSource", typeof(CommonStartMenuProgramSource)},
{"UserStartMenuProgramSource", typeof(UserStartMenuProgramSource)},
{"AppPathsProgramSource", typeof(AppPathsProgramSource)},
};
private PluginInitContext context;
public List<Result> Query(Query query)
{
if (query.RawQuery.Trim().Length <= 1) return new List<Result>();
var fuzzyMather = FuzzyMatcher.Create(query.RawQuery);
List<Program> returnList = programs.Where(o => MatchProgram(o, fuzzyMather)).ToList();
returnList.ForEach(ScoreFilter);
returnList = returnList.OrderByDescending(o => o.Score).ToList();
return returnList.Select(c => new Result()
{
Title = c.Title,
SubTitle = c.ExecutePath,
IcoPath = c.IcoPath,
Score = c.Score,
Action = (e) =>
{
context.API.HideApp();
context.API.ShellRun(c.ExecutePath);
return true;
},
ContextMenu = new List<Result>()
{
new Result()
{
Title = "Run As Administrator",
Action = _ =>
{
context.API.HideApp();
context.API.ShellRun(c.ExecutePath,true);
return true;
},
IcoPath = "Images/cmd.png"
}
}
}).ToList();
}
private bool MatchProgram(Program program, FuzzyMatcher matcher)
{
if ((program.Score = matcher.Evaluate(program.Title).Score) > 0) return true;
if ((program.Score = matcher.Evaluate(program.PinyinTitle).Score) > 0) return true;
if (program.AbbrTitle != null && (program.Score = matcher.Evaluate(program.AbbrTitle).Score) > 0) return true;
if (program.ExecuteName != null && (program.Score = matcher.Evaluate(program.ExecuteName).Score) > 0) return true;
return false;
}
public void Init(PluginInitContext context)
{
this.context = context;
programs = ProgramCacheStorage.Instance.Programs;
using (new Timeit("Program Index"))
{
IndexPrograms();
}
}
public static void IndexPrograms()
{
lock (lockObject)
{
List<ProgramSource> programSources = new List<ProgramSource>();
programSources.AddRange(LoadDeaultProgramSources());
if (UserSettingStorage.Instance.ProgramSources != null &&
UserSettingStorage.Instance.ProgramSources.Count(o => o.Enabled) > 0)
{
programSources.AddRange(UserSettingStorage.Instance.ProgramSources.Where(o => o.Enabled));
}
sources.Clear();
programSources.ForEach(source =>
{
Type sourceClass;
if (SourceTypes.TryGetValue(source.Type, out sourceClass))
{
ConstructorInfo constructorInfo = sourceClass.GetConstructor(new[] { typeof(ProgramSource) });
if (constructorInfo != null)
{
IProgramSource programSource =
constructorInfo.Invoke(new object[] { source }) as IProgramSource;
sources.Add(programSource);
}
}
});
var tempPrograms = new List<Program>();
foreach (var source in sources)
{
var list = source.LoadPrograms();
list.ForEach(o =>
{
o.Source = source;
});
tempPrograms.AddRange(list);
}
// filter duplicate program
programs = tempPrograms.GroupBy(x => new { x.ExecutePath, x.ExecuteName })
.Select(g => g.First()).ToList();
ProgramCacheStorage.Instance.Programs = programs;
ProgramCacheStorage.Instance.Save();
}
}
/// <summary>
/// Load program sources that wox always provide
/// </summary>
private static List<ProgramSource> LoadDeaultProgramSources()
{
var list = new List<ProgramSource>();
list.Add(new ProgramSource()
{
BonusPoints = 0,
Enabled = true,
Type = "CommonStartMenuProgramSource"
});
list.Add(new ProgramSource()
{
BonusPoints = 0,
Enabled = true,
Type = "UserStartMenuProgramSource"
});
list.Add(new ProgramSource()
{
BonusPoints = -10,
Enabled = true,
Type = "AppPathsProgramSource"
});
return list;
}
private void ScoreFilter(Program p)
{
p.Score += p.Source.BonusPoints;
if (p.Title.Contains("启动") || p.Title.ToLower().Contains("start"))
p.Score += 10;
if (p.Title.Contains("帮助") || p.Title.ToLower().Contains("help") || p.Title.Contains("文档") || p.Title.ToLower().Contains("documentation"))
p.Score -= 10;
if (p.Title.Contains("卸载") || p.Title.ToLower().Contains("uninstall"))
p.Score -= 20;
}
#region ISettingProvider Members
public System.Windows.Controls.Control CreateSettingPanel()
{
return new ProgramSetting();
}
#endregion
}
}

View File

@@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// 有关程序集的常规信息通过以下
// 特性集控制。更改这些特性值可修改
// 与程序集关联的信息。
[assembly: AssemblyTitle("Wox.Plugin.Program")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Wox.Plugin.Program")]
[assembly: AssemblyCopyright("Copyright © 2015")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// 将 ComVisible 设置为 false 使此程序集中的类型
// 对 COM 组件不可见。 如果需要从 COM 访问此程序集中的类型,
// 则将该类型上的 ComVisible 特性设置为 true。
[assembly: ComVisible(false)]
// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
[assembly: Guid("82f60d9a-9280-4b6a-8b21-f3c694cb7e1d")]
// 程序集的版本信息由下面四个值组成:
//
// 主版本
// 次版本
// 生成号
// 修订号
//
// 可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值,
// 方法是按如下所示使用“*”:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View File

@@ -0,0 +1,26 @@
using System;
using System.Windows.Data;
using System.Windows.Markup;
namespace Wox.Plugin.Program
{
public class StringEmptyConverter : MarkupExtension, IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return string.IsNullOrEmpty((string)value) ? parameter : value;
}
public object ConvertBack(
object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotSupportedException();
}
public override object ProvideValue(IServiceProvider serviceProvider)
{
return this;
}
}
}

View File

@@ -0,0 +1,124 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" 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>{FDB3555B-58EF-4AE6-B5F1-904719637AB4}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Wox.Plugin.Program</RootNamespace>
<AssemblyName>Wox.Plugin.Program</AssemblyName>
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
<RestorePackages>true</RestorePackages>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>..\..\Output\Debug\Plugins\Wox.Plugin.Program\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="log4net">
<HintPath>..\..\packages\log4net.2.0.3\lib\net35-full\log4net.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\packages\Newtonsoft.Json.6.0.7\lib\net35\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="PresentationCore" />
<Reference Include="PresentationFramework" />
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
<Reference Include="WindowsBase" />
</ItemGroup>
<ItemGroup>
<Compile Include="FileChangeWatcher.cs" />
<Compile Include="IProgramSource.cs" />
<Compile Include="Program.cs" />
<Compile Include="ProgramCacheStorage.cs" />
<Compile Include="Programs.cs" />
<Compile Include="ProgramSetting.xaml.cs">
<DependentUpon>ProgramSetting.xaml</DependentUpon>
</Compile>
<Compile Include="ProgramSources\AppPathsProgramSource.cs" />
<Compile Include="ProgramSources\CommonStartMenuProgramSource.cs" />
<Compile Include="ProgramSources\FileSystemProgramSource.cs" />
<Compile Include="ProgramSources\UserStartMenuProgramSource.cs" />
<Compile Include="ProgramSuffixes.xaml.cs">
<DependentUpon>ProgramSuffixes.xaml</DependentUpon>
</Compile>
<Compile Include="StringEmptyConverter.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
<None Include="plugin.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
<ItemGroup>
<None Include="Images\program.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<Content Include="Languages\en.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<Page Include="ProgramSetting.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="ProgramSuffixes.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Wox.Infrastructure\Wox.Infrastructure.csproj">
<Project>{4fd29318-a8ab-4d8f-aa47-60bc241b8da3}</Project>
<Name>Wox.Infrastructure</Name>
</ProjectReference>
<ProjectReference Include="..\..\Wox.Plugin\Wox.Plugin.csproj">
<Project>{8451ecdd-2ea4-4966-bb0a-7bbc40138e80}</Project>
<Name>Wox.Plugin</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>这台计算机上缺少此项目引用的 NuGet 程序包。启用“NuGet 程序包还原”可下载这些程序包。有关详细信息,请参阅 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('$(SolutionDir)\.nuget\NuGet.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\.nuget\NuGet.targets'))" />
</Target>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="log4net" version="2.0.3" targetFramework="net35" />
<package id="Newtonsoft.Json" version="6.0.7" targetFramework="net35" />
</packages>

View File

@@ -0,0 +1,12 @@
{
"ID":"791FC278BA414111B8D1886DFE447410",
"ActionKeyword":"*",
"Name":"Program",
"Description":"Provide programs search for Wox.",
"Author":"qianlifeng",
"Version":"1.0.0",
"Language":"csharp",
"Website":"http://www.getwox.com/plugin",
"ExecuteFileName":"Wox.Plugin.Program.dll",
"IcoPath":"Images\\program.png"
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 139 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 613 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// 有关程序集的常规信息通过以下
// 特性集控制。更改这些特性值可修改
// 与程序集关联的信息。
[assembly: AssemblyTitle("Wox.Plugin.Sys")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Wox.Plugin.Sys")]
[assembly: AssemblyCopyright("Copyright © 2015")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// 将 ComVisible 设置为 false 使此程序集中的类型
// 对 COM 组件不可见。 如果需要从 COM 访问此程序集中的类型,
// 则将该类型上的 ComVisible 特性设置为 true。
[assembly: ComVisible(false)]
// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
[assembly: Guid("e1eecff6-3f25-424d-9bbd-cbd7d6e1e11e")]
// 程序集的版本信息由下面四个值组成:
//
// 主版本
// 次版本
// 生成号
// 修订号
//
// 可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值,
// 方法是按如下所示使用“*”:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View File

@@ -0,0 +1,133 @@
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace Wox.Plugin.Sys
{
public class Sys : IPlugin, ISettingProvider
{
List<Result> availableResults = new List<Result>();
#region DllImport
internal const int EWX_LOGOFF = 0x00000000;
internal const int EWX_SHUTDOWN = 0x00000001;
internal const int EWX_REBOOT = 0x00000002;
internal const int EWX_FORCE = 0x00000004;
internal const int EWX_POWEROFF = 0x00000008;
internal const int EWX_FORCEIFHUNG = 0x00000010;
[DllImport("user32")]
private static extern bool ExitWindowsEx(uint uFlags, uint dwReason);
[DllImport("user32")]
private static extern void LockWorkStation();
#endregion
public System.Windows.Controls.Control CreateSettingPanel()
{
return new SysSettings(availableResults);
}
public List<Result> Query(Query query)
{
if (query.RawQuery.EndsWith(" ") || query.RawQuery.Length <= 1) return new List<Result>();
List<Result> results = new List<Result>();
foreach (Result availableResult in availableResults)
{
if (availableResult.Title.ToLower().StartsWith(query.RawQuery.ToLower()))
{
results.Add(availableResult);
}
}
return results;
}
public void Init(PluginInitContext context)
{
availableResults.AddRange(new Result[] {
new Result
{
Title = "Shutdown",
SubTitle = "Shutdown Computer",
Score = 100,
IcoPath = "Images\\exit.png",
Action = (c) =>
{
if (MessageBox.Show("Are you sure you want to shut the computer down?","Shutdown Computer?",MessageBoxButtons.YesNo,MessageBoxIcon.Warning) == DialogResult.Yes) {
Process.Start("shutdown", "/s /t 0");
}
return true;
}
},
new Result
{
Title = "Log off",
SubTitle = "Log off current user",
Score = 100,
IcoPath = "Images\\logoff.png",
Action = (c) => ExitWindowsEx(EWX_LOGOFF, 0)
},
new Result
{
Title = "Lock",
SubTitle = "Lock this computer",
Score = 100,
IcoPath = "Images\\lock.png",
Action = (c) =>
{
LockWorkStation();
return true;
}
},
new Result
{
Title = "Exit",
SubTitle = "Close this app",
Score = 110,
IcoPath = "Images\\app.png",
Action = (c) =>
{
context.API.CloseApp();
return true;
}
},
new Result
{
Title = "Restart Wox",
SubTitle = "Restart Wox",
Score = 110,
IcoPath = "Images\\restart.png",
Action = (c) =>
{
ProcessStartInfo Info = new ProcessStartInfo();
Info.Arguments = "/C ping 127.0.0.1 -n 1 && \"" + Application.ExecutablePath + "\"";
Info.WindowStyle = ProcessWindowStyle.Hidden;
Info.CreateNoWindow = true;
Info.FileName = "cmd.exe";
Process.Start(Info);
context.API.CloseApp();
return true;
}
},
new Result
{
Title = "Settings",
SubTitle = "Tweak this app",
Score = 100,
IcoPath = "Images\\app.png",
Action = (c) =>
{
context.API.OpenSettingDialog();
return true;
}
}
});
}
}
}

View File

@@ -0,0 +1,31 @@
<UserControl x:Class="Wox.Plugin.Sys.SysSettings"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid Margin="10">
<ListView x:Name="lbxCommands" Grid.Row="0">
<ListView.View>
<GridView>
<GridViewColumn Header="Command" Width="150">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Title}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Description" Width="Auto">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding SubTitle}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
</Grid>
</UserControl>

View File

@@ -0,0 +1,17 @@
using System.Collections.Generic;
using System.Windows.Controls;
namespace Wox.Plugin.Sys {
/// <summary>
/// Interaction logic for SysSettings.xaml
/// </summary>
public partial class SysSettings : UserControl {
public SysSettings(List<Result> Results) {
InitializeComponent();
foreach (var Result in Results) {
this.lbxCommands.Items.Add(Result);
}
}
}
}

View File

@@ -0,0 +1,123 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" 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>{0B9DE348-9361-4940-ADB6-F5953BFFCCEC}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Wox.Plugin.Sys</RootNamespace>
<AssemblyName>Wox.Plugin.Sys</AssemblyName>
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
<RestorePackages>true</RestorePackages>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>..\..\Output\Debug\Plugins\Wox.Plugin.Sys\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="log4net">
<HintPath>..\..\packages\log4net.2.0.3\lib\net35-full\log4net.dll</HintPath>
</Reference>
<Reference Include="PresentationCore" />
<Reference Include="PresentationFramework" />
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
<Reference Include="WindowsBase" />
</ItemGroup>
<ItemGroup>
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Sys.cs" />
<Compile Include="SysSettings.xaml.cs">
<DependentUpon>SysSettings.xaml</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Wox.Infrastructure\Wox.Infrastructure.csproj">
<Project>{4fd29318-a8ab-4d8f-aa47-60bc241b8da3}</Project>
<Name>Wox.Infrastructure</Name>
</ProjectReference>
<ProjectReference Include="..\..\Wox.Plugin\Wox.Plugin.csproj">
<Project>{8451ecdd-2ea4-4966-bb0a-7bbc40138e80}</Project>
<Name>Wox.Plugin</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Page Include="SysSettings.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
<None Include="plugin.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
<ItemGroup>
<None Include="Images\lock.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
<ItemGroup>
<None Include="Images\exit.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
<ItemGroup>
<None Include="Images\logoff.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
<ItemGroup>
<None Include="Images\close.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
<ItemGroup>
<None Include="Images\app.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
<ItemGroup>
<None Include="Images\restart.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>这台计算机上缺少此项目引用的 NuGet 程序包。启用“NuGet 程序包还原”可下载这些程序包。有关详细信息,请参阅 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('$(SolutionDir)\.nuget\NuGet.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\.nuget\NuGet.targets'))" />
</Target>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="log4net" version="2.0.3" targetFramework="net35" />
</packages>

View File

@@ -0,0 +1,12 @@
{
"ID":"CEA08895D2544B019B2E9C5009600DF4",
"ActionKeyword":"*",
"Name":"System Commands",
"Description":"Provide System related commands. e.g. shutdown,lock,setting etc.",
"Author":"qianlifeng",
"Version":"1.0.0",
"Language":"csharp",
"Website":"http://www.getwox.com/plugin",
"ExecuteFileName":"Wox.Plugin.Sys.dll",
"IcoPath":"Images\\lock.png"
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

View File

@@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// 有关程序集的常规信息通过以下
// 特性集控制。更改这些特性值可修改
// 与程序集关联的信息。
[assembly: AssemblyTitle("Wox.Plugin.Url")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Wox.Plugin.Url")]
[assembly: AssemblyCopyright("Copyright © 2015")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// 将 ComVisible 设置为 false 使此程序集中的类型
// 对 COM 组件不可见。 如果需要从 COM 访问此程序集中的类型,
// 则将该类型上的 ComVisible 特性设置为 true。
[assembly: ComVisible(false)]
// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
[assembly: Guid("ea42b60d-34ff-4656-8ee1-012afa397d3e")]
// 程序集的版本信息由下面四个值组成:
//
// 主版本
// 次版本
// 生成号
// 修订号
//
// 可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值,
// 方法是按如下所示使用“*”:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View File

@@ -0,0 +1,106 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text.RegularExpressions;
using System.Windows;
namespace Wox.Plugin.Url
{
public class UrlPlugin : IPlugin
{
//based on https://gist.github.com/dperini/729294
private const string urlPattern ="^" +
// protocol identifier
"(?:(?:https?|ftp)://|)" +
// user:pass authentication
"(?:\\S+(?::\\S*)?@)?" +
"(?:" +
// IP address exclusion
// private & local networks
"(?!(?:10|127)(?:\\.\\d{1,3}){3})" +
"(?!(?:169\\.254|192\\.168)(?:\\.\\d{1,3}){2})" +
"(?!172\\.(?:1[6-9]|2\\d|3[0-1])(?:\\.\\d{1,3}){2})" +
// IP address dotted notation octets
// excludes loopback network 0.0.0.0
// excludes reserved space >= 224.0.0.0
// excludes network & broacast addresses
// (first & last IP address of each class)
"(?:[1-9]\\d?|1\\d\\d|2[01]\\d|22[0-3])" +
"(?:\\.(?:1?\\d{1,2}|2[0-4]\\d|25[0-5])){2}" +
"(?:\\.(?:[1-9]\\d?|1\\d\\d|2[0-4]\\d|25[0-4]))" +
"|" +
// host name
"(?:(?:[a-z\\u00a1-\\uffff0-9]-*)*[a-z\\u00a1-\\uffff0-9]+)" +
// domain name
"(?:\\.(?:[a-z\\u00a1-\\uffff0-9]-*)*[a-z\\u00a1-\\uffff0-9]+)*" +
// TLD identifier
"(?:\\.(?:[a-z\\u00a1-\\uffff]{2,}))" +
")" +
// port number
"(?::\\d{2,5})?" +
// resource path
"(?:/\\S*)?" +
"$";
Regex reg = new Regex(urlPattern, RegexOptions.Compiled | RegexOptions.IgnoreCase);
public List<Result> Query(Query query)
{
if(string.IsNullOrEmpty(query.RawQuery)) return new List<Result>();
var raw = query.RawQuery;
if (IsURL(raw))
{
return new List<Result>
{
new Result
{
Title = raw,
SubTitle = "Open " + raw,
IcoPath = "Images/url.png",
Score = 8,
Action = _ =>
{
if (!raw.ToLower().StartsWith("http"))
{
raw = "http://" + raw;
}
try
{
Process.Start(raw);
return true;
}
catch(Exception ex)
{
MessageBox.Show(ex.Message, "Could not open " + raw);
return false;
}
}
}
};
}
return new List<Result>(0);
}
public bool IsURL(string raw)
{
raw = raw.ToLower();
if (reg.Match(raw).Value == raw) return true;
if (raw == "localhost" || raw.StartsWith("localhost:") ||
raw == "http://localhost" || raw.StartsWith("http://localhost:") ||
raw == "https://localhost" || raw.StartsWith("https://localhost:")
)
{
return true;
}
return false;
}
public void Init(PluginInitContext context)
{
}
}
}

View File

@@ -0,0 +1,71 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" 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>{A3DCCBCA-ACC1-421D-B16E-210896234C26}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Wox.Plugin.Url</RootNamespace>
<AssemblyName>Wox.Plugin.Url</AssemblyName>
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>..\..\Output\Debug\Plugins\Wox.Plugin.Url\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="PresentationCore" />
<Reference Include="PresentationFramework" />
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
<Reference Include="WindowsBase" />
</ItemGroup>
<ItemGroup>
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="UrlPlugin.cs" />
</ItemGroup>
<ItemGroup>
<None Include="plugin.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Wox.Plugin\Wox.Plugin.csproj">
<Project>{8451ecdd-2ea4-4966-bb0a-7bbc40138e80}</Project>
<Name>Wox.Plugin</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="Images\url.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@@ -0,0 +1,12 @@
{
"ID":"0308FD86DE0A4DEE8D62B9B535370992",
"ActionKeyword":"*",
"Name":"URL handler",
"Description":"Provide Opening the typed URL from Wox.",
"Author":"qianlifeng",
"Version":"1.0.0",
"Language":"csharp",
"Website":"http://www.getwox.com/plugin",
"ExecuteFileName":"Wox.Plugin.Url.dll",
"IcoPath":"Images\\url.png"
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// 有关程序集的常规信息通过以下
// 特性集控制。更改这些特性值可修改
// 与程序集关联的信息。
[assembly: AssemblyTitle("Wox.Plugin.WebSearch")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Wox.Plugin.WebSearch")]
[assembly: AssemblyCopyright("Copyright © 2015")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// 将 ComVisible 设置为 false 使此程序集中的类型
// 对 COM 组件不可见。 如果需要从 COM 访问此程序集中的类型,
// 则将该类型上的 ComVisible 特性设置为 true。
[assembly: ComVisible(false)]
// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
[assembly: Guid("42c17706-44ba-4549-ab66-7bd994706cd1")]
// 程序集的版本信息由下面四个值组成:
//
// 主版本
// 次版本
// 生成号
// 修订号
//
// 可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值,
// 方法是按如下所示使用“*”:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View File

@@ -0,0 +1,43 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Wox.Infrastructure.Http;
namespace Wox.Plugin.WebSearch.SuggestionSources
{
public class Baidu : AbstractSuggestionSource
{
Regex reg = new Regex("window.baidu.sug\\((.*)\\)");
public override List<string> GetSuggestions(string query)
{
var result = HttpRequest.Get("http://suggestion.baidu.com/su?json=1&wd=" + Uri.EscapeUriString(query), "GB2312");
if (string.IsNullOrEmpty(result)) return new List<string>();
Match match = reg.Match(result);
if (match.Success)
{
JContainer json = null;
try
{
json =JsonConvert.DeserializeObject(match.Groups[1].Value) as JContainer;
}
catch{}
if (json != null)
{
var results = json["s"] as JArray;
if (results != null)
{
return results.OfType<JValue>().Select(o => o.Value).OfType<string>().ToList();
}
}
}
return new List<string>();
}
}
}

View File

@@ -0,0 +1,34 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Wox.Infrastructure.Http;
namespace Wox.Plugin.WebSearch.SuggestionSources
{
public class Google : AbstractSuggestionSource
{
public override List<string> GetSuggestions(string query)
{
var result = HttpRequest.Get("https://www.google.com/complete/search?output=chrome&q=" + Uri.EscapeUriString(query));
if (string.IsNullOrEmpty(result)) return new List<string>();
try
{
JContainer json = JsonConvert.DeserializeObject(result) as JContainer;
if (json != null)
{
var results = json[1] as JContainer;
if (results != null)
{
return results.OfType<JValue>().Select(o => o.Value).OfType<string>().ToList();
}
}
}
catch { }
return new List<string>();
}
}
}

View File

@@ -0,0 +1,14 @@
using System.Collections.Generic;
namespace Wox.Plugin.WebSearch.SuggestionSources
{
public interface ISuggestionSource
{
List<string> GetSuggestions(string query);
}
public abstract class AbstractSuggestionSource : ISuggestionSource
{
public abstract List<string> GetSuggestions(string query);
}
}

View File

@@ -0,0 +1,20 @@
namespace Wox.Plugin.WebSearch.SuggestionSources
{
public class SuggestionSourceFactory
{
public static ISuggestionSource GetSuggestionSource(string name)
{
switch (name.ToLower())
{
case "google":
return new Google();
case "baidu":
return new Baidu();
default:
return null;
}
}
}
}

View File

@@ -0,0 +1,94 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using Wox.Infrastructure.Storage.UserSettings;
using Wox.Plugin.WebSearch.SuggestionSources;
namespace Wox.Plugin.WebSearch
{
public class WebSearchPlugin : IPlugin, ISettingProvider
{
private PluginInitContext context;
public List<Result> Query(Query query)
{
List<Result> results = new List<Result>();
Infrastructure.Storage.UserSettings.WebSearch webSearch =
UserSettingStorage.Instance.WebSearches.FirstOrDefault(o => o.ActionWord == query.ActionName && o.Enabled);
if (webSearch != null)
{
string keyword = query.ActionParameters.Count > 0 ? query.GetAllRemainingParameter() : "";
string title = keyword;
string subtitle = "Search " + webSearch.Title;
if (string.IsNullOrEmpty(keyword))
{
title = subtitle;
subtitle = null;
}
context.API.PushResults(query, context.CurrentPluginMetadata, new List<Result>()
{
new Result()
{
Title = title,
SubTitle = subtitle,
Score = 6,
IcoPath = webSearch.IconPath,
Action = (c) =>
{
Process.Start(webSearch.Url.Replace("{q}", Uri.EscapeDataString(keyword)));
return true;
}
}
});
if (UserSettingStorage.Instance.EnableWebSearchSuggestion && !string.IsNullOrEmpty(keyword))
{
ISuggestionSource sugg = SuggestionSourceFactory.GetSuggestionSource(
UserSettingStorage.Instance.WebSearchSuggestionSource);
if (sugg != null)
{
var result = sugg.GetSuggestions(keyword);
if (result != null)
{
context.API.PushResults(query, context.CurrentPluginMetadata,
result.Select(o => new Result()
{
Title = o,
SubTitle = subtitle,
Score = 5,
IcoPath = webSearch.IconPath,
Action = (c) =>
{
Process.Start(webSearch.Url.Replace("{q}", Uri.EscapeDataString(o)));
return true;
}
}).ToList());
}
}
}
}
return results;
}
public void Init(PluginInitContext context)
{
this.context = context;
if (UserSettingStorage.Instance.WebSearches == null)
UserSettingStorage.Instance.WebSearches = UserSettingStorage.Instance.LoadDefaultWebSearches();
}
#region ISettingProvider Members
public System.Windows.Controls.Control CreateSettingPanel()
{
return new WebSearchesSetting();
}
#endregion
}
}

View File

@@ -0,0 +1,43 @@
<Window x:Class="Wox.Plugin.WebSearch.WebSearchSetting"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
ResizeMode="NoResize"
WindowStartupLocation="CenterScreen"
Title="WebSearchSetting" Height="350" Width="674.766">
<Grid>
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
<RowDefinition Height="60"></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="120"></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock Margin="10" FontSize="14" Grid.Row="0" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right">Title:</TextBlock>
<TextBox x:Name="tbTitle" Margin="10" Grid.Row="0" Width="400" Grid.Column="1" VerticalAlignment="Center" HorizontalAlignment="Left"></TextBox>
<TextBlock Margin="10" FontSize="14" Grid.Row="1" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right">URL:</TextBlock>
<TextBox x:Name="tbUrl" Margin="10" Grid.Row="1" Width="400" Grid.Column="1" VerticalAlignment="Center" HorizontalAlignment="Left"></TextBox>
<TextBlock Margin="10" FontSize="14" Grid.Row="2" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right">ActionWord:</TextBlock>
<TextBox x:Name="tbActionword" Margin="10" Grid.Row="2" Width="400" Grid.Column="1" VerticalAlignment="Center" HorizontalAlignment="Left"></TextBox>
<TextBlock Margin="10" FontSize="14" Grid.Row="3" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right">Enable:</TextBlock>
<CheckBox x:Name="cbEnable" IsChecked="True" Margin="10" Grid.Row="3" Grid.Column="1" VerticalAlignment="Center"></CheckBox>
<TextBlock Margin="10" FontSize="14" Grid.Row="4" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right">Icon:</TextBlock>
<StackPanel Orientation="Horizontal" Grid.Row="4" Grid.Column="1" Margin="10">
<Image x:Name="imgIcon" Width="24" Height="24" Margin="0 0 10 0" />
<Button x:Name="btnSelectIcon" Height="24" Click="BtnSelectIcon_OnClick">Select Icon</Button>
<TextBlock x:Name="tbIconPath" Visibility="Hidden"></TextBlock>
</StackPanel>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right" Grid.Row="5" Grid.Column="1">
<Button x:Name="btnCancel" Click="BtnCancel_OnClick" Margin="10 0 10 0" Width="80" Height="25">Cancel</Button>
<Button x:Name="btnAdd" Margin="10 0 10 0" Width="80" Height="25" Click="btnAdd_OnClick"><TextBlock x:Name="lblAdd">Add</TextBlock></Button>
</StackPanel>
</Grid>
</Window>

View File

@@ -0,0 +1,144 @@
using System;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Windows;
using System.Windows.Media.Imaging;
using Microsoft.Win32;
using Wox.Infrastructure.Storage.UserSettings;
namespace Wox.Plugin.WebSearch
{
public partial class WebSearchSetting : Window
{
private string defaultWebSearchImageDirectory = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Images\\websearch");
private WebSearchesSetting settingWindow;
private bool update;
private Infrastructure.Storage.UserSettings.WebSearch updateWebSearch;
public WebSearchSetting(WebSearchesSetting settingWidow)
{
this.settingWindow = settingWidow;
InitializeComponent();
}
public void UpdateItem(Infrastructure.Storage.UserSettings.WebSearch webSearch)
{
updateWebSearch = UserSettingStorage.Instance.WebSearches.FirstOrDefault(o => o == webSearch);
if (updateWebSearch == null || string.IsNullOrEmpty(updateWebSearch.Url))
{
MessageBox.Show("Invalid web search");
Close();
return;
}
update = true;
lblAdd.Text = "Update";
tbIconPath.Text = webSearch.IconPath;
ShowIcon(webSearch.IconPath);
cbEnable.IsChecked = webSearch.Enabled;
tbTitle.Text = webSearch.Title;
tbUrl.Text = webSearch.Url;
tbActionword.Text = webSearch.ActionWord;
}
private void ShowIcon(string path)
{
try
{
imgIcon.Source = new BitmapImage(new Uri(path));
}
catch (Exception)
{
}
}
private void BtnCancel_OnClick(object sender, RoutedEventArgs e)
{
Close();
}
private void btnAdd_OnClick(object sender, RoutedEventArgs e)
{
string title = tbTitle.Text;
if (string.IsNullOrEmpty(title))
{
MessageBox.Show("Please input Title field");
return;
}
string url = tbUrl.Text;
if (string.IsNullOrEmpty(url))
{
MessageBox.Show("Please input URL field");
return;
}
string action = tbActionword.Text;
if (string.IsNullOrEmpty(action))
{
MessageBox.Show("Please input ActionWord field");
return;
}
if (!update)
{
if (UserSettingStorage.Instance.WebSearches.Exists(o => o.ActionWord == action))
{
MessageBox.Show("ActionWord has existed, please input a new one.");
return;
}
UserSettingStorage.Instance.WebSearches.Add(new Infrastructure.Storage.UserSettings.WebSearch()
{
ActionWord = action,
Enabled = cbEnable.IsChecked ?? false,
IconPath = tbIconPath.Text,
Url = url,
Title = title
});
MessageBox.Show(string.Format("Add {0} web search successfully!", title));
}
else
{
if (UserSettingStorage.Instance.WebSearches.Exists(o => o.ActionWord == action && o != updateWebSearch))
{
MessageBox.Show("ActionWord has existed, please input a new one.");
return;
}
updateWebSearch.ActionWord = action;
updateWebSearch.IconPath = tbIconPath.Text;
updateWebSearch.Enabled = cbEnable.IsChecked ?? false;
updateWebSearch.Url = url;
updateWebSearch.Title= title;
MessageBox.Show(string.Format("Update {0} web search successfully!", title));
}
UserSettingStorage.Instance.Save();
settingWindow.ReloadWebSearchView();
Close();
}
private void BtnSelectIcon_OnClick(object sender, RoutedEventArgs e)
{
if(!Directory.Exists(defaultWebSearchImageDirectory))
{
defaultWebSearchImageDirectory =
Path.GetDirectoryName(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location));
}
var dlg = new OpenFileDialog
{
InitialDirectory = defaultWebSearchImageDirectory,
Filter ="Image files (*.jpg, *.jpeg, *.gif, *.png, *.bmp) |*.jpg; *.jpeg; *.gif; *.png; *.bmp"
};
bool? result = dlg.ShowDialog();
if (result == true)
{
string filename = dlg.FileName;
tbIconPath.Text = filename;
ShowIcon(filename);
}
}
}
}

View File

@@ -0,0 +1,45 @@
<UserControl x:Class="Wox.Plugin.WebSearch.WebSearchesSetting"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid Margin="10">
<Grid.RowDefinitions>
<RowDefinition Height="42"/>
<RowDefinition/>
<RowDefinition Height="50"/>
</Grid.RowDefinitions>
<StackPanel Orientation="Horizontal" Grid.Row="0">
<CheckBox x:Name="cbEnableWebSearchSuggestion" Unchecked="CbEnableWebSearchSuggestion_OnUnchecked" Checked="CbEnableWebSearchSuggestion_OnChecked" Margin="0 10 10 10">Enable search suggestions</CheckBox>
<ComboBox x:Name="comboBoxSuggestionSource" SelectionChanged="ComboBoxSuggestionSource_OnSelectionChanged" Margin="10">
</ComboBox>
</StackPanel>
<ListView x:Name="webSearchView" Grid.Row="1">
<ListView.View>
<GridView>
<GridViewColumn Header="ActionWord" Width="180">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding ActionWord}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Url" Width="500">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Url}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
<StackPanel Grid.Row="2" HorizontalAlignment="Right" Orientation="Horizontal">
<Button x:Name="btnDeleteWebSearch" Click="btnDeleteWebSearch_OnClick" Width="100" Margin="10" Content="Delete"/>
<Button x:Name="btnEditWebSearch" Click="btnEditWebSearch_OnClick" Width="100" Margin="10" Content="Edit"/>
<Button x:Name="btnAddWebSearch" Click="btnAddWebSearch_OnClick" Width="100" Margin="10" Content="Add"/>
</StackPanel>
</Grid>
</UserControl>

View File

@@ -0,0 +1,112 @@
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using Wox.Infrastructure.Storage.UserSettings;
namespace Wox.Plugin.WebSearch
{
/// <summary>
/// Interaction logic for WebSearchesSetting.xaml
/// </summary>
public partial class WebSearchesSetting : UserControl
{
public WebSearchesSetting()
{
InitializeComponent();
Loaded += Setting_Loaded;
}
private void Setting_Loaded(object sender, RoutedEventArgs e)
{
webSearchView.ItemsSource = UserSettingStorage.Instance.WebSearches;
cbEnableWebSearchSuggestion.IsChecked = UserSettingStorage.Instance.EnableWebSearchSuggestion;
comboBoxSuggestionSource.Visibility = UserSettingStorage.Instance.EnableWebSearchSuggestion
? Visibility.Visible
: Visibility.Collapsed;
List<ComboBoxItem> items = new List<ComboBoxItem>()
{
new ComboBoxItem() {Content = "Google"},
new ComboBoxItem() {Content = "Baidu"},
};
ComboBoxItem selected = items.FirstOrDefault(o => o.Content.ToString() == UserSettingStorage.Instance.WebSearchSuggestionSource);
if (selected == null)
{
selected = items[0];
}
comboBoxSuggestionSource.ItemsSource = items;
comboBoxSuggestionSource.SelectedItem = selected;
}
public void ReloadWebSearchView()
{
webSearchView.Items.Refresh();
}
private void btnAddWebSearch_OnClick(object sender, RoutedEventArgs e)
{
WebSearchSetting webSearch = new WebSearchSetting(this);
webSearch.ShowDialog();
}
private void btnDeleteWebSearch_OnClick(object sender, RoutedEventArgs e)
{
Infrastructure.Storage.UserSettings.WebSearch selectedWebSearch = webSearchView.SelectedItem as Infrastructure.Storage.UserSettings.WebSearch;
if (selectedWebSearch != null)
{
if (MessageBox.Show("Are your sure to delete " + selectedWebSearch.Title, "Delete WebSearch",
MessageBoxButton.YesNo) == MessageBoxResult.Yes)
{
UserSettingStorage.Instance.WebSearches.Remove(selectedWebSearch);
webSearchView.Items.Refresh();
}
}
else
{
MessageBox.Show("Please select a web search");
}
}
private void btnEditWebSearch_OnClick(object sender, RoutedEventArgs e)
{
Infrastructure.Storage.UserSettings.WebSearch selectedWebSearch = webSearchView.SelectedItem as Infrastructure.Storage.UserSettings.WebSearch;
if (selectedWebSearch != null)
{
WebSearchSetting webSearch = new WebSearchSetting(this);
webSearch.UpdateItem(selectedWebSearch);
webSearch.ShowDialog();
}
else
{
MessageBox.Show("Please select a web search");
}
}
private void CbEnableWebSearchSuggestion_OnChecked(object sender, RoutedEventArgs e)
{
comboBoxSuggestionSource.Visibility = Visibility.Visible;
UserSettingStorage.Instance.EnableWebSearchSuggestion = true;
UserSettingStorage.Instance.Save();
}
private void CbEnableWebSearchSuggestion_OnUnchecked(object sender, RoutedEventArgs e)
{
comboBoxSuggestionSource.Visibility = Visibility.Collapsed;
UserSettingStorage.Instance.EnableWebSearchSuggestion = false;
UserSettingStorage.Instance.Save();
}
private void ComboBoxSuggestionSource_OnSelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (e.AddedItems.Count > 0)
{
UserSettingStorage.Instance.WebSearchSuggestionSource =
((ComboBoxItem) e.AddedItems[0]).Content.ToString();
UserSettingStorage.Instance.Save();
}
}
}
}

View File

@@ -0,0 +1,125 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" 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>{403B57F2-1856-4FC7-8A24-36AB346B763E}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Wox.Plugin.WebSearch</RootNamespace>
<AssemblyName>Wox.Plugin.WebSearch</AssemblyName>
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
<RestorePackages>true</RestorePackages>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>..\..\Output\Debug\Plugins\Wox.Plugin.WebSearch\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="log4net">
<HintPath>..\..\packages\log4net.2.0.3\lib\net35-full\log4net.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\packages\Newtonsoft.Json.6.0.7\lib\net35\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="PresentationCore" />
<Reference Include="PresentationFramework" />
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
<Reference Include="WindowsBase" />
</ItemGroup>
<ItemGroup>
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="SuggestionSources\Baidu.cs" />
<Compile Include="SuggestionSources\Google.cs" />
<Compile Include="SuggestionSources\ISuggestionSource.cs" />
<Compile Include="SuggestionSources\SuggestionSourceFactory.cs" />
<Compile Include="WebSearchesSetting.xaml.cs">
<DependentUpon>WebSearchesSetting.xaml</DependentUpon>
</Compile>
<Compile Include="WebSearchPlugin.cs" />
<Compile Include="WebSearchSetting.xaml.cs">
<DependentUpon>WebSearchSetting.xaml</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<Page Include="WebSearchesSetting.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="WebSearchSetting.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
</ItemGroup>
<ItemGroup>
<WCFMetadata Include="Service References\" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Wox.Infrastructure\Wox.Infrastructure.csproj">
<Project>{4fd29318-a8ab-4d8f-aa47-60bc241b8da3}</Project>
<Name>Wox.Infrastructure</Name>
</ProjectReference>
<ProjectReference Include="..\..\Wox.Plugin\Wox.Plugin.csproj">
<Project>{8451ecdd-2ea4-4966-bb0a-7bbc40138e80}</Project>
<Name>Wox.Plugin</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
<None Include="plugin.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
<ItemGroup>
<None Include="Images\web_search.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
<ItemGroup>
<None Include="Images\websearch\google.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
<ItemGroup>
<None Include="Images\websearch\wiki.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>这台计算机上缺少此项目引用的 NuGet 程序包。启用“NuGet 程序包还原”可下载这些程序包。有关详细信息,请参阅 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('$(SolutionDir)\.nuget\NuGet.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\.nuget\NuGet.targets'))" />
</Target>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="log4net" version="2.0.3" targetFramework="net35" />
<package id="Newtonsoft.Json" version="6.0.7" targetFramework="net35" />
</packages>

View File

@@ -0,0 +1,12 @@
{
"ID":"565B73353DBF4806919830B9202EE3BF",
"ActionKeyword":"*",
"Name":"Web Searches",
"Description":"Provide the web search ability.",
"Author":"qianlifeng",
"Version":"1.0.0",
"Language":"csharp",
"Website":"http://www.getwox.com/plugin",
"ExecuteFileName":"Wox.Plugin.WebSearch.dll",
"IcoPath":"Images\\web_search.png"
}