mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-04-06 03:07:04 +02:00
Add 'src/modules/launcher/' from commit '28acd466b352a807910cebbc74477d3173b31511'
git-subtree-dir: src/modules/launcher git-subtree-mainline:852689b3dfgit-subtree-split:28acd466b3
This commit is contained in:
15
src/modules/launcher/Wox.Plugin/ActionContext.cs
Normal file
15
src/modules/launcher/Wox.Plugin/ActionContext.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
namespace Wox.Plugin
|
||||
{
|
||||
public class ActionContext
|
||||
{
|
||||
public SpecialKeyState SpecialKeyState { get; set; }
|
||||
}
|
||||
|
||||
public class SpecialKeyState
|
||||
{
|
||||
public bool CtrlPressed { get; set; }
|
||||
public bool ShiftPressed { get; set; }
|
||||
public bool AltPressed { get; set; }
|
||||
public bool WinPressed { get; set; }
|
||||
}
|
||||
}
|
||||
27
src/modules/launcher/Wox.Plugin/AllowedLanguage.cs
Normal file
27
src/modules/launcher/Wox.Plugin/AllowedLanguage.cs
Normal file
@@ -0,0 +1,27 @@
|
||||
namespace Wox.Plugin
|
||||
{
|
||||
public static class AllowedLanguage
|
||||
{
|
||||
public static string Python
|
||||
{
|
||||
get { return "PYTHON"; }
|
||||
}
|
||||
|
||||
public static string CSharp
|
||||
{
|
||||
get { return "CSHARP"; }
|
||||
}
|
||||
|
||||
public static string Executable
|
||||
{
|
||||
get { return "EXECUTABLE"; }
|
||||
}
|
||||
|
||||
public static bool IsAllowed(string language)
|
||||
{
|
||||
return language.ToUpper() == Python.ToUpper()
|
||||
|| language.ToUpper() == CSharp.ToUpper()
|
||||
|| language.ToUpper() == Executable.ToUpper();
|
||||
}
|
||||
}
|
||||
}
|
||||
17
src/modules/launcher/Wox.Plugin/BaseModel.cs
Normal file
17
src/modules/launcher/Wox.Plugin/BaseModel.cs
Normal file
@@ -0,0 +1,17 @@
|
||||
using System.ComponentModel;
|
||||
using System.Runtime.CompilerServices;
|
||||
using JetBrains.Annotations;
|
||||
|
||||
namespace Wox.Plugin
|
||||
{
|
||||
public class BaseModel : INotifyPropertyChanged
|
||||
{
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
[NotifyPropertyChangedInvocator]
|
||||
protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
|
||||
{
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||
}
|
||||
}
|
||||
}
|
||||
30
src/modules/launcher/Wox.Plugin/EventHandler.cs
Normal file
30
src/modules/launcher/Wox.Plugin/EventHandler.cs
Normal file
@@ -0,0 +1,30 @@
|
||||
using System.Windows;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace Wox.Plugin
|
||||
{
|
||||
public delegate void WoxKeyDownEventHandler(WoxKeyDownEventArgs e);
|
||||
public delegate void AfterWoxQueryEventHandler(WoxQueryEventArgs e);
|
||||
|
||||
public delegate void ResultItemDropEventHandler(Result result, IDataObject dropObject, DragEventArgs e);
|
||||
|
||||
/// <summary>
|
||||
/// Global keyboard events
|
||||
/// </summary>
|
||||
/// <param name="keyevent">WM_KEYDOWN = 256,WM_KEYUP = 257,WM_SYSKEYUP = 261,WM_SYSKEYDOWN = 260</param>
|
||||
/// <param name="vkcode"></param>
|
||||
/// <param name="state"></param>
|
||||
/// <returns>return true to continue handling, return false to intercept system handling</returns>
|
||||
public delegate bool WoxGlobalKeyboardEventHandler(int keyevent, int vkcode, SpecialKeyState state);
|
||||
|
||||
public class WoxKeyDownEventArgs
|
||||
{
|
||||
public string Query { get; set; }
|
||||
public KeyEventArgs keyEventArgs { get; set; }
|
||||
}
|
||||
|
||||
public class WoxQueryEventArgs
|
||||
{
|
||||
public Query Query { get; set; }
|
||||
}
|
||||
}
|
||||
53
src/modules/launcher/Wox.Plugin/Feature.cs
Normal file
53
src/modules/launcher/Wox.Plugin/Feature.cs
Normal file
@@ -0,0 +1,53 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
|
||||
namespace Wox.Plugin
|
||||
{
|
||||
public interface IFeatures { }
|
||||
|
||||
public interface IContextMenu : IFeatures
|
||||
{
|
||||
List<Result> LoadContextMenus(Result selectedResult);
|
||||
}
|
||||
|
||||
[Obsolete("If a plugin has a action keyword, then it is exclusive. This interface will be remove in v1.3.0")]
|
||||
public interface IExclusiveQuery : IFeatures
|
||||
{
|
||||
[Obsolete("If a plugin has a action keyword, then it is exclusive. This method will be remove in v1.3.0")]
|
||||
bool IsExclusiveQuery(Query query);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represent plugin query will be executed in UI thread directly. Don't do long-running operation in Query method if you implement this interface
|
||||
/// <remarks>This will improve the performance of instant search like websearch or cmd plugin</remarks>
|
||||
/// </summary>
|
||||
[Obsolete("Wox is fast enough now, executed on ui thread is no longer needed")]
|
||||
public interface IInstantQuery : IFeatures
|
||||
{
|
||||
bool IsInstantQuery(string query);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represent plugins that support internationalization
|
||||
/// </summary>
|
||||
public interface IPluginI18n : IFeatures
|
||||
{
|
||||
string GetTranslatedPluginTitle();
|
||||
|
||||
string GetTranslatedPluginDescription();
|
||||
}
|
||||
|
||||
public interface IResultUpdated : IFeatures
|
||||
{
|
||||
event ResultUpdatedEventHandler ResultsUpdated;
|
||||
}
|
||||
|
||||
public delegate void ResultUpdatedEventHandler(IResultUpdated sender, ResultUpdatedEventArgs e);
|
||||
|
||||
public class ResultUpdatedEventArgs : EventArgs
|
||||
{
|
||||
public List<Result> Results;
|
||||
public Query Query;
|
||||
}
|
||||
}
|
||||
9
src/modules/launcher/Wox.Plugin/Features/IContextMenu.cs
Normal file
9
src/modules/launcher/Wox.Plugin/Features/IContextMenu.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
using System;
|
||||
|
||||
namespace Wox.Plugin.Features
|
||||
{
|
||||
[Obsolete("Delete Wox.Plugin.Features using directive, " +
|
||||
"and use Wox.Plugin.Feature.IContextMenu instead, " +
|
||||
"this method will be removed in v1.3.0")]
|
||||
public interface IContextMenu { }
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
using System;
|
||||
|
||||
namespace Wox.Plugin.Features
|
||||
{
|
||||
[Obsolete("Delete Wox.Plugin.Features using directive, " +
|
||||
"and use Wox.Plugin.Feature.IInstantQuery instead, " +
|
||||
"this method will be removed in v1.3.0")]
|
||||
public interface IExclusiveQuery { }
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
using System;
|
||||
|
||||
namespace Wox.Plugin.Features
|
||||
{
|
||||
[Obsolete("Delete Wox.Plugin.Features using directive, " +
|
||||
"and use Wox.Plugin.Feature.IInstantQuery instead, " +
|
||||
"this method will be removed in v1.3.0")]
|
||||
public interface IInstantQuery { }
|
||||
}
|
||||
4
src/modules/launcher/Wox.Plugin/FodyWeavers.xml
Normal file
4
src/modules/launcher/Wox.Plugin/FodyWeavers.xml
Normal file
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Weavers>
|
||||
<PropertyChanged />
|
||||
</Weavers>
|
||||
10
src/modules/launcher/Wox.Plugin/IPlugin.cs
Normal file
10
src/modules/launcher/Wox.Plugin/IPlugin.cs
Normal file
@@ -0,0 +1,10 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Wox.Plugin
|
||||
{
|
||||
public interface IPlugin
|
||||
{
|
||||
List<Result> Query(Query query);
|
||||
void Init(PluginInitContext context);
|
||||
}
|
||||
}
|
||||
129
src/modules/launcher/Wox.Plugin/IPublicAPI.cs
Normal file
129
src/modules/launcher/Wox.Plugin/IPublicAPI.cs
Normal file
@@ -0,0 +1,129 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Wox.Plugin
|
||||
{
|
||||
/// <summary>
|
||||
/// Public APIs that plugin can use
|
||||
/// </summary>
|
||||
public interface IPublicAPI
|
||||
{
|
||||
/// <summary>
|
||||
/// Push result to query box
|
||||
/// </summary>
|
||||
/// <param name="query"></param>
|
||||
/// <param name="plugin"></param>
|
||||
/// <param name="results"></param>
|
||||
[Obsolete("This method will be removed in Wox 1.3")]
|
||||
void PushResults(Query query, PluginMetadata plugin, List<Result> results);
|
||||
|
||||
/// <summary>
|
||||
/// Change Wox query
|
||||
/// </summary>
|
||||
/// <param name="query">query text</param>
|
||||
/// <param name="requery">
|
||||
/// force requery By default, Wox will not fire query if your query is same with existing one.
|
||||
/// Set this to true to force Wox requerying
|
||||
/// </param>
|
||||
void ChangeQuery(string query, bool requery = false);
|
||||
|
||||
/// <summary>
|
||||
/// Just change the query text, this won't raise search
|
||||
/// </summary>
|
||||
/// <param name="query"></param>
|
||||
[Obsolete]
|
||||
void ChangeQueryText(string query, bool selectAll = false);
|
||||
|
||||
/// <summary>
|
||||
/// Close Wox
|
||||
/// </summary>
|
||||
[Obsolete]
|
||||
void CloseApp();
|
||||
|
||||
/// <summary>
|
||||
/// Restart Wox
|
||||
/// </summary>
|
||||
void RestarApp();
|
||||
|
||||
/// <summary>
|
||||
/// Hide Wox
|
||||
/// </summary>
|
||||
[Obsolete]
|
||||
void HideApp();
|
||||
|
||||
/// <summary>
|
||||
/// Show Wox
|
||||
/// </summary>
|
||||
[Obsolete]
|
||||
void ShowApp();
|
||||
|
||||
/// <summary>
|
||||
/// Save all Wox settings
|
||||
/// </summary>
|
||||
void SaveAppAllSettings();
|
||||
|
||||
/// <summary>
|
||||
/// Reloads any Plugins that have the
|
||||
/// IReloadable implemented. It refeshes
|
||||
/// Plugin's in memory data with new content
|
||||
/// added by user.
|
||||
/// </summary>
|
||||
void ReloadAllPluginData();
|
||||
|
||||
/// <summary>
|
||||
/// Check for new Wox update
|
||||
/// </summary>
|
||||
void CheckForNewUpdate();
|
||||
|
||||
/// <summary>
|
||||
/// Show message box
|
||||
/// </summary>
|
||||
/// <param name="title">Message title</param>
|
||||
/// <param name="subTitle">Message subtitle</param>
|
||||
/// <param name="iconPath">Message icon path (relative path to your plugin folder)</param>
|
||||
void ShowMsg(string title, string subTitle = "", string iconPath = "", bool useMainWindowAsOwner = true);
|
||||
|
||||
/// <summary>
|
||||
/// Open setting dialog
|
||||
/// </summary>
|
||||
void OpenSettingDialog();
|
||||
|
||||
/// <summary>
|
||||
/// Show loading animation
|
||||
/// </summary>
|
||||
[Obsolete("automatically start")]
|
||||
void StartLoadingBar();
|
||||
|
||||
/// <summary>
|
||||
/// Stop loading animation
|
||||
/// </summary>
|
||||
[Obsolete("automatically stop")]
|
||||
void StopLoadingBar();
|
||||
|
||||
/// <summary>
|
||||
/// Install Wox plugin
|
||||
/// </summary>
|
||||
/// <param name="path">Plugin path (ends with .wox)</param>
|
||||
void InstallPlugin(string path);
|
||||
|
||||
/// <summary>
|
||||
/// Get translation of current language
|
||||
/// You need to implement IPluginI18n if you want to support multiple languages for your plugin
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
/// <returns></returns>
|
||||
string GetTranslation(string key);
|
||||
|
||||
/// <summary>
|
||||
/// Get all loaded plugins
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
List<PluginPair> GetAllPlugins();
|
||||
|
||||
/// <summary>
|
||||
/// Fired after global keyboard events
|
||||
/// if you want to hook something like Ctrl+R, you should use this event
|
||||
/// </summary>
|
||||
event WoxGlobalKeyboardEventHandler GlobalKeyboardEvent;
|
||||
}
|
||||
}
|
||||
9
src/modules/launcher/Wox.Plugin/ISettingProvider.cs
Normal file
9
src/modules/launcher/Wox.Plugin/ISettingProvider.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace Wox.Plugin
|
||||
{
|
||||
public interface ISettingProvider
|
||||
{
|
||||
Control CreateSettingPanel();
|
||||
}
|
||||
}
|
||||
18
src/modules/launcher/Wox.Plugin/Interfaces/IReloadable.cs
Normal file
18
src/modules/launcher/Wox.Plugin/Interfaces/IReloadable.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
namespace Wox.Plugin
|
||||
{
|
||||
/// <summary>
|
||||
/// This interface is to indicate and allow plugins to reload their
|
||||
/// in memory data cache or other mediums when user makes a new change
|
||||
/// that is not immediately captured. For example, for BrowserBookmark and Program
|
||||
/// plugin does not automatically detect when a user added a new bookmark or program,
|
||||
/// so this interface's function is exposed to allow user manually do the reloading after
|
||||
/// those new additions.
|
||||
///
|
||||
/// The command that allows user to manual reload is exposed via Plugin.Sys, and
|
||||
/// it will call the plugins that have implemented this interface.
|
||||
/// </summary>
|
||||
public interface IReloadable
|
||||
{
|
||||
void ReloadData();
|
||||
}
|
||||
}
|
||||
14
src/modules/launcher/Wox.Plugin/PluginInitContext.cs
Normal file
14
src/modules/launcher/Wox.Plugin/PluginInitContext.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
using System;
|
||||
|
||||
namespace Wox.Plugin
|
||||
{
|
||||
public class PluginInitContext
|
||||
{
|
||||
public PluginMetadata CurrentPluginMetadata { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// Public APIs for plugin invocation
|
||||
/// </summary>
|
||||
public IPublicAPI API { get; set; }
|
||||
}
|
||||
}
|
||||
59
src/modules/launcher/Wox.Plugin/PluginMetadata.cs
Normal file
59
src/modules/launcher/Wox.Plugin/PluginMetadata.cs
Normal file
@@ -0,0 +1,59 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Wox.Plugin
|
||||
{
|
||||
[JsonObject(MemberSerialization.OptOut)]
|
||||
public class PluginMetadata : BaseModel
|
||||
{
|
||||
private string _pluginDirectory;
|
||||
public string ID { get; set; }
|
||||
public string Name { get; set; }
|
||||
public string Author { get; set; }
|
||||
public string Version { get; set; }
|
||||
public string Language { get; set; }
|
||||
public string Description { get; set; }
|
||||
public string Website { get; set; }
|
||||
public bool Disabled { get; set; }
|
||||
public string ExecuteFilePath { get; private set;}
|
||||
|
||||
public string ExecuteFileName { get; set; }
|
||||
|
||||
public string PluginDirectory
|
||||
{
|
||||
get { return _pluginDirectory; }
|
||||
internal set
|
||||
{
|
||||
_pluginDirectory = value;
|
||||
ExecuteFilePath = Path.Combine(value, ExecuteFileName);
|
||||
IcoPath = Path.Combine(value, IcoPath);
|
||||
}
|
||||
}
|
||||
|
||||
public string ActionKeyword { get; set; }
|
||||
|
||||
public List<string> ActionKeywords { get; set; }
|
||||
|
||||
public string IcoPath { get; set;}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Name;
|
||||
}
|
||||
|
||||
[Obsolete("Use IcoPath")]
|
||||
public string FullIcoPath => IcoPath;
|
||||
|
||||
/// <summary>
|
||||
/// Init time include both plugin load time and init time
|
||||
/// </summary>
|
||||
[JsonIgnore]
|
||||
public long InitTime { get; set; }
|
||||
[JsonIgnore]
|
||||
public long AvgQueryTime { get; set; }
|
||||
[JsonIgnore]
|
||||
public int QueryCount { get; set; }
|
||||
}
|
||||
}
|
||||
34
src/modules/launcher/Wox.Plugin/PluginPair.cs
Normal file
34
src/modules/launcher/Wox.Plugin/PluginPair.cs
Normal file
@@ -0,0 +1,34 @@
|
||||
namespace Wox.Plugin
|
||||
{
|
||||
public class PluginPair
|
||||
{
|
||||
public IPlugin Plugin { get; internal set; }
|
||||
public PluginMetadata Metadata { get; internal set; }
|
||||
|
||||
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Metadata.Name;
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
PluginPair r = obj as PluginPair;
|
||||
if (r != null)
|
||||
{
|
||||
return string.Equals(r.Metadata.ID, Metadata.ID);
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
var hashcode = Metadata.ID?.GetHashCode() ?? 0;
|
||||
return hashcode;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
[assembly: AssemblyTitle("Wox.Plugin")]
|
||||
[assembly: Guid("c22be00d-a6f5-4e45-8ecc-09ebf297c812")]
|
||||
[assembly: InternalsVisibleTo("Wox")]
|
||||
[assembly: InternalsVisibleTo("Wox.Core")]
|
||||
[assembly: InternalsVisibleTo("Wox.Test")]
|
||||
107
src/modules/launcher/Wox.Plugin/Query.cs
Normal file
107
src/modules/launcher/Wox.Plugin/Query.cs
Normal file
@@ -0,0 +1,107 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Wox.Plugin
|
||||
{
|
||||
public class Query
|
||||
{
|
||||
internal Query() { }
|
||||
|
||||
/// <summary>
|
||||
/// to allow unit tests for plug ins
|
||||
/// </summary>
|
||||
public Query(string rawQuery, string search, string[] terms, string actionKeyword = "")
|
||||
{
|
||||
Search = search;
|
||||
RawQuery = rawQuery;
|
||||
Terms = terms;
|
||||
ActionKeyword = actionKeyword;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Raw query, this includes action keyword if it has
|
||||
/// We didn't recommend use this property directly. You should always use Search property.
|
||||
/// </summary>
|
||||
public string RawQuery { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// Search part of a query.
|
||||
/// This will not include action keyword if exclusive plugin gets it, otherwise it should be same as RawQuery.
|
||||
/// Since we allow user to switch a exclusive plugin to generic plugin,
|
||||
/// so this property will always give you the "real" query part of the query
|
||||
/// </summary>
|
||||
public string Search { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// The raw query splited into a string array.
|
||||
/// </summary>
|
||||
public string[] Terms { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Query can be splited into multiple terms by whitespace
|
||||
/// </summary>
|
||||
public const string TermSeperater = " ";
|
||||
/// <summary>
|
||||
/// User can set multiple action keywords seperated by ';'
|
||||
/// </summary>
|
||||
public const string ActionKeywordSeperater = ";";
|
||||
|
||||
/// <summary>
|
||||
/// '*' is used for System Plugin
|
||||
/// </summary>
|
||||
public const string GlobalPluginWildcardSign = "*";
|
||||
|
||||
public string ActionKeyword { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Return first search split by space if it has
|
||||
/// </summary>
|
||||
public string FirstSearch => SplitSearch(0);
|
||||
|
||||
/// <summary>
|
||||
/// strings from second search (including) to last search
|
||||
/// </summary>
|
||||
public string SecondToEndSearch
|
||||
{
|
||||
get
|
||||
{
|
||||
var index = string.IsNullOrEmpty(ActionKeyword) ? 1 : 2;
|
||||
return string.Join(TermSeperater, Terms.Skip(index).ToArray());
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return second search split by space if it has
|
||||
/// </summary>
|
||||
public string SecondSearch => SplitSearch(1);
|
||||
|
||||
/// <summary>
|
||||
/// Return third search split by space if it has
|
||||
/// </summary>
|
||||
public string ThirdSearch => SplitSearch(2);
|
||||
|
||||
private string SplitSearch(int index)
|
||||
{
|
||||
try
|
||||
{
|
||||
return string.IsNullOrEmpty(ActionKeyword) ? Terms[index] : Terms[index + 1];
|
||||
}
|
||||
catch (IndexOutOfRangeException)
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString() => RawQuery;
|
||||
|
||||
[Obsolete("Use ActionKeyword, this property will be removed in v1.3.0")]
|
||||
public string ActionName { get; internal set; }
|
||||
|
||||
[Obsolete("Use Search instead, this property will be removed in v1.3.0")]
|
||||
public List<string> ActionParameters { get; internal set; }
|
||||
|
||||
[Obsolete("Use Search instead, this method will be removed in v1.3.0")]
|
||||
public string GetAllRemainingParameter() => Search;
|
||||
}
|
||||
}
|
||||
6
src/modules/launcher/Wox.Plugin/README.md
Normal file
6
src/modules/launcher/Wox.Plugin/README.md
Normal file
@@ -0,0 +1,6 @@
|
||||
What does Wox.Plugin do?
|
||||
====
|
||||
|
||||
* Defines base objects and interfaces for plugins
|
||||
* Plugin authors making C# plugins should reference this DLL via nuget
|
||||
* Contains base commands used by all plugins
|
||||
127
src/modules/launcher/Wox.Plugin/Result.cs
Normal file
127
src/modules/launcher/Wox.Plugin/Result.cs
Normal file
@@ -0,0 +1,127 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Windows.Media;
|
||||
|
||||
namespace Wox.Plugin
|
||||
{
|
||||
|
||||
public class Result
|
||||
{
|
||||
|
||||
private string _pluginDirectory;
|
||||
private string _icoPath;
|
||||
public string Title { get; set; }
|
||||
public string SubTitle { get; set; }
|
||||
|
||||
public string IcoPath
|
||||
{
|
||||
get { return _icoPath; }
|
||||
set
|
||||
{
|
||||
if (!string.IsNullOrEmpty(PluginDirectory) && !Path.IsPathRooted(value))
|
||||
{
|
||||
_icoPath = Path.Combine(value, IcoPath);
|
||||
}
|
||||
else
|
||||
{
|
||||
_icoPath = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public delegate ImageSource IconDelegate();
|
||||
|
||||
public IconDelegate Icon;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// return true to hide wox after select result
|
||||
/// </summary>
|
||||
public Func<ActionContext, bool> Action { get; set; }
|
||||
|
||||
public int Score { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// A list of indexes for the characters to be highlighted in Title
|
||||
/// </summary>
|
||||
public IList<int> TitleHighlightData { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// A list of indexes for the characters to be highlighted in SubTitle
|
||||
/// </summary>
|
||||
public IList<int> SubTitleHighlightData { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Only resulsts that originQuery match with curren query will be displayed in the panel
|
||||
/// </summary>
|
||||
internal Query OriginQuery { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Plugin directory
|
||||
/// </summary>
|
||||
public string PluginDirectory
|
||||
{
|
||||
get { return _pluginDirectory; }
|
||||
set
|
||||
{
|
||||
_pluginDirectory = value;
|
||||
if (!string.IsNullOrEmpty(IcoPath) && !Path.IsPathRooted(IcoPath))
|
||||
{
|
||||
IcoPath = Path.Combine(value, IcoPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
var r = obj as Result;
|
||||
|
||||
var equality = string.Equals(r?.Title, Title) &&
|
||||
string.Equals(r?.SubTitle, SubTitle) &&
|
||||
string.Equals(r?.IcoPath, IcoPath) &&
|
||||
TitleHighlightData == r.TitleHighlightData &&
|
||||
SubTitleHighlightData == r.SubTitleHighlightData;
|
||||
|
||||
return equality;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
var hashcode = (Title?.GetHashCode() ?? 0) ^
|
||||
(SubTitle?.GetHashCode() ?? 0);
|
||||
return hashcode;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Title + SubTitle;
|
||||
}
|
||||
|
||||
[Obsolete("Use IContextMenu instead")]
|
||||
/// <summary>
|
||||
/// Context menus associate with this result
|
||||
/// </summary>
|
||||
public List<Result> ContextMenu { get; set; }
|
||||
|
||||
[Obsolete("Use Object initializers instead")]
|
||||
public Result(string Title, string IcoPath, string SubTitle = null)
|
||||
{
|
||||
this.Title = Title;
|
||||
this.IcoPath = IcoPath;
|
||||
this.SubTitle = SubTitle;
|
||||
}
|
||||
|
||||
public Result() { }
|
||||
|
||||
/// <summary>
|
||||
/// Additional data associate with this result
|
||||
/// </summary>
|
||||
public object ContextData { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Plugin ID that generated this result
|
||||
/// </summary>
|
||||
public string PluginID { get; internal set; }
|
||||
}
|
||||
}
|
||||
101
src/modules/launcher/Wox.Plugin/SharedCommands/FilesFolders.cs
Normal file
101
src/modules/launcher/Wox.Plugin/SharedCommands/FilesFolders.cs
Normal file
@@ -0,0 +1,101 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Windows;
|
||||
|
||||
namespace Wox.Plugin.SharedCommands
|
||||
{
|
||||
public static class FilesFolders
|
||||
{
|
||||
public static void Copy(this string sourcePath, string targetPath)
|
||||
{
|
||||
// Get the subdirectories for the specified directory.
|
||||
DirectoryInfo dir = new DirectoryInfo(sourcePath);
|
||||
|
||||
if (!dir.Exists)
|
||||
{
|
||||
throw new DirectoryNotFoundException(
|
||||
"Source directory does not exist or could not be found: "
|
||||
+ sourcePath);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
DirectoryInfo[] dirs = dir.GetDirectories();
|
||||
// If the destination directory doesn't exist, create it.
|
||||
if (!Directory.Exists(targetPath))
|
||||
{
|
||||
Directory.CreateDirectory(targetPath);
|
||||
}
|
||||
|
||||
// Get the files in the directory and copy them to the new location.
|
||||
FileInfo[] files = dir.GetFiles();
|
||||
foreach (FileInfo file in files)
|
||||
{
|
||||
string temppath = Path.Combine(targetPath, file.Name);
|
||||
file.CopyTo(temppath, false);
|
||||
}
|
||||
|
||||
// Recursively copy subdirectories by calling itself on each subdirectory until there are no more to copy
|
||||
foreach (DirectoryInfo subdir in dirs)
|
||||
{
|
||||
string temppath = Path.Combine(targetPath, subdir.Name);
|
||||
Copy(subdir.FullName, temppath);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
#if DEBUG
|
||||
throw e;
|
||||
#else
|
||||
MessageBox.Show(string.Format("Copying path {0} has failed, it will now be deleted for consistency", targetPath));
|
||||
RemoveFolder(targetPath);
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static bool VerifyBothFolderFilesEqual(this string fromPath, string toPath)
|
||||
{
|
||||
try
|
||||
{
|
||||
var fromDir = new DirectoryInfo(fromPath);
|
||||
var toDir = new DirectoryInfo(toPath);
|
||||
|
||||
if (fromDir.GetFiles("*", SearchOption.AllDirectories).Length != toDir.GetFiles("*", SearchOption.AllDirectories).Length)
|
||||
return false;
|
||||
|
||||
if (fromDir.GetDirectories("*", SearchOption.AllDirectories).Length != toDir.GetDirectories("*", SearchOption.AllDirectories).Length)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
#if DEBUG
|
||||
throw e;
|
||||
#else
|
||||
MessageBox.Show(string.Format("Unable to verify folders and files between {0} and {1}", fromPath, toPath));
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void RemoveFolder(this string path)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (Directory.Exists(path))
|
||||
Directory.Delete(path, true);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
#if DEBUG
|
||||
throw e;
|
||||
#else
|
||||
MessageBox.Show(string.Format("Not able to delete folder {0}, please go to the location and manually delete it", path));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
58
src/modules/launcher/Wox.Plugin/SharedCommands/SearchWeb.cs
Normal file
58
src/modules/launcher/Wox.Plugin/SharedCommands/SearchWeb.cs
Normal file
@@ -0,0 +1,58 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
namespace Wox.Plugin.SharedCommands
|
||||
{
|
||||
public static class SearchWeb
|
||||
{
|
||||
/// <summary>
|
||||
/// Opens search in a new browser. If no browser path is passed in then Chrome is used.
|
||||
/// Leave browser path blank to use Chrome.
|
||||
/// </summary>
|
||||
public static void NewBrowserWindow(this string url, string browserPath)
|
||||
{
|
||||
var browserExecutableName = browserPath?
|
||||
.Split(new[] { Path.DirectorySeparatorChar }, StringSplitOptions.None)
|
||||
.Last();
|
||||
|
||||
var browser = string.IsNullOrEmpty(browserExecutableName) ? "chrome" : browserPath;
|
||||
|
||||
// Internet Explorer will open url in new browser window, and does not take the --new-window parameter
|
||||
var browserArguements = browserExecutableName == "iexplore.exe" ? url : "--new-window " + url;
|
||||
|
||||
try
|
||||
{
|
||||
Process.Start(browser, browserArguements);
|
||||
}
|
||||
catch (System.ComponentModel.Win32Exception)
|
||||
{
|
||||
Process.Start(url);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Opens search as a tab in the default browser chosen in Windows settings.
|
||||
/// </summary>
|
||||
public static void NewTabInBrowser(this string url, string browserPath)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!string.IsNullOrEmpty(browserPath))
|
||||
{
|
||||
Process.Start(browserPath, url);
|
||||
}
|
||||
else
|
||||
{
|
||||
Process.Start(url);
|
||||
}
|
||||
}
|
||||
// This error may be thrown for Process.Start(browserPath, url)
|
||||
catch (System.ComponentModel.Win32Exception)
|
||||
{
|
||||
Process.Start(url);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Wox.Plugin.SharedCommands
|
||||
{
|
||||
public static class ShellCommand
|
||||
{
|
||||
public delegate bool EnumThreadDelegate(IntPtr hwnd, IntPtr lParam);
|
||||
[DllImport("user32.dll")] static extern bool EnumThreadWindows(uint threadId, EnumThreadDelegate lpfn, IntPtr lParam);
|
||||
[DllImport("user32.dll")] static extern int GetWindowText(IntPtr hwnd, StringBuilder lpString, int nMaxCount);
|
||||
[DllImport("user32.dll")] static extern int GetWindowTextLength(IntPtr hwnd);
|
||||
|
||||
private static bool containsSecurityWindow;
|
||||
|
||||
public static Process RunAsDifferentUser(ProcessStartInfo processStartInfo)
|
||||
{
|
||||
processStartInfo.Verb = "RunAsUser";
|
||||
var process = Process.Start(processStartInfo);
|
||||
|
||||
containsSecurityWindow = false;
|
||||
while (!containsSecurityWindow) // wait for windows to bring up the "Windows Security" dialog
|
||||
{
|
||||
CheckSecurityWindow();
|
||||
Thread.Sleep(25);
|
||||
}
|
||||
while (containsSecurityWindow) // while this process contains a "Windows Security" dialog, stay open
|
||||
{
|
||||
containsSecurityWindow = false;
|
||||
CheckSecurityWindow();
|
||||
Thread.Sleep(50);
|
||||
}
|
||||
|
||||
return process;
|
||||
}
|
||||
|
||||
private static void CheckSecurityWindow()
|
||||
{
|
||||
ProcessThreadCollection ptc = Process.GetCurrentProcess().Threads;
|
||||
for (int i = 0; i < ptc.Count; i++)
|
||||
EnumThreadWindows((uint)ptc[i].Id, CheckSecurityThread, IntPtr.Zero);
|
||||
}
|
||||
|
||||
private static bool CheckSecurityThread(IntPtr hwnd, IntPtr lParam)
|
||||
{
|
||||
if (GetWindowTitle(hwnd) == "Windows Security")
|
||||
containsSecurityWindow = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
private static string GetWindowTitle(IntPtr hwnd)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder(GetWindowTextLength(hwnd) + 1);
|
||||
GetWindowText(hwnd, sb, sb.Capacity);
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
public static ProcessStartInfo SetProcessStartInfo(this string fileName, string workingDirectory = "", string arguments = "", string verb = "")
|
||||
{
|
||||
var info = new ProcessStartInfo
|
||||
{
|
||||
FileName = fileName,
|
||||
WorkingDirectory = workingDirectory,
|
||||
Arguments = arguments,
|
||||
Verb = verb
|
||||
};
|
||||
|
||||
return info;
|
||||
}
|
||||
}
|
||||
}
|
||||
110
src/modules/launcher/Wox.Plugin/Wox.Plugin.csproj
Normal file
110
src/modules/launcher/Wox.Plugin/Wox.Plugin.csproj
Normal file
@@ -0,0 +1,110 @@
|
||||
<?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>{8451ECDD-2EA4-4966-BB0A-7BBC40138E80}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>Wox.Plugin</RootNamespace>
|
||||
<AssemblyName>Wox.Plugin</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<TargetFrameworkProfile />
|
||||
<NuGetPackageImportStamp>
|
||||
</NuGetPackageImportStamp>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>..\Output\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<Prefer32Bit>false</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>..\Output\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<Prefer32Bit>false</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="PresentationCore" />
|
||||
<Reference Include="PresentationFramework" />
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Xaml" />
|
||||
<Reference Include="WindowsBase" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="..\SolutionAssemblyInfo.cs">
|
||||
<Link>Properties\SolutionAssemblyInfo.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="AllowedLanguage.cs" />
|
||||
<Compile Include="BaseModel.cs" />
|
||||
<Compile Include="EventHandler.cs" />
|
||||
<Compile Include="Feature.cs" />
|
||||
<Compile Include="Features\IContextMenu.cs" />
|
||||
<Compile Include="Features\IExclusiveQuery.cs" />
|
||||
<Compile Include="Features\IInstantQuery.cs" />
|
||||
<Compile Include="Interfaces\IReloadable.cs" />
|
||||
<Compile Include="IPlugin.cs" />
|
||||
<Compile Include="IPublicAPI.cs" />
|
||||
<Compile Include="ISettingProvider.cs" />
|
||||
<Compile Include="PluginPair.cs" />
|
||||
<Compile Include="PluginInitContext.cs" />
|
||||
<Compile Include="PluginMetadata.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Query.cs" />
|
||||
<Compile Include="Result.cs" />
|
||||
<Compile Include="ActionContext.cs" />
|
||||
<Compile Include="SharedCommands\FilesFolders.cs" />
|
||||
<Compile Include="SharedCommands\SearchWeb.cs" />
|
||||
<Compile Include="SharedCommands\ShellCommand.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="README.md" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="FodyWeavers.xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Fody">
|
||||
<Version>1.29.2</Version>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="JetBrains.Annotations">
|
||||
<Version>10.3.0</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Mono.Cecil">
|
||||
<Version>0.9.6.1</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Newtonsoft.Json">
|
||||
<Version>9.0.1</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="PropertyChanged.Fody">
|
||||
<Version>1.51.0</Version>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="System.Runtime">
|
||||
<Version>4.0.0</Version>
|
||||
</PackageReference>
|
||||
</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>
|
||||
Reference in New Issue
Block a user