Merge PowerLauncher branch (#2345)

* minor modifications in README

* Added launcher project and changed references to common

* Added the code to launch another process

* added shellapi header

* Added launcher to runner

* added functions to remove the abstract class error

* added the wox launcher dll

* Readded the reference to common

* modified the additional include directories for the release version

* changed the name to be displayed from Wox.Launcher to Launcher

* Localized the strings of Launcher

* Added a SearchResult Helper class

* Created a helper class to use indexer and return search results

* Added the main and settings file which declare most of the plugin interfaces

* Added references and renamed a class

* Added the images folder which contains the windows indexer icon

* Added the image

* Added the plugin.json file

* Minor changes in project files

* Added plugin.json to the project

* Modified the output paths to create the dll for the plugin in the correct location

* Refactored the code to make it unit testable

* Made the code unit testable and added unit tests for the indexer plugin

* Removed commented out code

* Code to terminate wox when we exit PowerToys

* Copy from Jeremy's fork PR

* Removed unnecessary plugins from source tree

* add missing files

* Fix postbuild event

* Added x64 for all Wox project - Debug mode

* Removed the AnyCPU config - Debug

* Added the build paths for release x64 (removed AnyCPU)

* Set warning level to 4 : Release

* Set warning level 4 : Debug

* set optimize code to false

* Removed notify icon component

* Removed setting UI XAML file and references

* Readded necessary callback functions

* Removed python path and python plugin functions

* Removed UI related to python path and the bindings related to that

* Remove python bindings

* Removed the localized string translations from pythonDirectory and SelectPythonDirectory

* Manually resolving conflicts

* Fix Wox build in project settings

* deleting unused project files

* Undo change internal

* Fix internal variable

* All wox exceptions in debug are getting rethrown, and thus causing the app to crash.  This change removes the debug specific code and allows exceptions to be handled the same was as release.

* Ported Indexer plugin to .net core 3

* Added the test project back

* Removed the .net framework indexer folder

* readding the plugin.json file

* Changed the anyCPU config to x64 for windows indexer plugin

* Adding dependency to wox project on the runner.  This should make sure the wox.exe can be build and launched by the runner so wox can run as a background process.

* Updating build dependencies.  Wox.Launcher wasn't built as part of the F5 Experience, and nor were the plugins

* removing locks from the ResultListBox code behind file.  All callbacks are accessed from the Main/UI thread.

* Remove anyCPU config and changed it to x64

* Removed anycpu of test proj

* Adding dependency

* Renaming executable to PowerLauncher.  Replaceing icons with placeholder. Deleting Docs folder

* Renaming AppData directory from 'Wox' to 'PowerLauncher'.  Also replacing issue link with powertoys github.

* adding support for xaml islands

* Added Neils UI code

* Replace Niels Code references

* Added assets and behaviours

* Add missing reference

* Add main view model binding

* Using proper executable name when closing 'PowerLauncher' process

* changed x:bind to Binding to avoid reference

* Updated bindings for launcher

* Added binding on searchBox

* Adding Directory.Build.targets file to kill the PowerLauncher pprocess on Build or Clean operations of all 'Launcher' projects.

* Fixed exception preventing result display

* Fixed issue with wpf marshalling events to a non UI thread

* Optimised result binding by inserting search result from multiple plugin in parallel

* copy resource files to output folder

* Corrected the output path for the indexer plugin

* windows indexer plugin is working

* Remove console print statement

* Added callback function for mouse click on search result

* Working App execution

* Cherry picked pinyin performance changes from jjw24's master branch

* change nuget package to msft for winrt compat

* Working up/down arrow key

* updating references and removing a few that seem uneeded for how stuff is referenced

* adding two back in

* Removing Squirrel dll.  unsure on updating so i kept that logic in

* Updated functionality on suggestion chosen in autosuggestbox

* Added the <useWPF> tag to remove the warning

* Removed an unnecessary <useWindowsForms> tag

* Removed the item group for properties from calculator plugin

* Removed the item group for properties from folder plugin

* Removed the item group for properties from indexer, program and shell plugin

* Removed itemgrp from wox.core and wox.test csprojs

* Removed the unnecessary wox files to clean up codebase

* Renamed Wox.Plugin.Indexer to Microsoft.Plugin.Indexer

* Renamed Wox.Launcher to Microsoft.Launcher

* To avoid DBNull to String typecast exception

* Added query submitted event to handle default action on clicking a list view item

* Merge pull request #42 from microsoft/AddPinyinPerformance

Cherry picked pinyin performance changes from jjw24's master branch

(cherry picked from commit b9e437c6cd)

* Rectyfying title display

* Title display working correctly

* Removed .yml files

* adding checks

* Making wox.csproj build wox assembly instead of powerlauncher

* Removing update logic from PowerLuanch App.xaml.cs as was done in Wox project.

* Making Query internals visible to wox.

* Update Powerlauncher nuget packages to be same version as wox.csproj.   Note:  FoxyWeavers.xsd change is automatically done as part of nuget package update.

* Updating build dependencies to so that wox.launcher depends on powerlauncher.csproj not wox.csproj

* Removing 'Wox' branded logos from powerlauncher.csproj as was done previously or wox.csproj

* Downgraded the library to the latest stable version

* single thread execution of the indexer plugin and InvalidOperationException due to connection being closed on ExecuteReader, handled separately

* Modified the test, the connection need not be null after being disposed. There is no direct way of checking if an object has been disposed other than to throw the InvalidOperationException

* Removing x86,ARM,ARM64, build configurations, as these were added accidentally when adding xaml island support.

* Removed STAThread

* Modified the output folder produced

* Renamed the dll produced

* Added dependency on PowerLauncher to the Microsoft.Launcher project

* modified the name of the dll in the indexer plugin

* Ignoring 128 errors from taskkill, as this means the process isn't running. We don't want htis to show up in the warnings list on build

* Added fix for closing wox on pressing escape and app execution (#75)

* adding useWPF to get rid of warning

* Launcher resize issue on selecting search result (#77)

* Added fix for closing wox on pressing escape and app execution

* Added fix to prevent autosuggestbox resize

* Fixing xaml catastrophic failure, based on Miguels suggestion here: https://github.com/windows-toolkit/Microsoft.Toolkit.Win32/issues/210

* suggested fix

* removing unused mutex string

* Searches for keyword only in title and not content to improve the quality of results

* Display the title from System.Title directly instead of extracting it from the path

* Removed additional README instructions before moving to the powerToys repo

* Fix Query builder test (#86)

* Revert base viewModel class to fix tests.

* Removing unused post build and deploy scripts.

* tweaked url

* Update plugin.json

* Update README.md

* removed unused dep (#2080)

* removed reference to everything (#2133)

* SearchIndexer - Modifying QueryContentProperties and QuerySelectColumns to use System.FileName

* Search result thumbnail for PowerLauncher (#2124)

* Replace WPF Imaging library with UWP

* Removed UWP and WPF namespace conflicting files from Wox

* Removed Image hashing as it wasn't used anywhere

* Updated formatting

* Set MainViewModel visibility to hidden on startup

* Enable CI build on PowerLauncher Branch (#2181)

* Enable CI build on PowerLauncher Branch

* Updated Nuget restore to latest and added AssetTargetFallback property

* tweak text (#2177)

* [Window Walker] Migrate to Launcher (#2093)

* Copy the existing calc. plugin foldeR

* Blindly rename a bunch of things to Window Walker

* Update the solution to reference the new plugin

* Get basic Yo returned

* Remove all the languages except english

* Lower quality of icon as well as test showing it

* Add the core non-ui parts to the plugin

* Delete calculator png

* Get it to compile

* Added the actual code which apparently doesn't work

* Finally start showing results

* Fix up strings

* Switch working

* Remove unused classes

* Remove unneeded async

* Added MSI support for Launcher (#2242)

* Fixed typo in output folder of calculator plugin

* Calculator plugin works

* Modified the name of the image to remove space as space is assumed to be a separator in wcx file

* Fixed typo in calculator dll

* Fixed typo in calculator plugin

* Shell, Program, Folde and indexer plugin working

* Added the ww plugin

* Fixed typos in the calculator plugin

* Delete file that was added unintentionally

* revert calculator rename changes

* Reverted other files changed

* Reverted renaming of file with space

* Pull changes from master to dev/powerLauncher (#2255)

* Dpi unaware placement bug (#2121)

Fix for bug when placing dpi unaware window such as Notepad++ in left of right part of monitor. In that application gap of about 7px was left or right.
This fixes only single-monitor scenario
It skips correction for dpi unaware window that leaves a gap

* Move markdown parsing logic outside control thread (#2099)

* Move markdown parsing logic outside control thread

* Update MarkdownPreviewHandlerControl.cs

* Remove trailing whitespace.

That'll teach me for trying to make an edit from the GitHub page.

* Migrate power rename MRU lists from registry to JSON (#2090)

* Handle most recently used search/replace strings within settings.

* Check for last modified time of json file and reload it if needed.

* Handle changes in MRU search / replace lists size.

* Improve handling of changes in MRU list size.

* Don't check for last modified time in every getter method. Load only when starting application.

* Add const identifier to getter methods.

* Address PR comments: Add const to reg and json file paths and set them in constructor initializer. Check pushIdx validity. Move implementation to cpp of PowerRenameUI constructor.

* Add error checking when getting values from registry.

* Implementing changes suggested in #1992 (#2116)

* Implementing changes suggested in #1992

* Update Product.wxs

Co-authored-by: Ebenezer Ewumi <ebenezer.ewumi@wsu.edu>

* Fix for issue #1532 - [PowerToys tray icon] Show version on tooltip (#2117)

* Fix for issue #1532

[PowerToys] Show version on tooltip

* Update src/runner/tray_icon.cpp

Co-Authored-By: Andrey Nekrasov <yuyoyuppe@users.noreply.github.com>

Co-authored-by: Andrey Nekrasov <yuyoyuppe@users.noreply.github.com>

* FZ editor: Splitted zones positioning (#2158)

* Added a mutex to ZoneWindow, ensured no data races occur (#2154)

* Added a mutex to ZoneWindow, ensured no data races occur

* Protected draggedWindow* members with a mutex

* Ensured that critical reads happen in a single transaction

* Dpi unaware placement bug - multimontior with same DPI settings fix (#2156)

* Dpi unaware placement bug - multimontior with same DPI settings fix

* Using different enumerating method

* Changed AllMonitorHaveSameDpiScaling method

* Removed accidental file

* small rename

* Changed some methods to CamelCase

* Review comments fixes

Co-authored-by: PrzemyslawTusinski <61138537+PrzemyslawTusinski@users.noreply.github.com>
Co-authored-by: Ben Randall <veleek@gmail.com>
Co-authored-by: vldmr11080 <57061786+vldmr11080@users.noreply.github.com>
Co-authored-by: eduardodextil <55205162+eduardodextil@users.noreply.github.com>
Co-authored-by: Ebenezer Ewumi <ebenezer.ewumi@wsu.edu>
Co-authored-by: Nghia M. Luong <32159519+sqrlmn@users.noreply.github.com>
Co-authored-by: Andrey Nekrasov <yuyoyuppe@users.noreply.github.com>
Co-authored-by: Seraphima Zykova <zykovas91@gmail.com>
Co-authored-by: Ivan Stošić <ivan100sic@gmail.com>

* Somil55/merge custom ui into launcher (#2271)

* Remove Autosuggest box (#2192)

* Update Settings.Designer.cs

* Revert "Update Settings.Designer.cs"

This reverts commit a1bc0dda56.

* Updated LauncherControl XAML to add textbox and listview

* List View displayed

* Hooking up execution on the selected index, removing two way binding on selection, and experimenting with popup that doesn't work

* Updated MainViewModel to Remove context menu and history

* Added Resultist XAML Island project

* Updated SelectedItem and SelectedList Binding.
Issues :  List box doesn't open when query is written for first time but opens in subsequent queries.

* 1. Mouse Click working
2. List View is can't be focused
3. Fixed width of Launcher

* Removed two way QueryText box binding

* Removed SelectedItem two way binding and replaced with a callback

* [Cleaning] Remove redundant UWP project

* [Cleaning] Updated files to keep only atomic changes against dev/powerLauncher

* Thmbnail fixed for NEW UI

* Removed PreviewMouseDown function required by older WOX code

Co-authored-by: ryanbodrug-microsoft <56318517+ryanbodrug-microsoft@users.noreply.github.com>

* Added the auto-complete feature

* Removing ContextMenuPluginInfo, and ContextMenuTopMost as these commands are not used int the new design.

* Fixed merge conflicts

* Set only when index is 0

* One way binding

* Removed unnecessary binding

* Deleting unused (commented out code) that was legacy from wox project.

* Binding Buttons to appropriate context menu commands.
1. Buttons are dynamically loaded in a listview based on the actions supported be each plugin.

This change also deletes unused commands.

Note:  Most button events don't seem to be getting routed to the Selected Item.  Currently using 'PointerEntered' to validate the behavior.  The actions should be trigged by the button command property in the future.

* manually handling tab in mainwindow

* Loading context buttons on Selecting a suggestion list item

* Allowing hover event to load content menu items and display them as well.

* Adding context buttons to Indexer plugin.  This allows for the following:
1. [Files] Open Containing folder
2. [Folders/Files] Copy Path

* Remove White background of list (#2218)

* Remove white background of list

* Removed comments

* Changed to ContainerContentChanging event

* add const variables instead of numbers

* Added comment before the updatelistSize function

* Search box UI (#2224)

* Added backdrop and rounded corner

* Fix for two alt+space press to bring searchbox issue

* Fixed merge conflict

* Clean Mainwindow.xaml code

* Fix for textbox focus on first visible

* Allowing users to tab between the context buttons for the selected resut.  Also allowing users to press 'enter' to action on the selected items.

* Renaming SelectedIndex to ContextMenuSelectedIndex

* Enabling key accelerators on context buttons.
1. Add new object ContextMenuResult instead instead of reusing Result for both query results and context menu results.
2. Binding KeyboardAccelerator keys to contextmenuitemviewmodel
3. Enabling and disabling contextmenu items when selecting or deselecting each row.  Because we are manually maintaining selectionwe can't use ScopeOwners as the textbox is really the only item ever in focus.

* Launching explorer instead of the UWP application when selecting 'open file location'.

* Added fix for border showing up when result count is zero

* Updated fix for border on no result

* Adding visibility  after clearing result in MainViewmodel

* Launcher Light/Dark mode (#2235)

* Fixed issue with list view background not updating with Windows theme change

* Added theme change for WPF

* updated ShadowDepth for dropshadow

* Updated border thicknes of searchbox and listview

* Diff issue with ResultList.xaml

* Removed change in result delay

* Added code to pull colors from UWP

* Updated border resource to use system based SystemControlHighlightAccentBrush

* Updated corner radius in dark mode

* Updated Launcher description text

Co-authored-by: ryanbodrug-microsoft <56318517+ryanbodrug-microsoft@users.noreply.github.com>
Co-authored-by: Alekhya Reddy <reddykalekhya@gmail.com>

* Changed to SystemChromeLow from Accent brush (#2272)

* Removed ListView animations

* Positioning ContextButtons and adding background.

* Disabling scrollbars for gridview items.

* Removed folder plugin

* removed deployment for uwp apps (#2298)

* Simulating Win+backspace key press, instead of Win+Control as it was launching WW (#2250)

* text is selected whenever launcher gets hidden and is then set to visible (#2315)

* Update nuget packages across solution to latest (#2334)

* simplifying the xaml and making things tighter (#2327)

* Setting runcommand as the default execution method, and turning off run as admin by default.

* Opening explorer if the user has types a file path.

* Enable PowerLauncher toggle

* Launcher MSI - Added a required dll and removed folder plugin (#2355)

* Modified the product.wxs file

* Added the x64 config

* Modify scoring algorithm for fuzzy search (#2361)

* Modify scoring

* modified to if else

* Fixes race conditions with PointerEnter/Exit events conflicting with Selection and unselection.   This change provides better encapsulation of the logic to enable a selected item for accelerator (hotkey) events, and allow mouse input on results where the pointer is over.

* Fixes an issue where PointerExit would hide the selected context buttons.

* Result List - Bad rebase overwrote margin and translation fields.

* Fixed process executing on clicking enter if no text in search box

* Codeflow cleanup when selectedItem is not null

* adjusting how programs are displayed. (#2369)

* Removing description from title

* adjusting subtitle

* removing accidently paste

* removing desc for uwp apps

* Revert "Removed folder plugin"

This reverts commit 064d638588.

We will use the folder plugin to better mimic the way the start menu and run prompt deal with directories

* Updating JetBrains.Annotations to 2020.1.0 to be consistent with other projects.

* Replacing submenu text with full path as 'Ctrl-Enter' doesn't do anything.  Also reducing the String of CreateOpenCurrentResult to fit in one line.

* - Making Open Directory subtitle fixed, and the title as the current directory.

* Adding back binding to QueryText and updating the cursor position similar to how wox originally did it.

* Add the folder plugin wxs back in (#2374)

* Deduping results for program plugin (#2375)

* Removing description from title

* adjusting subtitle

* removing accidently paste

* removing desc for uwp apps

* Getting dups removed from list if LNK exists

* adjusting subtitle

* removing accidently paste

* Getting dups removed from list if LNK exists

* changed to normal forloop

* Removing WinR (#2381)

* Updated program execution to call action on background thread. (#2370)

* PowerLauncher Settings integration

* Added cold start fix (#2385)

* - Fixes cursor jumping around issue.
- Seperating the ability to set the text from initiating a query.
- Plugins have to explicitly request the query be updated.
- Updating Folder plugin to explicty update the query on folder selection.
- Removing unused changes from 'Wox' that don't compile.

* Fixing gap in logic where query was triggering when programatically setting text.

Updating the binding and settext both will trigger the TextChanged event on a seperate event dispatcher.  For this reason we dynamically detect which eventhandler is most approapriate on the textchanging event.

* Updating the QueryText to the selected item when navigating up/down with the  arrow keys.

* Removing action on folder result, and displaying folder path on selecting a folder result from the folder plugin.

* Making folder results from the search indexer plugin behave like folder results from folder plugin.

* Folder Results open the explorer window when selected.

* The Open Current Folder result shouldn't change the query text to 'Open {folder path}' when selecting the results.

* Initializing query text strings.

* Defensive check for QueryText being empty

* Adding file watchers for UWP detecting when apps are installed or deleted and reindexing the uwp apps

* Removing unused namespace.

* Looking at files and not filtering is better because the timer is more likely to reset while an install is happening, preventing uneeded indexing

* Fix project references

* Fix MaxResultsToShow

* Fix Alt + Space display

* Fix settings defaults

Co-authored-by: Alekhya Reddy Kommuru <reddykalekhya@gmail.com>
Co-authored-by: bkudiess <bakudies@microsoft.com>
Co-authored-by: Divyansh <somm14divi@gmail.com>
Co-authored-by: ryanbodrug-microsoft <56318517+ryanbodrug-microsoft@users.noreply.github.com>
Co-authored-by: Barbara Kudiess <bkudiess@me.com>
Co-authored-by: Jeremy Wu <jeremy24wu@gmail.com>
Co-authored-by: Clint Rutkas <clint@rutkas.com>
Co-authored-by: udit3333 <udit3333@gmail.com>
Co-authored-by: Betsegaw (Beta) Tadele <betsegaw.ta@gmail.com>
Co-authored-by: PrzemyslawTusinski <61138537+PrzemyslawTusinski@users.noreply.github.com>
Co-authored-by: Ben Randall <veleek@gmail.com>
Co-authored-by: vldmr11080 <57061786+vldmr11080@users.noreply.github.com>
Co-authored-by: eduardodextil <55205162+eduardodextil@users.noreply.github.com>
Co-authored-by: Ebenezer Ewumi <ebenezer.ewumi@wsu.edu>
Co-authored-by: Nghia M. Luong <32159519+sqrlmn@users.noreply.github.com>
Co-authored-by: Andrey Nekrasov <yuyoyuppe@users.noreply.github.com>
Co-authored-by: Seraphima Zykova <zykovas91@gmail.com>
Co-authored-by: Ivan Stošić <ivan100sic@gmail.com>
This commit is contained in:
Tomas Agustin Raies 2020-04-28 15:06:01 -07:00 committed by GitHub
parent 96b2145ba1
commit d9c4abe0df
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
491 changed files with 55627 additions and 169 deletions

View file

@ -4,6 +4,7 @@ trigger:
include:
- master
- dev/build-features
- dev/PowerLauncher
paths:
exclude:
- doc/*
@ -15,6 +16,7 @@ pr:
include:
- master
- dev/build-features
- dev/PowerLauncher
# 0.0.yyMM.dd##
# 0.0.1904.0900

View file

@ -17,8 +17,10 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "runner", "src\runner\runner
{D29DDD63-E2CF-4657-9FD5-2AEDE4257E5D} = {D29DDD63-E2CF-4657-9FD5-2AEDE4257E5D}
{5CCC8468-DEC8-4D36-99D4-5C891BEBD481} = {5CCC8468-DEC8-4D36-99D4-5C891BEBD481}
{0B593A6C-4143-4337-860E-DB5710FB87DB} = {0B593A6C-4143-4337-860E-DB5710FB87DB}
{E364F67B-BB12-4E91-B639-355866EBCD8B} = {E364F67B-BB12-4E91-B639-355866EBCD8B}
{DA425894-6E13-404F-8DCB-78584EC0557A} = {DA425894-6E13-404F-8DCB-78584EC0557A}
{2BE46397-4DFA-414C-9BD4-41E4BBF8CB34} = {2BE46397-4DFA-414C-9BD4-41E4BBF8CB34}
{A7D5099E-F0FD-4BF3-8522-5A682759F915} = {A7D5099E-F0FD-4BF3-8522-5A682759F915}
{0B43679E-EDFA-4DA0-AD30-F4628B308B1B} = {0B43679E-EDFA-4DA0-AD30-F4628B308B1B}
{B25AC7A5-FB9F-4789-B392-D5C85E948670} = {B25AC7A5-FB9F-4789-B392-D5C85E948670}
{E4E0D2AE-B17D-4BD4-8BEE-AFC8CC464C5F} = {E4E0D2AE-B17D-4BD4-8BEE-AFC8CC464C5F}
@ -29,7 +31,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "runner", "src\runner\runner
{F9C68EDF-AC74-4B77-9AF1-005D9C9F6A99} = {F9C68EDF-AC74-4B77-9AF1-005D9C9F6A99}
{07C389E3-6BC8-41CF-923E-307B1265FA2D} = {07C389E3-6BC8-41CF-923E-307B1265FA2D}
{89F34AF7-1C34-4A72-AA6E-534BCF972BD9} = {89F34AF7-1C34-4A72-AA6E-534BCF972BD9}
{A7D5099E-F0FD-4BF3-8522-5A682759F915} = {A7D5099E-F0FD-4BF3-8522-5A682759F915}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "common", "src\common\common.vcxproj", "{74485049-C722-400F-ABE5-86AC52D929B3}"
@ -164,6 +165,50 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "keyboardmanager", "keyboard
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "KeyboardManagerCommon", "src\modules\keyboardmanager\common\KeyboardManagerCommon.vcxproj", "{8AFFA899-0B73-49EC-8C50-0FADDA57B2FC}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "launcher", "launcher", "{C140A3EF-6DBF-4084-9D4C-4EB5A99FEE68}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Wox", "src\modules\launcher\Wox\Wox.csproj", "{DB90F671-D861-46BB-93A3-F1304F5BA1C5}"
ProjectSection(ProjectDependencies) = postProject
{FDB3555B-58EF-4AE6-B5F1-904719637AB4} = {FDB3555B-58EF-4AE6-B5F1-904719637AB4}
{59BD9891-3837-438A-958D-ADC7F91F6F7E} = {59BD9891-3837-438A-958D-ADC7F91F6F7E}
{C21BFF9C-2C99-4B5F-B7C9-A5E6DDDB37B0} = {C21BFF9C-2C99-4B5F-B7C9-A5E6DDDB37B0}
{787B8AA6-CA93-4C84-96FE-DF31110AD1C4} = {787B8AA6-CA93-4C84-96FE-DF31110AD1C4}
{F8B870EB-D5F5-45BA-9CF7-A5C459818820} = {F8B870EB-D5F5-45BA-9CF7-A5C459818820}
{74F1B9ED-F59C-4FE7-B473-7B453E30837E} = {74F1B9ED-F59C-4FE7-B473-7B453E30837E}
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Wox.Core", "src\modules\launcher\Wox.Core\Wox.Core.csproj", "{B749F0DB-8E75-47DB-9E5E-265D16D0C0D2}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Wox.Infrastructure", "src\modules\launcher\Wox.Infrastructure\Wox.Infrastructure.csproj", "{4FD29318-A8AB-4D8F-AA47-60BC241B8DA3}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Wox.Plugin", "src\modules\launcher\Wox.Plugin\Wox.Plugin.csproj", "{8451ECDD-2EA4-4966-BB0A-7BBC40138E80}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Wox.Test", "src\modules\launcher\Wox.Test\Wox.Test.csproj", "{FF742965-9A80-41A5-B042-D6C7D3A21708}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Plugins", "Plugins", "{4AFC9975-2456-4C70-94A4-84073C1CED93}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Wox.Plugin.Calculator", "src\modules\launcher\Plugins\Wox.Plugin.Calculator\Wox.Plugin.Calculator.csproj", "{59BD9891-3837-438A-958D-ADC7F91F6F7E}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Wox.Plugin.WindowWalker", "src\modules\launcher\Plugins\Wox.Plugin.WindowWalker\Wox.Plugin.WindowWalker.csproj", "{74F1B9ED-F59C-4FE7-B473-7B453E30837E}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Wox.Plugin.Program", "src\modules\launcher\Plugins\Wox.Plugin.Program\Wox.Plugin.Program.csproj", "{FDB3555B-58EF-4AE6-B5F1-904719637AB4}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Wox.Plugin.Shell", "src\modules\launcher\Plugins\Wox.Plugin.Shell\Wox.Plugin.Shell.csproj", "{C21BFF9C-2C99-4B5F-B7C9-A5E6DDDB37B0}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Plugin.Indexer", "src\modules\launcher\Plugins\Microsoft.Plugin.Indexer\Microsoft.Plugin.Indexer.csproj", "{F8B870EB-D5F5-45BA-9CF7-A5C459818820}"
ProjectSection(ProjectDependencies) = postProject
{8451ECDD-2EA4-4966-BB0A-7BBC40138E80} = {8451ECDD-2EA4-4966-BB0A-7BBC40138E80}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Microsoft.Launcher", "src\modules\launcher\Microsoft.Launcher\Microsoft.Launcher.vcxproj", "{E364F67B-BB12-4E91-B639-355866EBCD8B}"
ProjectSection(ProjectDependencies) = postProject
{F97E5003-F263-4D4A-A964-0F1F3C82DEF2} = {F97E5003-F263-4D4A-A964-0F1F3C82DEF2}
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PowerLauncher", "src\modules\launcher\PowerLauncher\PowerLauncher.csproj", "{F97E5003-F263-4D4A-A964-0F1F3C82DEF2}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PowerLauncher.UI", "src\modules\launcher\PowerLauncher.UI\PowerLauncher.UI.csproj", "{4A3DE70C-684C-410D-B851-C23B6DAEDF16}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{E775CC2C-24CB-48D6-9C3A-BE4CCE0DB17A}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "win-app-driver", "src\tests\win-app-driver\win-app-driver.csproj", "{880ED251-9E16-4713-9A70-D35FE0C01669}"
@ -208,192 +253,654 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "common-md-flag", "src\commo
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "interop-tests", "src\common\interop-tests\interop-tests.csproj", "{437AD818-3F1F-4CA5-A79B-25233A157026}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Wox.Plugin.Folder", "src\modules\launcher\Plugins\Wox.Plugin.Folder\Wox.Plugin.Folder.csproj", "{787B8AA6-CA93-4C84-96FE-DF31110AD1C4}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|ARM = Debug|ARM
Debug|ARM64 = Debug|ARM64
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|ARM = Release|ARM
Release|ARM64 = Release|ARM64
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{9412D5C6-2CF2-4FC2-A601-B55508EA9B27}.Debug|ARM.ActiveCfg = Debug|x64
{9412D5C6-2CF2-4FC2-A601-B55508EA9B27}.Debug|ARM64.ActiveCfg = Debug|x64
{9412D5C6-2CF2-4FC2-A601-B55508EA9B27}.Debug|x64.ActiveCfg = Debug|x64
{9412D5C6-2CF2-4FC2-A601-B55508EA9B27}.Debug|x64.Build.0 = Debug|x64
{9412D5C6-2CF2-4FC2-A601-B55508EA9B27}.Debug|x86.ActiveCfg = Debug|x64
{9412D5C6-2CF2-4FC2-A601-B55508EA9B27}.Release|ARM.ActiveCfg = Release|x64
{9412D5C6-2CF2-4FC2-A601-B55508EA9B27}.Release|ARM64.ActiveCfg = Release|x64
{9412D5C6-2CF2-4FC2-A601-B55508EA9B27}.Release|x64.ActiveCfg = Release|x64
{9412D5C6-2CF2-4FC2-A601-B55508EA9B27}.Release|x64.Build.0 = Release|x64
{9412D5C6-2CF2-4FC2-A601-B55508EA9B27}.Release|x86.ActiveCfg = Release|x64
{74485049-C722-400F-ABE5-86AC52D929B3}.Debug|ARM.ActiveCfg = Debug|x64
{74485049-C722-400F-ABE5-86AC52D929B3}.Debug|ARM64.ActiveCfg = Debug|x64
{74485049-C722-400F-ABE5-86AC52D929B3}.Debug|x64.ActiveCfg = Debug|x64
{74485049-C722-400F-ABE5-86AC52D929B3}.Debug|x64.Build.0 = Debug|x64
{74485049-C722-400F-ABE5-86AC52D929B3}.Debug|x86.ActiveCfg = Debug|x64
{74485049-C722-400F-ABE5-86AC52D929B3}.Release|ARM.ActiveCfg = Release|x64
{74485049-C722-400F-ABE5-86AC52D929B3}.Release|ARM64.ActiveCfg = Release|x64
{74485049-C722-400F-ABE5-86AC52D929B3}.Release|x64.ActiveCfg = Release|x64
{74485049-C722-400F-ABE5-86AC52D929B3}.Release|x64.Build.0 = Release|x64
{74485049-C722-400F-ABE5-86AC52D929B3}.Release|x86.ActiveCfg = Release|x64
{A46629C4-1A6C-40FA-A8B6-10E5102BB0BA}.Debug|ARM.ActiveCfg = Debug|x64
{A46629C4-1A6C-40FA-A8B6-10E5102BB0BA}.Debug|ARM64.ActiveCfg = Debug|x64
{A46629C4-1A6C-40FA-A8B6-10E5102BB0BA}.Debug|x64.ActiveCfg = Debug|x64
{A46629C4-1A6C-40FA-A8B6-10E5102BB0BA}.Debug|x64.Build.0 = Debug|x64
{A46629C4-1A6C-40FA-A8B6-10E5102BB0BA}.Debug|x86.ActiveCfg = Debug|x64
{A46629C4-1A6C-40FA-A8B6-10E5102BB0BA}.Release|ARM.ActiveCfg = Release|x64
{A46629C4-1A6C-40FA-A8B6-10E5102BB0BA}.Release|ARM64.ActiveCfg = Release|x64
{A46629C4-1A6C-40FA-A8B6-10E5102BB0BA}.Release|x64.ActiveCfg = Release|x64
{A46629C4-1A6C-40FA-A8B6-10E5102BB0BA}.Release|x64.Build.0 = Release|x64
{A46629C4-1A6C-40FA-A8B6-10E5102BB0BA}.Release|x86.ActiveCfg = Release|x64
{44CC9375-3E6E-4D99-8913-7FB748807EBD}.Debug|ARM.ActiveCfg = Debug|x64
{44CC9375-3E6E-4D99-8913-7FB748807EBD}.Debug|ARM64.ActiveCfg = Debug|x64
{44CC9375-3E6E-4D99-8913-7FB748807EBD}.Debug|x64.ActiveCfg = Debug|x64
{44CC9375-3E6E-4D99-8913-7FB748807EBD}.Debug|x64.Build.0 = Debug|x64
{44CC9375-3E6E-4D99-8913-7FB748807EBD}.Debug|x86.ActiveCfg = Debug|x64
{44CC9375-3E6E-4D99-8913-7FB748807EBD}.Release|ARM.ActiveCfg = Release|x64
{44CC9375-3E6E-4D99-8913-7FB748807EBD}.Release|ARM64.ActiveCfg = Release|x64
{44CC9375-3E6E-4D99-8913-7FB748807EBD}.Release|x64.ActiveCfg = Release|x64
{44CC9375-3E6E-4D99-8913-7FB748807EBD}.Release|x64.Build.0 = Release|x64
{44CC9375-3E6E-4D99-8913-7FB748807EBD}.Release|x86.ActiveCfg = Release|x64
{07C389E3-6BC8-41CF-923E-307B1265FA2D}.Debug|ARM.ActiveCfg = Debug|x64
{07C389E3-6BC8-41CF-923E-307B1265FA2D}.Debug|ARM64.ActiveCfg = Debug|x64
{07C389E3-6BC8-41CF-923E-307B1265FA2D}.Debug|x64.ActiveCfg = Debug|x64
{07C389E3-6BC8-41CF-923E-307B1265FA2D}.Debug|x64.Build.0 = Debug|x64
{07C389E3-6BC8-41CF-923E-307B1265FA2D}.Debug|x86.ActiveCfg = Debug|x64
{07C389E3-6BC8-41CF-923E-307B1265FA2D}.Release|ARM.ActiveCfg = Release|x64
{07C389E3-6BC8-41CF-923E-307B1265FA2D}.Release|ARM64.ActiveCfg = Release|x64
{07C389E3-6BC8-41CF-923E-307B1265FA2D}.Release|x64.ActiveCfg = Release|x64
{07C389E3-6BC8-41CF-923E-307B1265FA2D}.Release|x64.Build.0 = Release|x64
{07C389E3-6BC8-41CF-923E-307B1265FA2D}.Release|x86.ActiveCfg = Release|x64
{F9C68EDF-AC74-4B77-9AF1-005D9C9F6A99}.Debug|ARM.ActiveCfg = Debug|x64
{F9C68EDF-AC74-4B77-9AF1-005D9C9F6A99}.Debug|ARM64.ActiveCfg = Debug|x64
{F9C68EDF-AC74-4B77-9AF1-005D9C9F6A99}.Debug|x64.ActiveCfg = Debug|x64
{F9C68EDF-AC74-4B77-9AF1-005D9C9F6A99}.Debug|x64.Build.0 = Debug|x64
{F9C68EDF-AC74-4B77-9AF1-005D9C9F6A99}.Debug|x86.ActiveCfg = Debug|x64
{F9C68EDF-AC74-4B77-9AF1-005D9C9F6A99}.Release|ARM.ActiveCfg = Release|x64
{F9C68EDF-AC74-4B77-9AF1-005D9C9F6A99}.Release|ARM64.ActiveCfg = Release|x64
{F9C68EDF-AC74-4B77-9AF1-005D9C9F6A99}.Release|x64.ActiveCfg = Release|x64
{F9C68EDF-AC74-4B77-9AF1-005D9C9F6A99}.Release|x64.Build.0 = Release|x64
{F9C68EDF-AC74-4B77-9AF1-005D9C9F6A99}.Release|x86.ActiveCfg = Release|x64
{48804216-2A0E-4168-A6D8-9CD068D14227}.Debug|ARM.ActiveCfg = Debug|x64
{48804216-2A0E-4168-A6D8-9CD068D14227}.Debug|ARM64.ActiveCfg = Debug|x64
{48804216-2A0E-4168-A6D8-9CD068D14227}.Debug|x64.ActiveCfg = Debug|x64
{48804216-2A0E-4168-A6D8-9CD068D14227}.Debug|x64.Build.0 = Debug|x64
{48804216-2A0E-4168-A6D8-9CD068D14227}.Debug|x86.ActiveCfg = Debug|x64
{48804216-2A0E-4168-A6D8-9CD068D14227}.Release|ARM.ActiveCfg = Release|x64
{48804216-2A0E-4168-A6D8-9CD068D14227}.Release|ARM64.ActiveCfg = Release|x64
{48804216-2A0E-4168-A6D8-9CD068D14227}.Release|x64.ActiveCfg = Release|x64
{48804216-2A0E-4168-A6D8-9CD068D14227}.Release|x64.Build.0 = Release|x64
{48804216-2A0E-4168-A6D8-9CD068D14227}.Release|x86.ActiveCfg = Release|x64
{9C6A7905-72D4-4BF5-B256-ABFDAEF68AE9}.Debug|ARM.ActiveCfg = Debug|x64
{9C6A7905-72D4-4BF5-B256-ABFDAEF68AE9}.Debug|ARM64.ActiveCfg = Debug|x64
{9C6A7905-72D4-4BF5-B256-ABFDAEF68AE9}.Debug|x64.ActiveCfg = Debug|x64
{9C6A7905-72D4-4BF5-B256-ABFDAEF68AE9}.Debug|x64.Build.0 = Debug|x64
{9C6A7905-72D4-4BF5-B256-ABFDAEF68AE9}.Debug|x86.ActiveCfg = Debug|x64
{9C6A7905-72D4-4BF5-B256-ABFDAEF68AE9}.Release|ARM.ActiveCfg = Release|x64
{9C6A7905-72D4-4BF5-B256-ABFDAEF68AE9}.Release|ARM64.ActiveCfg = Release|x64
{9C6A7905-72D4-4BF5-B256-ABFDAEF68AE9}.Release|x64.ActiveCfg = Release|x64
{9C6A7905-72D4-4BF5-B256-ABFDAEF68AE9}.Release|x64.Build.0 = Release|x64
{9C6A7905-72D4-4BF5-B256-ABFDAEF68AE9}.Release|x86.ActiveCfg = Release|x64
{1A066C63-64B3-45F8-92FE-664E1CCE8077}.Debug|ARM.ActiveCfg = Debug|x64
{1A066C63-64B3-45F8-92FE-664E1CCE8077}.Debug|ARM64.ActiveCfg = Debug|x64
{1A066C63-64B3-45F8-92FE-664E1CCE8077}.Debug|x64.ActiveCfg = Debug|x64
{1A066C63-64B3-45F8-92FE-664E1CCE8077}.Debug|x64.Build.0 = Debug|x64
{1A066C63-64B3-45F8-92FE-664E1CCE8077}.Debug|x86.ActiveCfg = Debug|x64
{1A066C63-64B3-45F8-92FE-664E1CCE8077}.Release|ARM.ActiveCfg = Release|x64
{1A066C63-64B3-45F8-92FE-664E1CCE8077}.Release|ARM64.ActiveCfg = Release|x64
{1A066C63-64B3-45F8-92FE-664E1CCE8077}.Release|x64.ActiveCfg = Release|x64
{1A066C63-64B3-45F8-92FE-664E1CCE8077}.Release|x64.Build.0 = Release|x64
{1A066C63-64B3-45F8-92FE-664E1CCE8077}.Release|x86.ActiveCfg = Release|x64
{5CCC8468-DEC8-4D36-99D4-5C891BEBD481}.Debug|ARM.ActiveCfg = Debug|x64
{5CCC8468-DEC8-4D36-99D4-5C891BEBD481}.Debug|ARM64.ActiveCfg = Debug|x64
{5CCC8468-DEC8-4D36-99D4-5C891BEBD481}.Debug|x64.ActiveCfg = Debug|x64
{5CCC8468-DEC8-4D36-99D4-5C891BEBD481}.Debug|x64.Build.0 = Debug|x64
{5CCC8468-DEC8-4D36-99D4-5C891BEBD481}.Debug|x86.ActiveCfg = Debug|x64
{5CCC8468-DEC8-4D36-99D4-5C891BEBD481}.Release|ARM.ActiveCfg = Release|x64
{5CCC8468-DEC8-4D36-99D4-5C891BEBD481}.Release|ARM64.ActiveCfg = Release|x64
{5CCC8468-DEC8-4D36-99D4-5C891BEBD481}.Release|x64.ActiveCfg = Release|x64
{5CCC8468-DEC8-4D36-99D4-5C891BEBD481}.Release|x64.Build.0 = Release|x64
{5CCC8468-DEC8-4D36-99D4-5C891BEBD481}.Release|x86.ActiveCfg = Release|x64
{B25AC7A5-FB9F-4789-B392-D5C85E948670}.Debug|ARM.ActiveCfg = Debug|Win32
{B25AC7A5-FB9F-4789-B392-D5C85E948670}.Debug|ARM64.ActiveCfg = Debug|Win32
{B25AC7A5-FB9F-4789-B392-D5C85E948670}.Debug|x64.ActiveCfg = Debug|x64
{B25AC7A5-FB9F-4789-B392-D5C85E948670}.Debug|x64.Build.0 = Debug|x64
{B25AC7A5-FB9F-4789-B392-D5C85E948670}.Debug|x86.ActiveCfg = Debug|Win32
{B25AC7A5-FB9F-4789-B392-D5C85E948670}.Debug|x86.Build.0 = Debug|Win32
{B25AC7A5-FB9F-4789-B392-D5C85E948670}.Release|ARM.ActiveCfg = Release|Win32
{B25AC7A5-FB9F-4789-B392-D5C85E948670}.Release|ARM64.ActiveCfg = Release|Win32
{B25AC7A5-FB9F-4789-B392-D5C85E948670}.Release|x64.ActiveCfg = Release|x64
{B25AC7A5-FB9F-4789-B392-D5C85E948670}.Release|x64.Build.0 = Release|x64
{B25AC7A5-FB9F-4789-B392-D5C85E948670}.Release|x86.ActiveCfg = Release|Win32
{B25AC7A5-FB9F-4789-B392-D5C85E948670}.Release|x86.Build.0 = Release|Win32
{51920F1F-C28C-4ADF-8660-4238766796C2}.Debug|ARM.ActiveCfg = Debug|Win32
{51920F1F-C28C-4ADF-8660-4238766796C2}.Debug|ARM64.ActiveCfg = Debug|Win32
{51920F1F-C28C-4ADF-8660-4238766796C2}.Debug|x64.ActiveCfg = Debug|x64
{51920F1F-C28C-4ADF-8660-4238766796C2}.Debug|x64.Build.0 = Debug|x64
{51920F1F-C28C-4ADF-8660-4238766796C2}.Debug|x86.ActiveCfg = Debug|Win32
{51920F1F-C28C-4ADF-8660-4238766796C2}.Debug|x86.Build.0 = Debug|Win32
{51920F1F-C28C-4ADF-8660-4238766796C2}.Release|ARM.ActiveCfg = Release|Win32
{51920F1F-C28C-4ADF-8660-4238766796C2}.Release|ARM64.ActiveCfg = Release|Win32
{51920F1F-C28C-4ADF-8660-4238766796C2}.Release|x64.ActiveCfg = Release|x64
{51920F1F-C28C-4ADF-8660-4238766796C2}.Release|x64.Build.0 = Release|x64
{51920F1F-C28C-4ADF-8660-4238766796C2}.Release|x86.ActiveCfg = Release|Win32
{51920F1F-C28C-4ADF-8660-4238766796C2}.Release|x86.Build.0 = Release|Win32
{0E072714-D127-460B-AFAD-B4C40B412798}.Debug|ARM.ActiveCfg = Debug|x64
{0E072714-D127-460B-AFAD-B4C40B412798}.Debug|ARM64.ActiveCfg = Debug|x64
{0E072714-D127-460B-AFAD-B4C40B412798}.Debug|x64.ActiveCfg = Debug|x64
{0E072714-D127-460B-AFAD-B4C40B412798}.Debug|x64.Build.0 = Debug|x64
{0E072714-D127-460B-AFAD-B4C40B412798}.Debug|x86.ActiveCfg = Debug|x64
{0E072714-D127-460B-AFAD-B4C40B412798}.Release|ARM.ActiveCfg = Release|x64
{0E072714-D127-460B-AFAD-B4C40B412798}.Release|ARM64.ActiveCfg = Release|x64
{0E072714-D127-460B-AFAD-B4C40B412798}.Release|x64.ActiveCfg = Release|x64
{0E072714-D127-460B-AFAD-B4C40B412798}.Release|x64.Build.0 = Release|x64
{0E072714-D127-460B-AFAD-B4C40B412798}.Release|x86.ActiveCfg = Release|x64
{A3935CF4-46C5-4A88-84D3-6B12E16E6BA2}.Debug|ARM.ActiveCfg = Debug|Win32
{A3935CF4-46C5-4A88-84D3-6B12E16E6BA2}.Debug|ARM64.ActiveCfg = Debug|Win32
{A3935CF4-46C5-4A88-84D3-6B12E16E6BA2}.Debug|x64.ActiveCfg = Debug|x64
{A3935CF4-46C5-4A88-84D3-6B12E16E6BA2}.Debug|x64.Build.0 = Debug|x64
{A3935CF4-46C5-4A88-84D3-6B12E16E6BA2}.Debug|x86.ActiveCfg = Debug|Win32
{A3935CF4-46C5-4A88-84D3-6B12E16E6BA2}.Debug|x86.Build.0 = Debug|Win32
{A3935CF4-46C5-4A88-84D3-6B12E16E6BA2}.Release|ARM.ActiveCfg = Release|Win32
{A3935CF4-46C5-4A88-84D3-6B12E16E6BA2}.Release|ARM64.ActiveCfg = Release|Win32
{A3935CF4-46C5-4A88-84D3-6B12E16E6BA2}.Release|x64.ActiveCfg = Release|x64
{A3935CF4-46C5-4A88-84D3-6B12E16E6BA2}.Release|x64.Build.0 = Release|x64
{A3935CF4-46C5-4A88-84D3-6B12E16E6BA2}.Release|x86.ActiveCfg = Release|Win32
{A3935CF4-46C5-4A88-84D3-6B12E16E6BA2}.Release|x86.Build.0 = Release|Win32
{2151F984-E006-4A9F-92EF-C6DDE3DC8413}.Debug|ARM.ActiveCfg = Debug|Win32
{2151F984-E006-4A9F-92EF-C6DDE3DC8413}.Debug|ARM64.ActiveCfg = Debug|Win32
{2151F984-E006-4A9F-92EF-C6DDE3DC8413}.Debug|x64.ActiveCfg = Debug|x64
{2151F984-E006-4A9F-92EF-C6DDE3DC8413}.Debug|x64.Build.0 = Debug|x64
{2151F984-E006-4A9F-92EF-C6DDE3DC8413}.Debug|x86.ActiveCfg = Debug|Win32
{2151F984-E006-4A9F-92EF-C6DDE3DC8413}.Debug|x86.Build.0 = Debug|Win32
{2151F984-E006-4A9F-92EF-C6DDE3DC8413}.Release|ARM.ActiveCfg = Release|Win32
{2151F984-E006-4A9F-92EF-C6DDE3DC8413}.Release|ARM64.ActiveCfg = Release|Win32
{2151F984-E006-4A9F-92EF-C6DDE3DC8413}.Release|x64.ActiveCfg = Release|x64
{2151F984-E006-4A9F-92EF-C6DDE3DC8413}.Release|x64.Build.0 = Release|x64
{2151F984-E006-4A9F-92EF-C6DDE3DC8413}.Release|x86.ActiveCfg = Release|Win32
{2151F984-E006-4A9F-92EF-C6DDE3DC8413}.Release|x86.Build.0 = Release|Win32
{64A80062-4D8B-4229-8A38-DFA1D7497749}.Debug|ARM.ActiveCfg = Debug|x64
{64A80062-4D8B-4229-8A38-DFA1D7497749}.Debug|ARM64.ActiveCfg = Debug|x64
{64A80062-4D8B-4229-8A38-DFA1D7497749}.Debug|x64.ActiveCfg = Debug|x64
{64A80062-4D8B-4229-8A38-DFA1D7497749}.Debug|x64.Build.0 = Debug|x64
{64A80062-4D8B-4229-8A38-DFA1D7497749}.Debug|x86.ActiveCfg = Debug|x64
{64A80062-4D8B-4229-8A38-DFA1D7497749}.Release|ARM.ActiveCfg = Release|x64
{64A80062-4D8B-4229-8A38-DFA1D7497749}.Release|ARM64.ActiveCfg = Release|x64
{64A80062-4D8B-4229-8A38-DFA1D7497749}.Release|x64.ActiveCfg = Release|x64
{64A80062-4D8B-4229-8A38-DFA1D7497749}.Release|x64.Build.0 = Release|x64
{64A80062-4D8B-4229-8A38-DFA1D7497749}.Release|x86.ActiveCfg = Release|x64
{0485F45C-EA7A-4BB5-804B-3E8D14699387}.Debug|ARM.ActiveCfg = Debug|x64
{0485F45C-EA7A-4BB5-804B-3E8D14699387}.Debug|ARM64.ActiveCfg = Debug|x64
{0485F45C-EA7A-4BB5-804B-3E8D14699387}.Debug|x64.ActiveCfg = Debug|x64
{0485F45C-EA7A-4BB5-804B-3E8D14699387}.Debug|x64.Build.0 = Debug|x64
{0485F45C-EA7A-4BB5-804B-3E8D14699387}.Debug|x86.ActiveCfg = Debug|x64
{0485F45C-EA7A-4BB5-804B-3E8D14699387}.Release|ARM.ActiveCfg = Release|x64
{0485F45C-EA7A-4BB5-804B-3E8D14699387}.Release|ARM64.ActiveCfg = Release|x64
{0485F45C-EA7A-4BB5-804B-3E8D14699387}.Release|x64.ActiveCfg = Release|x64
{0485F45C-EA7A-4BB5-804B-3E8D14699387}.Release|x64.Build.0 = Release|x64
{0485F45C-EA7A-4BB5-804B-3E8D14699387}.Release|x86.ActiveCfg = Release|x64
{0B593A6C-4143-4337-860E-DB5710FB87DB}.Debug|ARM.ActiveCfg = Debug|ARM
{0B593A6C-4143-4337-860E-DB5710FB87DB}.Debug|ARM.Build.0 = Debug|ARM
{0B593A6C-4143-4337-860E-DB5710FB87DB}.Debug|ARM64.ActiveCfg = Debug|Win32
{0B593A6C-4143-4337-860E-DB5710FB87DB}.Debug|x64.ActiveCfg = Debug|x64
{0B593A6C-4143-4337-860E-DB5710FB87DB}.Debug|x64.Build.0 = Debug|x64
{0B593A6C-4143-4337-860E-DB5710FB87DB}.Debug|x86.ActiveCfg = Debug|Win32
{0B593A6C-4143-4337-860E-DB5710FB87DB}.Debug|x86.Build.0 = Debug|Win32
{0B593A6C-4143-4337-860E-DB5710FB87DB}.Release|ARM.ActiveCfg = Release|ARM
{0B593A6C-4143-4337-860E-DB5710FB87DB}.Release|ARM.Build.0 = Release|ARM
{0B593A6C-4143-4337-860E-DB5710FB87DB}.Release|ARM64.ActiveCfg = Release|Win32
{0B593A6C-4143-4337-860E-DB5710FB87DB}.Release|x64.ActiveCfg = Release|x64
{0B593A6C-4143-4337-860E-DB5710FB87DB}.Release|x64.Build.0 = Release|x64
{0B593A6C-4143-4337-860E-DB5710FB87DB}.Release|x86.ActiveCfg = Release|Win32
{0B593A6C-4143-4337-860E-DB5710FB87DB}.Release|x86.Build.0 = Release|Win32
{031AC72E-FA28-4AB7-B690-6F7B9C28AA73}.Debug|ARM.ActiveCfg = Debug|Win32
{031AC72E-FA28-4AB7-B690-6F7B9C28AA73}.Debug|ARM64.ActiveCfg = Debug|Win32
{031AC72E-FA28-4AB7-B690-6F7B9C28AA73}.Debug|x64.ActiveCfg = Debug|x64
{031AC72E-FA28-4AB7-B690-6F7B9C28AA73}.Debug|x64.Build.0 = Debug|x64
{031AC72E-FA28-4AB7-B690-6F7B9C28AA73}.Debug|x86.ActiveCfg = Debug|Win32
{031AC72E-FA28-4AB7-B690-6F7B9C28AA73}.Debug|x86.Build.0 = Debug|Win32
{031AC72E-FA28-4AB7-B690-6F7B9C28AA73}.Release|ARM.ActiveCfg = Release|Win32
{031AC72E-FA28-4AB7-B690-6F7B9C28AA73}.Release|ARM64.ActiveCfg = Release|Win32
{031AC72E-FA28-4AB7-B690-6F7B9C28AA73}.Release|x64.ActiveCfg = Release|x64
{031AC72E-FA28-4AB7-B690-6F7B9C28AA73}.Release|x64.Build.0 = Release|x64
{031AC72E-FA28-4AB7-B690-6F7B9C28AA73}.Release|x86.ActiveCfg = Release|Win32
{031AC72E-FA28-4AB7-B690-6F7B9C28AA73}.Release|x86.Build.0 = Release|Win32
{B9BDF8BE-FED7-49B5-A7AE-DD4D1CA2D9EB}.Debug|ARM.ActiveCfg = Debug|x64
{B9BDF8BE-FED7-49B5-A7AE-DD4D1CA2D9EB}.Debug|ARM64.ActiveCfg = Debug|x64
{B9BDF8BE-FED7-49B5-A7AE-DD4D1CA2D9EB}.Debug|x64.ActiveCfg = Debug|x64
{B9BDF8BE-FED7-49B5-A7AE-DD4D1CA2D9EB}.Debug|x64.Build.0 = Debug|x64
{B9BDF8BE-FED7-49B5-A7AE-DD4D1CA2D9EB}.Debug|x86.ActiveCfg = Debug|x64
{B9BDF8BE-FED7-49B5-A7AE-DD4D1CA2D9EB}.Release|ARM.ActiveCfg = Release|x64
{B9BDF8BE-FED7-49B5-A7AE-DD4D1CA2D9EB}.Release|ARM64.ActiveCfg = Release|x64
{B9BDF8BE-FED7-49B5-A7AE-DD4D1CA2D9EB}.Release|x64.ActiveCfg = Release|x64
{B9BDF8BE-FED7-49B5-A7AE-DD4D1CA2D9EB}.Release|x64.Build.0 = Release|x64
{B9BDF8BE-FED7-49B5-A7AE-DD4D1CA2D9EB}.Release|x86.ActiveCfg = Release|x64
{51D3BD1F-07A8-48EB-B2A0-0A249CD4E1A6}.Debug|ARM.ActiveCfg = Debug|x64
{51D3BD1F-07A8-48EB-B2A0-0A249CD4E1A6}.Debug|ARM64.ActiveCfg = Debug|x64
{51D3BD1F-07A8-48EB-B2A0-0A249CD4E1A6}.Debug|x64.ActiveCfg = Debug|x64
{51D3BD1F-07A8-48EB-B2A0-0A249CD4E1A6}.Debug|x64.Build.0 = Debug|x64
{51D3BD1F-07A8-48EB-B2A0-0A249CD4E1A6}.Debug|x86.ActiveCfg = Debug|x64
{51D3BD1F-07A8-48EB-B2A0-0A249CD4E1A6}.Release|ARM.ActiveCfg = Release|x64
{51D3BD1F-07A8-48EB-B2A0-0A249CD4E1A6}.Release|ARM64.ActiveCfg = Release|x64
{51D3BD1F-07A8-48EB-B2A0-0A249CD4E1A6}.Release|x64.ActiveCfg = Release|x64
{51D3BD1F-07A8-48EB-B2A0-0A249CD4E1A6}.Release|x64.Build.0 = Release|x64
{51D3BD1F-07A8-48EB-B2A0-0A249CD4E1A6}.Release|x86.ActiveCfg = Release|x64
{89F34AF7-1C34-4A72-AA6E-534BCF972BD9}.Debug|ARM.ActiveCfg = Debug|x64
{89F34AF7-1C34-4A72-AA6E-534BCF972BD9}.Debug|ARM64.ActiveCfg = Debug|x64
{89F34AF7-1C34-4A72-AA6E-534BCF972BD9}.Debug|x64.ActiveCfg = Debug|x64
{89F34AF7-1C34-4A72-AA6E-534BCF972BD9}.Debug|x64.Build.0 = Debug|x64
{89F34AF7-1C34-4A72-AA6E-534BCF972BD9}.Debug|x86.ActiveCfg = Debug|x64
{89F34AF7-1C34-4A72-AA6E-534BCF972BD9}.Release|ARM.ActiveCfg = Release|x64
{89F34AF7-1C34-4A72-AA6E-534BCF972BD9}.Release|ARM64.ActiveCfg = Release|x64
{89F34AF7-1C34-4A72-AA6E-534BCF972BD9}.Release|x64.ActiveCfg = Release|x64
{89F34AF7-1C34-4A72-AA6E-534BCF972BD9}.Release|x64.Build.0 = Release|x64
{89F34AF7-1C34-4A72-AA6E-534BCF972BD9}.Release|x86.ActiveCfg = Release|x64
{2BE46397-4DFA-414C-9BD4-41E4BBF8CB34}.Debug|ARM.ActiveCfg = Debug|x64
{2BE46397-4DFA-414C-9BD4-41E4BBF8CB34}.Debug|ARM64.ActiveCfg = Debug|x64
{2BE46397-4DFA-414C-9BD4-41E4BBF8CB34}.Debug|x64.ActiveCfg = Debug|x64
{2BE46397-4DFA-414C-9BD4-41E4BBF8CB34}.Debug|x64.Build.0 = Debug|x64
{2BE46397-4DFA-414C-9BD4-41E4BBF8CB34}.Debug|x86.ActiveCfg = Debug|x64
{2BE46397-4DFA-414C-9BD4-41E4BBF8CB34}.Release|ARM.ActiveCfg = Release|x64
{2BE46397-4DFA-414C-9BD4-41E4BBF8CB34}.Release|ARM64.ActiveCfg = Release|x64
{2BE46397-4DFA-414C-9BD4-41E4BBF8CB34}.Release|x64.ActiveCfg = Release|x64
{2BE46397-4DFA-414C-9BD4-41E4BBF8CB34}.Release|x64.Build.0 = Release|x64
{2BE46397-4DFA-414C-9BD4-41E4BBF8CB34}.Release|x86.ActiveCfg = Release|x64
{0B43679E-EDFA-4DA0-AD30-F4628B308B1B}.Debug|ARM.ActiveCfg = Debug|Win32
{0B43679E-EDFA-4DA0-AD30-F4628B308B1B}.Debug|ARM64.ActiveCfg = Debug|Win32
{0B43679E-EDFA-4DA0-AD30-F4628B308B1B}.Debug|x64.ActiveCfg = Debug|x64
{0B43679E-EDFA-4DA0-AD30-F4628B308B1B}.Debug|x64.Build.0 = Debug|x64
{0B43679E-EDFA-4DA0-AD30-F4628B308B1B}.Debug|x86.ActiveCfg = Debug|Win32
{0B43679E-EDFA-4DA0-AD30-F4628B308B1B}.Debug|x86.Build.0 = Debug|Win32
{0B43679E-EDFA-4DA0-AD30-F4628B308B1B}.Release|ARM.ActiveCfg = Release|Win32
{0B43679E-EDFA-4DA0-AD30-F4628B308B1B}.Release|ARM64.ActiveCfg = Release|Win32
{0B43679E-EDFA-4DA0-AD30-F4628B308B1B}.Release|x64.ActiveCfg = Release|x64
{0B43679E-EDFA-4DA0-AD30-F4628B308B1B}.Release|x64.Build.0 = Release|x64
{0B43679E-EDFA-4DA0-AD30-F4628B308B1B}.Release|x86.ActiveCfg = Release|Win32
{0B43679E-EDFA-4DA0-AD30-F4628B308B1B}.Release|x86.Build.0 = Release|Win32
{E0CC7526-D85E-43AC-844F-D5DF0D2F5AB8}.Debug|ARM.ActiveCfg = Debug|x64
{E0CC7526-D85E-43AC-844F-D5DF0D2F5AB8}.Debug|ARM64.ActiveCfg = Debug|x64
{E0CC7526-D85E-43AC-844F-D5DF0D2F5AB8}.Debug|x64.ActiveCfg = Debug|x64
{E0CC7526-D85E-43AC-844F-D5DF0D2F5AB8}.Debug|x64.Build.0 = Debug|x64
{E0CC7526-D85E-43AC-844F-D5DF0D2F5AB8}.Debug|x86.ActiveCfg = Debug|x64
{E0CC7526-D85E-43AC-844F-D5DF0D2F5AB8}.Release|ARM.ActiveCfg = Release|x64
{E0CC7526-D85E-43AC-844F-D5DF0D2F5AB8}.Release|ARM64.ActiveCfg = Release|x64
{E0CC7526-D85E-43AC-844F-D5DF0D2F5AB8}.Release|x64.ActiveCfg = Release|x64
{E0CC7526-D85E-43AC-844F-D5DF0D2F5AB8}.Release|x64.Build.0 = Release|x64
{E0CC7526-D85E-43AC-844F-D5DF0D2F5AB8}.Release|x86.ActiveCfg = Release|x64
{EAF23649-EF6E-478B-980E-81FAD96CCA2A}.Debug|ARM.ActiveCfg = Debug|x64
{EAF23649-EF6E-478B-980E-81FAD96CCA2A}.Debug|ARM64.ActiveCfg = Debug|x64
{EAF23649-EF6E-478B-980E-81FAD96CCA2A}.Debug|x64.ActiveCfg = Debug|x64
{EAF23649-EF6E-478B-980E-81FAD96CCA2A}.Debug|x64.Build.0 = Debug|x64
{EAF23649-EF6E-478B-980E-81FAD96CCA2A}.Debug|x86.ActiveCfg = Debug|x64
{EAF23649-EF6E-478B-980E-81FAD96CCA2A}.Release|ARM.ActiveCfg = Release|x64
{EAF23649-EF6E-478B-980E-81FAD96CCA2A}.Release|ARM64.ActiveCfg = Release|x64
{EAF23649-EF6E-478B-980E-81FAD96CCA2A}.Release|x64.ActiveCfg = Release|x64
{EAF23649-EF6E-478B-980E-81FAD96CCA2A}.Release|x64.Build.0 = Release|x64
{EAF23649-EF6E-478B-980E-81FAD96CCA2A}.Release|x86.ActiveCfg = Release|x64
{D29DDD63-E2CF-4657-9FD5-2AEDE4257E5D}.Debug|ARM.ActiveCfg = Debug|Win32
{D29DDD63-E2CF-4657-9FD5-2AEDE4257E5D}.Debug|ARM64.ActiveCfg = Debug|Win32
{D29DDD63-E2CF-4657-9FD5-2AEDE4257E5D}.Debug|x64.ActiveCfg = Debug|x64
{D29DDD63-E2CF-4657-9FD5-2AEDE4257E5D}.Debug|x64.Build.0 = Debug|x64
{D29DDD63-E2CF-4657-9FD5-2AEDE4257E5D}.Debug|x86.ActiveCfg = Debug|Win32
{D29DDD63-E2CF-4657-9FD5-2AEDE4257E5D}.Debug|x86.Build.0 = Debug|Win32
{D29DDD63-E2CF-4657-9FD5-2AEDE4257E5D}.Release|ARM.ActiveCfg = Release|Win32
{D29DDD63-E2CF-4657-9FD5-2AEDE4257E5D}.Release|ARM64.ActiveCfg = Release|Win32
{D29DDD63-E2CF-4657-9FD5-2AEDE4257E5D}.Release|x64.ActiveCfg = Release|x64
{D29DDD63-E2CF-4657-9FD5-2AEDE4257E5D}.Release|x64.Build.0 = Release|x64
{D29DDD63-E2CF-4657-9FD5-2AEDE4257E5D}.Release|x86.ActiveCfg = Release|Win32
{D29DDD63-E2CF-4657-9FD5-2AEDE4257E5D}.Release|x86.Build.0 = Release|Win32
{17DA04DF-E393-4397-9CF0-84DABE11032E}.Debug|ARM.ActiveCfg = Debug|Win32
{17DA04DF-E393-4397-9CF0-84DABE11032E}.Debug|ARM64.ActiveCfg = Debug|Win32
{17DA04DF-E393-4397-9CF0-84DABE11032E}.Debug|x64.ActiveCfg = Debug|x64
{17DA04DF-E393-4397-9CF0-84DABE11032E}.Debug|x64.Build.0 = Debug|x64
{17DA04DF-E393-4397-9CF0-84DABE11032E}.Debug|x86.ActiveCfg = Debug|Win32
{17DA04DF-E393-4397-9CF0-84DABE11032E}.Debug|x86.Build.0 = Debug|Win32
{17DA04DF-E393-4397-9CF0-84DABE11032E}.Release|ARM.ActiveCfg = Release|Win32
{17DA04DF-E393-4397-9CF0-84DABE11032E}.Release|ARM64.ActiveCfg = Release|Win32
{17DA04DF-E393-4397-9CF0-84DABE11032E}.Release|x64.ActiveCfg = Release|x64
{17DA04DF-E393-4397-9CF0-84DABE11032E}.Release|x64.Build.0 = Release|x64
{17DA04DF-E393-4397-9CF0-84DABE11032E}.Release|x86.ActiveCfg = Release|Win32
{17DA04DF-E393-4397-9CF0-84DABE11032E}.Release|x86.Build.0 = Release|Win32
{8AFFA899-0B73-49EC-8C50-0FADDA57B2FC}.Debug|ARM.ActiveCfg = Debug|x64
{8AFFA899-0B73-49EC-8C50-0FADDA57B2FC}.Debug|ARM64.ActiveCfg = Debug|x64
{8AFFA899-0B73-49EC-8C50-0FADDA57B2FC}.Debug|x64.ActiveCfg = Debug|x64
{8AFFA899-0B73-49EC-8C50-0FADDA57B2FC}.Debug|x64.Build.0 = Debug|x64
{8AFFA899-0B73-49EC-8C50-0FADDA57B2FC}.Debug|x86.ActiveCfg = Debug|x64
{8AFFA899-0B73-49EC-8C50-0FADDA57B2FC}.Release|ARM.ActiveCfg = Release|x64
{8AFFA899-0B73-49EC-8C50-0FADDA57B2FC}.Release|ARM64.ActiveCfg = Release|x64
{8AFFA899-0B73-49EC-8C50-0FADDA57B2FC}.Release|x64.ActiveCfg = Release|x64
{8AFFA899-0B73-49EC-8C50-0FADDA57B2FC}.Release|x64.Build.0 = Release|x64
{8AFFA899-0B73-49EC-8C50-0FADDA57B2FC}.Release|x86.ActiveCfg = Release|x64
{DB90F671-D861-46BB-93A3-F1304F5BA1C5}.Debug|ARM.ActiveCfg = Debug|x64
{DB90F671-D861-46BB-93A3-F1304F5BA1C5}.Debug|ARM64.ActiveCfg = Debug|x64
{DB90F671-D861-46BB-93A3-F1304F5BA1C5}.Debug|x64.ActiveCfg = Debug|x64
{DB90F671-D861-46BB-93A3-F1304F5BA1C5}.Debug|x64.Build.0 = Debug|x64
{DB90F671-D861-46BB-93A3-F1304F5BA1C5}.Debug|x86.ActiveCfg = Debug|x64
{DB90F671-D861-46BB-93A3-F1304F5BA1C5}.Release|ARM.ActiveCfg = Release|x64
{DB90F671-D861-46BB-93A3-F1304F5BA1C5}.Release|ARM64.ActiveCfg = Release|x64
{DB90F671-D861-46BB-93A3-F1304F5BA1C5}.Release|x64.ActiveCfg = Release|x64
{DB90F671-D861-46BB-93A3-F1304F5BA1C5}.Release|x64.Build.0 = Release|x64
{DB90F671-D861-46BB-93A3-F1304F5BA1C5}.Release|x86.ActiveCfg = Release|x64
{B749F0DB-8E75-47DB-9E5E-265D16D0C0D2}.Debug|ARM.ActiveCfg = Debug|x64
{B749F0DB-8E75-47DB-9E5E-265D16D0C0D2}.Debug|ARM64.ActiveCfg = Debug|x64
{B749F0DB-8E75-47DB-9E5E-265D16D0C0D2}.Debug|x64.ActiveCfg = Debug|x64
{B749F0DB-8E75-47DB-9E5E-265D16D0C0D2}.Debug|x64.Build.0 = Debug|x64
{B749F0DB-8E75-47DB-9E5E-265D16D0C0D2}.Debug|x86.ActiveCfg = Debug|x64
{B749F0DB-8E75-47DB-9E5E-265D16D0C0D2}.Release|ARM.ActiveCfg = Release|x64
{B749F0DB-8E75-47DB-9E5E-265D16D0C0D2}.Release|ARM64.ActiveCfg = Release|x64
{B749F0DB-8E75-47DB-9E5E-265D16D0C0D2}.Release|x64.ActiveCfg = Release|x64
{B749F0DB-8E75-47DB-9E5E-265D16D0C0D2}.Release|x64.Build.0 = Release|x64
{B749F0DB-8E75-47DB-9E5E-265D16D0C0D2}.Release|x86.ActiveCfg = Release|x64
{4FD29318-A8AB-4D8F-AA47-60BC241B8DA3}.Debug|ARM.ActiveCfg = Debug|x64
{4FD29318-A8AB-4D8F-AA47-60BC241B8DA3}.Debug|ARM64.ActiveCfg = Debug|x64
{4FD29318-A8AB-4D8F-AA47-60BC241B8DA3}.Debug|x64.ActiveCfg = Debug|x64
{4FD29318-A8AB-4D8F-AA47-60BC241B8DA3}.Debug|x64.Build.0 = Debug|x64
{4FD29318-A8AB-4D8F-AA47-60BC241B8DA3}.Debug|x86.ActiveCfg = Debug|x64
{4FD29318-A8AB-4D8F-AA47-60BC241B8DA3}.Release|ARM.ActiveCfg = Release|x64
{4FD29318-A8AB-4D8F-AA47-60BC241B8DA3}.Release|ARM64.ActiveCfg = Release|x64
{4FD29318-A8AB-4D8F-AA47-60BC241B8DA3}.Release|x64.ActiveCfg = Release|x64
{4FD29318-A8AB-4D8F-AA47-60BC241B8DA3}.Release|x64.Build.0 = Release|x64
{4FD29318-A8AB-4D8F-AA47-60BC241B8DA3}.Release|x86.ActiveCfg = Release|x64
{8451ECDD-2EA4-4966-BB0A-7BBC40138E80}.Debug|ARM.ActiveCfg = Debug|x64
{8451ECDD-2EA4-4966-BB0A-7BBC40138E80}.Debug|ARM64.ActiveCfg = Debug|x64
{8451ECDD-2EA4-4966-BB0A-7BBC40138E80}.Debug|x64.ActiveCfg = Debug|x64
{8451ECDD-2EA4-4966-BB0A-7BBC40138E80}.Debug|x64.Build.0 = Debug|x64
{8451ECDD-2EA4-4966-BB0A-7BBC40138E80}.Debug|x86.ActiveCfg = Debug|x64
{8451ECDD-2EA4-4966-BB0A-7BBC40138E80}.Release|ARM.ActiveCfg = Release|x64
{8451ECDD-2EA4-4966-BB0A-7BBC40138E80}.Release|ARM64.ActiveCfg = Release|x64
{8451ECDD-2EA4-4966-BB0A-7BBC40138E80}.Release|x64.ActiveCfg = Release|x64
{8451ECDD-2EA4-4966-BB0A-7BBC40138E80}.Release|x64.Build.0 = Release|x64
{8451ECDD-2EA4-4966-BB0A-7BBC40138E80}.Release|x86.ActiveCfg = Release|x64
{FF742965-9A80-41A5-B042-D6C7D3A21708}.Debug|ARM.ActiveCfg = Debug|x64
{FF742965-9A80-41A5-B042-D6C7D3A21708}.Debug|ARM64.ActiveCfg = Debug|x64
{FF742965-9A80-41A5-B042-D6C7D3A21708}.Debug|x64.ActiveCfg = Debug|x64
{FF742965-9A80-41A5-B042-D6C7D3A21708}.Debug|x64.Build.0 = Debug|x64
{FF742965-9A80-41A5-B042-D6C7D3A21708}.Debug|x86.ActiveCfg = Debug|x64
{FF742965-9A80-41A5-B042-D6C7D3A21708}.Release|ARM.ActiveCfg = Release|x64
{FF742965-9A80-41A5-B042-D6C7D3A21708}.Release|ARM64.ActiveCfg = Release|x64
{FF742965-9A80-41A5-B042-D6C7D3A21708}.Release|x64.ActiveCfg = Release|x64
{FF742965-9A80-41A5-B042-D6C7D3A21708}.Release|x64.Build.0 = Release|x64
{FF742965-9A80-41A5-B042-D6C7D3A21708}.Release|x86.ActiveCfg = Release|x64
{59BD9891-3837-438A-958D-ADC7F91F6F7E}.Debug|ARM.ActiveCfg = Debug|x64
{59BD9891-3837-438A-958D-ADC7F91F6F7E}.Debug|ARM64.ActiveCfg = Debug|x64
{59BD9891-3837-438A-958D-ADC7F91F6F7E}.Debug|x64.ActiveCfg = Debug|x64
{59BD9891-3837-438A-958D-ADC7F91F6F7E}.Debug|x64.Build.0 = Debug|x64
{59BD9891-3837-438A-958D-ADC7F91F6F7E}.Debug|x86.ActiveCfg = Debug|x64
{59BD9891-3837-438A-958D-ADC7F91F6F7E}.Release|ARM.ActiveCfg = Release|x64
{59BD9891-3837-438A-958D-ADC7F91F6F7E}.Release|ARM64.ActiveCfg = Release|x64
{59BD9891-3837-438A-958D-ADC7F91F6F7E}.Release|x64.ActiveCfg = Release|x64
{59BD9891-3837-438A-958D-ADC7F91F6F7E}.Release|x64.Build.0 = Release|x64
{59BD9891-3837-438A-958D-ADC7F91F6F7E}.Release|x86.ActiveCfg = Release|x64
{74F1B9ED-F59C-4FE7-B473-7B453E30837E}.Debug|ARM.ActiveCfg = Debug|x64
{74F1B9ED-F59C-4FE7-B473-7B453E30837E}.Debug|ARM64.ActiveCfg = Debug|x64
{74F1B9ED-F59C-4FE7-B473-7B453E30837E}.Debug|x64.ActiveCfg = Debug|x64
{74F1B9ED-F59C-4FE7-B473-7B453E30837E}.Debug|x64.Build.0 = Debug|x64
{74F1B9ED-F59C-4FE7-B473-7B453E30837E}.Debug|x86.ActiveCfg = Debug|x64
{74F1B9ED-F59C-4FE7-B473-7B453E30837E}.Release|ARM.ActiveCfg = Release|x64
{74F1B9ED-F59C-4FE7-B473-7B453E30837E}.Release|ARM64.ActiveCfg = Release|x64
{74F1B9ED-F59C-4FE7-B473-7B453E30837E}.Release|x64.ActiveCfg = Release|x64
{74F1B9ED-F59C-4FE7-B473-7B453E30837E}.Release|x64.Build.0 = Release|x64
{74F1B9ED-F59C-4FE7-B473-7B453E30837E}.Release|x86.ActiveCfg = Release|x64
{FDB3555B-58EF-4AE6-B5F1-904719637AB4}.Debug|ARM.ActiveCfg = Debug|x64
{FDB3555B-58EF-4AE6-B5F1-904719637AB4}.Debug|ARM64.ActiveCfg = Debug|x64
{FDB3555B-58EF-4AE6-B5F1-904719637AB4}.Debug|x64.ActiveCfg = Debug|x64
{FDB3555B-58EF-4AE6-B5F1-904719637AB4}.Debug|x64.Build.0 = Debug|x64
{FDB3555B-58EF-4AE6-B5F1-904719637AB4}.Debug|x86.ActiveCfg = Debug|x64
{FDB3555B-58EF-4AE6-B5F1-904719637AB4}.Release|ARM.ActiveCfg = Release|x64
{FDB3555B-58EF-4AE6-B5F1-904719637AB4}.Release|ARM64.ActiveCfg = Release|x64
{FDB3555B-58EF-4AE6-B5F1-904719637AB4}.Release|x64.ActiveCfg = Release|x64
{FDB3555B-58EF-4AE6-B5F1-904719637AB4}.Release|x64.Build.0 = Release|x64
{FDB3555B-58EF-4AE6-B5F1-904719637AB4}.Release|x86.ActiveCfg = Release|x64
{C21BFF9C-2C99-4B5F-B7C9-A5E6DDDB37B0}.Debug|ARM.ActiveCfg = Debug|x64
{C21BFF9C-2C99-4B5F-B7C9-A5E6DDDB37B0}.Debug|ARM64.ActiveCfg = Debug|x64
{C21BFF9C-2C99-4B5F-B7C9-A5E6DDDB37B0}.Debug|x64.ActiveCfg = Debug|x64
{C21BFF9C-2C99-4B5F-B7C9-A5E6DDDB37B0}.Debug|x64.Build.0 = Debug|x64
{C21BFF9C-2C99-4B5F-B7C9-A5E6DDDB37B0}.Debug|x86.ActiveCfg = Debug|x64
{C21BFF9C-2C99-4B5F-B7C9-A5E6DDDB37B0}.Release|ARM.ActiveCfg = Release|x64
{C21BFF9C-2C99-4B5F-B7C9-A5E6DDDB37B0}.Release|ARM64.ActiveCfg = Release|x64
{C21BFF9C-2C99-4B5F-B7C9-A5E6DDDB37B0}.Release|x64.ActiveCfg = Release|x64
{C21BFF9C-2C99-4B5F-B7C9-A5E6DDDB37B0}.Release|x64.Build.0 = Release|x64
{C21BFF9C-2C99-4B5F-B7C9-A5E6DDDB37B0}.Release|x86.ActiveCfg = Release|x64
{F8B870EB-D5F5-45BA-9CF7-A5C459818820}.Debug|ARM.ActiveCfg = Debug|x64
{F8B870EB-D5F5-45BA-9CF7-A5C459818820}.Debug|ARM64.ActiveCfg = Debug|x64
{F8B870EB-D5F5-45BA-9CF7-A5C459818820}.Debug|x64.ActiveCfg = Debug|x64
{F8B870EB-D5F5-45BA-9CF7-A5C459818820}.Debug|x64.Build.0 = Debug|x64
{F8B870EB-D5F5-45BA-9CF7-A5C459818820}.Debug|x86.ActiveCfg = Debug|x64
{F8B870EB-D5F5-45BA-9CF7-A5C459818820}.Release|ARM.ActiveCfg = Release|x64
{F8B870EB-D5F5-45BA-9CF7-A5C459818820}.Release|ARM64.ActiveCfg = Release|x64
{F8B870EB-D5F5-45BA-9CF7-A5C459818820}.Release|x64.ActiveCfg = Release|x64
{F8B870EB-D5F5-45BA-9CF7-A5C459818820}.Release|x64.Build.0 = Release|x64
{F8B870EB-D5F5-45BA-9CF7-A5C459818820}.Release|x86.ActiveCfg = Release|x64
{E364F67B-BB12-4E91-B639-355866EBCD8B}.Debug|ARM.ActiveCfg = Debug|x64
{E364F67B-BB12-4E91-B639-355866EBCD8B}.Debug|ARM64.ActiveCfg = Debug|x64
{E364F67B-BB12-4E91-B639-355866EBCD8B}.Debug|x64.ActiveCfg = Debug|x64
{E364F67B-BB12-4E91-B639-355866EBCD8B}.Debug|x64.Build.0 = Debug|x64
{E364F67B-BB12-4E91-B639-355866EBCD8B}.Debug|x86.ActiveCfg = Debug|x64
{E364F67B-BB12-4E91-B639-355866EBCD8B}.Release|ARM.ActiveCfg = Release|x64
{E364F67B-BB12-4E91-B639-355866EBCD8B}.Release|ARM64.ActiveCfg = Release|x64
{E364F67B-BB12-4E91-B639-355866EBCD8B}.Release|x64.ActiveCfg = Release|x64
{E364F67B-BB12-4E91-B639-355866EBCD8B}.Release|x64.Build.0 = Release|x64
{E364F67B-BB12-4E91-B639-355866EBCD8B}.Release|x86.ActiveCfg = Release|x64
{F97E5003-F263-4D4A-A964-0F1F3C82DEF2}.Debug|ARM.ActiveCfg = Debug|x64
{F97E5003-F263-4D4A-A964-0F1F3C82DEF2}.Debug|ARM64.ActiveCfg = Debug|x64
{F97E5003-F263-4D4A-A964-0F1F3C82DEF2}.Debug|x64.ActiveCfg = Debug|x64
{F97E5003-F263-4D4A-A964-0F1F3C82DEF2}.Debug|x64.Build.0 = Debug|x64
{F97E5003-F263-4D4A-A964-0F1F3C82DEF2}.Debug|x86.ActiveCfg = Debug|x64
{F97E5003-F263-4D4A-A964-0F1F3C82DEF2}.Release|ARM.ActiveCfg = Release|x64
{F97E5003-F263-4D4A-A964-0F1F3C82DEF2}.Release|ARM64.ActiveCfg = Release|x64
{F97E5003-F263-4D4A-A964-0F1F3C82DEF2}.Release|x64.ActiveCfg = Release|x64
{F97E5003-F263-4D4A-A964-0F1F3C82DEF2}.Release|x64.Build.0 = Release|x64
{F97E5003-F263-4D4A-A964-0F1F3C82DEF2}.Release|x86.ActiveCfg = Release|x64
{4A3DE70C-684C-410D-B851-C23B6DAEDF16}.Debug|ARM.ActiveCfg = Debug|x64
{4A3DE70C-684C-410D-B851-C23B6DAEDF16}.Debug|ARM64.ActiveCfg = Debug|x64
{4A3DE70C-684C-410D-B851-C23B6DAEDF16}.Debug|x64.ActiveCfg = Debug|x64
{4A3DE70C-684C-410D-B851-C23B6DAEDF16}.Debug|x64.Build.0 = Debug|x64
{4A3DE70C-684C-410D-B851-C23B6DAEDF16}.Debug|x86.ActiveCfg = Debug|x64
{4A3DE70C-684C-410D-B851-C23B6DAEDF16}.Release|ARM.ActiveCfg = Release|x64
{4A3DE70C-684C-410D-B851-C23B6DAEDF16}.Release|ARM64.ActiveCfg = Release|x64
{4A3DE70C-684C-410D-B851-C23B6DAEDF16}.Release|x64.ActiveCfg = Release|x64
{4A3DE70C-684C-410D-B851-C23B6DAEDF16}.Release|x64.Build.0 = Release|x64
{4A3DE70C-684C-410D-B851-C23B6DAEDF16}.Release|x86.ActiveCfg = Release|x64
{880ED251-9E16-4713-9A70-D35FE0C01669}.Debug|ARM.ActiveCfg = Debug|x64
{880ED251-9E16-4713-9A70-D35FE0C01669}.Debug|ARM64.ActiveCfg = Debug|x64
{880ED251-9E16-4713-9A70-D35FE0C01669}.Debug|x64.ActiveCfg = Debug|x64
{880ED251-9E16-4713-9A70-D35FE0C01669}.Debug|x64.Build.0 = Debug|x64
{880ED251-9E16-4713-9A70-D35FE0C01669}.Debug|x86.ActiveCfg = Debug|x64
{880ED251-9E16-4713-9A70-D35FE0C01669}.Release|ARM.ActiveCfg = Release|x64
{880ED251-9E16-4713-9A70-D35FE0C01669}.Release|ARM64.ActiveCfg = Release|x64
{880ED251-9E16-4713-9A70-D35FE0C01669}.Release|x64.ActiveCfg = Release|x64
{880ED251-9E16-4713-9A70-D35FE0C01669}.Release|x64.Build.0 = Release|x64
{880ED251-9E16-4713-9A70-D35FE0C01669}.Release|x86.ActiveCfg = Release|x64
{AF2349B8-E5B6-4004-9502-687C1C7730B1}.Debug|ARM.ActiveCfg = Debug|x64
{AF2349B8-E5B6-4004-9502-687C1C7730B1}.Debug|ARM64.ActiveCfg = Debug|x64
{AF2349B8-E5B6-4004-9502-687C1C7730B1}.Debug|x64.ActiveCfg = Debug|x64
{AF2349B8-E5B6-4004-9502-687C1C7730B1}.Debug|x64.Build.0 = Debug|x64
{AF2349B8-E5B6-4004-9502-687C1C7730B1}.Debug|x86.ActiveCfg = Debug|x64
{AF2349B8-E5B6-4004-9502-687C1C7730B1}.Release|ARM.ActiveCfg = Release|x64
{AF2349B8-E5B6-4004-9502-687C1C7730B1}.Release|ARM64.ActiveCfg = Release|x64
{AF2349B8-E5B6-4004-9502-687C1C7730B1}.Release|x64.ActiveCfg = Release|x64
{AF2349B8-E5B6-4004-9502-687C1C7730B1}.Release|x64.Build.0 = Release|x64
{AF2349B8-E5B6-4004-9502-687C1C7730B1}.Release|x86.ActiveCfg = Release|x64
{6A71162E-FC4C-4A2C-B90F-3CF94F59A9BB}.Debug|ARM.ActiveCfg = Debug|x64
{6A71162E-FC4C-4A2C-B90F-3CF94F59A9BB}.Debug|ARM64.ActiveCfg = Debug|x64
{6A71162E-FC4C-4A2C-B90F-3CF94F59A9BB}.Debug|x64.ActiveCfg = Debug|x64
{6A71162E-FC4C-4A2C-B90F-3CF94F59A9BB}.Debug|x64.Build.0 = Debug|x64
{6A71162E-FC4C-4A2C-B90F-3CF94F59A9BB}.Debug|x86.ActiveCfg = Debug|x64
{6A71162E-FC4C-4A2C-B90F-3CF94F59A9BB}.Release|ARM.ActiveCfg = Release|x64
{6A71162E-FC4C-4A2C-B90F-3CF94F59A9BB}.Release|ARM64.ActiveCfg = Release|x64
{6A71162E-FC4C-4A2C-B90F-3CF94F59A9BB}.Release|x64.ActiveCfg = Release|x64
{6A71162E-FC4C-4A2C-B90F-3CF94F59A9BB}.Release|x64.Build.0 = Release|x64
{6A71162E-FC4C-4A2C-B90F-3CF94F59A9BB}.Release|x86.ActiveCfg = Release|x64
{A2B51B8B-8F90-424E-BC97-F9AB7D76CA1A}.Debug|ARM.ActiveCfg = Debug|x64
{A2B51B8B-8F90-424E-BC97-F9AB7D76CA1A}.Debug|ARM64.ActiveCfg = Debug|x64
{A2B51B8B-8F90-424E-BC97-F9AB7D76CA1A}.Debug|x64.ActiveCfg = Debug|x64
{A2B51B8B-8F90-424E-BC97-F9AB7D76CA1A}.Debug|x64.Build.0 = Debug|x64
{A2B51B8B-8F90-424E-BC97-F9AB7D76CA1A}.Debug|x86.ActiveCfg = Debug|x64
{A2B51B8B-8F90-424E-BC97-F9AB7D76CA1A}.Release|ARM.ActiveCfg = Release|x64
{A2B51B8B-8F90-424E-BC97-F9AB7D76CA1A}.Release|ARM64.ActiveCfg = Release|x64
{A2B51B8B-8F90-424E-BC97-F9AB7D76CA1A}.Release|x64.ActiveCfg = Release|x64
{A2B51B8B-8F90-424E-BC97-F9AB7D76CA1A}.Release|x64.Build.0 = Release|x64
{A2B51B8B-8F90-424E-BC97-F9AB7D76CA1A}.Release|x86.ActiveCfg = Release|x64
{DA425894-6E13-404F-8DCB-78584EC0557A}.Debug|ARM.ActiveCfg = Debug|x64
{DA425894-6E13-404F-8DCB-78584EC0557A}.Debug|ARM64.ActiveCfg = Debug|x64
{DA425894-6E13-404F-8DCB-78584EC0557A}.Debug|x64.ActiveCfg = Debug|x64
{DA425894-6E13-404F-8DCB-78584EC0557A}.Debug|x64.Build.0 = Debug|x64
{DA425894-6E13-404F-8DCB-78584EC0557A}.Debug|x86.ActiveCfg = Debug|x64
{DA425894-6E13-404F-8DCB-78584EC0557A}.Release|ARM.ActiveCfg = Release|x64
{DA425894-6E13-404F-8DCB-78584EC0557A}.Release|ARM64.ActiveCfg = Release|x64
{DA425894-6E13-404F-8DCB-78584EC0557A}.Release|x64.ActiveCfg = Release|x64
{DA425894-6E13-404F-8DCB-78584EC0557A}.Release|x64.Build.0 = Release|x64
{DA425894-6E13-404F-8DCB-78584EC0557A}.Release|x86.ActiveCfg = Release|x64
{060D75DA-2D1C-48E6-A4A1-6F0718B64661}.Debug|ARM.ActiveCfg = Debug|x64
{060D75DA-2D1C-48E6-A4A1-6F0718B64661}.Debug|ARM64.ActiveCfg = Debug|x64
{060D75DA-2D1C-48E6-A4A1-6F0718B64661}.Debug|x64.ActiveCfg = Debug|x64
{060D75DA-2D1C-48E6-A4A1-6F0718B64661}.Debug|x64.Build.0 = Debug|x64
{060D75DA-2D1C-48E6-A4A1-6F0718B64661}.Debug|x86.ActiveCfg = Debug|x64
{060D75DA-2D1C-48E6-A4A1-6F0718B64661}.Release|ARM.ActiveCfg = Release|x64
{060D75DA-2D1C-48E6-A4A1-6F0718B64661}.Release|ARM64.ActiveCfg = Release|x64
{060D75DA-2D1C-48E6-A4A1-6F0718B64661}.Release|x64.ActiveCfg = Release|x64
{060D75DA-2D1C-48E6-A4A1-6F0718B64661}.Release|x64.Build.0 = Release|x64
{060D75DA-2D1C-48E6-A4A1-6F0718B64661}.Release|x86.ActiveCfg = Release|x64
{748417CA-F17E-487F-9411-CAFB6D3F4877}.Debug|ARM.ActiveCfg = Debug|x64
{748417CA-F17E-487F-9411-CAFB6D3F4877}.Debug|ARM64.ActiveCfg = Debug|x64
{748417CA-F17E-487F-9411-CAFB6D3F4877}.Debug|x64.ActiveCfg = Debug|x64
{748417CA-F17E-487F-9411-CAFB6D3F4877}.Debug|x64.Build.0 = Debug|x64
{748417CA-F17E-487F-9411-CAFB6D3F4877}.Debug|x86.ActiveCfg = Debug|x64
{748417CA-F17E-487F-9411-CAFB6D3F4877}.Release|ARM.ActiveCfg = Release|x64
{748417CA-F17E-487F-9411-CAFB6D3F4877}.Release|ARM64.ActiveCfg = Release|x64
{748417CA-F17E-487F-9411-CAFB6D3F4877}.Release|x64.ActiveCfg = Release|x64
{748417CA-F17E-487F-9411-CAFB6D3F4877}.Release|x64.Build.0 = Release|x64
{748417CA-F17E-487F-9411-CAFB6D3F4877}.Release|x86.ActiveCfg = Release|x64
{217DF501-135C-4E38-BFC8-99D4821032EA}.Debug|ARM.ActiveCfg = Debug|x64
{217DF501-135C-4E38-BFC8-99D4821032EA}.Debug|ARM64.ActiveCfg = Debug|x64
{217DF501-135C-4E38-BFC8-99D4821032EA}.Debug|x64.ActiveCfg = Debug|x64
{217DF501-135C-4E38-BFC8-99D4821032EA}.Debug|x64.Build.0 = Debug|x64
{217DF501-135C-4E38-BFC8-99D4821032EA}.Debug|x86.ActiveCfg = Debug|x64
{217DF501-135C-4E38-BFC8-99D4821032EA}.Release|ARM.ActiveCfg = Release|x64
{217DF501-135C-4E38-BFC8-99D4821032EA}.Release|ARM64.ActiveCfg = Release|x64
{217DF501-135C-4E38-BFC8-99D4821032EA}.Release|x64.ActiveCfg = Release|x64
{217DF501-135C-4E38-BFC8-99D4821032EA}.Release|x64.Build.0 = Release|x64
{217DF501-135C-4E38-BFC8-99D4821032EA}.Release|x86.ActiveCfg = Release|x64
{47310AB4-9034-4BD1-8D8B-E88AD21A171B}.Debug|ARM.ActiveCfg = Debug|Win32
{47310AB4-9034-4BD1-8D8B-E88AD21A171B}.Debug|ARM64.ActiveCfg = Debug|Win32
{47310AB4-9034-4BD1-8D8B-E88AD21A171B}.Debug|x64.ActiveCfg = Debug|x64
{47310AB4-9034-4BD1-8D8B-E88AD21A171B}.Debug|x64.Build.0 = Debug|x64
{47310AB4-9034-4BD1-8D8B-E88AD21A171B}.Debug|x86.ActiveCfg = Debug|Win32
{47310AB4-9034-4BD1-8D8B-E88AD21A171B}.Debug|x86.Build.0 = Debug|Win32
{47310AB4-9034-4BD1-8D8B-E88AD21A171B}.Release|ARM.ActiveCfg = Release|Win32
{47310AB4-9034-4BD1-8D8B-E88AD21A171B}.Release|ARM64.ActiveCfg = Release|Win32
{47310AB4-9034-4BD1-8D8B-E88AD21A171B}.Release|x64.ActiveCfg = Release|x64
{47310AB4-9034-4BD1-8D8B-E88AD21A171B}.Release|x64.Build.0 = Release|x64
{47310AB4-9034-4BD1-8D8B-E88AD21A171B}.Release|x86.ActiveCfg = Release|Win32
{47310AB4-9034-4BD1-8D8B-E88AD21A171B}.Release|x86.Build.0 = Release|Win32
{E4E0D2AE-B17D-4BD4-8BEE-AFC8CC464C5F}.Debug|ARM.ActiveCfg = Debug|x64
{E4E0D2AE-B17D-4BD4-8BEE-AFC8CC464C5F}.Debug|ARM64.ActiveCfg = Debug|x64
{E4E0D2AE-B17D-4BD4-8BEE-AFC8CC464C5F}.Debug|x64.ActiveCfg = Debug|x64
{E4E0D2AE-B17D-4BD4-8BEE-AFC8CC464C5F}.Debug|x64.Build.0 = Debug|x64
{E4E0D2AE-B17D-4BD4-8BEE-AFC8CC464C5F}.Debug|x86.ActiveCfg = Debug|x64
{E4E0D2AE-B17D-4BD4-8BEE-AFC8CC464C5F}.Release|ARM.ActiveCfg = Release|x64
{E4E0D2AE-B17D-4BD4-8BEE-AFC8CC464C5F}.Release|ARM64.ActiveCfg = Release|x64
{E4E0D2AE-B17D-4BD4-8BEE-AFC8CC464C5F}.Release|x64.ActiveCfg = Release|x64
{E4E0D2AE-B17D-4BD4-8BEE-AFC8CC464C5F}.Release|x64.Build.0 = Release|x64
{E4E0D2AE-B17D-4BD4-8BEE-AFC8CC464C5F}.Release|x86.ActiveCfg = Release|x64
{A7D5099E-F0FD-4BF3-8522-5A682759F915}.Debug|ARM.ActiveCfg = Debug|Win32
{A7D5099E-F0FD-4BF3-8522-5A682759F915}.Debug|ARM64.ActiveCfg = Debug|Win32
{A7D5099E-F0FD-4BF3-8522-5A682759F915}.Debug|x64.ActiveCfg = Debug|x64
{A7D5099E-F0FD-4BF3-8522-5A682759F915}.Debug|x64.Build.0 = Debug|x64
{A7D5099E-F0FD-4BF3-8522-5A682759F915}.Debug|x86.ActiveCfg = Debug|Win32
{A7D5099E-F0FD-4BF3-8522-5A682759F915}.Debug|x86.Build.0 = Debug|Win32
{A7D5099E-F0FD-4BF3-8522-5A682759F915}.Debug|x86.Deploy.0 = Debug|Win32
{A7D5099E-F0FD-4BF3-8522-5A682759F915}.Release|ARM.ActiveCfg = Release|Win32
{A7D5099E-F0FD-4BF3-8522-5A682759F915}.Release|ARM64.ActiveCfg = Release|Win32
{A7D5099E-F0FD-4BF3-8522-5A682759F915}.Release|x64.ActiveCfg = Release|x64
{A7D5099E-F0FD-4BF3-8522-5A682759F915}.Release|x64.Build.0 = Release|x64
{A7D5099E-F0FD-4BF3-8522-5A682759F915}.Release|x86.ActiveCfg = Release|x64
{A7D5099E-F0FD-4BF3-8522-5A682759F915}.Release|x86.Build.0 = Release|x64
{A7D5099E-F0FD-4BF3-8522-5A682759F915}.Release|x86.Deploy.0 = Release|x64
{B1BCC8C6-46B5-4BFA-8F22-20F32D99EC6A}.Debug|ARM.ActiveCfg = Debug|Any CPU
{B1BCC8C6-46B5-4BFA-8F22-20F32D99EC6A}.Debug|ARM.Build.0 = Debug|Any CPU
{B1BCC8C6-46B5-4BFA-8F22-20F32D99EC6A}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{B1BCC8C6-46B5-4BFA-8F22-20F32D99EC6A}.Debug|ARM64.Build.0 = Debug|Any CPU
{B1BCC8C6-46B5-4BFA-8F22-20F32D99EC6A}.Debug|x64.ActiveCfg = Debug|x64
{B1BCC8C6-46B5-4BFA-8F22-20F32D99EC6A}.Debug|x64.Build.0 = Debug|x64
{B1BCC8C6-46B5-4BFA-8F22-20F32D99EC6A}.Debug|x86.ActiveCfg = Debug|Any CPU
{B1BCC8C6-46B5-4BFA-8F22-20F32D99EC6A}.Debug|x86.Build.0 = Debug|Any CPU
{B1BCC8C6-46B5-4BFA-8F22-20F32D99EC6A}.Release|ARM.ActiveCfg = Release|Any CPU
{B1BCC8C6-46B5-4BFA-8F22-20F32D99EC6A}.Release|ARM.Build.0 = Release|Any CPU
{B1BCC8C6-46B5-4BFA-8F22-20F32D99EC6A}.Release|ARM64.ActiveCfg = Release|Any CPU
{B1BCC8C6-46B5-4BFA-8F22-20F32D99EC6A}.Release|ARM64.Build.0 = Release|Any CPU
{B1BCC8C6-46B5-4BFA-8F22-20F32D99EC6A}.Release|x64.ActiveCfg = Release|x64
{B1BCC8C6-46B5-4BFA-8F22-20F32D99EC6A}.Release|x64.Build.0 = Release|x64
{B1BCC8C6-46B5-4BFA-8F22-20F32D99EC6A}.Release|x86.ActiveCfg = Release|x64
{B1BCC8C6-46B5-4BFA-8F22-20F32D99EC6A}.Release|x86.Build.0 = Release|x64
{A80355C2-780D-4245-BD80-25B8DE698EE3}.Debug|ARM.ActiveCfg = Debug|ARM
{A80355C2-780D-4245-BD80-25B8DE698EE3}.Debug|ARM.Build.0 = Debug|ARM
{A80355C2-780D-4245-BD80-25B8DE698EE3}.Debug|ARM.Deploy.0 = Debug|ARM
{A80355C2-780D-4245-BD80-25B8DE698EE3}.Debug|ARM64.ActiveCfg = Debug|ARM64
{A80355C2-780D-4245-BD80-25B8DE698EE3}.Debug|ARM64.Build.0 = Debug|ARM64
{A80355C2-780D-4245-BD80-25B8DE698EE3}.Debug|ARM64.Deploy.0 = Debug|ARM64
{A80355C2-780D-4245-BD80-25B8DE698EE3}.Debug|x64.ActiveCfg = Debug|x64
{A80355C2-780D-4245-BD80-25B8DE698EE3}.Debug|x64.Build.0 = Debug|x64
{A80355C2-780D-4245-BD80-25B8DE698EE3}.Debug|x86.ActiveCfg = Debug|x86
{A80355C2-780D-4245-BD80-25B8DE698EE3}.Debug|x86.Build.0 = Debug|x86
{A80355C2-780D-4245-BD80-25B8DE698EE3}.Debug|x86.Deploy.0 = Debug|x86
{A80355C2-780D-4245-BD80-25B8DE698EE3}.Release|ARM.ActiveCfg = Release|ARM
{A80355C2-780D-4245-BD80-25B8DE698EE3}.Release|ARM.Build.0 = Release|ARM
{A80355C2-780D-4245-BD80-25B8DE698EE3}.Release|ARM.Deploy.0 = Release|ARM
{A80355C2-780D-4245-BD80-25B8DE698EE3}.Release|ARM64.ActiveCfg = Release|ARM64
{A80355C2-780D-4245-BD80-25B8DE698EE3}.Release|ARM64.Build.0 = Release|ARM64
{A80355C2-780D-4245-BD80-25B8DE698EE3}.Release|ARM64.Deploy.0 = Release|ARM64
{A80355C2-780D-4245-BD80-25B8DE698EE3}.Release|x64.ActiveCfg = Release|x64
{A80355C2-780D-4245-BD80-25B8DE698EE3}.Release|x64.Build.0 = Release|x64
{A80355C2-780D-4245-BD80-25B8DE698EE3}.Release|x86.ActiveCfg = Release|x64
{A80355C2-780D-4245-BD80-25B8DE698EE3}.Release|x86.Build.0 = Release|x64
{A80355C2-780D-4245-BD80-25B8DE698EE3}.Release|x86.Deploy.0 = Release|x64
{F055103B-F80B-4D0C-BF48-057C55620033}.Debug|ARM.ActiveCfg = Debug|x64
{F055103B-F80B-4D0C-BF48-057C55620033}.Debug|ARM64.ActiveCfg = Debug|x64
{F055103B-F80B-4D0C-BF48-057C55620033}.Debug|x64.ActiveCfg = Debug|x64
{F055103B-F80B-4D0C-BF48-057C55620033}.Debug|x64.Build.0 = Debug|x64
{F055103B-F80B-4D0C-BF48-057C55620033}.Debug|x86.ActiveCfg = Debug|x64
{F055103B-F80B-4D0C-BF48-057C55620033}.Release|ARM.ActiveCfg = Release|x64
{F055103B-F80B-4D0C-BF48-057C55620033}.Release|ARM64.ActiveCfg = Release|x64
{F055103B-F80B-4D0C-BF48-057C55620033}.Release|x64.ActiveCfg = Release|x64
{F055103B-F80B-4D0C-BF48-057C55620033}.Release|x64.Build.0 = Release|x64
{F055103B-F80B-4D0C-BF48-057C55620033}.Release|x86.ActiveCfg = Release|x64
{985B3F2F-CEED-4C0A-A249-69257E719145}.Debug|ARM.ActiveCfg = Debug|x64
{985B3F2F-CEED-4C0A-A249-69257E719145}.Debug|ARM64.ActiveCfg = Debug|x64
{985B3F2F-CEED-4C0A-A249-69257E719145}.Debug|x64.ActiveCfg = Debug|x64
{985B3F2F-CEED-4C0A-A249-69257E719145}.Debug|x64.Build.0 = Debug|x64
{985B3F2F-CEED-4C0A-A249-69257E719145}.Debug|x86.ActiveCfg = Debug|x64
{985B3F2F-CEED-4C0A-A249-69257E719145}.Release|ARM.ActiveCfg = Release|x64
{985B3F2F-CEED-4C0A-A249-69257E719145}.Release|ARM64.ActiveCfg = Release|x64
{985B3F2F-CEED-4C0A-A249-69257E719145}.Release|x64.ActiveCfg = Release|x64
{985B3F2F-CEED-4C0A-A249-69257E719145}.Release|x64.Build.0 = Release|x64
{985B3F2F-CEED-4C0A-A249-69257E719145}.Release|x86.ActiveCfg = Release|x64
{437AD818-3F1F-4CA5-A79B-25233A157026}.Debug|ARM.ActiveCfg = Debug|x64
{437AD818-3F1F-4CA5-A79B-25233A157026}.Debug|ARM64.ActiveCfg = Debug|x64
{437AD818-3F1F-4CA5-A79B-25233A157026}.Debug|x64.ActiveCfg = Debug|x64
{437AD818-3F1F-4CA5-A79B-25233A157026}.Debug|x64.Build.0 = Debug|x64
{437AD818-3F1F-4CA5-A79B-25233A157026}.Debug|x86.ActiveCfg = Debug|x64
{437AD818-3F1F-4CA5-A79B-25233A157026}.Release|ARM.ActiveCfg = Release|x64
{437AD818-3F1F-4CA5-A79B-25233A157026}.Release|ARM64.ActiveCfg = Release|x64
{437AD818-3F1F-4CA5-A79B-25233A157026}.Release|x64.ActiveCfg = Release|x64
{437AD818-3F1F-4CA5-A79B-25233A157026}.Release|x64.Build.0 = Release|x64
{437AD818-3F1F-4CA5-A79B-25233A157026}.Release|x86.ActiveCfg = Release|x64
{787B8AA6-CA93-4C84-96FE-DF31110AD1C4}.Debug|ARM.ActiveCfg = Debug|x64
{787B8AA6-CA93-4C84-96FE-DF31110AD1C4}.Debug|ARM64.ActiveCfg = Debug|x64
{787B8AA6-CA93-4C84-96FE-DF31110AD1C4}.Debug|x64.ActiveCfg = Debug|x64
{787B8AA6-CA93-4C84-96FE-DF31110AD1C4}.Debug|x64.Build.0 = Debug|x64
{787B8AA6-CA93-4C84-96FE-DF31110AD1C4}.Debug|x86.ActiveCfg = Debug|x64
{787B8AA6-CA93-4C84-96FE-DF31110AD1C4}.Release|ARM.ActiveCfg = Release|x64
{787B8AA6-CA93-4C84-96FE-DF31110AD1C4}.Release|ARM64.ActiveCfg = Release|x64
{787B8AA6-CA93-4C84-96FE-DF31110AD1C4}.Release|x64.ActiveCfg = Release|x64
{787B8AA6-CA93-4C84-96FE-DF31110AD1C4}.Release|x64.Build.0 = Release|x64
{787B8AA6-CA93-4C84-96FE-DF31110AD1C4}.Release|x86.ActiveCfg = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -431,6 +938,21 @@ Global
{17DA04DF-E393-4397-9CF0-84DABE11032E} = {1AFB6476-670D-4E80-A464-657E01DFF482}
{38BDB927-829B-4C65-9CD9-93FB05D66D65} = {4574FDD0-F61D-4376-98BF-E5A1262C11EC}
{8AFFA899-0B73-49EC-8C50-0FADDA57B2FC} = {38BDB927-829B-4C65-9CD9-93FB05D66D65}
{C140A3EF-6DBF-4084-9D4C-4EB5A99FEE68} = {4574FDD0-F61D-4376-98BF-E5A1262C11EC}
{DB90F671-D861-46BB-93A3-F1304F5BA1C5} = {C140A3EF-6DBF-4084-9D4C-4EB5A99FEE68}
{B749F0DB-8E75-47DB-9E5E-265D16D0C0D2} = {C140A3EF-6DBF-4084-9D4C-4EB5A99FEE68}
{4FD29318-A8AB-4D8F-AA47-60BC241B8DA3} = {C140A3EF-6DBF-4084-9D4C-4EB5A99FEE68}
{8451ECDD-2EA4-4966-BB0A-7BBC40138E80} = {C140A3EF-6DBF-4084-9D4C-4EB5A99FEE68}
{FF742965-9A80-41A5-B042-D6C7D3A21708} = {C140A3EF-6DBF-4084-9D4C-4EB5A99FEE68}
{4AFC9975-2456-4C70-94A4-84073C1CED93} = {C140A3EF-6DBF-4084-9D4C-4EB5A99FEE68}
{59BD9891-3837-438A-958D-ADC7F91F6F7E} = {4AFC9975-2456-4C70-94A4-84073C1CED93}
{74F1B9ED-F59C-4FE7-B473-7B453E30837E} = {4AFC9975-2456-4C70-94A4-84073C1CED93}
{FDB3555B-58EF-4AE6-B5F1-904719637AB4} = {4AFC9975-2456-4C70-94A4-84073C1CED93}
{C21BFF9C-2C99-4B5F-B7C9-A5E6DDDB37B0} = {4AFC9975-2456-4C70-94A4-84073C1CED93}
{F8B870EB-D5F5-45BA-9CF7-A5C459818820} = {4AFC9975-2456-4C70-94A4-84073C1CED93}
{E364F67B-BB12-4E91-B639-355866EBCD8B} = {C140A3EF-6DBF-4084-9D4C-4EB5A99FEE68}
{F97E5003-F263-4D4A-A964-0F1F3C82DEF2} = {C140A3EF-6DBF-4084-9D4C-4EB5A99FEE68}
{4A3DE70C-684C-410D-B851-C23B6DAEDF16} = {C140A3EF-6DBF-4084-9D4C-4EB5A99FEE68}
{880ED251-9E16-4713-9A70-D35FE0C01669} = {E775CC2C-24CB-48D6-9C3A-BE4CCE0DB17A}
{2F305555-C296-497E-AC20-5FA1B237996A} = {4574FDD0-F61D-4376-98BF-E5A1262C11EC}
{AF2349B8-E5B6-4004-9502-687C1C7730B1} = {2F305555-C296-497E-AC20-5FA1B237996A}
@ -448,6 +970,7 @@ Global
{F055103B-F80B-4D0C-BF48-057C55620033} = {1AFB6476-670D-4E80-A464-657E01DFF482}
{985B3F2F-CEED-4C0A-A249-69257E719145} = {1AFB6476-670D-4E80-A464-657E01DFF482}
{437AD818-3F1F-4CA5-A79B-25233A157026} = {1AFB6476-670D-4E80-A464-657E01DFF482}
{787B8AA6-CA93-4C84-96FE-DF31110AD1C4} = {4AFC9975-2456-4C70-94A4-84073C1CED93}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {C3A2F9D1-7930-4EF4-A6FC-7EE0A99821D0}

File diff suppressed because one or more lines are too long

View file

@ -29,9 +29,7 @@
<ProjectName>common</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<ImportGroup Label="Shared">
<Import Project="..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.190716.2\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.190716.2\build\native\Microsoft.Windows.ImplementationLibrary.targets')" />
</ImportGroup>
<ImportGroup Label="Shared" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
@ -179,11 +177,12 @@
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
<Import Project="..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.191107.2\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.191107.2\build\native\Microsoft.Windows.ImplementationLibrary.targets')" />
</ImportGroup>
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.190716.2\build\native\Microsoft.Windows.ImplementationLibrary.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.190716.2\build\native\Microsoft.Windows.ImplementationLibrary.targets'))" />
<Error Condition="!Exists('..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.191107.2\build\native\Microsoft.Windows.ImplementationLibrary.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.191107.2\build\native\Microsoft.Windows.ImplementationLibrary.targets'))" />
</Target>
</Project>

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200117.5\build\native\Microsoft.Windows.CppWinRT.props" Condition="Exists('..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200117.5\build\native\Microsoft.Windows.CppWinRT.props')" />
<Import Project="..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200316.3\build\native\Microsoft.Windows.CppWinRT.props" Condition="Exists('..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200316.3\build\native\Microsoft.Windows.CppWinRT.props')" />
<PropertyGroup Label="Globals">
<CppWinRTOptimized>true</CppWinRTOptimized>
<CppWinRTRootNamespaceAutoMerge>true</CppWinRTRootNamespaceAutoMerge>
@ -147,13 +147,13 @@
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
<Import Project="..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200117.5\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200117.5\build\native\Microsoft.Windows.CppWinRT.targets')" />
<Import Project="..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200316.3\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200316.3\build\native\Microsoft.Windows.CppWinRT.targets')" />
</ImportGroup>
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200117.5\build\native\Microsoft.Windows.CppWinRT.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200117.5\build\native\Microsoft.Windows.CppWinRT.props'))" />
<Error Condition="!Exists('..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200117.5\build\native\Microsoft.Windows.CppWinRT.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200117.5\build\native\Microsoft.Windows.CppWinRT.targets'))" />
<Error Condition="!Exists('..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200316.3\build\native\Microsoft.Windows.CppWinRT.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200316.3\build\native\Microsoft.Windows.CppWinRT.props'))" />
<Error Condition="!Exists('..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200316.3\build\native\Microsoft.Windows.CppWinRT.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200316.3\build\native\Microsoft.Windows.CppWinRT.targets'))" />
</Target>
</Project>

View file

@ -18,11 +18,9 @@
<ClInclude Include="pch.h" />
<ClInclude Include="handler_functions.h" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<None Include="PropertySheet.props" />
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<Midl Include="BackgroundHandler.idl" />

View file

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.Windows.CppWinRT" version="2.0.200117.5" targetFramework="native" />
<package id="Microsoft.Windows.CppWinRT" version="2.0.200316.3" targetFramework="native" />
</packages>

View file

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.Windows.ImplementationLibrary" version="1.0.190716.2" targetFramework="native" />
<package id="Microsoft.Windows.ImplementationLibrary" version="1.0.191107.2" targetFramework="native" />
</packages>

View file

@ -16,6 +16,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib
this.FileExplorerPreview = false;
this.PowerRename = false;
this.ShortcutGuide = false;
this.PowerLauncher = true;
}
[JsonPropertyName("FancyZones")]
@ -34,6 +35,9 @@ namespace Microsoft.PowerToys.Settings.UI.Lib
[JsonPropertyName("Keyboard Manager")]
public bool KeyboardManager { get; set; }
[JsonPropertyName("Launcher")]
public bool PowerLauncher { get; set; }
public string ToJsonString()
{

View file

@ -2,6 +2,7 @@
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using Microsoft.PowerToys.Settings.UI.Lib.Utilities;
using System.Text;
using System.Text.Json.Serialization;
@ -61,8 +62,19 @@ namespace Microsoft.PowerToys.Settings.UI.Lib
output.Append("Shift + ");
}
output.Append(Key);
var localKey = Helper.GetKeyName((uint) Code);
output.Append(localKey);
return output.ToString();
}
public bool IsValid()
{
return (Alt || Ctrl || Win || Shift) && Code != 0;
}
public bool IsEmpty()
{
return !Alt && !Ctrl && !Win && !Shift && Code == 0;
}
}
}

View file

@ -6,8 +6,6 @@ namespace Microsoft.PowerToys.Settings.UI.Lib
{
public class PowerLauncherProperties
{
public bool enable_powerlauncher { get; set; }
public string search_result_preference { get; set; }
public string search_type_preference { get; set; }

View file

@ -8,7 +8,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib
{
public class PowerLauncherSettings : BasePTModuleSettings
{
public const string POWERTOYNAME = "PowerLauncher";
public const string POWERTOYNAME = "Launcher";
public PowerLauncherProperties properties { get; set; }
@ -16,7 +16,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib
{
properties = new PowerLauncherProperties();
version = "1";
name = "_unset_";
name = POWERTOYNAME;
}
public virtual void Save()

View file

@ -23,6 +23,7 @@ namespace Microsoft.PowerToys.Settings.UI.Controls
null);
private HotkeySettings hotkeySettings;
private HotkeySettings internalSettings = new HotkeySettings();
public HotkeySettings HotkeySettings
{
@ -45,7 +46,10 @@ namespace Microsoft.PowerToys.Settings.UI.Controls
public HotkeySettingsControl()
{
InitializeComponent();
internalSettings = new HotkeySettings();
HotkeyTextBox.PreviewKeyDown += HotkeyTextBox_KeyDown;
HotkeyTextBox.LostFocus += HotkeyTextBox_LosingFocus;
}
private static bool IsDown(Windows.System.VirtualKey key)
@ -66,6 +70,13 @@ namespace Microsoft.PowerToys.Settings.UI.Controls
return;
}
if (e.Key == Windows.System.VirtualKey.Escape)
{
internalSettings = new HotkeySettings();
HotkeySettings = new HotkeySettings();
return;
}
var settings = new HotkeySettings();
// Display HotKey value
@ -92,9 +103,19 @@ namespace Microsoft.PowerToys.Settings.UI.Controls
settings.Key = Lib.Utilities.Helper.GetKeyName((uint)e.Key);
// TODO: Check that e.OriginalKey is the ScanCode. It is not clear from docs.
settings.Code = (int)e.OriginalKey;
HotkeySettings = settings;
internalSettings = settings;
HotkeyTextBox.Text = internalSettings.ToString();
}
private void HotkeyTextBox_LosingFocus(object sender, RoutedEventArgs e)
{
if (internalSettings.IsValid() || internalSettings.IsEmpty())
{
HotkeySettings = internalSettings;
}
HotkeyTextBox.Text = hotkeySettings.ToString();
}
}
}

View file

@ -134,7 +134,7 @@
<comment>Navigation view item name for General</comment>
</data>
<data name="Shell_PowerLauncher.Content" xml:space="preserve">
<value>PowerLauncher [Not Functional]</value>
<value>PowerLauncher</value>
<comment>Navigation view item name for PowerLauncher</comment>
</data>
<data name="Shell_PowerRename.Content" xml:space="preserve">

View file

@ -13,13 +13,20 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
public class PowerLauncherViewModel : Observable
{
private PowerLauncherSettings settings;
private GeneralSettings generalSettings;
public delegate void SendCallback(PowerLauncherSettings settings);
private readonly SendCallback callback;
public PowerLauncherViewModel()
{
{
callback = (PowerLauncherSettings settings) =>
{
// Propagate changes to Power Launcher through IPC
ShellPage.DefaultSndMSGCallback(
string.Format("{{ \"powertoys\": {{ \"{0}\": {1} }} }}", PowerLauncherSettings.POWERTOYNAME, JsonSerializer.Serialize(settings)));
};
if (SettingsUtils.SettingsExists(PowerLauncherSettings.POWERTOYNAME))
{
settings = SettingsUtils.GetSettings<PowerLauncherSettings>(PowerLauncherSettings.POWERTOYNAME);
@ -27,15 +34,20 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
else
{
settings = new PowerLauncherSettings();
settings.properties.open_powerlauncher.Alt = true;
settings.properties.open_powerlauncher.Code = (int)Windows.System.VirtualKey.Space;
settings.properties.maximum_number_of_results = 4;
callback(settings);
}
callback = (PowerLauncherSettings settings) =>
if (SettingsUtils.SettingsExists())
{
// Propagate changes to Power Launcher through IPC
var propertiesJson = JsonSerializer.Serialize(settings.properties);
ShellPage.DefaultSndMSGCallback(
string.Format("{{ \"{0}\": {1} }}", PowerLauncherSettings.POWERTOYNAME, JsonSerializer.Serialize(settings.properties)));
};
generalSettings = SettingsUtils.GetSettings<GeneralSettings>();
}
else
{
generalSettings = new GeneralSettings();
}
}
public PowerLauncherViewModel(PowerLauncherSettings settings, SendCallback callback)
@ -49,7 +61,6 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
// Notify UI of property change
OnPropertyChanged(propertyName);
settings.Save();
callback(settings);
}
@ -57,15 +68,17 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
{
get
{
return settings.properties.enable_powerlauncher;
return generalSettings.Enabled.PowerLauncher;
}
set
{
if (settings.properties.enable_powerlauncher != value)
if (generalSettings.Enabled.PowerLauncher != value)
{
settings.properties.enable_powerlauncher = value;
UpdateSettings();
generalSettings.Enabled.PowerLauncher = value;
OnPropertyChanged(nameof(EnablePowerLauncher));
OutGoingGeneralSettings outgoing = new OutGoingGeneralSettings(generalSettings);
ShellPage.DefaultSndMSGCallback(outgoing.ToString());
}
}
}

View file

@ -61,6 +61,7 @@
SelectedItem="{x:Bind Mode=TwoWay, Path=SelectedSearchResultPreference}"
SelectedValuePath="Item2"
DisplayMemberPath="Item1"
IsEnabled="False"
/>
<ComboBox x:Uid="PowerLauncher_SearchTypePreference"
@ -70,6 +71,7 @@
SelectedItem="{x:Bind Mode=TwoWay, Path=SelectedSearchTypePreference}"
SelectedValuePath="Item2"
DisplayMemberPath="Item1"
IsEnabled="False"
/>
<muxc:NumberBox x:Uid="PowerLauncher_MaximumNumberOfResults"
@ -78,7 +80,8 @@
SpinButtonPlacementMode="Inline"
HorizontalAlignment="Left"
Margin="{StaticResource SmallTopMargin}"
Minimum="1"/>
Minimum="1"
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.EnablePowerLauncher}"/>
<TextBlock x:Uid="PowerLauncher_Shortcuts"
Width="320"
@ -90,37 +93,42 @@
HorizontalAlignment="Left"
Margin="{StaticResource SmallTopMargin}"
HotkeySettings="{x:Bind Path=ViewModel.OpenPowerLauncher, Mode=TwoWay}"
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.EnablePowerLauncher}"
/>
<Custom:HotkeySettingsControl x:Uid="PowerLauncher_OpenFileLocation"
Width="320"
HorizontalAlignment="Left"
Margin="{StaticResource SmallTopMargin}"
HotkeySettings="{x:Bind Path=ViewModel.OpenFileLocation, Mode=TwoWay}"
IsEnabled="False"
/>
<Custom:HotkeySettingsControl x:Uid="PowerLauncher_CopyPathLocation"
Width="320"
HorizontalAlignment="Left"
Margin="{StaticResource SmallTopMargin}"
HotkeySettings="{x:Bind Path=ViewModel.CopyPathLocation, Mode=TwoWay}"
IsEnabled="False"
/>
<Custom:HotkeySettingsControl x:Uid="PowerLauncher_OpenConsole"
Width="320"
HorizontalAlignment="Left"
Margin="{StaticResource SmallTopMargin}"
HotkeySettings="{x:Bind Path=ViewModel.OpenConsole, Mode=TwoWay}"
IsEnabled="False"
/>
<CheckBox x:Uid="PowerLauncher_OverrideWinRKey"
Margin="{StaticResource SmallTopMargin}"
IsChecked="{x:Bind Mode=TwoWay, Path=ViewModel.OverrideWinRKey}"/>
IsChecked="{x:Bind Mode=TwoWay, Path=ViewModel.OverrideWinRKey}"
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.EnablePowerLauncher}"
/>
<CheckBox x:Uid="PowerLauncher_OverrideWinSKey"
Margin="{StaticResource SmallTopMargin}"
IsChecked="{x:Bind Mode=TwoWay, Path=ViewModel.OverrideWinSKey}" />
IsChecked="{x:Bind Mode=TwoWay, Path=ViewModel.OverrideWinSKey}"
IsEnabled="False"
/>
</StackPanel>
<StackPanel
x:Name="SidePanel"
Orientation="Vertical"

View file

@ -47,17 +47,6 @@ namespace ViewModelTests
);
}
[TestMethod]
public void IsEnabled_ShouldEnableModule()
{
viewModel.EnablePowerLauncher = true;
Assert.AreEqual(sendCallbackMock.TimesSent, 1);
Assert.AreEqual(mockSettings.TimesSaved, 1);
Assert.IsTrue(mockSettings.properties.enable_powerlauncher == true);
}
[TestMethod]
public void SearchPreference_ShouldUpdatePreferences()
{

View file

@ -36,7 +36,7 @@
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
<Import Project="..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.190716.2\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.190716.2\build\native\Microsoft.Windows.ImplementationLibrary.targets')" />
<Import Project="..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.191107.2\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.191107.2\build\native\Microsoft.Windows.ImplementationLibrary.targets')" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
@ -121,16 +121,16 @@
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
<ResourceCompile Include="..\lib\fancyzones.rc" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="..\lib\fancyzones.rc" />
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.190716.2\build\native\Microsoft.Windows.ImplementationLibrary.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.190716.2\build\native\Microsoft.Windows.ImplementationLibrary.targets'))" />
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.191107.2\build\native\Microsoft.Windows.ImplementationLibrary.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.191107.2\build\native\Microsoft.Windows.ImplementationLibrary.targets'))" />
</Target>
</Project>

View file

@ -24,10 +24,10 @@
<UniqueIdentifier>{2f10207d-d8d1-4a42-8027-8ca597b3cb23}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="..\lib\fancyzones.rc" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
</Project>

View file

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.Windows.ImplementationLibrary" version="1.0.190716.2" targetFramework="native" />
<package id="Microsoft.Windows.ImplementationLibrary" version="1.0.191107.2" targetFramework="native" />
</packages>

View file

@ -131,12 +131,12 @@
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
<Import Project="..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.190716.2\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.190716.2\build\native\Microsoft.Windows.ImplementationLibrary.targets')" />
<Import Project="..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.191107.2\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.191107.2\build\native\Microsoft.Windows.ImplementationLibrary.targets')" />
</ImportGroup>
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.190716.2\build\native\Microsoft.Windows.ImplementationLibrary.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.190716.2\build\native\Microsoft.Windows.ImplementationLibrary.targets'))" />
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.191107.2\build\native\Microsoft.Windows.ImplementationLibrary.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.191107.2\build\native\Microsoft.Windows.ImplementationLibrary.targets'))" />
</Target>
</Project>

View file

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.Windows.ImplementationLibrary" version="1.0.190716.2" targetFramework="native" />
<package id="Microsoft.Windows.ImplementationLibrary" version="1.0.191107.2" targetFramework="native" />
</packages>

View file

@ -130,12 +130,12 @@
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
<Import Project="..\..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.190716.2\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('..\..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.190716.2\build\native\Microsoft.Windows.ImplementationLibrary.targets')" />
<Import Project="..\..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.191107.2\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('..\..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.191107.2\build\native\Microsoft.Windows.ImplementationLibrary.targets')" />
</ImportGroup>
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.190716.2\build\native\Microsoft.Windows.ImplementationLibrary.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.190716.2\build\native\Microsoft.Windows.ImplementationLibrary.targets'))" />
<Error Condition="!Exists('..\..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.191107.2\build\native\Microsoft.Windows.ImplementationLibrary.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.191107.2\build\native\Microsoft.Windows.ImplementationLibrary.targets'))" />
</Target>
</Project>

View file

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.Windows.ImplementationLibrary" version="1.0.190716.2" targetFramework="native" />
<package id="Microsoft.Windows.ImplementationLibrary" version="1.0.191107.2" targetFramework="native" />
</packages>

View file

@ -0,0 +1,14 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="KillPowerLauncher" BeforeTargets="PreBuildEvent;BeforeClean">
<Message Text="Killing process 'PowerLauncher.exe'" Importance="normal" ContinueOnError="true" />
<Exec Command="taskkill /F /IM PowerLauncher.exe"
IgnoreExitCode="true"
IgnoreStandardErrorWarningFormat="true">
<Output TaskParameter="ExitCode" PropertyName="ErrorCode"/>
</Exec>
<Error Text="Cannot kill PowerLauncher.exe process." Condition="$(ErrorCode) == 1"/>
<Message Text="Process PowerLauncher.exe does not exist." Condition="$(ErrorCode) == 128"/>
</Target>
</Project>

View file

@ -0,0 +1,115 @@
# -*- coding: utf-8 -*-
from __future__ import print_function
import json
import sys
import inspect
class Wox(object):
"""
Wox python plugin base
"""
def __init__(self):
rpc_request = json.loads(sys.argv[1])
# proxy is not working now
self.proxy = rpc_request.get("proxy",{})
request_method_name = rpc_request.get("method")
request_parameters = rpc_request.get("parameters")
methods = inspect.getmembers(self, predicate=inspect.ismethod)
request_method = dict(methods)[request_method_name]
results = request_method(*request_parameters)
if request_method_name == "query" or request_method_name == "context_menu":
print(json.dumps({"result": results}))
def query(self,query):
"""
sub class need to override this method
"""
return []
def context_menu(self, data):
"""
optional context menu entries for a result
"""
return []
def debug(self,msg):
"""
alert msg
"""
print("DEBUG:{}".format(msg))
sys.exit()
class WoxAPI(object):
@classmethod
def change_query(cls,query,requery = False):
"""
change wox query
"""
print(json.dumps({"method": "Wox.ChangeQuery","parameters":[query,requery]}))
@classmethod
def shell_run(cls,cmd):
"""
run shell commands
"""
print(json.dumps({"method": "Wox.ShellRun","parameters":[cmd]}))
@classmethod
def close_app(cls):
"""
close wox
"""
print(json.dumps({"method": "Wox.CloseApp","parameters":[]}))
@classmethod
def hide_app(cls):
"""
hide wox
"""
print(json.dumps({"method": "Wox.HideApp","parameters":[]}))
@classmethod
def show_app(cls):
"""
show wox
"""
print(json.dumps({"method": "Wox.ShowApp","parameters":[]}))
@classmethod
def show_msg(cls,title,sub_title,ico_path=""):
"""
show messagebox
"""
print(json.dumps({"method": "Wox.ShowMsg","parameters":[title,sub_title,ico_path]}))
@classmethod
def open_setting_dialog(cls):
"""
open setting dialog
"""
print(json.dumps({"method": "Wox.OpenSettingDialog","parameters":[]}))
@classmethod
def start_loadingbar(cls):
"""
start loading animation in wox
"""
print(json.dumps({"method": "Wox.StartLoadingBar","parameters":[]}))
@classmethod
def stop_loadingbar(cls):
"""
stop loading animation in wox
"""
print(json.dumps({"method": "Wox.StopLoadingBar","parameters":[]}))
@classmethod
def reload_plugins(cls):
"""
reload all wox plugins
"""
print(json.dumps({"method": "Wox.ReloadPlugins","parameters":[]}))

View file

@ -0,0 +1,20 @@
The MIT License (MIT)
Copyright (c) 2015 Wox
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View file

@ -0,0 +1,40 @@
#include "resource.h"
<EFBFBD>
匀吀刀䤀一䜀吀䄀䈀䰀䔀ഀ<EFBFBD>
䈀䔀䜀䤀一ഀ<EFBFBD>
    䤀䐀匀开䰀䄀唀一䌀䠀䔀刀开一䄀䴀䔀 䰀∀䰀愀甀渀挀栀攀爀∀ <EFBFBD>
    䤀䐀匀开䰀䄀唀一䌀䠀䔀刀开匀䔀吀吀䤀一䜀匀开䐀䔀匀䌀 䰀∀㰀一漀 搀攀猀挀爀椀瀀琀椀漀渀㸀∀ഀ<EFBFBD>
䔀一䐀ഀ<EFBFBD>
<EFBFBD>
 嘀䔀刀匀䤀伀一䤀一䘀伀ഀ<EFBFBD>
 䘀䤀䰀䔀嘀䔀刀匀䤀伀一  Ⰰ㄀Ⰰ  <EFBFBD>
 倀刀伀䐀唀䌀吀嘀䔀刀匀䤀伀一  Ⰰ㄀Ⰰ  <EFBFBD>
 䘀䤀䰀䔀䘀䰀䄀䜀匀䴀䄀匀䬀  砀㌀昀䰀ഀ<EFBFBD>
⌀椀昀搀攀昀 开䐀䔀䈀唀䜀ഀ<EFBFBD>
 䘀䤀䰀䔀䘀䰀䄀䜀匀  砀㄀䰀ഀ<EFBFBD>
⌀攀氀猀攀ഀ<EFBFBD>
 䘀䤀䰀䔀䘀䰀䄀䜀匀   䰀ഀ<EFBFBD>
⌀攀渀搀椀昀ഀ<EFBFBD>
 䘀䤀䰀䔀伀匀  砀㐀   㐀䰀ഀ<EFBFBD>
 䘀䤀䰀䔀吀夀倀䔀  砀㈀䰀ഀ<EFBFBD>
 䘀䤀䰀䔀匀唀䈀吀夀倀䔀   䰀ഀ<EFBFBD>
䈀䔀䜀䤀一ഀ<EFBFBD>
    䈀䰀伀䌀䬀 ∀匀琀爀椀渀最䘀椀氀攀䤀渀昀漀∀ഀ<EFBFBD>
    䈀䔀䜀䤀一ഀ<EFBFBD>
        䈀䰀伀䌀䬀    㐀戀 ∀ഀ<EFBFBD>
        䈀䔀䜀䤀一ഀ<EFBFBD>
            嘀䄀䰀唀䔀 ∀䌀漀洀瀀愀渀礀一愀洀攀∀Ⰰ ∀䌀漀洀瀀愀渀礀 一愀洀攀∀ഀ<EFBFBD>
            嘀䄀䰀唀䔀 ∀䘀椀氀攀䐀攀猀挀爀椀瀀琀椀漀渀∀Ⰰ ∀圀漀砀⸀䰀愀甀渀挀栀攀爀 䴀漀搀甀氀攀∀ഀ<EFBFBD>
            嘀䄀䰀唀䔀 ∀䘀椀氀攀嘀攀爀猀椀漀渀∀Ⰰ  ⸀㄀⸀  ∀ഀ<EFBFBD>
            嘀䄀䰀唀䔀 ∀䤀渀琀攀爀渀愀氀一愀洀攀∀Ⰰ ∀圀漀砀⸀䰀愀甀渀挀栀攀爀∀ഀ<EFBFBD>
            嘀䄀䰀唀䔀 ∀䰀攀最愀氀䌀漀瀀礀爀椀最栀琀∀Ⰰ ∀䌀漀瀀礀爀椀最栀琀 䌀⤀  ㄀㤀 䌀漀洀瀀愀渀礀 一愀洀攀∀ഀ<EFBFBD>
            嘀䄀䰀唀䔀 ∀伀爀椀最椀渀愀氀䘀椀氀攀渀愀洀攀∀Ⰰ ∀圀漀砀⸀䰀愀甀渀挀栀攀爀⸀搀氀氀∀ഀ<EFBFBD>
            嘀䄀䰀唀䔀 ∀倀爀漀搀甀挀琀一愀洀攀∀Ⰰ ∀圀漀砀⸀䰀愀甀渀挀栀攀爀∀ഀ<EFBFBD>
            嘀䄀䰀唀䔀 ∀倀爀漀搀甀挀琀嘀攀爀猀椀漀渀∀Ⰰ  ⸀㄀⸀  ∀ഀ<EFBFBD>
        䔀一䐀ഀ<EFBFBD>
    䔀一䐀ഀ<EFBFBD>
    䈀䰀伀䌀䬀 ∀嘀愀爀䘀椀氀攀䤀渀昀漀∀ഀ<EFBFBD>
    䈀䔀䜀䤀一ഀ<EFBFBD>
        嘀䄀䰀唀䔀 ∀吀爀愀渀猀氀愀琀椀漀渀∀Ⰰ  砀㐀 㤀Ⰰ ㄀㈀  <EFBFBD>
    䔀一䐀ഀ<EFBFBD>
䔀一䐀<EFBFBD>

View file

@ -0,0 +1,123 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>15.0</VCProjectVersion>
<ProjectGuid>{e364f67b-bb12-4e91-b639-355866ebcd8b}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>Wox_Launcher</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
<ProjectName>Microsoft.Launcher</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\modules\</OutDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\modules\</OutDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_DEBUG;EXAMPLEPOWERTOY_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<AdditionalIncludeDirectories>..\..\..\common\inc;..\..\..\common\Telemetry;..\..\;..\..\..\;..\..\..\..\deps\cpprestsdk\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<LanguageStandard>stdcpplatest</LanguageStandard>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NDEBUG;EXAMPLEPOWERTOY_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<AdditionalIncludeDirectories>..\..\..\common\inc;..\..\..\common\Telemetry;..\..\;..\..\..\;..\..\..\..\deps\cpprestsdk\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<LanguageStandard>stdcpplatest</LanguageStandard>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="pch.h" />
<ClInclude Include="resource.h" />
<ClInclude Include="trace.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="dllmain.cpp" />
<ClCompile Include="pch.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">pch.h</PrecompiledHeaderFile>
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|x64'">pch.h</PrecompiledHeaderFile>
</ClCompile>
<ClCompile Include="trace.cpp" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\common\common.vcxproj">
<Project>{74485049-c722-400f-abe5-86ac52d929b3}</Project>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="Microsoft.Launcher.rc" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View file

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<ClCompile Include="pch.cpp" />
<ClCompile Include="dllmain.cpp" />
<ClCompile Include="trace.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="pch.h" />
<ClInclude Include="trace.h" />
<ClInclude Include="resource.h" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="Microsoft.Launcher.rc" />
</ItemGroup>
</Project>

View file

@ -0,0 +1,197 @@
#include "pch.h"
#include <interface/powertoy_module_interface.h>
#include <interface/lowlevel_keyboard_event_data.h>
#include <interface/win_hook_event_data.h>
#include <common/settings_objects.h>
#include "trace.h"
#include "resource.h"
extern "C" IMAGE_DOS_HEADER __ImageBase;
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
switch (ul_reason_for_call) {
case DLL_PROCESS_ATTACH:
Trace::RegisterProvider();
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH:
Trace::UnregisterProvider();
break;
}
return TRUE;
}
// These are the properties shown in the Settings page.
struct ModuleSettings {
} g_settings;
// Implement the PowerToy Module Interface and all the required methods.
class Microsoft_Launcher : public PowertoyModuleIface {
private:
// The PowerToy state.
bool m_enabled = false;
// Load initial settings from the persisted values.
void init_settings();
// Handle to launch and terminate the launcher
HANDLE m_hProcess;
//contains the name of the powerToys
std::wstring app_name;
public:
// Constructor
Microsoft_Launcher() {
app_name = GET_RESOURCE_STRING(IDS_LAUNCHER_NAME);
init_settings();
};
~Microsoft_Launcher() {
if (m_enabled)
{
TerminateProcess(m_hProcess, 1);
}
m_enabled = false;
}
// Destroy the powertoy and free memory
virtual void destroy() override {
delete this;
}
// Return the display name of the powertoy, this will be cached by the runner
virtual const wchar_t* get_name() override {
return app_name.c_str();
}
// Return array of the names of all events that this powertoy listens for, with
// nullptr as the last element of the array. Nullptr can also be retured for empty
// list.
virtual const wchar_t** get_events() override {
static const wchar_t* events[] = { nullptr };
// Available events:
// - ll_keyboard
// - win_hook_event
//
// static const wchar_t* events[] = { ll_keyboard,
// win_hook_event,
// nullptr };
return events;
}
// Return JSON with the configuration options.
virtual bool get_config(wchar_t* buffer, int* buffer_size) override {
HINSTANCE hinstance = reinterpret_cast<HINSTANCE>(&__ImageBase);
// Create a Settings object.
PowerToysSettings::Settings settings(hinstance, get_name());
settings.set_description(GET_RESOURCE_STRING(IDS_LAUNCHER_SETTINGS_DESC));
return settings.serialize_to_buffer(buffer, buffer_size);
}
// Signal from the Settings editor to call a custom action.
// This can be used to spawn more complex editors.
virtual void call_custom_action(const wchar_t* action) override {
static UINT custom_action_num_calls = 0;
try {
// Parse the action values, including name.
PowerToysSettings::CustomActionObject action_object =
PowerToysSettings::CustomActionObject::from_json_string(action);
}
catch (std::exception ex) {
// Improper JSON.
}
}
// Called by the runner to pass the updated settings values as a serialized JSON.
virtual void set_config(const wchar_t* config) override {
try {
// Parse the input JSON string.
PowerToysSettings::PowerToyValues values =
PowerToysSettings::PowerToyValues::from_json_string(config);
// If you don't need to do any custom processing of the settings, proceed
// to persists the values calling:
values.save_to_settings_file();
// Otherwise call a custom function to process the settings before saving them to disk:
// save_settings();
}
catch (std::exception ex) {
// Improper JSON.
}
}
// Enable the powertoy
virtual void enable()
{
SHELLEXECUTEINFO sei{ sizeof(sei) };
sei.fMask = { SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_NO_UI };
sei.lpFile = L"modules\\launcher\\PowerLauncher.exe";
sei.nShow = SW_SHOWNORMAL;
ShellExecuteEx(&sei);
m_hProcess = sei.hProcess;
m_enabled = true;
}
// Disable the powertoy
virtual void disable()
{
if (m_enabled)
{
TerminateProcess(m_hProcess, 1);
}
m_enabled = false;
}
// Returns if the powertoys is enabled
virtual bool is_enabled() override {
return m_enabled;
}
// Handle incoming event, data is event-specific
virtual intptr_t signal_event(const wchar_t* name, intptr_t data) override {
if (wcscmp(name, ll_keyboard) == 0) {
auto& event = *(reinterpret_cast<LowlevelKeyboardEvent*>(data));
// Return 1 if the keypress is to be suppressed (not forwarded to Windows),
// otherwise return 0.
return 0;
}
else if (wcscmp(name, win_hook_event) == 0) {
auto& event = *(reinterpret_cast<WinHookEvent*>(data));
// Return value is ignored
return 0;
}
return 0;
}
/* Register helper class to handle system menu items related actions. */
virtual void register_system_menu_helper(PowertoySystemMenuIface* helper) {}
/* Handle action on system menu item. */
virtual void signal_system_menu_action(const wchar_t* name) {}
};
// Load the settings file.
void Microsoft_Launcher::init_settings() {
try {
// Load and parse the settings file for this PowerToy.
PowerToysSettings::PowerToyValues settings =
PowerToysSettings::PowerToyValues::load_from_settings_file(get_name());
}
catch (std::exception ex) {
// Error while loading from the settings file. Let default values stay as they are.
}
}
extern "C" __declspec(dllexport) PowertoyModuleIface* __cdecl powertoy_create() {
return new Microsoft_Launcher();
}

View file

@ -0,0 +1,3 @@
#include "pch.h"
#pragma comment(lib, "windowsapp")
#pragma comment(lib, "shlwapi.lib")

View file

@ -0,0 +1,7 @@
#pragma once
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <common/common.h>
#include <ProjectTelemetry.h>
#include <shellapi.h>
#include <Shlwapi.h>

View file

@ -0,0 +1,2 @@
#define IDS_LAUNCHER_NAME 601
#define IDS_LAUNCHER_SETTINGS_DESC 602

View file

@ -0,0 +1,26 @@
#include "pch.h"
#include "trace.h"
TRACELOGGING_DEFINE_PROVIDER(
g_hProvider,
"Microsoft.PowerToys",
// {38e8889b-9731-53f5-e901-e8a7c1753074}
(0x38e8889b, 0x9731, 0x53f5, 0xe9, 0x01, 0xe8, 0xa7, 0xc1, 0x75, 0x30, 0x74),
TraceLoggingOptionProjectTelemetry());
void Trace::RegisterProvider() {
TraceLoggingRegister(g_hProvider);
}
void Trace::UnregisterProvider() {
TraceLoggingUnregister(g_hProvider);
}
void Trace::MyEvent() {
TraceLoggingWrite(
g_hProvider,
"PowerToyName::Event::MyEvent",
ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance),
TraceLoggingBoolean(TRUE, "UTCReplace_AppSessionGuid"),
TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE));
}

View file

@ -0,0 +1,8 @@
#pragma once
class Trace {
public:
static void RegisterProvider();
static void UnregisterProvider();
static void MyEvent();
};

View file

@ -0,0 +1,104 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Windows;
using Wox.Infrastructure.Logger;
using Wox.Plugin;
using Microsoft.Plugin.Indexer.SearchHelper;
namespace Microsoft.Plugin.Indexer
{
internal class ContextMenuLoader : IContextMenu
{
private readonly PluginInitContext _context;
public enum ResultType
{
Folder,
File
}
public ContextMenuLoader(PluginInitContext context)
{
_context = context;
}
public List<ContextMenuResult> LoadContextMenus(Result selectedResult)
{
var contextMenus = new List<ContextMenuResult>();
if (selectedResult.ContextData is SearchResult record)
{
ResultType type = Path.HasExtension(record.Path) ? ResultType.File : ResultType.Folder;
if (type == ResultType.File)
{
contextMenus.Add(CreateOpenContainingFolderResult(record));
}
var fileOrFolder = (type == ResultType.File) ? "file" : "folder";
contextMenus.Add(new ContextMenuResult
{
Title = "Copy path",
Glyph = "\xE8C8",
FontFamily = "Segoe MDL2 Assets",
SubTitle = $"Copy the current {fileOrFolder} path to clipboard",
AcceleratorKey = "C",
AcceleratorModifiers = "Control",
Action = (context) =>
{
try
{
Clipboard.SetText(record.Path);
return true;
}
catch (Exception e)
{
var message = "Fail to set text in clipboard";
LogException(message, e);
_context.API.ShowMsg(message);
return false;
}
}
});
}
return contextMenus;
}
private ContextMenuResult CreateOpenContainingFolderResult(SearchResult record)
{
return new ContextMenuResult
{
Title = "Open containing folder",
Glyph = "\xE838",
FontFamily = "Segoe MDL2 Assets",
AcceleratorKey = "E",
AcceleratorModifiers = "Control,Shift",
Action = _ =>
{
try
{
Process.Start("explorer.exe", $" /select,\"{record.Path}\"");
}
catch(Exception e)
{
var message = $"Fail to open file at {record.Path}";
LogException(message, e);
_context.API.ShowMsg(message);
return false;
}
return true;
},
};
}
public void LogException(string message, Exception e)
{
Log.Exception($"|Wox.Plugin.Folder.ContextMenu|{message}", e);
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

View file

@ -0,0 +1,156 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Diagnostics;
using System.Text;
using System.Threading.Tasks;
using Wox.Plugin;
using System.IO;
using System.ComponentModel;
using Wox.Infrastructure.Storage;
using Microsoft.Plugin.Indexer.SearchHelper;
using Microsoft.Search.Interop;
using Microsoft.PowerToys.Settings.UI.Lib;
using System.Windows.Controls;
namespace Microsoft.Plugin.Indexer
{
class Main : ISettingProvider, IPlugin, ISavable, IPluginI18n, IContextMenu
{
// This variable contains metadata about the Plugin
private PluginInitContext _context;
// This variable contains information about the context menus
private Settings _settings;
// Contains information about the plugin stored in json format
private PluginJsonStorage<Settings> _storage;
// To access Windows Search functionalities
private readonly WindowsSearchAPI _api = new WindowsSearchAPI();
private IContextMenu _contextMenuLoader;
// To save the configurations of plugins
public void Save()
{
_storage.Save();
}
// This function uses the Windows indexer and returns the list of results obtained
public List<Result> Query(Query query)
{
var results = new List<Result>();
if (!string.IsNullOrEmpty(query.Search))
{
var searchQuery = query.Search;
if (_settings.MaxSearchCount <= 0)
{
_settings.MaxSearchCount = 50;
}
try
{
var searchResultsList = _api.Search(searchQuery, maxCount: _settings.MaxSearchCount).ToList();
foreach (var searchResult in searchResultsList)
{
var path = searchResult.Path;
string workingDir = null;
if (_settings.UseLocationAsWorkingDir)
workingDir = Path.GetDirectoryName(path);
Result r = new Result();
r.Title = searchResult.Title;
r.SubTitle = path;
r.IcoPath = path;
r.Action = c =>
{
bool hide;
try
{
Process.Start(new ProcessStartInfo
{
FileName = path,
UseShellExecute = true,
WorkingDirectory = workingDir
});
hide = true;
}
catch (Win32Exception)
{
var name = $"Plugin: {_context.CurrentPluginMetadata.Name}";
var msg = "Can't Open this file";
_context.API.ShowMsg(name, msg, string.Empty);
hide = false;
}
return hide;
};
r.ContextData = searchResult;
//If the result is a directory, then it's display should show a directory.
if(Directory.Exists(path))
{
r.QueryTextDisplay = path;
}
results.Add(r);
}
}
catch(InvalidOperationException)
{
//The connection has closed, internal error of ExecuteReader()
//Not showing this exception to the users
}
catch (Exception ex)
{
results.Add(new Result
{
Title = ex.ToString(),
IcoPath = "Images\\WindowsIndexerImg.bmp"
});
}
}
return results;
}
public void Init(PluginInitContext context)
{
// initialize the context of the plugin
_context = context;
_contextMenuLoader = new ContextMenuLoader(context);
_storage = new PluginJsonStorage<Settings>();
_settings = _storage.Load();
}
// TODO: Localize the strings
// Set the Plugin Title
public string GetTranslatedPluginTitle()
{
return "Windows Indexer Plugin";
}
// TODO: Localize the string
// Set the plugin Description
public string GetTranslatedPluginDescription()
{
return "Returns files and folders";
}
public List<ContextMenuResult> LoadContextMenus(Result selectedResult)
{
return _contextMenuLoader.LoadContextMenus(selectedResult);
}
public void UpdateSettings(PowerLauncherSettings settings)
{
_settings.MaxSearchCount = settings.properties.maximum_number_of_results;
}
public Control CreateSettingPanel()
{
throw new NotImplementedException();
}
}
}

View file

@ -0,0 +1,59 @@
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<ProjectGuid>{F8B870EB-D5F5-45BA-9CF7-A5C459818820}</ProjectGuid>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Microsoft.Plugin.Indexer</RootNamespace>
<AssemblyName>Microsoft.Plugin.Indexer</AssemblyName>
<useWPF>true</useWPF>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
<Platforms>x64</Platforms>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>..\..\..\..\..\x64\Debug\modules\launcher\Plugins\Microsoft.Plugin.Indexer\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>x64</PlatformTarget>
<LangVersion>7.3</LangVersion>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<WarningLevel>4</WarningLevel>
<Optimize>false</Optimize>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<OutputPath>..\..\..\..\..\x64\Release\modules\launcher\Plugins\Microsoft.Plugin.Indexer\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x64</PlatformTarget>
<LangVersion>7.3</LangVersion>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="System.Data.OleDb" Version="4.7.0" />
<PackageReference Include="tlbimp-Microsoft.Search.Interop" Version="1.0.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\core\Microsoft.PowerToys.Settings.UI.Lib\Microsoft.PowerToys.Settings.UI.Lib.csproj" />
<ProjectReference Include="..\..\Wox.Infrastructure\Wox.Infrastructure.csproj" />
</ItemGroup>
<ItemGroup>
<None Update="Images\WindowsIndexerImg.bmp">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="plugin.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>

View file

@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Microsoft.Plugin.Indexer.SearchHelper
{
public class SearchResult
{
// Contains the Path of the file or folder
public string Path { get; set; }
// Contains the Title of the file or folder
public string Title { get; set; }
}
}

View file

@ -0,0 +1,115 @@
using System;
using System.Collections.Generic;
using System.Data.OleDb;
using Microsoft.Search.Interop;
namespace Microsoft.Plugin.Indexer.SearchHelper
{
public class WindowsSearchAPI
{
public OleDbConnection conn;
public OleDbCommand command;
public OleDbDataReader WDSResults;
private readonly object _lock = new object();
public List<SearchResult> ExecuteQuery(ISearchQueryHelper queryHelper, string keyword)
{
List<SearchResult> _Result = new List<SearchResult>();
// Generate SQL from our parameters, converting the userQuery from AQS->WHERE clause
string sqlQuery = queryHelper.GenerateSQLFromUserQuery(keyword);
// --- Perform the query ---
// create an OleDbConnection object which connects to the indexer provider with the windows application
using (conn = new OleDbConnection(queryHelper.ConnectionString))
{
// open the connection
conn.Open();
// now create an OleDB command object with the query we built above and the connection we just opened.
using (command = new OleDbCommand(sqlQuery, conn))
{
// execute the command, which returns the results as an OleDbDataReader.
using (WDSResults = command.ExecuteReader())
{
if(WDSResults.HasRows)
{
while (WDSResults.Read())
{
if(WDSResults.GetValue(0) != DBNull.Value && WDSResults.GetValue(1) != DBNull.Value)
{
var result = new SearchResult
{
Path = WDSResults.GetString(0),
Title = WDSResults.GetString(1)
};
_Result.Add(result);
}
}
}
}
}
}
return _Result;
}
public void ModifyQueryHelper(ref ISearchQueryHelper queryHelper, string pattern)
{
// convert file pattern if it is not '*'. Don't create restriction for '*' as it includes all files.
if (pattern != "*")
{
pattern = pattern.Replace("*", "%");
pattern = pattern.Replace("?", "_");
if (pattern.Contains("%") || pattern.Contains("_"))
{
queryHelper.QueryWhereRestrictions += " AND System.FileName LIKE '" + pattern + "' ";
}
else
{
// if there are no wildcards we can use a contains which is much faster as it uses the index
queryHelper.QueryWhereRestrictions += " AND Contains(System.FileName, '" + pattern + "') ";
}
}
}
public void InitQueryHelper(out ISearchQueryHelper queryHelper, int maxCount)
{
// This uses the Microsoft.Search.Interop assembly
CSearchManager manager = new CSearchManager();
// SystemIndex catalog is the default catalog in Windows
ISearchCatalogManager catalogManager = manager.GetCatalog("SystemIndex");
// Get the ISearchQueryHelper which will help us to translate AQS --> SQL necessary to query the indexer
queryHelper = catalogManager.GetQueryHelper();
// Set the number of results we want. Don't set this property if all results are needed.
queryHelper.QueryMaxResults = maxCount;
// Set list of columns we want to display, getting the path presently
queryHelper.QuerySelectColumns = "System.ItemPathDisplay, System.FileName";
// Set additional query restriction
queryHelper.QueryWhereRestrictions = "AND scope='file:'";
// To filter based on title for now
queryHelper.QueryContentProperties = "System.FileName";
// Set sorting order
queryHelper.QuerySorting = "System.DateModified DESC";
}
public IEnumerable<SearchResult> Search(string keyword, string pattern = "*", int maxCount = 100)
{
lock(_lock){
ISearchQueryHelper queryHelper;
InitQueryHelper(out queryHelper, maxCount);
ModifyQueryHelper(ref queryHelper, pattern);
return ExecuteQuery(queryHelper, keyword);
}
}
}
}

View file

@ -0,0 +1,23 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Microsoft.Plugin.Indexer
{
public class Settings
{
public List<ContextMenu> ContextMenus = new List<ContextMenu>();
public int MaxSearchCount { get; set; } = 100;
public bool UseLocationAsWorkingDir { get; set; } = false;
}
public class ContextMenu
{
public string Name { get; set; }
public string Command { get; set; }
public string Argument { get; set; }
public string ImagePath { get; set; }
}
}

View file

@ -0,0 +1,12 @@
{
"ID": "2140FC9819AD43A3A616E2735815C27C",
"ActionKeyword": "*",
"Name": "Windows Indexer",
"Description": "Search for files and folders",
"Author": "Microsoft",
"Version": "1.0.0",
"Language": "csharp",
"Website": "http://aka.ms/PowerToys",
"ExecuteFileName": "Microsoft.Plugin.Indexer.dll",
"IcoPath": "Images\\WindowsIndexerImg.bmp"
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 597 B

View file

@ -0,0 +1,10 @@
<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">
<system:String x:Key="wox_plugin_caculator_plugin_name">Rechner</system:String>
<system:String x:Key="wox_plugin_caculator_plugin_description">Stellt mathematische Berechnungen bereit.(Versuche 5*3-2 in Wox)</system:String>
<system:String x:Key="wox_plugin_calculator_not_a_number">Keine Zahl (NaN)</system:String>
<system:String x:Key="wox_plugin_calculator_expression_not_complete">Ausdruck falsch oder nicht vollständig (Klammern vergessen?)</system:String>
<system:String x:Key="wox_plugin_calculator_copy_number_to_clipboard">Diese Zahl in die Zwischenablage kopieren</system:String>
</ResourceDictionary>

View file

@ -0,0 +1,10 @@
<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">
<system:String x:Key="wox_plugin_caculator_plugin_name">Calculator</system:String>
<system:String x:Key="wox_plugin_caculator_plugin_description">Allows to do mathematical calculations.(Try 5*3-2 in Wox)</system:String>
<system:String x:Key="wox_plugin_calculator_not_a_number">Not a number (NaN)</system:String>
<system:String x:Key="wox_plugin_calculator_expression_not_complete">Expression wrong or incomplete (Did you forget some parentheses?)</system:String>
<system:String x:Key="wox_plugin_calculator_copy_number_to_clipboard">Copy this number to the clipboard</system:String>
</ResourceDictionary>

View file

@ -0,0 +1,8 @@
<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">
<system:String x:Key="wox_plugin_caculator_plugin_name">Kalkulator</system:String>
<system:String x:Key="wox_plugin_caculator_plugin_description">Szybkie wykonywanie obliczeń matematycznych. (Spróbuj wpisać 5*3-2 w oknie Woxa)</system:String>
</ResourceDictionary>

View file

@ -0,0 +1,10 @@
<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">
<system:String x:Key="wox_plugin_caculator_plugin_name">Hesap Makinesi</system:String>
<system:String x:Key="wox_plugin_caculator_plugin_description">Matematiksel hesaplamalar yapmaya yarar. (5*3-2 yazmayı deneyin)</system:String>
<system:String x:Key="wox_plugin_calculator_not_a_number">Sayı değil (NaN)</system:String>
<system:String x:Key="wox_plugin_calculator_expression_not_complete">İfade hatalı ya da eksik. (Parantez koymayı mı unuttunuz?)</system:String>
<system:String x:Key="wox_plugin_calculator_copy_number_to_clipboard">Bu sayıyı panoya kopyala</system:String>
</ResourceDictionary>

View file

@ -0,0 +1,8 @@
<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">
<system:String x:Key="wox_plugin_caculator_plugin_name">计算器</system:String>
<system:String x:Key="wox_plugin_caculator_plugin_description">为Wox提供数学计算能力。(试着在Wox输入 5*3-2)</system:String>
</ResourceDictionary>

View file

@ -0,0 +1,8 @@
<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">
<system:String x:Key="wox_plugin_caculator_plugin_name">計算機</system:String>
<system:String x:Key="wox_plugin_caculator_plugin_description">為 Wox 提供數學計算功能。(試著在 Wox 輸入 5*3-2)</system:String>
</ResourceDictionary>

View file

@ -0,0 +1,115 @@
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using System.Windows;
using Mages.Core;
namespace Wox.Plugin.Caculator
{
public class Main : IPlugin, IPluginI18n
{
private static readonly Regex RegValidExpressChar = new Regex(
@"^(" +
@"ceil|floor|exp|pi|e|max|min|det|abs|log|ln|sqrt|" +
@"sin|cos|tan|arcsin|arccos|arctan|" +
@"eigval|eigvec|eig|sum|polar|plot|round|sort|real|zeta|" +
@"bin2dec|hex2dec|oct2dec|" +
@"==|~=|&&|\|\||" +
@"[ei]|[0-9]|[\+\-\*\/\^\., ""]|[\(\)\|\!\[\]]" +
@")+$", RegexOptions.Compiled);
private static readonly Regex RegBrackets = new Regex(@"[\(\)\[\]]", RegexOptions.Compiled);
private static readonly Engine MagesEngine;
private PluginInitContext Context { get; set; }
static Main()
{
MagesEngine = new Engine();
}
public List<Result> Query(Query query)
{
if (query.Search.Length <= 2 // don't affect when user only input "e" or "i" keyword
|| !RegValidExpressChar.IsMatch(query.Search)
|| !IsBracketComplete(query.Search)) return new List<Result>();
try
{
var result = MagesEngine.Interpret(query.Search);
if (result.ToString() == "NaN")
result = Context.API.GetTranslation("wox_plugin_calculator_not_a_number");
if (result is Function)
result = Context.API.GetTranslation("wox_plugin_calculator_expression_not_complete");
if (!string.IsNullOrEmpty(result?.ToString()))
{
return new List<Result>
{
new Result
{
Title = result.ToString(),
IcoPath = "Images/calculator.png",
Score = 300,
SubTitle = Context.API.GetTranslation("wox_plugin_calculator_copy_number_to_clipboard"),
Action = c =>
{
try
{
Clipboard.SetText(result.ToString());
return true;
}
catch (ExternalException)
{
MessageBox.Show("Copy failed, please try later");
return false;
}
}
}
};
}
}
catch
{
// ignored
}
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)
{
Context = context;
}
public string GetTranslatedPluginTitle()
{
return Context.API.GetTranslation("wox_plugin_caculator_plugin_name");
}
public string GetTranslatedPluginDescription()
{
return Context.API.GetTranslation("wox_plugin_caculator_plugin_description");
}
}
}

View file

@ -0,0 +1,95 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
namespace Wox.Plugin.Caculator
{
/// <summary>
/// Tries to convert all numbers in a text from one culture format to another.
/// </summary>
public class NumberTranslator
{
private readonly CultureInfo sourceCulture;
private readonly CultureInfo targetCulture;
private readonly Regex splitRegexForSource;
private readonly Regex splitRegexForTarget;
private NumberTranslator(CultureInfo sourceCulture, CultureInfo targetCulture)
{
this.sourceCulture = sourceCulture;
this.targetCulture = targetCulture;
this.splitRegexForSource = GetSplitRegex(this.sourceCulture);
this.splitRegexForTarget = GetSplitRegex(this.targetCulture);
}
/// <summary>
/// Create a new <see cref="NumberTranslator"/> - returns null if no number conversion
/// is required between the cultures.
/// </summary>
/// <param name="sourceCulture">source culture</param>
/// <param name="targetCulture">target culture</param>
/// <returns></returns>
public static NumberTranslator Create(CultureInfo sourceCulture, CultureInfo targetCulture)
{
bool conversionRequired = sourceCulture.NumberFormat.NumberDecimalSeparator != targetCulture.NumberFormat.NumberDecimalSeparator
|| sourceCulture.NumberFormat.PercentGroupSeparator != targetCulture.NumberFormat.PercentGroupSeparator
|| sourceCulture.NumberFormat.NumberGroupSizes != targetCulture.NumberFormat.NumberGroupSizes;
return conversionRequired
? new NumberTranslator(sourceCulture, targetCulture)
: null;
}
/// <summary>
/// Translate from source to target culture.
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
public string Translate(string input)
{
return this.Translate(input, this.sourceCulture, this.targetCulture, this.splitRegexForSource);
}
/// <summary>
/// Translate from target to source culture.
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
public string TranslateBack(string input)
{
return this.Translate(input, this.targetCulture, this.sourceCulture, this.splitRegexForTarget);
}
private string Translate(string input, CultureInfo cultureFrom, CultureInfo cultureTo, Regex splitRegex)
{
var outputBuilder = new StringBuilder();
string[] tokens = splitRegex.Split(input);
foreach (string token in tokens)
{
decimal number;
outputBuilder.Append(
decimal.TryParse(token, NumberStyles.Number, cultureFrom, out number)
? number.ToString(cultureTo)
: token);
}
return outputBuilder.ToString();
}
private Regex GetSplitRegex(CultureInfo culture)
{
var splitPattern = $"((?:\\d|{Regex.Escape(culture.NumberFormat.NumberDecimalSeparator)}";
if (!string.IsNullOrEmpty(culture.NumberFormat.NumberGroupSeparator))
{
splitPattern += $"|{Regex.Escape(culture.NumberFormat.NumberGroupSeparator)}";
}
splitPattern += ")+)";
return new Regex(splitPattern);
}
}
}

View file

@ -0,0 +1,111 @@
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<ProjectGuid>{59BD9891-3837-438A-958D-ADC7F91F6F7E}</ProjectGuid>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Wox.Plugin.Caculator</RootNamespace>
<AssemblyName>Wox.Plugin.Caculator</AssemblyName>
<useWPF>true</useWPF>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
<Platforms>x64</Platforms>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>..\..\..\..\..\x64\Debug\modules\launcher\Plugins\Wox.Plugin.Caculator\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>x64</PlatformTarget>
<LangVersion>7.3</LangVersion>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<WarningLevel>4</WarningLevel>
<Optimize>false</Optimize>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<OutputPath>..\..\..\..\..\x64\Release\modules\launcher\Plugins\Wox.Plugin.Caculator\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x64</PlatformTarget>
<LangVersion>7.3</LangVersion>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<None Include="plugin.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Wox.Infrastructure\Wox.Infrastructure.csproj" />
<ProjectReference Include="..\..\Wox.Plugin\Wox.Plugin.csproj" />
</ItemGroup>
<ItemGroup>
<None Include="Images\calculator.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
<ItemGroup>
<Content Include="Languages\en.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<Content Include="Languages\zh-cn.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<Content Include="Languages\zh-tw.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<Content Include="Languages\de.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<Content Include="Languages\pl.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<Content Include="Languages\tr.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<PackageReference Include="JetBrains.Annotations" Version="2020.1.0" />
<PackageReference Include="Mages" Version="1.6.0" />
<PackageReference Include="System.Runtime" Version="4.3.1" />
</ItemGroup>
</Project>

View file

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

View file

@ -0,0 +1,151 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Threading.Tasks;
using System.Windows;
using Wox.Infrastructure.Logger;
using Wox.Infrastructure.Image;
using Wox.Plugin.SharedCommands;
namespace Wox.Plugin.Folder
{
internal class ContextMenuLoader : IContextMenu
{
private readonly PluginInitContext _context;
public ContextMenuLoader(PluginInitContext context)
{
_context = context;
}
public List<ContextMenuResult> LoadContextMenus(Result selectedResult)
{
var contextMenus = new List<ContextMenuResult>();
if (selectedResult.ContextData is SearchResult record)
{
if (record.Type == ResultType.File)
{
contextMenus.Add(CreateOpenContainingFolderResult(record));
}
var icoPath = (record.Type == ResultType.File) ? Main.FileImagePath : Main.FolderImagePath;
var fileOrFolder = (record.Type == ResultType.File) ? "file" : "folder";
contextMenus.Add(new ContextMenuResult
{
Title = "Copy path",
Glyph = "\xE8C8",
FontFamily = "Segoe MDL2 Assets",
SubTitle = $"Copy the current {fileOrFolder} path to clipboard",
AcceleratorKey = "C",
AcceleratorModifiers = "Control",
Action = (context) =>
{
try
{
Clipboard.SetText(record.FullPath);
return true;
}
catch (Exception e)
{
var message = "Fail to set text in clipboard";
LogException(message, e);
_context.API.ShowMsg(message);
return false;
}
}
});
}
return contextMenus;
}
private ContextMenuResult CreateOpenContainingFolderResult(SearchResult record)
{
return new ContextMenuResult
{
Title = "Open containing folder",
Glyph = "\xE838",
FontFamily = "Segoe MDL2 Assets",
AcceleratorKey = "E",
AcceleratorModifiers = "Control,Shift",
Action = _ =>
{
try
{
Process.Start("explorer.exe", $" /select,\"{record.FullPath}\"");
}
catch(Exception e)
{
var message = $"Fail to open file at {record.FullPath}";
LogException(message, e);
_context.API.ShowMsg(message);
return false;
}
return true;
}
};
}
private Result CreateOpenWithEditorResult(SearchResult record)
{
string editorPath = "notepad.exe"; // TODO add the ability to create a custom editor
var name = "Open With Editor: " + Path.GetFileNameWithoutExtension(editorPath);
return new Result
{
Title = name,
Action = _ =>
{
try
{
Process.Start(editorPath, record.FullPath);
return true;
}
catch (Exception e)
{
var message = $"Fail to editor for file at {record.FullPath}";
LogException(message, e);
_context.API.ShowMsg(message);
return false;
}
},
IcoPath = editorPath
};
}
public void LogException(string message, Exception e)
{
Log.Exception($"|Wox.Plugin.Folder.ContextMenu|{message}", e);
}
private bool CanRunAsDifferentUser(string path)
{
switch(Path.GetExtension(path))
{
case ".exe":
case ".bat":
return true;
default:
return false;
}
}
}
public class SearchResult
{
public string FullPath { get; set; }
public ResultType Type { get; set; }
}
public enum ResultType
{
Volume,
Folder,
File
}
}

View file

@ -0,0 +1,18 @@
using System;
using System.Linq;
using Newtonsoft.Json;
namespace Wox.Plugin.Folder
{
[JsonObject(MemberSerialization.OptIn)]
public class FolderLink
{
[JsonProperty]
public string Path { get; set; }
public string Nickname =>
Path.Split(new[] { System.IO.Path.DirectorySeparatorChar }, StringSplitOptions.None)
.Last()
+ " (" + System.IO.Path.GetDirectoryName(Path) + ")";
}
}

View file

@ -0,0 +1,34 @@
<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="500">
<Grid Margin="10">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="50"/>
</Grid.RowDefinitions>
<ListView x:Name="lbxFolders" Grid.Row="0" AllowDrop="True"
Drop="lbxFolders_Drop"
DragEnter="lbxFolders_DragEnter">
<ListView.View>
<GridView>
<GridViewColumn Header="{DynamicResource wox_plugin_folder_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="{DynamicResource wox_plugin_folder_delete}"/>
<Button x:Name="btnEdit" Click="btnEdit_Click" Width="100" Margin="10" Content="{DynamicResource wox_plugin_folder_edit}"/>
<Button x:Name="btnAdd" Click="btnAdd_Click" Width="100" Margin="10" Content="{DynamicResource wox_plugin_folder_add}"/>
</StackPanel>
</Grid>
</UserControl>

View file

@ -0,0 +1,130 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Windows;
using System.Windows.Forms;
using DataFormats = System.Windows.DataFormats;
using DragDropEffects = System.Windows.DragDropEffects;
using DragEventArgs = System.Windows.DragEventArgs;
using MessageBox = System.Windows.MessageBox;
namespace Wox.Plugin.Folder
{
public partial class FileSystemSettings
{
private IPublicAPI woxAPI;
private Settings _settings;
public FileSystemSettings(IPublicAPI woxAPI, Settings settings)
{
this.woxAPI = woxAPI;
InitializeComponent();
_settings = settings;
lbxFolders.ItemsSource = _settings.FolderLinks;
}
private void btnDelete_Click(object sender, RoutedEventArgs e)
{
var selectedFolder = lbxFolders.SelectedItem as FolderLink;
if (selectedFolder != null)
{
string msg = string.Format(woxAPI.GetTranslation("wox_plugin_folder_delete_folder_link"), selectedFolder.Path);
if (MessageBox.Show(msg, string.Empty, MessageBoxButton.YesNo) == MessageBoxResult.Yes)
{
_settings.FolderLinks.Remove(selectedFolder);
lbxFolders.Items.Refresh();
}
}
else
{
string warning = woxAPI.GetTranslation("wox_plugin_folder_select_folder_link_warning");
MessageBox.Show(warning);
}
}
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 = _settings.FolderLinks.First(x => x.Path == selectedFolder.Path);
link.Path = folderBrowserDialog.SelectedPath;
}
lbxFolders.Items.Refresh();
}
else
{
string warning = woxAPI.GetTranslation("wox_plugin_folder_select_folder_link_warning");
MessageBox.Show(warning);
}
}
private void btnAdd_Click(object sender, RoutedEventArgs e)
{
var folderBrowserDialog = new FolderBrowserDialog();
if (folderBrowserDialog.ShowDialog() == DialogResult.OK)
{
var newFolder = new FolderLink
{
Path = folderBrowserDialog.SelectedPath
};
if (_settings.FolderLinks == null)
{
_settings.FolderLinks = new List<FolderLink>();
}
_settings.FolderLinks.Add(newFolder);
}
lbxFolders.Items.Refresh();
}
private void lbxFolders_Drop(object sender, DragEventArgs e)
{
string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
if (files != null && files.Count() > 0)
{
if (_settings.FolderLinks == null)
{
_settings.FolderLinks = new List<FolderLink>();
}
foreach (string s in files)
{
if (Directory.Exists(s))
{
var newFolder = new FolderLink
{
Path = s
};
_settings.FolderLinks.Add(newFolder);
}
lbxFolders.Items.Refresh();
}
}
}
private void lbxFolders_DragEnter(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(DataFormats.FileDrop))
{
e.Effects = DragDropEffects.Link;
}
else
{
e.Effects = DragDropEffects.None;
}
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 501 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 290 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 468 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

View file

@ -0,0 +1,15 @@
<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">
<system:String x:Key="wox_plugin_folder_delete">Löschen</system:String>
<system:String x:Key="wox_plugin_folder_edit">Bearbeiten</system:String>
<system:String x:Key="wox_plugin_folder_add">Hinzufügen</system:String>
<system:String x:Key="wox_plugin_folder_folder_path">Ordnerpfad</system:String>
<system:String x:Key="wox_plugin_folder_select_folder_link_warning">Bitte wähle eine Ordnerverknüpfung</system:String>
<system:String x:Key="wox_plugin_folder_delete_folder_link">Bist du sicher {0} zu löschen?</system:String>
<system:String x:Key="wox_plugin_folder_plugin_name">Ordner</system:String>
<system:String x:Key="wox_plugin_folder_plugin_description">Öffne deine Lieblingsordner direkt von Wox aus</system:String>
</ResourceDictionary>

View file

@ -0,0 +1,15 @@
<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">
<system:String x:Key="wox_plugin_folder_delete">Delete</system:String>
<system:String x:Key="wox_plugin_folder_edit">Edit</system:String>
<system:String x:Key="wox_plugin_folder_add">Add</system:String>
<system:String x:Key="wox_plugin_folder_folder_path">Folder Path</system:String>
<system:String x:Key="wox_plugin_folder_select_folder_link_warning">Please select a folder link</system:String>
<system:String x:Key="wox_plugin_folder_delete_folder_link">Are you sure you want to delete {0}?</system:String>
<system:String x:Key="wox_plugin_folder_plugin_name">Folder</system:String>
<system:String x:Key="wox_plugin_folder_plugin_description">Open favorite folder from Wox directly</system:String>
</ResourceDictionary>

View file

@ -0,0 +1,15 @@
<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">
<system:String x:Key="wox_plugin_folder_delete">Usuń</system:String>
<system:String x:Key="wox_plugin_folder_edit">Edytuj</system:String>
<system:String x:Key="wox_plugin_folder_add">Dodaj</system:String>
<system:String x:Key="wox_plugin_folder_folder_path">Ścieżka folderu</system:String>
<system:String x:Key="wox_plugin_folder_select_folder_link_warning">Musisz wybrać któryś folder z listy</system:String>
<system:String x:Key="wox_plugin_folder_delete_folder_link">Czy jesteś pewien że chcesz usunąć {0}?</system:String>
<system:String x:Key="wox_plugin_folder_plugin_name">Foldery</system:String>
<system:String x:Key="wox_plugin_folder_plugin_description">Otwórz ulubione foldery bezpośrednio z poziomu Woxa</system:String>
</ResourceDictionary>

View file

@ -0,0 +1,15 @@
<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">
<system:String x:Key="wox_plugin_folder_delete">Sil</system:String>
<system:String x:Key="wox_plugin_folder_edit">Düzenle</system:String>
<system:String x:Key="wox_plugin_folder_add">Ekle</system:String>
<system:String x:Key="wox_plugin_folder_folder_path">Klasör Konumu</system:String>
<system:String x:Key="wox_plugin_folder_select_folder_link_warning">Lütfen bir klasör bağlantısı seçin</system:String>
<system:String x:Key="wox_plugin_folder_delete_folder_link">{0} bağlantısını silmek istediğinize emin misiniz?</system:String>
<system:String x:Key="wox_plugin_folder_plugin_name">Klasör</system:String>
<system:String x:Key="wox_plugin_folder_plugin_description">Favori klasörünüzü doğrudan Wox'tan açın</system:String>
</ResourceDictionary>

View file

@ -0,0 +1,15 @@
<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">
<system:String x:Key="wox_plugin_folder_delete">删除</system:String>
<system:String x:Key="wox_plugin_folder_edit">编辑</system:String>
<system:String x:Key="wox_plugin_folder_add">添加</system:String>
<system:String x:Key="wox_plugin_folder_folder_path">文件夹路径</system:String>
<system:String x:Key="wox_plugin_folder_select_folder_link_warning">请选择一个文件夹</system:String>
<system:String x:Key="wox_plugin_folder_delete_folder_link">你确定要删除{0}吗?</system:String>
<system:String x:Key="wox_plugin_folder_plugin_name">文件夹</system:String>
<system:String x:Key="wox_plugin_folder_plugin_description">在Wox中直接打开收藏的文件夹</system:String>
</ResourceDictionary>

View file

@ -0,0 +1,15 @@
<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">
<system:String x:Key="wox_plugin_folder_delete">刪除</system:String>
<system:String x:Key="wox_plugin_folder_edit">編輯</system:String>
<system:String x:Key="wox_plugin_folder_add">新增</system:String>
<system:String x:Key="wox_plugin_folder_folder_path">資料夾路徑</system:String>
<system:String x:Key="wox_plugin_folder_select_folder_link_warning">請選擇一個資料夾</system:String>
<system:String x:Key="wox_plugin_folder_delete_folder_link">你確認要刪除{0}嗎?</system:String>
<system:String x:Key="wox_plugin_folder_plugin_name">資料夾</system:String>
<system:String x:Key="wox_plugin_folder_plugin_description">在 Wox 中直接開啟收藏的資料夾</system:String>
</ResourceDictionary>

View file

@ -0,0 +1,293 @@
using Microsoft.PowerToys.Settings.UI.Lib;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using Wox.Infrastructure;
using Wox.Infrastructure.Storage;
namespace Wox.Plugin.Folder
{
public class Main : IPlugin, ISettingProvider, IPluginI18n, ISavable, IContextMenu
{
public const string FolderImagePath = "Images\\folder.png";
public const string FileImagePath = "Images\\file.png";
public const string DeleteFileFolderImagePath = "Images\\deletefilefolder.png";
public const string CopyImagePath = "Images\\copy.png";
private const string _fileExplorerProgramName = "explorer";
private static List<string> _driverNames;
private PluginInitContext _context;
private readonly Settings _settings;
private readonly PluginJsonStorage<Settings> _storage;
private IContextMenu _contextMenuLoader;
public Main()
{
_storage = new PluginJsonStorage<Settings>();
_settings = _storage.Load();
}
public void Save()
{
_storage.Save();
}
public Control CreateSettingPanel()
{
return new FileSystemSettings(_context.API, _settings);
}
public void Init(PluginInitContext context)
{
_context = context;
_contextMenuLoader = new ContextMenuLoader(context);
InitialDriverList();
}
public List<Result> Query(Query query)
{
var results = GetUserFolderResults(query);
string search = query.Search.ToLower();
if (!IsDriveOrSharedFolder(search))
return results;
results.AddRange(QueryInternal_Directory_Exists(query));
// todo why was this hack here?
foreach (var result in results)
{
result.Score += 10;
}
return results;
}
private static bool IsDriveOrSharedFolder(string search)
{
if (search.StartsWith(@"\\"))
{ // share folder
return true;
}
if (_driverNames != null && _driverNames.Any(search.StartsWith))
{ // normal drive letter
return true;
}
if (_driverNames == null && search.Length > 2 && char.IsLetter(search[0]) && search[1] == ':')
{ // when we don't have the drive letters we can try...
return true; // we don't know so let's give it the possibility
}
return false;
}
private Result CreateFolderResult(string title, string subtitle, string path, Query query)
{
return new Result
{
Title = title,
IcoPath = path,
SubTitle = subtitle,
QueryTextDisplay = path,
TitleHighlightData = StringMatcher.FuzzySearch(query.Search, title).MatchData,
ContextData = new SearchResult { Type = ResultType.Folder, FullPath = path },
Action = c =>
{
Process.Start(_fileExplorerProgramName, path);
return true;
}
};
}
private List<Result> GetUserFolderResults(Query query)
{
string search = query.Search.ToLower();
var userFolderLinks = _settings.FolderLinks.Where(
x => x.Nickname.StartsWith(search, StringComparison.OrdinalIgnoreCase));
var results = userFolderLinks.Select(item =>
CreateFolderResult(item.Nickname, item.Path, item.Path, query)).ToList();
return results;
}
private void InitialDriverList()
{
if (_driverNames == null)
{
_driverNames = new List<string>();
var allDrives = DriveInfo.GetDrives();
foreach (DriveInfo driver in allDrives)
{
_driverNames.Add(driver.Name.ToLower().TrimEnd('\\'));
}
}
}
private static readonly char[] _specialSearchChars = new char[]
{
'?', '*', '>'
};
private List<Result> QueryInternal_Directory_Exists(Query query)
{
var search = query.Search;
var results = new List<Result>();
var hasSpecial = search.IndexOfAny(_specialSearchChars) >= 0;
string incompleteName = "";
if (hasSpecial || !Directory.Exists(search + "\\"))
{
// if folder doesn't exist, we want to take the last part and use it afterwards to help the user
// find the right folder.
int index = search.LastIndexOf('\\');
if (index > 0 && index < (search.Length - 1))
{
incompleteName = search.Substring(index + 1).ToLower();
search = search.Substring(0, index + 1);
if (!Directory.Exists(search))
{
return results;
}
}
else
{
return results;
}
}
else
{
// folder exist, add \ at the end of doesn't exist
if (!search.EndsWith("\\"))
{
search += "\\";
}
}
results.Add(CreateOpenCurrentFolderResult(incompleteName, search));
var searchOption = SearchOption.TopDirectoryOnly;
incompleteName += "*";
// give the ability to search all folder when starting with >
if (incompleteName.StartsWith(">"))
{
searchOption = SearchOption.AllDirectories;
// match everything before and after search term using supported wildcard '*', ie. *searchterm*
incompleteName = "*" + incompleteName.Substring(1);
}
var folderList = new List<Result>();
var fileList = new List<Result>();
try
{
// search folder and add results
var directoryInfo = new DirectoryInfo(search);
var fileSystemInfos = directoryInfo.GetFileSystemInfos(incompleteName, searchOption);
foreach (var fileSystemInfo in fileSystemInfos)
{
if ((fileSystemInfo.Attributes & FileAttributes.Hidden) == FileAttributes.Hidden) continue;
if(fileSystemInfo is DirectoryInfo)
{
var folderSubtitleString = fileSystemInfo.FullName;
folderList.Add(CreateFolderResult(fileSystemInfo.Name, folderSubtitleString, fileSystemInfo.FullName, query));
}
else
{
fileList.Add(CreateFileResult(fileSystemInfo.FullName, query));
}
}
}
catch (Exception e)
{
if (e is UnauthorizedAccessException || e is ArgumentException)
{
results.Add(new Result { Title = e.Message, Score = 501 });
return results;
}
throw;
}
// Intial ordering, this order can be updated later by UpdateResultView.MainViewModel based on history of user selection.
return results.Concat(folderList.OrderBy(x => x.Title)).Concat(fileList.OrderBy(x => x.Title)).ToList();
}
private static Result CreateFileResult(string filePath, Query query)
{
var result = new Result
{
Title = Path.GetFileName(filePath),
SubTitle = filePath,
IcoPath = filePath,
TitleHighlightData = StringMatcher.FuzzySearch(query.Search, Path.GetFileName(filePath)).MatchData,
Action = c =>
{
try
{
Process.Start(_fileExplorerProgramName, filePath);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Could not start " + filePath);
}
return true;
},
ContextData = new SearchResult { Type = ResultType.File, FullPath = filePath}
};
return result;
}
private static Result CreateOpenCurrentFolderResult(string incompleteName, string search)
{
var firstResult = "Open " + search;
var folderName = search.TrimEnd('\\').Split(new[] { Path.DirectorySeparatorChar }, StringSplitOptions.None).Last();
return new Result
{
Title = firstResult,
QueryTextDisplay = search,
SubTitle = $"Use > to search within the directory. Use * to search for file extensions. Or use both >*.",
IcoPath = search,
Score = 500,
Action = c =>
{
Process.Start(_fileExplorerProgramName, search);
return true;
}
};
}
public string GetTranslatedPluginTitle()
{
return _context.API.GetTranslation("wox_plugin_folder_plugin_name");
}
public string GetTranslatedPluginDescription()
{
return _context.API.GetTranslation("wox_plugin_folder_plugin_description");
}
public List<ContextMenuResult> LoadContextMenus(Result selectedResult)
{
return _contextMenuLoader.LoadContextMenus(selectedResult);
}
public void UpdateSettings(PowerLauncherSettings settings)
{
}
}
}

View file

@ -0,0 +1,12 @@
using System.Collections.Generic;
using Newtonsoft.Json;
using Wox.Infrastructure.Storage;
namespace Wox.Plugin.Folder
{
public class Settings
{
[JsonProperty]
public List<FolderLink> FolderLinks { get; set; } = new List<FolderLink>();
}
}

View file

@ -0,0 +1,113 @@
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<ProjectGuid>{787B8AA6-CA93-4C84-96FE-DF31110AD1C4}</ProjectGuid>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Wox.Plugin.Folder</RootNamespace>
<AssemblyName>Wox.Plugin.Folder</AssemblyName>
<UseWindowsForms>true</UseWindowsForms>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
<Platforms>x64</Platforms>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>..\..\..\..\..\x64\Debug\modules\launcher\Plugins\Wox.Plugin.Folder\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>x64</PlatformTarget>
<LangVersion>7.3</LangVersion>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<WarningLevel>4</WarningLevel>
<Optimize>false</Optimize>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<OutputPath>..\..\..\..\..\x64\Release\modules\launcher\Plugins\Wox.Plugin.Folder\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x64</PlatformTarget>
<LangVersion>7.3</LangVersion>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<None Include="plugin.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
<ItemGroup>
<Page Include="FolderPluginSettings.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<None Include="Images\copy.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="Images\deletefilefolder.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<Content Include="Images\file.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<None Include="Images\user.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<Content Include="Languages\en.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Languages\zh-cn.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Languages\zh-tw.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Languages\de.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Languages\pl.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Languages\tr.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\core\Microsoft.PowerToys.Settings.UI.Lib\Microsoft.PowerToys.Settings.UI.Lib.csproj" />
<ProjectReference Include="..\..\Wox.Infrastructure\Wox.Infrastructure.csproj" />
<ProjectReference Include="..\..\Wox.Plugin\Wox.Plugin.csproj" />
</ItemGroup>
<ItemGroup>
<None Include="Images\folder.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
<ItemGroup>
<PackageReference Include="JetBrains.Annotations" Version="2020.1.0" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
<PackageReference Include="System.Runtime" Version="4.3.1" />
</ItemGroup>
</Project>

View file

@ -0,0 +1,12 @@
{
"ID":"B4D3B69656E14D44865C8D818EAE47C4",
"ActionKeyword":"*",
"Name":"Folder",
"Description":"Open favorite folder from wox directorily",
"Author":"qianlifeng",
"Version":"1.0.0",
"Language":"csharp",
"Website":"http://www.wox.one/plugin",
"ExecuteFileName":"Wox.Plugin.Folder.dll",
"IcoPath":"Images\\folder.png"
}

View file

@ -0,0 +1,22 @@
<Window x:Class="Wox.Plugin.Program.AddProgramSource"
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="120"
WindowStartupLocation="CenterScreen">
<StackPanel Orientation="Vertical">
<StackPanel Orientation="Horizontal">
<Label Content="{DynamicResource wox_plugin_program_directory}"/>
<TextBox Name="Directory" VerticalAlignment="Center" Width="300" Margin="0,7" />
</StackPanel>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
<Button Click="BrowseButton_Click" Content="{DynamicResource wox_plugin_program_browse}"
HorizontalAlignment="Right" Margin="10" Height="20" Width="70" />
<Button Click="ButtonAdd_OnClick" Content="{DynamicResource wox_plugin_program_update}"
HorizontalAlignment="Right" Margin="10" Height="20" Width="70" />
</StackPanel>
</StackPanel>
</Window>

View file

@ -0,0 +1,76 @@
using System.Windows;
using System.Windows.Forms;
using Wox.Plugin.Program.Views.Models;
using Wox.Plugin.Program.Views;
using System.Linq;
namespace Wox.Plugin.Program
{
/// <summary>
/// Interaction logic for AddProgramSource.xaml
/// </summary>
public partial class AddProgramSource
{
private PluginInitContext _context;
private Settings.ProgramSource _editing;
private Settings _settings;
public AddProgramSource(PluginInitContext context, Settings settings)
{
InitializeComponent();
_context = context;
_settings = settings;
Directory.Focus();
}
public AddProgramSource(Settings.ProgramSource edit, Settings settings)
{
_editing = edit;
_settings = settings;
InitializeComponent();
Directory.Text = _editing.Location;
}
private void BrowseButton_Click(object sender, RoutedEventArgs e)
{
var dialog = new FolderBrowserDialog();
DialogResult result = dialog.ShowDialog();
if (result == System.Windows.Forms.DialogResult.OK)
{
Directory.Text = dialog.SelectedPath;
}
}
private void ButtonAdd_OnClick(object sender, RoutedEventArgs e)
{
string s = Directory.Text;
if (!System.IO.Directory.Exists(s))
{
System.Windows.MessageBox.Show(_context.API.GetTranslation("wox_plugin_program_invalid_path"));
return;
}
if (_editing == null)
{
if (!ProgramSetting.ProgramSettingDisplayList.Any(x => x.UniqueIdentifier == Directory.Text))
{
var source = new ProgramSource
{
Location = Directory.Text,
UniqueIdentifier = Directory.Text
};
_settings.ProgramSources.Insert(0, source);
ProgramSetting.ProgramSettingDisplayList.Add(source);
}
}
else
{
_editing.Location = Directory.Text;
}
DialogResult = true;
Close();
}
}
}

View file

@ -0,0 +1,58 @@
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using Wox.Infrastructure.Logger;
using Wox.Plugin.Program.Programs;
namespace Wox.Plugin.Program
{
//internal static class FileChangeWatcher
//{
// private static readonly List<string> WatchedPath = new List<string>();
// // todo remove previous watcher events
// public static void AddAll(List<UnregisteredPrograms> sources, string[] suffixes)
// {
// foreach (var s in sources)
// {
// if (Directory.Exists(s.Location))
// {
// AddWatch(s.Location, suffixes);
// }
// }
// }
// public static void AddWatch(string path, string[] programSuffixes, bool includingSubDirectory = true)
// {
// if (WatchedPath.Contains(path)) return;
// if (!Directory.Exists(path))
// {
// Log.Warn($"|FileChangeWatcher|{path} doesn't exist");
// return;
// }
// WatchedPath.Add(path);
// foreach (string fileType in programSuffixes)
// {
// FileSystemWatcher watcher = new FileSystemWatcher
// {
// Path = path,
// IncludeSubdirectories = includingSubDirectory,
// Filter = $"*.{fileType}",
// EnableRaisingEvents = true
// };
// watcher.Changed += FileChanged;
// watcher.Created += FileChanged;
// watcher.Deleted += FileChanged;
// watcher.Renamed += FileChanged;
// }
// }
// private static void FileChanged(object source, FileSystemEventArgs e)
// {
// Task.Run(() =>
// {
// Main.IndexPrograms();
// });
// }
//}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 752 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 468 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 774 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

View file

@ -0,0 +1,37 @@
<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">
<!--Program setting-->
<system:String x:Key="wox_plugin_program_delete">Löschen</system:String>
<system:String x:Key="wox_plugin_program_edit">Bearbeiten</system:String>
<system:String x:Key="wox_plugin_program_add">Hinzufügen</system:String>
<system:String x:Key="wox_plugin_program_location">Speicherort</system:String>
<system:String x:Key="wox_plugin_program_suffixes">Indexiere Dateiendungen</system:String>
<system:String x:Key="wox_plugin_program_reindex">erneut Indexieren</system:String>
<system:String x:Key="wox_plugin_program_indexing">Indexieren</system:String>
<system:String x:Key="wox_plugin_program_index_start">Indexierungs Startmenü</system:String>
<system:String x:Key="wox_plugin_program_index_registry">Indexierungsspeicher</system:String>
<system:String x:Key="wox_plugin_program_suffixes_header">Endungen</system:String>
<system:String x:Key="wox_plugin_program_max_depth_header">Maximale Tiefe</system:String>
<system:String x:Key="wox_plugin_program_directory">Verzeichnis:</system:String>
<system:String x:Key="wox_plugin_program_browse">Durchsuchen</system:String>
<system:String x:Key="wox_plugin_program_file_suffixes">Dateiendungen:</system:String>
<system:String x:Key="wox_plugin_program_max_search_depth">Maximale Suchtiefe (-1 ist unlimitiert):</system:String>
<system:String x:Key="wox_plugin_program_pls_select_program_source">Bitte wähle eine Programmquelle</system:String>
<system:String x:Key="wox_plugin_program_update">Aktualisieren</system:String>
<system:String x:Key="wox_plugin_program_only_index_tip">Wox indexiert nur Datien mit folgenden Endungen:</system:String>
<system:String x:Key="wox_plugin_program_split_by_tip">(Jede Endung muss durch ein ; getrennt werden)</system:String>
<system:String x:Key="wox_plugin_program_update_file_suffixes">Dateiendungen wurden erfolgreich aktualisiert</system:String>
<system:String x:Key="wox_plugin_program_suffixes_cannot_empty">Dateiendungen dürfen nicht leer sein</system:String>
<system:String x:Key="wox_plugin_program_run_as_administrator">Als Administrator ausführen</system:String>
<system:String x:Key="wox_plugin_program_open_containing_folder">Enthaltenden Ordner öffnen</system:String>
<system:String x:Key="wox_plugin_program_plugin_name">Programm</system:String>
<system:String x:Key="wox_plugin_program_plugin_description">Suche Programme mit Wox</system:String>
</ResourceDictionary>

View file

@ -0,0 +1,48 @@
<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">
<!--Program setting-->
<system:String x:Key="wox_plugin_program_delete">Delete</system:String>
<system:String x:Key="wox_plugin_program_edit">Edit</system:String>
<system:String x:Key="wox_plugin_program_add">Add</system:String>
<system:String x:Key="wox_plugin_program_disable">Disable</system:String>
<system:String x:Key="wox_plugin_program_location">Location</system:String>
<system:String x:Key="wox_plugin_program_all_programs">All Programs</system:String>
<system:String x:Key="wox_plugin_program_suffixes">File Suffixes</system:String>
<system:String x:Key="wox_plugin_program_reindex">Reindex</system:String>
<system:String x:Key="wox_plugin_program_indexing">Indexing</system:String>
<system:String x:Key="wox_plugin_program_index_start">Index Start Menu</system:String>
<system:String x:Key="wox_plugin_program_index_registry">Index Registry</system:String>
<system:String x:Key="wox_plugin_program_suffixes_header">Suffixes</system:String>
<system:String x:Key="wox_plugin_program_max_depth_header">Max Depth</system:String>
<system:String x:Key="wox_plugin_program_directory">Directory:</system:String>
<system:String x:Key="wox_plugin_program_browse">Browse</system:String>
<system:String x:Key="wox_plugin_program_file_suffixes">File Suffixes:</system:String>
<system:String x:Key="wox_plugin_program_max_search_depth">Maximum Search Depth (-1 is unlimited):</system:String>
<system:String x:Key="wox_plugin_program_pls_select_program_source">Please select a program source</system:String>
<system:String x:Key="wox_plugin_program_delete_program_source">Are you sure you want to delete the selected program sources?</system:String>
<system:String x:Key="wox_plugin_program_update">Update</system:String>
<system:String x:Key="wox_plugin_program_only_index_tip">Wox will only index files that end with the following suffixes:</system:String>
<system:String x:Key="wox_plugin_program_split_by_tip">(Each suffix should split by ';' )</system:String>
<system:String x:Key="wox_plugin_program_update_file_suffixes">Successfully updated file suffixes</system:String>
<system:String x:Key="wox_plugin_program_suffixes_cannot_empty">File suffixes can't be empty</system:String>
<system:String x:Key="wox_plugin_program_run_as_different_user">Run As Different User</system:String>
<system:String x:Key="wox_plugin_program_run_as_administrator">Run As Administrator</system:String>
<system:String x:Key="wox_plugin_program_open_containing_folder">Open containing folder</system:String>
<system:String x:Key="wox_plugin_program_disable_program">Disable this program from displaying</system:String>
<system:String x:Key="wox_plugin_program_plugin_name">Program</system:String>
<system:String x:Key="wox_plugin_program_plugin_description">Search programs in Wox</system:String>
<system:String x:Key="wox_plugin_program_invalid_path">Invalid Path</system:String>
<!--Dialogs-->
<system:String x:Key="wox_plugin_program_disable_dlgtitle_success">Success</system:String>
<system:String x:Key="wox_plugin_program_disable_dlgtitle_success_message">Successfully disabled this program from displaying in your query</system:String>
</ResourceDictionary>

View file

@ -0,0 +1,38 @@
<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">
<!--Program setting-->
<system:String x:Key="wox_plugin_program_delete">Delete</system:String>
<system:String x:Key="wox_plugin_program_edit">Edit</system:String>
<system:String x:Key="wox_plugin_program_add">Add</system:String>
<system:String x:Key="wox_plugin_program_location">Location</system:String>
<system:String x:Key="wox_plugin_program_suffixes">Index file suffixes</system:String>
<system:String x:Key="wox_plugin_program_reindex">Reindex</system:String>
<system:String x:Key="wox_plugin_program_indexing">Indexing</system:String>
<system:String x:Key="wox_plugin_program_index_start">Index Start Menu</system:String>
<system:String x:Key="wox_plugin_program_index_registry">Index Registry</system:String>
<system:String x:Key="wox_plugin_program_suffixes_header">Suffixes</system:String>
<system:String x:Key="wox_plugin_program_max_depth_header">Max Depth</system:String>
<system:String x:Key="wox_plugin_program_directory">Directory:</system:String>
<system:String x:Key="wox_plugin_program_browse">Browse</system:String>
<system:String x:Key="wox_plugin_program_file_suffixes">File Suffixes:</system:String>
<system:String x:Key="wox_plugin_program_max_search_depth">Maximum Search Depth (-1 is unlimited):</system:String>
<system:String x:Key="wox_plugin_program_pls_select_program_source">Please select a program source</system:String>
<system:String x:Key="wox_plugin_program_delete_program_source">Are your sure to delete {0}?</system:String>
<system:String x:Key="wox_plugin_program_update">Update</system:String>
<system:String x:Key="wox_plugin_program_only_index_tip">Wox will only index files that end with following suffixes:</system:String>
<system:String x:Key="wox_plugin_program_split_by_tip">(Each suffix should split by ;)</system:String>
<system:String x:Key="wox_plugin_program_update_file_suffixes">Sucessfully update file suffixes</system:String>
<system:String x:Key="wox_plugin_program_suffixes_cannot_empty">File suffixes can't be empty</system:String>
<system:String x:Key="wox_plugin_program_run_as_administrator">Run As Administrator</system:String>
<system:String x:Key="wox_plugin_program_open_containing_folder">Open containing folder</system:String>
<system:String x:Key="wox_plugin_program_plugin_name">Program</system:String>
<system:String x:Key="wox_plugin_program_plugin_description">Search programs in Wox</system:String>
</ResourceDictionary>

View file

@ -0,0 +1,37 @@
<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">
<!--Program setting-->
<system:String x:Key="wox_plugin_program_delete">Usuń</system:String>
<system:String x:Key="wox_plugin_program_edit">Edytuj</system:String>
<system:String x:Key="wox_plugin_program_add">Dodaj</system:String>
<system:String x:Key="wox_plugin_program_location">Lokalizacja</system:String>
<system:String x:Key="wox_plugin_program_suffixes">Rozszerzenia indeksowanych plików</system:String>
<system:String x:Key="wox_plugin_program_reindex">Re-indeksuj</system:String>
<system:String x:Key="wox_plugin_program_indexing">Indeksowanie</system:String>
<system:String x:Key="wox_plugin_program_index_start">Indeksuj Menu Start</system:String>
<system:String x:Key="wox_plugin_program_index_registry">Indeksuj rejestr</system:String>
<system:String x:Key="wox_plugin_program_suffixes_header">Rozszerzenia</system:String>
<system:String x:Key="wox_plugin_program_max_depth_header">Maksymalna głębokość</system:String>
<system:String x:Key="wox_plugin_program_directory">Katalog:</system:String>
<system:String x:Key="wox_plugin_program_browse">Przeglądaj</system:String>
<system:String x:Key="wox_plugin_program_file_suffixes">Rozszerzenia plików:</system:String>
<system:String x:Key="wox_plugin_program_max_search_depth">Maksymalna głębokość wyszukiwania (-1 to nieograniczona):</system:String>
<system:String x:Key="wox_plugin_program_pls_select_program_source">Musisz wybrać katalog programu</system:String>
<system:String x:Key="wox_plugin_program_update">Aktualizuj</system:String>
<system:String x:Key="wox_plugin_program_only_index_tip">Wox będzie indeksował tylko te pliki z podanymi rozszerzeniami:</system:String>
<system:String x:Key="wox_plugin_program_split_by_tip">(Każde rozszerzenie musi być oddzielone ;)</system:String>
<system:String x:Key="wox_plugin_program_update_file_suffixes">Pomyślnie zaktualizowano rozszerzenia plików</system:String>
<system:String x:Key="wox_plugin_program_suffixes_cannot_empty">Musisz podać rozszerzenia plików</system:String>
<system:String x:Key="wox_plugin_program_run_as_administrator">Uruchom jako administrator</system:String>
<system:String x:Key="wox_plugin_program_open_containing_folder">Otwórz folder zawierający</system:String>
<system:String x:Key="wox_plugin_program_plugin_name">Programy</system:String>
<system:String x:Key="wox_plugin_program_plugin_description">Szukaj i uruchamiaj programy z poziomu Woxa</system:String>
</ResourceDictionary>

View file

@ -0,0 +1,39 @@
<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">
<!--Program setting-->
<system:String x:Key="wox_plugin_program_delete">Sil</system:String>
<system:String x:Key="wox_plugin_program_edit">Düzenle</system:String>
<system:String x:Key="wox_plugin_program_add">Ekle</system:String>
<system:String x:Key="wox_plugin_program_location">Konum</system:String>
<system:String x:Key="wox_plugin_program_suffixes">İndekslenecek Uzantılar</system:String>
<system:String x:Key="wox_plugin_program_reindex">Yeniden İndeksle</system:String>
<system:String x:Key="wox_plugin_program_indexing">İndeksleniyor</system:String>
<system:String x:Key="wox_plugin_program_index_start">Başlat Menüsünü İndeksle</system:String>
<system:String x:Key="wox_plugin_program_index_registry">Registry'i İndeksle</system:String>
<system:String x:Key="wox_plugin_program_suffixes_header">Uzantılar</system:String>
<system:String x:Key="wox_plugin_program_max_depth_header">Derinlik</system:String>
<system:String x:Key="wox_plugin_program_directory">Dizin:</system:String>
<system:String x:Key="wox_plugin_program_browse">Gözat</system:String>
<system:String x:Key="wox_plugin_program_file_suffixes">Dosya Uzantıları:</system:String>
<system:String x:Key="wox_plugin_program_max_search_depth">Maksimum Arama Derinliği (Limitsiz için -1):</system:String>
<system:String x:Key="wox_plugin_program_pls_select_program_source">İşlem yapmak istediğiniz klasörü seçin.</system:String>
<system:String x:Key="wox_plugin_program_update">Güncelle</system:String>
<system:String x:Key="wox_plugin_program_only_index_tip">Wox yalnızca aşağıdaki uzantılara sahip dosyaları indeksleyecektir:</system:String>
<system:String x:Key="wox_plugin_program_split_by_tip">(Her uzantıyı ; işareti ile ayırın)</system:String>
<system:String x:Key="wox_plugin_program_update_file_suffixes">Dosya uzantıları başarıyla güncellendi</system:String>
<system:String x:Key="wox_plugin_program_suffixes_cannot_empty">Dosya uzantıları boş olamaz</system:String>
<system:String x:Key="wox_plugin_program_run_as_administrator">Yönetici Olarak Çalıştır</system:String>
<system:String x:Key="wox_plugin_program_open_containing_folder">İçeren Klasörü Aç</system:String>
<system:String x:Key="wox_plugin_program_plugin_name">Program</system:String>
<system:String x:Key="wox_plugin_program_plugin_description">Programları Wox'tan arayın</system:String>
<system:String x:Key="wox_plugin_program_invalid_path">Geçersiz Konum</system:String>
</ResourceDictionary>

View file

@ -0,0 +1,39 @@
<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">
<!--Program setting-->
<system:String x:Key="wox_plugin_program_delete">删除</system:String>
<system:String x:Key="wox_plugin_program_edit">编辑</system:String>
<system:String x:Key="wox_plugin_program_add">增加</system:String>
<system:String x:Key="wox_plugin_program_location">位置</system:String>
<system:String x:Key="wox_plugin_program_suffixes">索引文件后缀</system:String>
<system:String x:Key="wox_plugin_program_reindex">重新索引</system:String>
<system:String x:Key="wox_plugin_program_indexing">索引中</system:String>
<system:String x:Key="wox_plugin_program_index_start">索引开始菜单</system:String>
<system:String x:Key="wox_plugin_program_index_registry">索引注册表</system:String>
<system:String x:Key="wox_plugin_program_suffixes_header">后缀</system:String>
<system:String x:Key="wox_plugin_program_max_depth_header">最大深度</system:String>
<system:String x:Key="wox_plugin_program_directory">目录</system:String>
<system:String x:Key="wox_plugin_program_browse">浏览</system:String>
<system:String x:Key="wox_plugin_program_file_suffixes">文件后缀</system:String>
<system:String x:Key="wox_plugin_program_max_search_depth">最大搜索深度(-1是无限的</system:String>
<system:String x:Key="wox_plugin_program_pls_select_program_source">请先选择一项</system:String>
<system:String x:Key="wox_plugin_program_update">更新</system:String>
<system:String x:Key="wox_plugin_program_only_index_tip">Wox仅索引下列后缀的文件</system:String>
<system:String x:Key="wox_plugin_program_split_by_tip">(每个后缀以英文状态下的分号分隔)</system:String>
<system:String x:Key="wox_plugin_program_update_file_suffixes">成功更新索引文件后缀</system:String>
<system:String x:Key="wox_plugin_program_suffixes_cannot_empty">文件后缀不能为空</system:String>
<system:String x:Key="wox_plugin_program_run_as_administrator">以管理员身份运行</system:String>
<system:String x:Key="wox_plugin_program_open_containing_folder">打开所属文件夹</system:String>
<system:String x:Key="wox_plugin_program_plugin_name">程序</system:String>
<system:String x:Key="wox_plugin_program_plugin_description">在Wox中搜索程序</system:String>
<system:String x:Key="wox_plugin_program_invalid_path">无效路径</system:String>
</ResourceDictionary>

View file

@ -0,0 +1,36 @@
<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">
<!--Program setting-->
<system:String x:Key="wox_plugin_program_delete">刪除</system:String>
<system:String x:Key="wox_plugin_program_edit">編輯</system:String>
<system:String x:Key="wox_plugin_program_add">新增</system:String>
<system:String x:Key="wox_plugin_program_location">路徑</system:String>
<system:String x:Key="wox_plugin_program_suffixes">索引副檔名清單</system:String>
<system:String x:Key="wox_plugin_program_reindex">重新建立索引</system:String>
<system:String x:Key="wox_plugin_program_indexing">正在建立索引</system:String>
<system:String x:Key="wox_plugin_program_index_start">替開始選單建立索引</system:String>
<system:String x:Key="wox_plugin_program_index_registry">替登錄檔建立索引</system:String>
<system:String x:Key="wox_plugin_program_suffixes_header">副檔名</system:String>
<system:String x:Key="wox_plugin_program_max_depth_header">最大深度</system:String>
<system:String x:Key="wox_plugin_program_directory">目錄</system:String>
<system:String x:Key="wox_plugin_program_browse">瀏覽</system:String>
<system:String x:Key="wox_plugin_program_file_suffixes">副檔名</system:String>
<system:String x:Key="wox_plugin_program_max_search_depth">最大搜尋深度(-1是無限的</system:String>
<system:String x:Key="wox_plugin_program_pls_select_program_source">請先選擇一項</system:String>
<system:String x:Key="wox_plugin_program_update">更新</system:String>
<system:String x:Key="wox_plugin_program_only_index_tip">Wox 僅索引下列副檔名的檔案:</system:String>
<system:String x:Key="wox_plugin_program_split_by_tip">(每個副檔名以英文的分號分隔)</system:String>
<system:String x:Key="wox_plugin_program_update_file_suffixes">成功更新索引副檔名清單</system:String>
<system:String x:Key="wox_plugin_program_suffixes_cannot_empty">副檔名不能為空</system:String>
<system:String x:Key="wox_plugin_program_run_as_administrator">以系統管理員身分執行</system:String>
<system:String x:Key="wox_plugin_program_open_containing_folder">開啟檔案位置</system:String>
<system:String x:Key="wox_plugin_program_plugin_name">程式</system:String>
<system:String x:Key="wox_plugin_program_plugin_description">在 Wox 中搜尋程式</system:String>
</ResourceDictionary>

View file

@ -0,0 +1,33 @@
using System;
using System.Globalization;
using System.Windows.Data;
using System.Windows.Markup;
namespace Wox.Plugin.Program
{
public class LocationConverter : MarkupExtension, IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var text = value as string;
if (string.IsNullOrEmpty(text))
{
return string.Empty;
}
else
{
return text;
}
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotSupportedException();
}
public override object ProvideValue(IServiceProvider serviceProvider)
{
return this;
}
}
}

View file

@ -0,0 +1,139 @@
using NLog;
using NLog.Config;
using NLog.Targets;
using System;
using System.Diagnostics;
using System.IO;
using System.Runtime.CompilerServices;
using System.Security;
using Wox.Infrastructure;
namespace Wox.Plugin.Program.Logger
{
/// <summary>
/// The Program plugin has seen many issues recorded in the Wox repo related to various loading of Windows programs.
/// This is a dedicated logger for this Program plugin with the aim to output a more friendlier message and clearer
/// log that will allow debugging to be quicker and easier.
/// </summary>
internal static class ProgramLogger
{
public const string DirectoryName = "Logs";
static ProgramLogger()
{
var path = Path.Combine(Constant.DataDirectory, DirectoryName, Constant.Version);
if (!Directory.Exists(path))
{
Directory.CreateDirectory(path);
}
var configuration = new LoggingConfiguration();
var target = new FileTarget();
configuration.AddTarget("file", target);
target.FileName = path.Replace(@"\", "/") + "/${shortdate}.txt";
#if DEBUG
var rule = new LoggingRule("*", LogLevel.Debug, target);
#else
var rule = new LoggingRule("*", LogLevel.Error, target);
#endif
configuration.LoggingRules.Add(rule);
LogManager.Configuration = configuration;
}
/// <summary>
/// Logs an exception
/// </summary>
[MethodImpl(MethodImplOptions.Synchronized)]
internal static void LogException(string classname, string callingMethodName, string loadingProgramPath,
string interpretationMessage, Exception e)
{
Debug.WriteLine($"ERROR{classname}|{callingMethodName}|{loadingProgramPath}|{interpretationMessage}");
var logger = LogManager.GetLogger("");
var innerExceptionNumber = 1;
var possibleResolution = "Not yet known";
var errorStatus = "UNKNOWN";
logger.Error("------------- BEGIN Wox.Plugin.Program exception -------------");
do
{
if (IsKnownWinProgramError(e, callingMethodName) || IsKnownUWPProgramError(e, callingMethodName))
{
possibleResolution = "Can be ignored and Wox should still continue, however the program may not be loaded";
errorStatus = "KNOWN";
}
var calledMethod = e.TargetSite != null ? e.TargetSite.ToString() : e.StackTrace;
calledMethod = string.IsNullOrEmpty(calledMethod) ? "Not available" : calledMethod;
logger.Error($"\nException full name: {e.GetType().FullName}"
+ $"\nError status: {errorStatus}"
+ $"\nClass name: {classname}"
+ $"\nCalling method: {callingMethodName}"
+ $"\nProgram path: {loadingProgramPath}"
+ $"\nInnerException number: {innerExceptionNumber}"
+ $"\nException message: {e.Message}"
+ $"\nException error type: HResult {e.HResult}"
+ $"\nException thrown in called method: {calledMethod}"
+ $"\nPossible interpretation of the error: {interpretationMessage}"
+ $"\nPossible resolution: {possibleResolution}");
innerExceptionNumber++;
e = e.InnerException;
} while (e != null);
logger.Error("------------- END Wox.Plugin.Program exception -------------");
}
/// <summary>
/// Please follow exception format: |class name|calling method name|loading program path|user friendly message that explains the error
/// => Example: |Win32|LnkProgram|c:\..\chrome.exe|Permission denied on directory, but Wox should continue
/// </summary>
[MethodImpl(MethodImplOptions.Synchronized)]
internal static void LogException(string message, Exception e)
{
//Index 0 is always empty.
var parts = message.Split('|');
if (parts.Length < 4)
{
var logger = LogManager.GetLogger("");
logger.Error(e, $"fail to log exception in program logger, parts length is too small: {parts.Length}, message: {message}");
}
var classname = parts[1];
var callingMethodName = parts[2];
var loadingProgramPath = parts[3];
var interpretationMessage = parts[4];
LogException(classname, callingMethodName, loadingProgramPath, interpretationMessage, e);
}
private static bool IsKnownWinProgramError(Exception e, string callingMethodName)
{
if (e.TargetSite?.Name == "GetDescription" && callingMethodName == "LnkProgram")
return true;
if (e is SecurityException || e is UnauthorizedAccessException || e is DirectoryNotFoundException)
return true;
return false;
}
private static bool IsKnownUWPProgramError(Exception e, string callingMethodName)
{
if (((e.HResult == -2147024774 || e.HResult == -2147009769) && callingMethodName == "ResourceFromPri")
|| (e.HResult == -2147024894 && (callingMethodName == "LogoPathFromUri" || callingMethodName == "ImageFromPath"))
|| (e.HResult == -2147024864 && callingMethodName == "InitializeAppInfo"))
return true;
if (callingMethodName == "XmlNamespaces")
return true;
return false;
}
}
}

View file

@ -0,0 +1,235 @@
using Microsoft.PowerToys.Settings.UI.Lib;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Timers;
using System.Windows.Controls;
using Wox.Infrastructure.Logger;
using Wox.Infrastructure.Storage;
using Wox.Plugin.Program.Programs;
using Wox.Plugin.Program.Views;
using Stopwatch = Wox.Infrastructure.Stopwatch;
namespace Wox.Plugin.Program
{
public class Main : ISettingProvider, IPlugin, IPluginI18n, IContextMenu, ISavable, IReloadable
{
private static readonly object IndexLock = new object();
internal static Win32[] _win32s { get; set; }
internal static UWP.Application[] _uwps { get; set; }
internal static Settings _settings { get; set; }
FileSystemWatcher _watcher = null;
System.Timers.Timer _timer = null;
private static bool IsStartupIndexProgramsRequired => _settings.LastIndexTime.AddDays(3) < DateTime.Today;
private static PluginInitContext _context;
private static BinaryStorage<Win32[]> _win32Storage;
private static BinaryStorage<UWP.Application[]> _uwpStorage;
private readonly PluginJsonStorage<Settings> _settingsStorage;
public Main()
{
_settingsStorage = new PluginJsonStorage<Settings>();
_settings = _settingsStorage.Load();
Stopwatch.Normal("|Wox.Plugin.Program.Main|Preload programs cost", () =>
{
_win32Storage = new BinaryStorage<Win32[]>("Win32");
_win32s = _win32Storage.TryLoad(new Win32[] { });
_uwpStorage = new BinaryStorage<UWP.Application[]>("UWP");
_uwps = _uwpStorage.TryLoad(new UWP.Application[] { });
});
Log.Info($"|Wox.Plugin.Program.Main|Number of preload win32 programs <{_win32s.Length}>");
Log.Info($"|Wox.Plugin.Program.Main|Number of preload uwps <{_uwps.Length}>");
var a = Task.Run(() =>
{
if (IsStartupIndexProgramsRequired || !_win32s.Any())
Stopwatch.Normal("|Wox.Plugin.Program.Main|Win32Program index cost", IndexWin32Programs);
});
var b = Task.Run(() =>
{
if (IsStartupIndexProgramsRequired || !_uwps.Any())
Stopwatch.Normal("|Wox.Plugin.Program.Main|Win32Program index cost", IndexUWPPrograms);
});
Task.WaitAll(a, b);
_settings.LastIndexTime = DateTime.Today;
InitializeFileWatchers();
InitializeTimer();
}
public void Save()
{
_settingsStorage.Save();
_win32Storage.Save(_win32s);
_uwpStorage.Save(_uwps);
}
public List<Result> Query(Query query)
{
Win32[] win32;
UWP.Application[] uwps;
lock (IndexLock)
{
// just take the reference inside the lock to eliminate query time issues.
win32 = _win32s;
uwps = _uwps;
}
var results1 = win32.AsParallel()
.Where(p => p.Enabled)
.Select(p => p.Result(query.Search, _context.API));
var results2 = uwps.AsParallel()
.Where(p => p.Enabled)
.Select(p => p.Result(query.Search, _context.API));
var result = results1.Concat(results2).Where(r => r != null && r.Score > 0).ToList();
return result;
}
public void Init(PluginInitContext context)
{
_context = context;
}
public static void IndexWin32Programs()
{
var win32S = Win32.All(_settings);
lock (IndexLock)
{
_win32s = win32S;
}
}
public static void IndexUWPPrograms()
{
var windows10 = new Version(10, 0);
var support = Environment.OSVersion.Version.Major >= windows10.Major;
var applications = support ? UWP.All() : new UWP.Application[] { };
lock (IndexLock)
{
_uwps = applications;
}
}
public static void IndexPrograms()
{
var t1 = Task.Run(() => IndexWin32Programs());
var t2 = Task.Run(() => IndexUWPPrograms());
Task.WaitAll(t1, t2);
_settings.LastIndexTime = DateTime.Today;
}
public Control CreateSettingPanel()
{
return new ProgramSetting(_context, _settings, _win32s, _uwps);
}
public string GetTranslatedPluginTitle()
{
return _context.API.GetTranslation("wox_plugin_program_plugin_name");
}
public string GetTranslatedPluginDescription()
{
return _context.API.GetTranslation("wox_plugin_program_plugin_description");
}
public List<ContextMenuResult> LoadContextMenus(Result selectedResult)
{
var menuOptions = new List<ContextMenuResult>();
var program = selectedResult.ContextData as IProgram;
if (program != null)
{
menuOptions = program.ContextMenus(_context.API);
}
return menuOptions;
}
public static void StartProcess(Func<ProcessStartInfo, Process> runProcess, ProcessStartInfo info)
{
try
{
runProcess(info);
}
catch (Exception)
{
var name = "Plugin: Program";
var message = $"Unable to start: {info.FileName}";
_context.API.ShowMsg(name, message, string.Empty);
}
}
public void ReloadData()
{
IndexPrograms();
}
public void UpdateSettings(PowerLauncherSettings settings)
{
}
void InitializeFileWatchers()
{
// Create a new FileSystemWatcher and set its properties.
_watcher = new FileSystemWatcher();
var resolvedPath = Environment.ExpandEnvironmentVariables("%ProgramFiles%");
_watcher.Path = resolvedPath;
//Filter to create and deletes of 'microsoft.system.package.metadata' directories.
_watcher.NotifyFilter = NotifyFilters.DirectoryName | NotifyFilters.FileName;
_watcher.IncludeSubdirectories = true;
// Add event handlers.
_watcher.Created += OnChanged;
_watcher.Deleted += OnChanged;
// Begin watching.
_watcher.EnableRaisingEvents = true;
}
void InitializeTimer()
{
//multiple file writes occur on install / unistall. Adding a delay before actually indexing.
var delayInterval = 5000;
_timer = new System.Timers.Timer(delayInterval);
_timer.Enabled = true;
_timer.AutoReset = false;
_timer.Elapsed += FileWatchElapsedTimer;
_timer.Stop();
}
//When a watched directory changes then reset the timer.
private void OnChanged(object source, FileSystemEventArgs e)
{
Log.Debug($"|Wox.Plugin.Program.Main|Directory Changed: {e.FullPath} {e.ChangeType} - Resetting timer.");
_timer.Stop();
_timer.Start();
}
private void FileWatchElapsedTimer(object sender, ElapsedEventArgs e)
{
Task.Run(() =>
{
Log.Debug($"|Wox.Plugin.Program.Main| ReIndexing UWP Programs");
IndexUWPPrograms();
Log.Debug($"|Wox.Plugin.Program.Main| Done ReIndexing");
});
}
}
}

View file

@ -0,0 +1,24 @@
<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="180"
WindowStartupLocation="CenterScreen"
d:DesignHeight="400" d:DesignWidth="300">
<StackPanel>
<TextBlock Margin="10 10 0 0" Foreground="Gray" Text="{DynamicResource wox_plugin_program_only_index_tip}" />
<TextBlock Margin="10 10 0 0" Foreground="Gray" Text="{DynamicResource wox_plugin_program_split_by_tip}" />
<TextBox x:Name="tbSuffixes" Margin="10"/>
<Button HorizontalAlignment="Right" Height="30" Width="80" Click="ButtonBase_OnClick" Margin="10" Content="{DynamicResource wox_plugin_program_update}" />
</StackPanel>
</Window>

View file

@ -0,0 +1,37 @@
using System.Windows;
namespace Wox.Plugin.Program
{
/// <summary>
/// ProgramSuffixes.xaml 的交互逻辑
/// </summary>
public partial class ProgramSuffixes
{
private PluginInitContext context;
private Settings _settings;
public ProgramSuffixes(PluginInitContext context, Settings settings)
{
this.context = context;
InitializeComponent();
_settings = settings;
tbSuffixes.Text = string.Join(Settings.SuffixSeperator.ToString(), _settings.ProgramSuffixes);
}
private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
{
if (string.IsNullOrEmpty(tbSuffixes.Text))
{
string warning = context.API.GetTranslation("wox_plugin_program_suffixes_cannot_empty");
MessageBox.Show(warning);
return;
}
_settings.ProgramSuffixes = tbSuffixes.Text.Split(Settings.SuffixSeperator);
string msg = context.API.GetTranslation("wox_plugin_program_update_file_suffixes");
MessageBox.Show(msg);
DialogResult = true;
}
}
}

View file

@ -0,0 +1,13 @@
using System.Collections.Generic;
namespace Wox.Plugin.Program.Programs
{
public interface IProgram
{
List<ContextMenuResult> ContextMenus(IPublicAPI api);
Result Result(string query, IPublicAPI api);
string UniqueIdentifier { get; set; }
string Name { get; }
string Location { get; }
}
}

View file

@ -0,0 +1,570 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Security.Principal;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
using Windows.ApplicationModel;
using Windows.Management.Deployment;
using AppxPackaing;
using Shell;
using Wox.Infrastructure;
using Wox.Plugin.Program.Logger;
using IStream = AppxPackaing.IStream;
using Rect = System.Windows.Rect;
using Windows.UI.Xaml.Media.Imaging;
using Windows.UI.Xaml.Media;
using System.Windows.Controls;
namespace Wox.Plugin.Program.Programs
{
[Serializable]
public class UWP
{
public string Name { get; }
public string FullName { get; }
public string FamilyName { get; }
public string Location { get; set; }
public Application[] Apps { get; set; }
public PackageVersion Version { get; set; }
public UWP(Package package)
{
Location = package.InstalledLocation.Path;
Name = package.Id.Name;
FullName = package.Id.FullName;
FamilyName = package.Id.FamilyName;
InitializeAppInfo();
Apps = Apps.Where(a =>
{
var valid =
!string.IsNullOrEmpty(a.UserModelId) &&
!string.IsNullOrEmpty(a.DisplayName);
return valid;
}).ToArray();
}
private void InitializeAppInfo()
{
var path = Path.Combine(Location, "AppxManifest.xml");
var namespaces = XmlNamespaces(path);
InitPackageVersion(namespaces);
var appxFactory = new AppxFactory();
IStream stream;
const uint noAttribute = 0x80;
const Stgm exclusiveRead = Stgm.Read | Stgm.ShareExclusive;
var hResult = SHCreateStreamOnFileEx(path, exclusiveRead, noAttribute, false, null, out stream);
if (hResult == Hresult.Ok)
{
var reader = appxFactory.CreateManifestReader(stream);
var manifestApps = reader.GetApplications();
var apps = new List<Application>();
while (manifestApps.GetHasCurrent() != 0)
{
var manifestApp = manifestApps.GetCurrent();
var appListEntry = manifestApp.GetStringValue("AppListEntry");
if (appListEntry != "none")
{
var app = new Application(manifestApp, this);
apps.Add(app);
}
manifestApps.MoveNext();
}
Apps = apps.Where(a => a.AppListEntry != "none").ToArray();
}
else
{
var e = Marshal.GetExceptionForHR((int)hResult);
ProgramLogger.LogException($"|UWP|InitializeAppInfo|{path}" +
"|Error caused while trying to get the details of the UWP program", e);
Apps = new List<Application>().ToArray();
}
}
/// http://www.hanselman.com/blog/GetNamespacesFromAnXMLDocumentWithXPathDocumentAndLINQToXML.aspx
private string[] XmlNamespaces(string path)
{
XDocument z = XDocument.Load(path);
if (z.Root != null)
{
var namespaces = z.Root.Attributes().
Where(a => a.IsNamespaceDeclaration).
GroupBy(
a => a.Name.Namespace == XNamespace.None ? string.Empty : a.Name.LocalName,
a => XNamespace.Get(a.Value)
).Select(
g => g.First().ToString()
).ToArray();
return namespaces;
}
else
{
ProgramLogger.LogException($"|UWP|XmlNamespaces|{path}" +
$"|Error occured while trying to get the XML from {path}", new ArgumentNullException());
return new string[] { };
}
}
private void InitPackageVersion(string[] namespaces)
{
var versionFromNamespace = new Dictionary<string, PackageVersion>
{
{"http://schemas.microsoft.com/appx/manifest/foundation/windows10", PackageVersion.Windows10},
{"http://schemas.microsoft.com/appx/2013/manifest", PackageVersion.Windows81},
{"http://schemas.microsoft.com/appx/2010/manifest", PackageVersion.Windows8},
};
foreach (var n in versionFromNamespace.Keys)
{
if (namespaces.Contains(n))
{
Version = versionFromNamespace[n];
return;
}
}
ProgramLogger.LogException($"|UWP|XmlNamespaces|{Location}" +
"|Trying to get the package version of the UWP program, but a unknown UWP appmanifest version "
+ $"{FullName} from location {Location} is returned.", new FormatException());
Version = PackageVersion.Unknown;
}
public static Application[] All()
{
var windows10 = new Version(10, 0);
var support = Environment.OSVersion.Version.Major >= windows10.Major;
if (support)
{
var applications = CurrentUserPackages().AsParallel().SelectMany(p =>
{
UWP u;
try
{
u = new UWP(p);
}
#if !DEBUG
catch (Exception e)
{
ProgramLogger.LogException($"|UWP|All|{p.InstalledLocation}|An unexpected error occured and "
+ $"unable to convert Package to UWP for {p.Id.FullName}", e);
return new Application[] { };
}
#endif
#if DEBUG //make developer aware and implement handling
catch
{
throw;
}
#endif
return u.Apps;
}).ToArray();
var updatedListWithoutDisabledApps = applications
.Where(t1 => !Main._settings.DisabledProgramSources
.Any(x => x.UniqueIdentifier == t1.UniqueIdentifier))
.Select(x => x);
return updatedListWithoutDisabledApps.ToArray();
}
else
{
return new Application[] { };
}
}
private static IEnumerable<Package> CurrentUserPackages()
{
var u = WindowsIdentity.GetCurrent().User;
if (u != null)
{
var id = u.Value;
var m = new PackageManager();
var ps = m.FindPackagesForUser(id);
ps = ps.Where(p =>
{
bool valid;
try
{
var f = p.IsFramework;
var d = p.IsDevelopmentMode;
var path = p.InstalledLocation.Path;
valid = !f && !d && !string.IsNullOrEmpty(path);
}
catch (Exception e)
{
ProgramLogger.LogException("UWP" ,"CurrentUserPackages", $"id","An unexpected error occured and "
+ $"unable to verify if package is valid", e);
return false;
}
return valid;
});
return ps;
}
else
{
return new Package[] { };
}
}
public override string ToString()
{
return FamilyName;
}
public override bool Equals(object obj)
{
if (obj is UWP uwp)
{
return FamilyName.Equals(uwp.FamilyName);
}
else
{
return false;
}
}
public override int GetHashCode()
{
return FamilyName.GetHashCode();
}
[Serializable]
public class Application : IProgram
{
public string AppListEntry { get; set; }
public string UniqueIdentifier { get; set; }
public string DisplayName { get; set; }
public string Description { get; set; }
public string UserModelId { get; set; }
public string BackgroundColor { get; set; }
public string Name => DisplayName;
public string Location => Package.Location;
public bool Enabled { get; set; }
public string LogoUri { get; set; }
public string LogoPath { get; set; }
public UWP Package { get; set; }
private int Score(string query)
{
var displayNameMatch = StringMatcher.FuzzySearch(query, DisplayName);
var descriptionMatch = StringMatcher.FuzzySearch(query, Description);
var score = new[] { displayNameMatch.Score, descriptionMatch.Score }.Max();
return score;
}
public Result Result(string query, IPublicAPI api)
{
var score = Score(query);
if (score <= 0)
{ // no need to create result if score is 0
return null;
}
var result = new Result
{
SubTitle = "UWP application",
Icon = Logo,
Score = score,
ContextData = this,
Action = e =>
{
Launch(api);
return true;
}
};
if (Description.Length >= DisplayName.Length &&
Description.Substring(0, DisplayName.Length) == DisplayName)
{
result.Title = Description;
result.TitleHighlightData = StringMatcher.FuzzySearch(query, Description).MatchData;
}
else
{
result.Title = DisplayName;
result.TitleHighlightData = StringMatcher.FuzzySearch(query, DisplayName).MatchData;
}
return result;
}
public List<ContextMenuResult> ContextMenus(IPublicAPI api)
{
var contextMenus = new List<ContextMenuResult>
{
new ContextMenuResult
{
Title = api.GetTranslation("wox_plugin_program_open_containing_folder"),
Glyph = "\xE838",
FontFamily = "Segoe MDL2 Assets",
AcceleratorKey = "E",
AcceleratorModifiers = "Control,Shift",
Action = _ =>
{
Main.StartProcess(Process.Start, new ProcessStartInfo("explorer", Package.Location));
return true;
}
}
};
return contextMenus;
}
private async void Launch(IPublicAPI api)
{
var appManager = new ApplicationActivationManager();
uint unusedPid;
const string noArgs = "";
const ACTIVATEOPTIONS noFlags = ACTIVATEOPTIONS.AO_NONE;
await Task.Run(() =>
{
try
{
appManager.ActivateApplication(UserModelId, noArgs, noFlags, out unusedPid);
}
catch (Exception)
{
var name = "Plugin: Program";
var message = $"Can't start UWP: {DisplayName}";
api.ShowMsg(name, message, string.Empty);
}
});
}
public Application(IAppxManifestApplication manifestApp, UWP package)
{
UserModelId = manifestApp.GetAppUserModelId();
UniqueIdentifier = manifestApp.GetAppUserModelId();
DisplayName = manifestApp.GetStringValue("DisplayName");
Description = manifestApp.GetStringValue("Description");
BackgroundColor = manifestApp.GetStringValue("BackgroundColor");
Package = package;
DisplayName = ResourceFromPri(package.FullName, DisplayName);
Description = ResourceFromPri(package.FullName, Description);
LogoUri = LogoUriFromManifest(manifestApp);
LogoPath = LogoPathFromUri(LogoUri);
Enabled = true;
}
internal string ResourceFromPri(string packageFullName, string resourceReference)
{
const string prefix = "ms-resource:";
if (!string.IsNullOrWhiteSpace(resourceReference) && resourceReference.StartsWith(prefix))
{
// magic comes from @talynone
// https://github.com/talynone/Wox.Plugin.WindowsUniversalAppLauncher/blob/master/StoreAppLauncher/Helpers/NativeApiHelper.cs#L139-L153
string key = resourceReference.Substring(prefix.Length);
string parsed;
if (key.StartsWith("//"))
{
parsed = prefix + key;
}
else if (key.StartsWith("/"))
{
parsed = prefix + "//" + key;
}
else
{
parsed = prefix + "///resources/" + key;
}
var outBuffer = new StringBuilder(128);
string source = $"@{{{packageFullName}? {parsed}}}";
var capacity = (uint)outBuffer.Capacity;
var hResult = SHLoadIndirectString(source, outBuffer, capacity, IntPtr.Zero);
if (hResult == Hresult.Ok)
{
var loaded = outBuffer.ToString();
if (!string.IsNullOrEmpty(loaded))
{
return loaded;
}
else
{
ProgramLogger.LogException($"|UWP|ResourceFromPri|{Package.Location}|Can't load null or empty result "
+ $"pri {source} in uwp location {Package.Location}", new NullReferenceException());
return string.Empty;
}
}
else
{
// https://github.com/Wox-launcher/Wox/issues/964
// known hresult 2147942522:
// 'Microsoft Corporation' violates pattern constraint of '\bms-resource:.{1,256}'.
// for
// Microsoft.MicrosoftOfficeHub_17.7608.23501.0_x64__8wekyb3d8bbwe: ms-resource://Microsoft.MicrosoftOfficeHub/officehubintl/AppManifest_GetOffice_Description
// Microsoft.BingFoodAndDrink_3.0.4.336_x64__8wekyb3d8bbwe: ms-resource:AppDescription
var e = Marshal.GetExceptionForHR((int)hResult);
ProgramLogger.LogException($"|UWP|ResourceFromPri|{Package.Location}|Load pri failed {source} with HResult {hResult} and location {Package.Location}", e);
return string.Empty;
}
}
else
{
return resourceReference;
}
}
internal string LogoUriFromManifest(IAppxManifestApplication app)
{
var logoKeyFromVersion = new Dictionary<PackageVersion, string>
{
{ PackageVersion.Windows10, "Square44x44Logo" },
{ PackageVersion.Windows81, "Square30x30Logo" },
{ PackageVersion.Windows8, "SmallLogo" },
};
if (logoKeyFromVersion.ContainsKey(Package.Version))
{
var key = logoKeyFromVersion[Package.Version];
var logoUri = app.GetStringValue(key);
return logoUri;
}
else
{
return string.Empty;
}
}
internal string LogoPathFromUri(string uri)
{
// all https://msdn.microsoft.com/windows/uwp/controls-and-patterns/tiles-and-notifications-app-assets
// windows 10 https://msdn.microsoft.com/en-us/library/windows/apps/dn934817.aspx
// windows 8.1 https://msdn.microsoft.com/en-us/library/windows/apps/hh965372.aspx#target_size
// windows 8 https://msdn.microsoft.com/en-us/library/windows/apps/br211475.aspx
string path;
if (uri.Contains("\\"))
{
path = Path.Combine(Package.Location, uri);
}
else
{
// for C:\Windows\MiracastView etc
path = Path.Combine(Package.Location, "Assets", uri);
}
var extension = Path.GetExtension(path);
if (extension != null)
{
var end = path.Length - extension.Length;
var prefix = path.Substring(0, end);
var paths = new List<string> { path };
var scaleFactors = new Dictionary<PackageVersion, List<int>>
{
// scale factors on win10: https://docs.microsoft.com/en-us/windows/uwp/controls-and-patterns/tiles-and-notifications-app-assets#asset-size-tables,
{ PackageVersion.Windows10, new List<int> { 100, 125, 150, 200, 400 } },
{ PackageVersion.Windows81, new List<int> { 100, 120, 140, 160, 180 } },
{ PackageVersion.Windows8, new List<int> { 100 } }
};
if (scaleFactors.ContainsKey(Package.Version))
{
foreach (var factor in scaleFactors[Package.Version])
{
paths.Add($"{prefix}.scale-{factor}{extension}");
}
}
var selected = paths.FirstOrDefault(File.Exists);
if (!string.IsNullOrEmpty(selected))
{
return selected;
}
else
{
ProgramLogger.LogException($"|UWP|LogoPathFromUri|{Package.Location}" +
$"|{UserModelId} can't find logo uri for {uri} in package location: {Package.Location}", new FileNotFoundException());
return string.Empty;
}
}
else
{
ProgramLogger.LogException($"|UWP|LogoPathFromUri|{Package.Location}" +
$"|Unable to find extension from {uri} for {UserModelId} " +
$"in package location {Package.Location}", new FileNotFoundException());
return string.Empty;
}
}
public ImageSource Logo()
{
var logo = ImageFromPath(LogoPath);
return logo;
}
private BitmapImage ImageFromPath(string path)
{
if (File.Exists(path))
{
var image = new BitmapImage(new Uri(path));
return image;
}
else
{
ProgramLogger.LogException($"|UWP|ImageFromPath|{path}" +
$"|Unable to get logo for {UserModelId} from {path} and" +
$" located in {Package.Location}", new FileNotFoundException());
return new BitmapImage(new Uri(Constant.ErrorIcon));
}
}
public override string ToString()
{
return $"{DisplayName}: {Description}";
}
}
public enum PackageVersion
{
Windows10,
Windows81,
Windows8,
Unknown
}
[Flags]
private enum Stgm : uint
{
Read = 0x0,
ShareExclusive = 0x10,
}
private enum Hresult : uint
{
Ok = 0x0000,
}
[DllImport("shlwapi.dll", CharSet = CharSet.Unicode)]
private static extern Hresult SHCreateStreamOnFileEx(string fileName, Stgm grfMode, uint attributes, bool create,
IStream reserved, out IStream stream);
[DllImport("shlwapi.dll", CharSet = CharSet.Unicode)]
private static extern Hresult SHLoadIndirectString(string pszSource, StringBuilder pszOutBuf, uint cchOutBuf,
IntPtr ppvReserved);
}
}

View file

@ -0,0 +1,500 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Security;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Win32;
using Shell;
using Wox.Infrastructure;
using Wox.Plugin.Program.Logger;
namespace Wox.Plugin.Program.Programs
{
[Serializable]
public class Win32 : IProgram
{
public string Name { get; set; }
public string UniqueIdentifier { get; set; }
public string IcoPath { get; set; }
public string FullPath { get; set; }
public string LnkResolvedPath { get; set; }
public string ParentDirectory { get; set; }
public string ExecutableName { get; set; }
public string Description { get; set; }
public bool Valid { get; set; }
public bool Enabled { get; set; }
public string Location => ParentDirectory;
private const string ShortcutExtension = "lnk";
private const string ApplicationReferenceExtension = "appref-ms";
private const string ExeExtension = "exe";
private int Score(string query)
{
var nameMatch = StringMatcher.FuzzySearch(query, Name);
var descriptionMatch = StringMatcher.FuzzySearch(query, Description);
var executableNameMatch = StringMatcher.FuzzySearch(query, ExecutableName);
var score = new[] { nameMatch.Score, descriptionMatch.Score, executableNameMatch.Score }.Max();
return score;
}
public Result Result(string query, IPublicAPI api)
{
var score = Score(query);
if (score <= 0)
{ // no need to create result if this is zero
return null;
}
var result = new Result
{
SubTitle = "Win32 application",
IcoPath = IcoPath,
Score = score,
ContextData = this,
Action = e =>
{
var info = new ProcessStartInfo
{
FileName = FullPath,
WorkingDirectory = ParentDirectory,
UseShellExecute = true
};
Main.StartProcess(Process.Start, info);
return true;
}
};
if (Description.Length >= Name.Length &&
Description.Substring(0, Name.Length) == Name)
{
result.Title = Description;
result.TitleHighlightData = StringMatcher.FuzzySearch(query, Description).MatchData;
}
else
{
result.Title = Name;
result.TitleHighlightData = StringMatcher.FuzzySearch(query, Name).MatchData;
}
return result;
}
public List<ContextMenuResult> ContextMenus(IPublicAPI api)
{
var contextMenus = new List<ContextMenuResult>
{
new ContextMenuResult
{
Title = api.GetTranslation("wox_plugin_program_run_as_administrator"),
Glyph = "\xE7EF",
FontFamily = "Segoe MDL2 Assets",
AcceleratorKey = "Enter",
AcceleratorModifiers = "Control,Shift",
Action = _ =>
{
var info = new ProcessStartInfo
{
FileName = FullPath,
WorkingDirectory = ParentDirectory,
Verb = "runas",
UseShellExecute = true
};
Task.Run(() => Main.StartProcess(Process.Start, info));
return true;
}
},
new ContextMenuResult
{
Title = api.GetTranslation("wox_plugin_program_open_containing_folder"),
Glyph = "\xE838",
FontFamily = "Segoe MDL2 Assets",
AcceleratorKey = "E",
AcceleratorModifiers = "Control,Shift",
Action = _ =>
{
Main.StartProcess(Process.Start, new ProcessStartInfo("explorer", ParentDirectory));
return true;
}
}
};
return contextMenus;
}
public override string ToString()
{
return ExecutableName;
}
private static Win32 Win32Program(string path)
{
try
{
var p = new Win32
{
Name = Path.GetFileNameWithoutExtension(path),
ExecutableName = Path.GetFileName(path),
IcoPath = path,
FullPath = path.ToLower(),
UniqueIdentifier = path,
ParentDirectory = Directory.GetParent(path).FullName,
Description = string.Empty,
Valid = true,
Enabled = true
};
return p;
}
catch (Exception e) when (e is SecurityException || e is UnauthorizedAccessException)
{
ProgramLogger.LogException($"|Win32|Win32Program|{path}" +
$"|Permission denied when trying to load the program from {path}", e);
return new Win32() { Valid = false, Enabled = false };
}
}
private static Win32 LnkProgram(string path)
{
var program = Win32Program(path);
try
{
var link = new ShellLink();
const uint STGM_READ = 0;
((IPersistFile)link).Load(path, STGM_READ);
var hwnd = new _RemotableHandle();
link.Resolve(ref hwnd, 0);
const int MAX_PATH = 260;
StringBuilder buffer = new StringBuilder(MAX_PATH);
var data = new _WIN32_FIND_DATAW();
const uint SLGP_SHORTPATH = 1;
link.GetPath(buffer, buffer.Capacity, ref data, SLGP_SHORTPATH);
var target = buffer.ToString();
if (!string.IsNullOrEmpty(target))
{
var extension = Extension(target);
if (extension == ExeExtension && File.Exists(target))
{
program.LnkResolvedPath = program.FullPath;
program.FullPath = Path.GetFullPath(target).ToLower();
program.ExecutableName = Path.GetFileName(target);
buffer = new StringBuilder(MAX_PATH);
link.GetDescription(buffer, MAX_PATH);
var description = buffer.ToString();
if (!string.IsNullOrEmpty(description))
{
program.Description = description;
}
else
{
var info = FileVersionInfo.GetVersionInfo(target);
if (!string.IsNullOrEmpty(info.FileDescription))
{
program.Description = info.FileDescription;
}
}
}
}
return program;
}
catch (COMException e)
{
// C:\\ProgramData\\Microsoft\\Windows\\Start Menu\\Programs\\MiracastView.lnk always cause exception
ProgramLogger.LogException($"|Win32|LnkProgram|{path}" +
"|Error caused likely due to trying to get the description of the program", e);
program.Valid = false;
return program;
}
#if !DEBUG //Only do a catch all in production. This is so make developer aware of any unhandled exception and add the exception handling in.
catch (Exception e)
{
ProgramLogger.LogException($"|Win32|LnkProgram|{path}" +
"|An unexpected error occurred in the calling method LnkProgram", e);
program.Valid = false;
return program;
}
#endif
}
private static Win32 ExeProgram(string path)
{
try
{
var program = Win32Program(path);
var info = FileVersionInfo.GetVersionInfo(path);
if (!string.IsNullOrEmpty(info.FileDescription))
{
program.Description = info.FileDescription;
}
return program;
}
catch (Exception e) when (e is SecurityException || e is UnauthorizedAccessException)
{
ProgramLogger.LogException($"|Win32|ExeProgram|{path}" +
$"|Permission denied when trying to load the program from {path}", e);
return new Win32() { Valid = false, Enabled = false };
}
}
private static IEnumerable<string> ProgramPaths(string directory, string[] suffixes)
{
if (!Directory.Exists(directory))
{
return new string[] { };
}
var files = new List<string>();
var folderQueue = new Queue<string>();
folderQueue.Enqueue(directory);
do
{
var currentDirectory = folderQueue.Dequeue();
try
{
foreach (var suffix in suffixes)
{
try
{
files.AddRange(Directory.EnumerateFiles(currentDirectory, $"*.{suffix}", SearchOption.TopDirectoryOnly));
}
catch (DirectoryNotFoundException e)
{
ProgramLogger.LogException($"|Win32|ProgramPaths|{currentDirectory}" +
"|The directory trying to load the program from does not exist", e);
}
}
}
catch (Exception e) when (e is SecurityException || e is UnauthorizedAccessException)
{
ProgramLogger.LogException($"|Win32|ProgramPaths|{currentDirectory}" +
$"|Permission denied when trying to load programs from {currentDirectory}", e);
}
try
{
foreach (var childDirectory in Directory.EnumerateDirectories(currentDirectory, "*", SearchOption.TopDirectoryOnly))
{
folderQueue.Enqueue(childDirectory);
}
}
catch (Exception e) when (e is SecurityException || e is UnauthorizedAccessException)
{
ProgramLogger.LogException($"|Win32|ProgramPaths|{currentDirectory}" +
$"|Permission denied when trying to load programs from {currentDirectory}", e);
}
} while (folderQueue.Any());
return files;
}
private static string Extension(string path)
{
var extension = Path.GetExtension(path)?.ToLower();
if (!string.IsNullOrEmpty(extension))
{
return extension.Substring(1);
}
else
{
return string.Empty;
}
}
private static ParallelQuery<Win32> UnregisteredPrograms(List<Settings.ProgramSource> sources, string[] suffixes)
{
var listToAdd = new List<string>();
sources.Where(s => Directory.Exists(s.Location) && s.Enabled)
.SelectMany(s => ProgramPaths(s.Location, suffixes))
.ToList()
.Where(t1 => !Main._settings.DisabledProgramSources.Any(x => t1 == x.UniqueIdentifier))
.ToList()
.ForEach(x => listToAdd.Add(x));
var paths = listToAdd.Distinct().ToArray();
var programs1 = paths.AsParallel().Where(p => Extension(p) == ExeExtension).Select(ExeProgram);
var programs2 = paths.AsParallel().Where(p => Extension(p) == ShortcutExtension).Select(ExeProgram);
var programs3 = from p in paths.AsParallel()
let e = Extension(p)
where e != ShortcutExtension && e != ExeExtension
select Win32Program(p);
return programs1.Concat(programs2).Concat(programs3);
}
private static ParallelQuery<Win32> StartMenuPrograms(string[] suffixes)
{
var disabledProgramsList = Main._settings.DisabledProgramSources;
var directory1 = Environment.GetFolderPath(Environment.SpecialFolder.Programs);
var directory2 = Environment.GetFolderPath(Environment.SpecialFolder.CommonPrograms);
var paths1 = ProgramPaths(directory1, suffixes);
var paths2 = ProgramPaths(directory2, suffixes);
var toFilter = paths1.Concat(paths2);
var paths = toFilter
.Where(t1 => !disabledProgramsList.Any(x => x.UniqueIdentifier == t1))
.Select(t1 => t1)
.Distinct()
.ToArray();
var programs1 = paths.AsParallel().Where(p => Extension(p) == ShortcutExtension).Select(LnkProgram);
var programs2 = paths.AsParallel().Where(p => Extension(p) == ApplicationReferenceExtension).Select(Win32Program);
return programs1.Concat(programs2).Where(p => p.Valid);
}
private static ParallelQuery<Win32> AppPathsPrograms(string[] suffixes)
{
// https://msdn.microsoft.com/en-us/library/windows/desktop/ee872121
const string appPaths = @"SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths";
var programs = new List<Win32>();
using (var root = Registry.LocalMachine.OpenSubKey(appPaths))
{
if (root != null)
{
programs.AddRange(GetProgramsFromRegistry(root));
}
}
using (var root = Registry.CurrentUser.OpenSubKey(appPaths))
{
if (root != null)
{
programs.AddRange(GetProgramsFromRegistry(root));
}
}
var disabledProgramsList = Main._settings.DisabledProgramSources;
var toFilter = programs.AsParallel().Where(p => suffixes.Contains(Extension(p.ExecutableName)));
var filtered = toFilter.Where(t1 => !disabledProgramsList.Any(x => x.UniqueIdentifier == t1.UniqueIdentifier)).Select(t1 => t1);
return filtered;
}
private static IEnumerable<Win32> GetProgramsFromRegistry(RegistryKey root)
{
return root
.GetSubKeyNames()
.Select(x => GetProgramPathFromRegistrySubKeys(root, x))
.Distinct()
.Select(x => GetProgramFromPath(x));
}
private static string GetProgramPathFromRegistrySubKeys(RegistryKey root, string subkey)
{
var path = string.Empty;
try
{
using (var key = root.OpenSubKey(subkey))
{
if (key == null)
return string.Empty;
var defaultValue = string.Empty;
path = key.GetValue(defaultValue) as string;
}
if (string.IsNullOrEmpty(path))
return string.Empty;
// fix path like this: ""\"C:\\folder\\executable.exe\""
return path = path.Trim('"', ' ');
}
catch (Exception e) when (e is SecurityException || e is UnauthorizedAccessException)
{
ProgramLogger.LogException($"|Win32|GetProgramPathFromRegistrySubKeys|{path}" +
$"|Permission denied when trying to load the program from {path}", e);
return string.Empty;
}
}
private static Win32 GetProgramFromPath(string path)
{
if (string.IsNullOrEmpty(path))
return new Win32();
path = Environment.ExpandEnvironmentVariables(path);
if (!File.Exists(path))
return new Win32();
var entry = Win32Program(path);
entry.ExecutableName = Path.GetFileName(path);
return entry;
}
public static Win32[] All(Settings settings)
{
try
{
var programs = new List<Win32>().AsParallel();
var unregistered = UnregisteredPrograms(settings.ProgramSources, settings.ProgramSuffixes);
programs = programs.Concat(unregistered);
if (settings.EnableRegistrySource)
{
var appPaths = AppPathsPrograms(settings.ProgramSuffixes);
programs = programs.Concat(appPaths);
}
if (settings.EnableStartMenuSource)
{
var startMenu = StartMenuPrograms(settings.ProgramSuffixes);
programs = programs.Concat(startMenu);
}
var programsWithoutLnk = programs.Where(x => string.IsNullOrEmpty(x.LnkResolvedPath));
var programsAsList = programs.ToList();
foreach(var app in programsWithoutLnk)
{
programsAsList.RemoveAll(x => (x.FullPath == app.FullPath) && string.IsNullOrEmpty(x.LnkResolvedPath));
}
return programsAsList.ToArray();
}
#if DEBUG //This is to make developer aware of any unhandled exception and add in handling.
catch (Exception e)
{
throw e;
}
#endif
#if !DEBUG //Only do a catch all in production.
catch (Exception e)
{
ProgramLogger.LogException("|Win32|All|Not available|An unexpected error occurred", e);
return new Win32[0];
}
#endif
}
}
}

View file

@ -0,0 +1,40 @@
using System;
using System.Collections.Generic;
using System.IO;
namespace Wox.Plugin.Program
{
public class Settings
{
public DateTime LastIndexTime { get; set; }
public List<ProgramSource> ProgramSources { get; set; } = new List<ProgramSource>();
public List<DisabledProgramSource> DisabledProgramSources { get; set; } = new List<DisabledProgramSource>();
public string[] ProgramSuffixes { get; set; } = {"bat", "appref-ms", "exe", "lnk"};
public bool EnableStartMenuSource { get; set; } = true;
public bool EnableRegistrySource { get; set; } = true;
internal const char SuffixSeperator = ';';
/// <summary>
/// Contains user added folder location contents as well as all user disabled applications
/// </summary>
/// <remarks>
/// <para>Win32 class applications set UniqueIdentifier using their full file path</para>
/// <para>UWP class applications set UniqueIdentifier using their Application User Model ID</para>
/// <para>Custom user added program sources set UniqueIdentifier using their location</para>
/// </remarks>
public class ProgramSource
{
private string name;
public string Location { get; set; }
public string Name { get => name ?? new DirectoryInfo(Location).Name; set => name = value; }
public bool Enabled { get; set; } = true;
public string UniqueIdentifier { get; set; }
}
public class DisabledProgramSource : ProgramSource { }
}
}

Some files were not shown because too many files have changed in this diff Show more