mirror of
https://github.com/microsoft/PowerToys.git
synced 2025-12-14 18:57:55 +01:00
[PTRun]New plugin: Value generator with hashing functions (#26097)
* Add hashing plugin for Run * Cleanup logic for hasher plugin - The IComputeRequest interface should make it easier to implement new generators in the future - The GUID generator can now generate all versions of GUID (a.k.a. UUID) - The input for the hash functions is not quite right. The Wox.Plugin.Query class doesn't actually have a way to ge the raw query as given by the user. The issue is with multiple spaces. An input like "a a a a a" would only be accessible as "a a a a a" using the Query class. So for now, hashing only works correctly if the input doesn't contain multiple consecutive spaces. - Need a way to make clear the usage for generating GUIDv3 and v5, since they take 2 parameters. There are defaults, but they aren't very clear. * Change plugin name to ValueGenerator * Clean up error handling for the input parser * Add result type and description to subtitle * Change the icons * Add Base64 encoding and unit tests This commit adds Base64 encoding as a utility of the value generator plugin. The command is `# base64 ***input***`. Also added unit tests for the UUID/GUID generator and for the input parser. I don't think tests are necessary for the hashing functions or for the base64 encoder, since those were part of the the system libraries. I'll open a PR for the documentation tomorrow and mark this draft for review. * Excluded UUIDv2 * Change icons * Add RawUserQuery to Wox.Plugin.Query Getting the RawUserQuery is necessary to be able to handle queries like `# md5 a a`, where the intent is to get the hash for `a a`. The existing `RawQuery` removes consecutive whitespaces and there was no other way of getting the request as entered by the user. * Add ValueGenerator plugin to installer Also add the unit tests for the plugin to the pipeline. * Small cleanup * Fix spelling * Fix spelling again * Spell check for guiddata * More fixes This commit adds the dev docs explaining the classes in the new plugin. It also fixes the following issues: 1. ValueGenerator was not a dependency for the PowerLauncher project 2. The error message for an invalid SHA variant now displays the supported SHA variants 3. Hash requests now wait for a string to hash (i.e. no longer hash an empty string) 4. GUID v3 and v5 namespace aliases allow lowercase notation 5. Unnecessary debug logs 6. An empty query will now just log "Empty request" 7. An invalid query will also log user query * Spell check fix again * Change error message for unsupported GUID versions * Remove Any CPU from the solution * Add to installer * Remove duplicated ValueGeneratorPluginFolder entry
This commit is contained in:
12
.github/actions/spell-check/expect.txt
vendored
12
.github/actions/spell-check/expect.txt
vendored
@@ -423,6 +423,7 @@ DARKPURPLE
|
||||
DARKTEAL
|
||||
DARKYELLOW
|
||||
datareader
|
||||
datatracker
|
||||
Datavalue
|
||||
dataversion
|
||||
DATAW
|
||||
@@ -519,7 +520,7 @@ dllexport
|
||||
dllhost
|
||||
dllmain
|
||||
DNLEN
|
||||
Dns
|
||||
dns
|
||||
DONOTROUND
|
||||
DONTVALIDATEPATH
|
||||
dotnet
|
||||
@@ -790,7 +791,10 @@ graphql
|
||||
GSM
|
||||
gtm
|
||||
gui
|
||||
guiddata
|
||||
guiddef
|
||||
guidgenerator
|
||||
GUIDv
|
||||
GUITHREADINFO
|
||||
GValue
|
||||
gwl
|
||||
@@ -862,6 +866,7 @@ HOLDESC
|
||||
HOMEPATH
|
||||
homljgmgpmcbpjbnjpfijnhipfkiclkd
|
||||
HOOKPROC
|
||||
Horvalds
|
||||
Hostbackdropbrush
|
||||
hotkeycontrol
|
||||
hotkeys
|
||||
@@ -916,6 +921,7 @@ IDR
|
||||
idx
|
||||
IDXGI
|
||||
IEnum
|
||||
ietf
|
||||
IExec
|
||||
IEXPLORE
|
||||
Iface
|
||||
@@ -956,6 +962,7 @@ INPUTHARDWARE
|
||||
INPUTKEYBOARD
|
||||
INPUTLANGCHANGED
|
||||
INPUTMOUSE
|
||||
inputparser
|
||||
INPUTSINK
|
||||
INPUTTYPE
|
||||
INSTALLDESKTOPSHORTCUT
|
||||
@@ -1428,6 +1435,7 @@ odbccp
|
||||
Oem
|
||||
officehubintl
|
||||
ofs
|
||||
oid
|
||||
oldcolor
|
||||
olditem
|
||||
oldnewthing
|
||||
@@ -1760,6 +1768,7 @@ roslyn
|
||||
roundf
|
||||
ROUNDSMALL
|
||||
Rpc
|
||||
rpcrt
|
||||
RRF
|
||||
rrr
|
||||
RSAT
|
||||
@@ -2172,6 +2181,7 @@ uxtheme
|
||||
UYVY
|
||||
vabdq
|
||||
validmodulename
|
||||
valuegenerator
|
||||
Vanara
|
||||
variantassignment
|
||||
vcamp
|
||||
|
||||
@@ -131,6 +131,7 @@
|
||||
"modules\\launcher\\Plugins\\TimeDate\\Microsoft.PowerToys.Run.Plugin.TimeDate.dll",
|
||||
"modules\\launcher\\Plugins\\WebSearch\\Community.PowerToys.Run.Plugin.WebSearch.dll",
|
||||
"modules\\launcher\\Plugins\\WindowsTerminal\\Microsoft.PowerToys.Run.Plugin.WindowsTerminal.dll",
|
||||
"modules\\launcher\\Plugins\\ValueGenerator\\Community.PowerToys.Run.Plugin.ValueGenerator.dll",
|
||||
|
||||
"modules\\MeasureTool\\PowerToys.MeasureToolModuleInterface.dll",
|
||||
"modules\\MeasureTool\\PowerToys.MeasureToolCore.dll",
|
||||
|
||||
@@ -231,6 +231,7 @@ steps:
|
||||
**\Microsoft.Interop.Tests.dll
|
||||
**\ImageResizer.Test.dll
|
||||
**\Community.PowerToys.Run.Plugin.UnitConverter.UnitTest.dll
|
||||
**\Community.PowerToys.Run.Plugin.ValueGenerator.UnitTests.dll
|
||||
**\Microsoft.Plugin.Folder.UnitTests.dll
|
||||
**\Microsoft.Plugin.Program.UnitTests.dll
|
||||
**\Microsoft.PowerToys.Run.Plugin.Calculator.UnitTest.dll
|
||||
|
||||
@@ -140,6 +140,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PowerLauncher", "src\module
|
||||
{A2D583F0-B70C-4462-B1F0-8E81AFB7BA85} = {A2D583F0-B70C-4462-B1F0-8E81AFB7BA85}
|
||||
{BB23A474-5058-4F75-8FA3-5FE3DE53CDF4} = {BB23A474-5058-4F75-8FA3-5FE3DE53CDF4}
|
||||
{C21BFF9C-2C99-4B5F-B7C9-A5E6DDDB37B0} = {C21BFF9C-2C99-4B5F-B7C9-A5E6DDDB37B0}
|
||||
{D095BE44-1F2E-463E-A494-121892A75EA2} = {D095BE44-1F2E-463E-A494-121892A75EA2}
|
||||
{F8B870EB-D5F5-45BA-9CF7-A5C459818820} = {F8B870EB-D5F5-45BA-9CF7-A5C459818820}
|
||||
{FD8EB419-FF9C-4D88-BB6F-BF6CED37747B} = {FD8EB419-FF9C-4D88-BB6F-BF6CED37747B}
|
||||
{FDB3555B-58EF-4AE6-B5F1-904719637AB4} = {FDB3555B-58EF-4AE6-B5F1-904719637AB4}
|
||||
@@ -525,6 +526,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FilePreviewCommon", "src\co
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.PowerToys.Run.Plugin.PowerToys", "src\modules\launcher\Plugins\Microsoft.PowerToys.Run.Plugin.PowerToys\Microsoft.PowerToys.Run.Plugin.PowerToys.csproj", "{500DED3E-CFB5-4ED5-ACC6-02B3D6DC336D}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Community.PowerToys.Run.Plugin.ValueGenerator", "src\modules\launcher\Plugins\Community.PowerToys.Run.Plugin.ValueGenerator\Community.PowerToys.Run.Plugin.ValueGenerator.csproj", "{D095BE44-1F2E-463E-A494-121892A75EA2}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Community.PowerToys.Run.Plugin.ValueGenerator.UnitTests", "src\modules\launcher\Plugins\Community.PowerToys.Run.Plugin.ValueGenerator.UnitTests\Community.PowerToys.Run.Plugin.ValueGenerator.UnitTests.csproj", "{90F9FA90-2C20-4004-96E6-F3B78151F5A5}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|ARM64 = Debug|ARM64
|
||||
@@ -2247,6 +2252,30 @@ Global
|
||||
{500DED3E-CFB5-4ED5-ACC6-02B3D6DC336D}.Release|x64.Build.0 = Release|x64
|
||||
{500DED3E-CFB5-4ED5-ACC6-02B3D6DC336D}.Release|x86.ActiveCfg = Release|x64
|
||||
{500DED3E-CFB5-4ED5-ACC6-02B3D6DC336D}.Release|x86.Build.0 = Release|x64
|
||||
{D095BE44-1F2E-463E-A494-121892A75EA2}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||
{D095BE44-1F2E-463E-A494-121892A75EA2}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||
{D095BE44-1F2E-463E-A494-121892A75EA2}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{D095BE44-1F2E-463E-A494-121892A75EA2}.Debug|x64.Build.0 = Debug|x64
|
||||
{D095BE44-1F2E-463E-A494-121892A75EA2}.Debug|x86.ActiveCfg = Debug|x64
|
||||
{D095BE44-1F2E-463E-A494-121892A75EA2}.Debug|x86.Build.0 = Debug|x64
|
||||
{D095BE44-1F2E-463E-A494-121892A75EA2}.Release|ARM64.ActiveCfg = Release|ARM64
|
||||
{D095BE44-1F2E-463E-A494-121892A75EA2}.Release|ARM64.Build.0 = Release|ARM64
|
||||
{D095BE44-1F2E-463E-A494-121892A75EA2}.Release|x64.ActiveCfg = Release|x64
|
||||
{D095BE44-1F2E-463E-A494-121892A75EA2}.Release|x64.Build.0 = Release|x64
|
||||
{D095BE44-1F2E-463E-A494-121892A75EA2}.Release|x86.ActiveCfg = Release|x64
|
||||
{D095BE44-1F2E-463E-A494-121892A75EA2}.Release|x86.Build.0 = Release|x64
|
||||
{90F9FA90-2C20-4004-96E6-F3B78151F5A5}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||
{90F9FA90-2C20-4004-96E6-F3B78151F5A5}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||
{90F9FA90-2C20-4004-96E6-F3B78151F5A5}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{90F9FA90-2C20-4004-96E6-F3B78151F5A5}.Debug|x64.Build.0 = Debug|x64
|
||||
{90F9FA90-2C20-4004-96E6-F3B78151F5A5}.Debug|x86.ActiveCfg = Debug|x64
|
||||
{90F9FA90-2C20-4004-96E6-F3B78151F5A5}.Debug|x86.Build.0 = Debug|x64
|
||||
{90F9FA90-2C20-4004-96E6-F3B78151F5A5}.Release|ARM64.ActiveCfg = Release|ARM64
|
||||
{90F9FA90-2C20-4004-96E6-F3B78151F5A5}.Release|ARM64.Build.0 = Release|ARM64
|
||||
{90F9FA90-2C20-4004-96E6-F3B78151F5A5}.Release|x64.ActiveCfg = Release|x64
|
||||
{90F9FA90-2C20-4004-96E6-F3B78151F5A5}.Release|x64.Build.0 = Release|x64
|
||||
{90F9FA90-2C20-4004-96E6-F3B78151F5A5}.Release|x86.ActiveCfg = Release|x64
|
||||
{90F9FA90-2C20-4004-96E6-F3B78151F5A5}.Release|x86.Build.0 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
@@ -2436,6 +2465,8 @@ Global
|
||||
{929C1324-22E8-4412-A9A8-80E85F3985A5} = {4574FDD0-F61D-4376-98BF-E5A1262C11EC}
|
||||
{9EBAA524-0EDA-470B-95D4-39383285CBB2} = {1AFB6476-670D-4E80-A464-657E01DFF482}
|
||||
{500DED3E-CFB5-4ED5-ACC6-02B3D6DC336D} = {4AFC9975-2456-4C70-94A4-84073C1CED93}
|
||||
{D095BE44-1F2E-463E-A494-121892A75EA2} = {4AFC9975-2456-4C70-94A4-84073C1CED93}
|
||||
{90F9FA90-2C20-4004-96E6-F3B78151F5A5} = {4AFC9975-2456-4C70-94A4-84073C1CED93}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {C3A2F9D1-7930-4EF4-A6FC-7EE0A99821D0}
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
# Value Generator Plugin
|
||||
|
||||
The Value Generator plugin is used to generate hashes for strings, to calculate base64 encodings and to generate GUIDs versions 1, 3, 4 and 5.
|
||||
|
||||

|
||||
|
||||
### [`IComputeRequest`](/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.ValueGenerator/IComputeRequest.cs)
|
||||
- Interface for a request for computation
|
||||
- the `bool Compute()` method must populate the `IsSuccessful` and one of the `Result` and `ErrorMessage` fields
|
||||
- The result of `string ResultToString()` will be used for the Result's title
|
||||
- The `Description` field will be used for the Result's subtitle
|
||||
|
||||
### [`HashRequest`](/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.ValueGenerator/Hashing/HashRequest.cs)
|
||||
- Implements IComputeRequest
|
||||
- Supports the hashing algorithms from System.Security.Cryptography:
|
||||
- MD5
|
||||
- SHA1
|
||||
- SHA256
|
||||
- SHA384
|
||||
- SHA512
|
||||
- If other algorithms are added to System.Security.Cryptography, they can be added to the `_algorithms` dictionary. [`InputParser.ParseInput()`](#inputparser) will need to return a `HashRequest` for the algorithm in the query
|
||||
|
||||
### [`Base64Request`](/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.ValueGenerator/Base64/Base64Request.cs)
|
||||
- Implements IComputeRequest
|
||||
- `Compute()` will populate `Result` with the base64 encoding of the byte array passed in the constructor
|
||||
|
||||
### [`GUIDRequest`](/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.ValueGenerator/GUID/GUIDRequest.cs)
|
||||
- Implements IComputeRequest
|
||||
- Uses the [`GUIDGenerator`](#guidgenerator) class to generate or compute the requested GUID
|
||||
|
||||
### [`GUIDGenerator`](/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.ValueGenerator/GUID/GUIDGenerator.cs)
|
||||
- Utility class for generating or calculating GUIDs
|
||||
- Generating GUID versions 1 and 4 is done using builtin APIs. [`UuidCreateSequential`](https://learn.microsoft.com/en-us/windows/win32/api/rpcdce/nf-rpcdce-uuidcreatesequential) for version 1 and `System.Guid.NewGuid()` for version 4
|
||||
- Versions 3 and 5 take two parameters, a namespace and a name
|
||||
- The namespace must be a valid GUID or one of the [predefined ones](https://datatracker.ietf.org/doc/html/rfc4122#appendix-C)
|
||||
- The `PredefinedNamespaces` dictionary contains aliases for the predefined namespaces
|
||||
- The name can be any string
|
||||
|
||||
### [`InputParser`](/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.ValueGenerator/InputParser.cs)
|
||||
- It is responsible only for parsing the query from the user
|
||||
- Based on the user query, the `ParseInput()` method must return an object that implements the `IComputeRequest` interface or it must throw one of `FormatException` or `ArgumentException`
|
||||
- Throwing an `ArgumentException` should signal the fact the query contains a mistake that the user can fix (eg. an unsupported hash function, an invalid GUID version, an invalid namespace, etc)
|
||||
> The error message will be shown to the user and no log message will be created
|
||||
- Throwing a `FormatException` should signal either:
|
||||
- that the query may become valid, and so it does not make sense to show an error just yet (eg. the query does not contain a request yet, a hash request without a string to hash)
|
||||
- that the query is completely invalid
|
||||
> The error message will not be shown to the user but a log message will be created
|
||||
|
||||
### Adding a new value generator
|
||||
1. To add a new value generator, create a folder under `/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.ValueGenerator/` and inside it add a class that implements `IComputeRequest`.
|
||||
2. Add any utility classes that are specific to the new generator inside the same folder to keep them separated from the other generators.
|
||||
3. Modify the `InputParser.ParseInput()` to handle a request for the new generator and return an instance of the class you created in step 1
|
||||
BIN
doc/images/launcher/plugins/community.valuegenerator.png
Normal file
BIN
doc/images/launcher/plugins/community.valuegenerator.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 18 KiB |
@@ -597,6 +597,9 @@
|
||||
<Directory Id="PowerToysPluginFolder" Name="PowerToys">
|
||||
<Directory Id="PowerToysImagesFolder" Name="Images" />
|
||||
</Directory>
|
||||
<Directory Id="ValueGeneratorPluginFolder" Name="ValueGenerator">
|
||||
<Directory Id="ValueGeneratorImagesFolder" Name="Images" />
|
||||
</Directory>
|
||||
<Directory Id="RegistryPluginFolder" Name="Registry">
|
||||
<Directory Id="RegistryImagesFolder" Name="Images" />
|
||||
</Directory>
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
<Fragment>
|
||||
<!-- Resource directories should be added only if the installer is built on the build farm -->
|
||||
<?ifdef env.IsPipeline?>
|
||||
<?foreach ParentDirectory in LauncherInstallFolder;FancyZonesInstallFolder;ImageResizerInstallFolder;ColorPickerInstallFolder;FileExplorerPreviewInstallFolder;HistoryPluginFolder;CalculatorPluginFolder;FolderPluginFolder;ProgramPluginFolder;ShellPluginFolder;IndexerPluginFolder;UnitConverterPluginFolder;UriPluginFolder;WindowWalkerPluginFolder;OneNotePluginFolder;RegistryPluginFolder;VSCodeWorkspacesPluginFolder;ServicePluginFolder;SystemPluginFolder;TimeDatePluginFolder;WindowsSettingsPluginFolder;WindowsTerminalPluginFolder;WebSearchPluginFolder;PowerToysPluginFolder?>
|
||||
<?foreach ParentDirectory in LauncherInstallFolder;FancyZonesInstallFolder;ImageResizerInstallFolder;ColorPickerInstallFolder;FileExplorerPreviewInstallFolder;HistoryPluginFolder;CalculatorPluginFolder;FolderPluginFolder;ProgramPluginFolder;ShellPluginFolder;IndexerPluginFolder;UnitConverterPluginFolder;ValueGeneratorPluginFolder;UriPluginFolder;WindowWalkerPluginFolder;OneNotePluginFolder;RegistryPluginFolder;VSCodeWorkspacesPluginFolder;ServicePluginFolder;SystemPluginFolder;TimeDatePluginFolder;WindowsSettingsPluginFolder;WindowsTerminalPluginFolder;WebSearchPluginFolder;PowerToysPluginFolder?>
|
||||
<DirectoryRef Id="$(var.ParentDirectory)">
|
||||
<!-- Resource file directories -->
|
||||
<?foreach Language in $(var.LocLanguageList)?>
|
||||
@@ -393,6 +393,15 @@
|
||||
</RegistryKey>
|
||||
<File Id="Launcher_PowerToys_$(var.IdSafeLanguage)_File" Source="$(var.BinDir)modules\launcher\Plugins\PowerToys\$(var.Language)\Microsoft.PowerToys.Run.Plugin.PowerToys.resources.dll" />
|
||||
</Component>
|
||||
<Component
|
||||
Id="Launcher_ValueGenerator_$(var.IdSafeLanguage)_Component"
|
||||
Guid="$(var.CompGUIDPrefix)1D"
|
||||
Directory="Resource$(var.IdSafeLanguage)ValueGeneratorPluginFolder">
|
||||
<RegistryKey Root="$(var.RegistryScope)" Key="Software\Classes\powertoys\components">
|
||||
<RegistryValue Type="string" Name="Launcher_ValueGenerator_$(var.IdSafeLanguage)_Component" Value="" KeyPath="yes"/>
|
||||
</RegistryKey>
|
||||
<File Id="Launcher_ValueGenerator_$(var.IdSafeLanguage)_File" Source="$(var.BinDir)modules\launcher\Plugins\ValueGenerator\$(var.Language)\Community.PowerToys.Run.Plugin.ValueGenerator.resources.dll" />
|
||||
</Component>
|
||||
<?undef IdSafeLanguage?>
|
||||
<?undef CompGUIDPrefix?>
|
||||
<?endforeach?>
|
||||
@@ -474,6 +483,7 @@
|
||||
<RemoveFolder Id="RemoveFolderResourcesResource$(var.IdSafeLanguage)OneNotePluginFolder" Directory="Resource$(var.IdSafeLanguage)OneNotePluginFolder" On="uninstall"/>
|
||||
<RemoveFolder Id="RemoveFolderResourcesResource$(var.IdSafeLanguage)HistoryPluginFolder" Directory="Resource$(var.IdSafeLanguage)HistoryPluginFolder" On="uninstall"/>
|
||||
<RemoveFolder Id="RemoveFolderResourcesResource$(var.IdSafeLanguage)PowerToysPluginFolder" Directory="Resource$(var.IdSafeLanguage)PowerToysPluginFolder" On="uninstall"/>
|
||||
<RemoveFolder Id="RemoveFolderResourcesResource$(var.IdSafeLanguage)ValueGeneratorPluginFolder" Directory="Resource$(var.IdSafeLanguage)ValueGeneratorPluginFolder" On="uninstall"/>
|
||||
<?undef IdSafeLanguage?>
|
||||
<?endforeach?>
|
||||
</Component>
|
||||
|
||||
@@ -105,6 +105,11 @@
|
||||
<?define PowerToysImagesCmpFiles=?>
|
||||
<?define PowerToysImagesCmpFilesPath=$(var.BinDir)modules\launcher\Plugins\PowerToys\Images\?>
|
||||
|
||||
<?define ValueGeneratorCmpFiles=?>
|
||||
<?define ValueGeneratorCmpFilesPath=$(var.BinDir)modules\launcher\Plugins\ValueGenerator\?>
|
||||
<?define ValueGeneratorImagesCmpFiles=?>
|
||||
<?define ValueGeneratorImagesCmpFilesPath=$(var.BinDir)modules\launcher\Plugins\ValueGenerator\Images\?>
|
||||
|
||||
<Fragment>
|
||||
<DirectoryRef Id="LauncherInstallFolder" FileSource="$(var.launcherFilesPath)">
|
||||
<!-- Generated by generateFileComponents.ps1 -->
|
||||
@@ -319,6 +324,16 @@
|
||||
<!--PowerToysImagesCmpFiles_Component_Def-->
|
||||
</DirectoryRef>
|
||||
|
||||
<DirectoryRef Id="ValueGeneratorPluginFolder" FileSource="$(var.ValueGeneratorCmpFilesPath)">
|
||||
<!-- Generated by generateFileComponents.ps1 -->
|
||||
<!--ValueGeneratorCmpFiles_Component_Def-->
|
||||
</DirectoryRef>
|
||||
|
||||
<DirectoryRef Id="ValueGeneratorImagesFolder" FileSource="$(var.ValueGeneratorImagesCmpFilesPath)">
|
||||
<!-- Generated by generateFileComponents.ps1 -->
|
||||
<!--ValueGeneratorImagesCmpFiles_Component_Def-->
|
||||
</DirectoryRef>
|
||||
|
||||
<ComponentGroup Id="RunComponentGroup">
|
||||
<Component Id="RemoveLauncherFolder" Guid="3FFDC0B6-82BC-4C57-AEB1-C710DB108C23" Directory="LauncherInstallFolder" >
|
||||
<RegistryKey Root="$(var.RegistryScope)" Key="Software\Classes\powertoys\components">
|
||||
@@ -365,6 +380,8 @@
|
||||
<RemoveFolder Id="RemoveFolderWindowsTerminalImagesFolder" Directory="WindowsTerminalImagesFolder" On="uninstall"/>
|
||||
<RemoveFolder Id="RemoveFolderPowerToysPluginFolder" Directory="PowerToysPluginFolder" On="uninstall"/>
|
||||
<RemoveFolder Id="RemoveFolderPowerToysImagesFolder" Directory="PowerToysImagesFolder" On="uninstall"/>
|
||||
<RemoveFolder Id="RemoveFolderValueGeneratorPluginFolder" Directory="ValueGeneratorPluginFolder" On="uninstall"/>
|
||||
<RemoveFolder Id="RemoveFolderValueGeneratorImagesFolder" Directory="ValueGeneratorImagesFolder" On="uninstall"/>
|
||||
</Component>
|
||||
</ComponentGroup>
|
||||
</Fragment>
|
||||
|
||||
@@ -203,6 +203,11 @@ Invoke-Expression -Command "$PSScriptRoot\generateFileList.ps1 -fileDepsJson ""$
|
||||
Invoke-Expression -Command "$PSScriptRoot\generateFileList.ps1 -fileDepsJson """" -fileListName PowerToysImagesCmpFiles -wxsFilePath $PSScriptRoot\Run.wxs -depsPath ""$PSScriptRoot..\..\..\$platform\Release\modules\launcher\Plugins\PowerToys\Images"""
|
||||
Invoke-Expression -Command "$PSScriptRoot\generateFileComponents.ps1 -fileListName ""PowerToysCmpFiles"" -wxsFilePath $PSScriptRoot\Run.wxs -regroot $registryroot"
|
||||
Invoke-Expression -Command "$PSScriptRoot\generateFileComponents.ps1 -fileListName ""PowerToysImagesCmpFiles"" -wxsFilePath $PSScriptRoot\Run.wxs -regroot $registryroot"
|
||||
###ValueGenerator
|
||||
Invoke-Expression -Command "$PSScriptRoot\generateFileList.ps1 -fileDepsJson ""$PSScriptRoot..\..\..\$platform\Release\modules\launcher\Plugins\ValueGenerator\Community.PowerToys.Run.Plugin.ValueGenerator.deps.json"" -fileListName ValueGeneratorCmpFiles -wxsFilePath $PSScriptRoot\Run.wxs -isLauncherPlugin 1"
|
||||
Invoke-Expression -Command "$PSScriptRoot\generateFileList.ps1 -fileDepsJson """" -fileListName ValueGeneratorImagesCmpFiles -wxsFilePath $PSScriptRoot\Run.wxs -depsPath ""$PSScriptRoot..\..\..\$platform\Release\modules\launcher\Plugins\ValueGenerator\Images"""
|
||||
Invoke-Expression -Command "$PSScriptRoot\generateFileComponents.ps1 -fileListName ""ValueGeneratorCmpFiles"" -wxsFilePath $PSScriptRoot\Run.wxs -regroot $registryroot"
|
||||
Invoke-Expression -Command "$PSScriptRoot\generateFileComponents.ps1 -fileListName ""ValueGeneratorImagesCmpFiles"" -wxsFilePath $PSScriptRoot\Run.wxs -regroot $registryroot"
|
||||
## Plugins
|
||||
|
||||
#ShortcutGuide
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net7.0-windows</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<IsPackable>false</IsPackable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="MSTest.TestAdapter" />
|
||||
<PackageReference Include="MSTest.TestFramework" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Community.PowerToys.Run.Plugin.ValueGenerator\Community.PowerToys.Run.Plugin.ValueGenerator.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,140 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
|
||||
namespace Community.PowerToys.Run.Plugin.ValueGenerator.UnitTests
|
||||
{
|
||||
[TestClass]
|
||||
public class GUIDGeneratorTests
|
||||
{
|
||||
[TestMethod]
|
||||
public void GUIDv1Generator()
|
||||
{
|
||||
var guidRequest = new GUID.GUIDRequest(1);
|
||||
guidRequest.Compute();
|
||||
var guid = guidRequest.Result;
|
||||
|
||||
Assert.IsNotNull(guid);
|
||||
Assert.AreEqual(0x1000, GetGUIDVersion(guid));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void GUIDv3Generator()
|
||||
{
|
||||
var guidRequest = new GUID.GUIDRequest(3, "ns:DNS", "abc");
|
||||
guidRequest.Compute();
|
||||
var guid = guidRequest.Result;
|
||||
|
||||
Assert.IsNotNull(guid);
|
||||
Assert.AreEqual(0x3000, GetGUIDVersion(guid));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void GUIDv4Generator()
|
||||
{
|
||||
var guidRequest = new GUID.GUIDRequest(4);
|
||||
guidRequest.Compute();
|
||||
var guid = guidRequest.Result;
|
||||
|
||||
Assert.IsNotNull(guid);
|
||||
Assert.AreEqual(0x4000, GetGUIDVersion(guid));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void GUIDv5Generator()
|
||||
{
|
||||
var guidRequest = new GUID.GUIDRequest(5, "ns:DNS", "abc");
|
||||
guidRequest.Compute();
|
||||
var guid = guidRequest.Result;
|
||||
|
||||
Assert.IsNotNull(guid);
|
||||
Assert.AreEqual(0x5000, GetGUIDVersion(guid));
|
||||
}
|
||||
|
||||
[DataTestMethod]
|
||||
[DataRow(3, "ns:DNS", "abc", "5bd670ce-29c8-3369-a8a1-10ce44c7259e")]
|
||||
[DataRow(3, "ns:URL", "abc", "874a8cb4-4e91-3055-a476-3d3e2ffe375f")]
|
||||
[DataRow(3, "ns:OID", "abc", "5557cd36-6b67-38ac-83fe-825f5905fc15")]
|
||||
[DataRow(3, "ns:X500", "abc", "589392cb-93e1-392c-a846-367c45ed1ecc")]
|
||||
[DataRow(3, "589392cb-93e1-392c-a846-367c45ed1ecc", "abc", "f55f77d2-feed-378e-aa47-2f716b07aaad")]
|
||||
[DataRow(3, "abc", "abc", null)]
|
||||
[DataRow(3, "", "abc", null)]
|
||||
[DataRow(3, null, "abc", null)]
|
||||
[DataRow(3, "abc", "", null)]
|
||||
[DataRow(3, "abc", null, null)]
|
||||
[DataRow(5, "ns:DNS", "abc", "6cb8e707-0fc5-5f55-88d4-d4fed43e64a8")]
|
||||
[DataRow(5, "ns:URL", "abc", "68661508-f3c4-55b4-945d-ae2b4dfe5db4")]
|
||||
[DataRow(5, "ns:OID", "abc", "7697a46f-b283-5da3-8e7c-62c11c03dd9e")]
|
||||
[DataRow(5, "ns:X500", "abc", "53e882a6-63b1-578b-8bf1-8f0878cfa6b7")]
|
||||
[DataRow(5, "589392cb-93e1-392c-a846-367c45ed1ecc", "abc", "396466f5-96f4-57e2-aea1-78e1bb1bacc6")]
|
||||
[DataRow(5, "abc", "abc", null)]
|
||||
[DataRow(5, "", "abc", null)]
|
||||
[DataRow(5, null, "abc", null)]
|
||||
[DataRow(5, "abc", "", null)]
|
||||
[DataRow(5, "abc", null, null)]
|
||||
public void GUIDv3Andv5(int version, string namespaceName, string name, string expectedResult)
|
||||
{
|
||||
var expectException = false;
|
||||
if (namespaceName == null)
|
||||
{
|
||||
expectException = true;
|
||||
}
|
||||
|
||||
string[] predefinedNamespaces = new string[] { "ns:DNS", "ns:URL", "ns:OID", "ns:X500" };
|
||||
if (namespaceName != null &&
|
||||
!Guid.TryParse(namespaceName, out _) &&
|
||||
!predefinedNamespaces.Contains(namespaceName))
|
||||
{
|
||||
expectException = true;
|
||||
}
|
||||
|
||||
if (name == null)
|
||||
{
|
||||
expectException = true;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var guidRequest = new GUID.GUIDRequest(version, namespaceName, name);
|
||||
|
||||
guidRequest.Compute();
|
||||
|
||||
if (expectException)
|
||||
{
|
||||
Assert.Fail("GUID generator should have thrown an exception");
|
||||
}
|
||||
|
||||
if (namespaceName != string.Empty)
|
||||
{
|
||||
Assert.IsTrue(guidRequest.IsSuccessful);
|
||||
Assert.AreEqual(expectedResult, guidRequest.ResultToString());
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.IsFalse(guidRequest.IsSuccessful);
|
||||
}
|
||||
}
|
||||
catch (AssertFailedException)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
catch
|
||||
{
|
||||
if (!expectException)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static short GetGUIDVersion(byte[] guid)
|
||||
{
|
||||
var time_hi_and_version = BitConverter.ToInt16(guid.AsSpan()[6..8]);
|
||||
return (short)(time_hi_and_version & 0xF000);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using Wox.Plugin;
|
||||
|
||||
namespace Community.PowerToys.Run.Plugin.ValueGenerator.UnitTests
|
||||
{
|
||||
[TestClass]
|
||||
public class InputParserTests
|
||||
{
|
||||
[DataTestMethod]
|
||||
[DataRow("md5 abc", typeof(Hashing.HashRequest))]
|
||||
[DataRow("sha1 abc", typeof(Hashing.HashRequest))]
|
||||
[DataRow("sha256 abc", typeof(Hashing.HashRequest))]
|
||||
[DataRow("sha384 abc", typeof(Hashing.HashRequest))]
|
||||
[DataRow("sha512 abc", typeof(Hashing.HashRequest))]
|
||||
[DataRow("sha1111 abc", null)]
|
||||
[DataRow("uuid", typeof(GUID.GUIDRequest))]
|
||||
[DataRow("guidv3 ns:DNS abc", typeof(GUID.GUIDRequest))]
|
||||
[DataRow("guidv2 ns:DNS abc", null)]
|
||||
[DataRow("uUiD5 ns:URL abc", typeof(GUID.GUIDRequest))]
|
||||
[DataRow("Guidvv ns:DNS abc", null)]
|
||||
[DataRow("guidv4", typeof(GUID.GUIDRequest))]
|
||||
[DataRow("base64 abc", typeof(Base64.Base64Request))]
|
||||
[DataRow("base99 abc", null)]
|
||||
[DataRow("base64s abc", null)]
|
||||
public void ParserTest(string input, Type? expectedRequestType)
|
||||
{
|
||||
var parser = new InputParser();
|
||||
var query = new Query(input);
|
||||
|
||||
var expectException = false;
|
||||
string? command = null;
|
||||
if (query.Terms.Count == 0)
|
||||
{
|
||||
expectException = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
command = query.Terms[0];
|
||||
}
|
||||
|
||||
if (command != null && !CommandIsKnown(command))
|
||||
{
|
||||
expectException = true;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
IComputeRequest request = parser.ParseInput(query);
|
||||
if (expectException)
|
||||
{
|
||||
Assert.Fail("Parser should have thrown an exception");
|
||||
}
|
||||
|
||||
Assert.IsNotNull(request);
|
||||
|
||||
Assert.AreEqual(expectedRequestType, request.GetType());
|
||||
}
|
||||
catch (AssertFailedException)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
catch
|
||||
{
|
||||
if (!expectException)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static bool CommandIsKnown(string command)
|
||||
{
|
||||
string[] hashes = new string[] { "md5", "sha1", "sha256", "sha384", "sha512", "base64" };
|
||||
|
||||
if (hashes.Contains(command.ToLowerInvariant()))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
Regex regex = new Regex("^(guid|uuid)([1345]{0,1}|v[1345]{1})$", RegexOptions.IgnoreCase | RegexOptions.Compiled);
|
||||
|
||||
return regex.IsMatch(command);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.Text;
|
||||
using Wox.Plugin.Logger;
|
||||
|
||||
namespace Community.PowerToys.Run.Plugin.ValueGenerator.Base64
|
||||
{
|
||||
public class Base64Request : IComputeRequest
|
||||
{
|
||||
public byte[] Result { get; set; }
|
||||
|
||||
public string Description => "Base64 Encoding";
|
||||
|
||||
public bool IsSuccessful { get; set; }
|
||||
|
||||
public string ErrorMessage { get; set; }
|
||||
|
||||
private byte[] DataToEncode { get; set; }
|
||||
|
||||
public Base64Request(byte[] dataToEncode)
|
||||
{
|
||||
DataToEncode = dataToEncode ?? throw new ArgumentNullException(nameof(dataToEncode));
|
||||
}
|
||||
|
||||
public bool Compute()
|
||||
{
|
||||
IsSuccessful = true;
|
||||
try
|
||||
{
|
||||
Result = Encoding.UTF8.GetBytes(System.Convert.ToBase64String(DataToEncode));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.Exception(e.Message, e, GetType());
|
||||
ErrorMessage = e.Message;
|
||||
IsSuccessful = false;
|
||||
}
|
||||
|
||||
return IsSuccessful;
|
||||
}
|
||||
|
||||
public string ResultToString()
|
||||
{
|
||||
return Encoding.UTF8.GetString(Result);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Import Project="..\..\..\..\Version.props" />
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net7.0-windows</TargetFramework>
|
||||
<ProjectGuid>{D095BE44-1F2E-463E-A494-121892A75EA2}</ProjectGuid>
|
||||
<UseWPF>true</UseWPF>
|
||||
<Version>$(Version).0</Version>
|
||||
<AssemblyName>Community.PowerToys.Run.Plugin.ValueGenerator</AssemblyName>
|
||||
<RootNamespace>Community.PowerToys.Run.Plugin.ValueGenerator</RootNamespace>
|
||||
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
||||
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
|
||||
<GenerateSatelliteAssembliesForCore>true</GenerateSatelliteAssembliesForCore>
|
||||
<OutputPath>..\..\..\..\..\$(Platform)\$(Configuration)\modules\launcher\Plugins\ValueGenerator\</OutputPath>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)'=='Debug'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)'=='Release'">
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\Wox.Infrastructure\Wox.Infrastructure.csproj">
|
||||
<Private>false</Private>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\Wox.Plugin\Wox.Plugin.csproj">
|
||||
<Private>false</Private>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="plugin.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Update="Properties\Resources.Designer.cs">
|
||||
<DesignTime>True</DesignTime>
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>Resources.resx</DependentUpon>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Update="Properties\Resources.resx">
|
||||
<Generator>PublicResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="Images\ValueGenerator.dark.png">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="Images\ValueGenerator.light.png">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="Images\Warning.dark.png">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="Images\Warning.light.png">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,119 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using Wox.Plugin.Common.Win32;
|
||||
|
||||
namespace Community.PowerToys.Run.Plugin.ValueGenerator.GUID
|
||||
{
|
||||
internal sealed class GUIDGenerator
|
||||
{
|
||||
// As defined in https://datatracker.ietf.org/doc/html/rfc4122#appendix-C
|
||||
public static readonly Dictionary<string, Guid> PredefinedNamespaces = new Dictionary<string, Guid>()
|
||||
{
|
||||
{ "ns:dns", new Guid(0x6ba7b810, 0x9dad, 0x11d1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8) },
|
||||
{ "ns:url", new Guid(0x6ba7b811, 0x9dad, 0x11d1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8) },
|
||||
{ "ns:oid", new Guid(0x6ba7b812, 0x9dad, 0x11d1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8) },
|
||||
{ "ns:x500", new Guid(0x6ba7b814, 0x9dad, 0x11d1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8) },
|
||||
};
|
||||
|
||||
public static Guid V1()
|
||||
{
|
||||
GUIDDATA guiddata;
|
||||
|
||||
int uuidCreateResult = NativeMethods.UuidCreateSequential(out guiddata);
|
||||
|
||||
if (uuidCreateResult != Win32Constants.RPC_S_OK && uuidCreateResult != Win32Constants.RPC_S_UUID_LOCAL_ONLY)
|
||||
{
|
||||
throw new InvalidOperationException("Failed to create GUID version 1");
|
||||
}
|
||||
|
||||
return new Guid(guiddata.Data1, guiddata.Data2, guiddata.Data3, guiddata.Data4);
|
||||
}
|
||||
|
||||
public static Guid V3(Guid uuidNamespace, string uuidName)
|
||||
{
|
||||
return V3AndV5(uuidNamespace, uuidName, 3);
|
||||
}
|
||||
|
||||
public static Guid V4()
|
||||
{
|
||||
return Guid.NewGuid();
|
||||
}
|
||||
|
||||
public static Guid V5(Guid uuidNamespace, string uuidName)
|
||||
{
|
||||
return V3AndV5(uuidNamespace, uuidName, 5);
|
||||
}
|
||||
|
||||
private static Guid V3AndV5(Guid uuidNamespace, string uuidName, short version)
|
||||
{
|
||||
byte[] namespaceBytes = uuidNamespace.ToByteArray();
|
||||
byte[] networkEndianNamespaceBytes = namespaceBytes;
|
||||
|
||||
// Convert time_low, time_mid and time_hi_and_version to network order
|
||||
int time_low = IPAddress.HostToNetworkOrder(BitConverter.ToInt32(networkEndianNamespaceBytes.AsSpan()[0..4]));
|
||||
short time_mid = IPAddress.HostToNetworkOrder(BitConverter.ToInt16(networkEndianNamespaceBytes.AsSpan()[4..6]));
|
||||
short time_hi_and_version = IPAddress.HostToNetworkOrder(BitConverter.ToInt16(networkEndianNamespaceBytes.AsSpan()[6..8]));
|
||||
|
||||
Buffer.BlockCopy(BitConverter.GetBytes(time_low), 0, networkEndianNamespaceBytes, 0, 4);
|
||||
Buffer.BlockCopy(BitConverter.GetBytes(time_mid), 0, networkEndianNamespaceBytes, 4, 2);
|
||||
Buffer.BlockCopy(BitConverter.GetBytes(time_hi_and_version), 0, networkEndianNamespaceBytes, 6, 2);
|
||||
|
||||
byte[] nameBytes = Encoding.ASCII.GetBytes(uuidName);
|
||||
|
||||
byte[] namespaceAndNameBytes = new byte[networkEndianNamespaceBytes.Length + nameBytes.Length];
|
||||
Buffer.BlockCopy(networkEndianNamespaceBytes, 0, namespaceAndNameBytes, 0, namespaceBytes.Length);
|
||||
Buffer.BlockCopy(nameBytes, 0, namespaceAndNameBytes, networkEndianNamespaceBytes.Length, nameBytes.Length);
|
||||
|
||||
byte[] hash;
|
||||
if (version == 3)
|
||||
{
|
||||
#pragma warning disable CA5351 // Do Not Use Broken Cryptographic Algorithms
|
||||
hash = MD5.HashData(namespaceAndNameBytes);
|
||||
#pragma warning restore CA5351 // Do Not Use Broken Cryptographic Algorithms
|
||||
}
|
||||
else if (version == 5)
|
||||
{
|
||||
#pragma warning disable CA5350 // Do Not Use Weak Cryptographic Algorithms
|
||||
hash = SHA1.HashData(namespaceAndNameBytes);
|
||||
#pragma warning restore CA5350 // Do Not Use Weak Cryptographic Algorithms
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new InvalidOperationException($"GUID version {version} does not exist");
|
||||
}
|
||||
|
||||
byte[] result = new byte[16];
|
||||
|
||||
// Copy first 16-bytes of the hash into our Uuid result
|
||||
Buffer.BlockCopy(hash, 0, result, 0, 16);
|
||||
|
||||
// Convert put time_low, time_mid and time_hi_and_version back to host order
|
||||
time_low = IPAddress.NetworkToHostOrder(BitConverter.ToInt32(result.AsSpan()[0..4]));
|
||||
time_mid = IPAddress.NetworkToHostOrder(BitConverter.ToInt16(result.AsSpan()[4..6]));
|
||||
time_hi_and_version = IPAddress.NetworkToHostOrder(BitConverter.ToInt16(result.AsSpan()[6..8]));
|
||||
|
||||
// Set version 'version' in time_hi_and_version field according to https://datatracker.ietf.org/doc/html/rfc4122#section-4.1.3
|
||||
time_hi_and_version &= 0x0FFF;
|
||||
#pragma warning disable CS0675 // Bitwise-or operator used on a sign-extended operand
|
||||
time_hi_and_version = (short)(time_hi_and_version | (version << 12));
|
||||
#pragma warning restore CS0675 // Bitwise-or operator used on a sign-extended operand
|
||||
|
||||
Buffer.BlockCopy(BitConverter.GetBytes(time_low), 0, result, 0, 4);
|
||||
Buffer.BlockCopy(BitConverter.GetBytes(time_mid), 0, result, 4, 2);
|
||||
Buffer.BlockCopy(BitConverter.GetBytes(time_hi_and_version), 0, result, 6, 2);
|
||||
|
||||
// Set upper two bits to "10"
|
||||
result[8] &= 0x3F;
|
||||
result[8] |= 0x80;
|
||||
|
||||
return new Guid(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,148 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.Security.Cryptography;
|
||||
using Wox.Plugin.Logger;
|
||||
|
||||
namespace Community.PowerToys.Run.Plugin.ValueGenerator.GUID
|
||||
{
|
||||
public class GUIDRequest : IComputeRequest
|
||||
{
|
||||
public byte[] Result { get; set; }
|
||||
|
||||
public bool IsSuccessful { get; set; }
|
||||
|
||||
public string ErrorMessage { get; set; }
|
||||
|
||||
private int Version { get; set; }
|
||||
|
||||
public string Description
|
||||
{
|
||||
get
|
||||
{
|
||||
switch (Version)
|
||||
{
|
||||
case 1:
|
||||
return "Version 1: Time base GUID";
|
||||
case 3:
|
||||
case 5:
|
||||
string hashAlgorithm;
|
||||
if (Version == 3)
|
||||
{
|
||||
hashAlgorithm = HashAlgorithmName.MD5.ToString();
|
||||
}
|
||||
else
|
||||
{
|
||||
hashAlgorithm = HashAlgorithmName.SHA1.ToString();
|
||||
}
|
||||
|
||||
return $"Version {Version} ({hashAlgorithm}): Namespace and name based GUID.";
|
||||
case 4:
|
||||
return "Version 4: Randomly generated GUID";
|
||||
default:
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Guid? GuidNamespace { get; set; }
|
||||
|
||||
private string GuidName { get; set; }
|
||||
|
||||
private Guid GuidResult { get; set; }
|
||||
|
||||
private static readonly string NullNamespaceError = $"The first parameter needs to be a valid GUID or one of: {string.Join(", ", GUIDGenerator.PredefinedNamespaces.Keys)}";
|
||||
|
||||
public GUIDRequest(int version, string guidNamespace = null, string name = null)
|
||||
{
|
||||
Version = version;
|
||||
|
||||
if (Version < 1 || Version > 5 || Version == 2)
|
||||
{
|
||||
throw new ArgumentException("Unsupported GUID version. Supported versions are 1, 3, 4 and 5");
|
||||
}
|
||||
|
||||
if (version == 3 || version == 5)
|
||||
{
|
||||
if (guidNamespace == null)
|
||||
{
|
||||
throw new ArgumentNullException(null, NullNamespaceError);
|
||||
}
|
||||
|
||||
Guid guid;
|
||||
if (GUIDGenerator.PredefinedNamespaces.TryGetValue(guidNamespace.ToLowerInvariant(), out guid))
|
||||
{
|
||||
GuidNamespace = guid;
|
||||
}
|
||||
else if (Guid.TryParse(guidNamespace, out guid))
|
||||
{
|
||||
GuidNamespace = guid;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new ArgumentNullException(null, NullNamespaceError);
|
||||
}
|
||||
|
||||
if (name == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(name));
|
||||
}
|
||||
else
|
||||
{
|
||||
GuidName = name;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
GuidNamespace = null;
|
||||
}
|
||||
|
||||
ErrorMessage = null;
|
||||
}
|
||||
|
||||
public bool Compute()
|
||||
{
|
||||
IsSuccessful = true;
|
||||
try
|
||||
{
|
||||
switch (Version)
|
||||
{
|
||||
case 1:
|
||||
GuidResult = GUIDGenerator.V1();
|
||||
break;
|
||||
case 3:
|
||||
GuidResult = GUIDGenerator.V3(GuidNamespace.Value, GuidName);
|
||||
break;
|
||||
case 4:
|
||||
GuidResult = GUIDGenerator.V4();
|
||||
break;
|
||||
case 5:
|
||||
GuidResult = GUIDGenerator.V5(GuidNamespace.Value, GuidName);
|
||||
break;
|
||||
}
|
||||
|
||||
Result = GuidResult.ToByteArray();
|
||||
}
|
||||
catch (InvalidOperationException e)
|
||||
{
|
||||
Log.Exception(e.Message, e, GetType());
|
||||
ErrorMessage = e.Message;
|
||||
IsSuccessful = false;
|
||||
}
|
||||
|
||||
return IsSuccessful;
|
||||
}
|
||||
|
||||
public string ResultToString()
|
||||
{
|
||||
if (!IsSuccessful)
|
||||
{
|
||||
return ErrorMessage;
|
||||
}
|
||||
|
||||
return GuidResult.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using Wox.Plugin.Logger;
|
||||
|
||||
namespace Community.PowerToys.Run.Plugin.ValueGenerator.Hashing
|
||||
{
|
||||
public class HashRequest : IComputeRequest
|
||||
{
|
||||
public byte[] Result { get; set; }
|
||||
|
||||
public bool IsSuccessful { get; set; }
|
||||
|
||||
public string ErrorMessage { get; set; }
|
||||
|
||||
public string Description
|
||||
{
|
||||
get
|
||||
{
|
||||
return $"{AlgorithmName}({Encoding.UTF8.GetString(DataToHash)})";
|
||||
}
|
||||
}
|
||||
|
||||
public HashAlgorithmName AlgorithmName { get; set; }
|
||||
|
||||
private byte[] DataToHash { get; set; }
|
||||
|
||||
private static Dictionary<HashAlgorithmName, HashAlgorithm> _algorithms = new Dictionary<HashAlgorithmName, HashAlgorithm>()
|
||||
{
|
||||
#pragma warning disable CA5351 // Do Not Use Broken Cryptographic Algorithms
|
||||
{ HashAlgorithmName.MD5, MD5.Create() },
|
||||
#pragma warning restore CA5351 // Do Not Use Broken Cryptographic Algorithms
|
||||
|
||||
#pragma warning disable CA5350 // Do Not Use Weak Cryptographic Algorithms
|
||||
{ HashAlgorithmName.SHA1, SHA1.Create() },
|
||||
#pragma warning restore CA5350 // Do Not Use Weak Cryptographic Algorithms
|
||||
{ HashAlgorithmName.SHA256, SHA256.Create() },
|
||||
{ HashAlgorithmName.SHA384, SHA384.Create() },
|
||||
{ HashAlgorithmName.SHA512, SHA512.Create() },
|
||||
};
|
||||
|
||||
public HashRequest(HashAlgorithmName algorithmName, byte[] dataToHash)
|
||||
{
|
||||
AlgorithmName = algorithmName;
|
||||
DataToHash = dataToHash ?? throw new ArgumentNullException(nameof(dataToHash));
|
||||
}
|
||||
|
||||
public bool Compute()
|
||||
{
|
||||
if (DataToHash == null)
|
||||
{
|
||||
ErrorMessage = "Null data passed to hash request";
|
||||
Log.Exception(ErrorMessage, new InvalidOperationException(ErrorMessage), GetType());
|
||||
IsSuccessful = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
Result = _algorithms[AlgorithmName].ComputeHash(DataToHash);
|
||||
IsSuccessful = true;
|
||||
}
|
||||
|
||||
return IsSuccessful;
|
||||
}
|
||||
|
||||
public string ResultToString()
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
foreach (var b in Result)
|
||||
{
|
||||
sb.Append(b.ToString("X2", null));
|
||||
}
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
|
||||
namespace Community.PowerToys.Run.Plugin.ValueGenerator
|
||||
{
|
||||
public interface IComputeRequest
|
||||
{
|
||||
public byte[] Result { get; set; }
|
||||
|
||||
public string Description { get; }
|
||||
|
||||
public bool IsSuccessful { get; set; }
|
||||
|
||||
public string ErrorMessage { get; set; }
|
||||
|
||||
bool Compute();
|
||||
|
||||
public string ResultToString();
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 882 B |
Binary file not shown.
|
After Width: | Height: | Size: 1.3 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 300 B |
Binary file not shown.
|
After Width: | Height: | Size: 300 B |
@@ -0,0 +1,132 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using Community.PowerToys.Run.Plugin.ValueGenerator.Base64;
|
||||
using Community.PowerToys.Run.Plugin.ValueGenerator.GUID;
|
||||
using Community.PowerToys.Run.Plugin.ValueGenerator.Hashing;
|
||||
using Wox.Plugin;
|
||||
using Wox.Plugin.Logger;
|
||||
|
||||
namespace Community.PowerToys.Run.Plugin.ValueGenerator
|
||||
{
|
||||
public class InputParser
|
||||
{
|
||||
public IComputeRequest ParseInput(Query query)
|
||||
{
|
||||
IComputeRequest request;
|
||||
|
||||
if (query.Terms.Count == 0)
|
||||
{
|
||||
throw new FormatException("Empty request");
|
||||
}
|
||||
|
||||
string command = query.Terms[0];
|
||||
|
||||
if (command.ToLower(null) == "md5")
|
||||
{
|
||||
int commandIndex = query.RawUserQuery.IndexOf(command, StringComparison.InvariantCultureIgnoreCase);
|
||||
string content = query.RawUserQuery.Substring(commandIndex + command.Length).Trim();
|
||||
|
||||
if (content == string.Empty)
|
||||
{
|
||||
throw new FormatException("Empty hash request");
|
||||
}
|
||||
|
||||
Log.Debug($"Will calculate MD5 hash for: {content}", GetType());
|
||||
request = new HashRequest(HashAlgorithmName.MD5, Encoding.UTF8.GetBytes(content));
|
||||
}
|
||||
else if (command.StartsWith("sha", StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
int commandIndex = query.RawUserQuery.IndexOf(command, StringComparison.InvariantCultureIgnoreCase);
|
||||
string content = query.RawUserQuery.Substring(commandIndex + command.Length).Trim();
|
||||
HashAlgorithmName algorithmName;
|
||||
|
||||
switch (command.Substring(3))
|
||||
{
|
||||
case "1":
|
||||
algorithmName = HashAlgorithmName.SHA1;
|
||||
break;
|
||||
|
||||
case "256":
|
||||
algorithmName = HashAlgorithmName.SHA256;
|
||||
break;
|
||||
|
||||
case "384":
|
||||
algorithmName = HashAlgorithmName.SHA384;
|
||||
break;
|
||||
|
||||
case "512":
|
||||
algorithmName = HashAlgorithmName.SHA512;
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentException("Unknown SHA variant. Supported variants: SHA1, SHA256, SHA384, SHA512");
|
||||
}
|
||||
|
||||
if (content == string.Empty)
|
||||
{
|
||||
throw new FormatException("Empty hash request");
|
||||
}
|
||||
|
||||
Log.Debug($"Will calculate {algorithmName} hash for: {content}", GetType());
|
||||
request = new HashRequest(algorithmName, Encoding.UTF8.GetBytes(content));
|
||||
}
|
||||
else if (command.StartsWith("guid", StringComparison.InvariantCultureIgnoreCase) ||
|
||||
command.StartsWith("uuid", StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
string content = query.Search.Substring(command.Length).Trim();
|
||||
|
||||
// Default to version 4
|
||||
int version = 4;
|
||||
string versionQuery = command.Substring(4);
|
||||
|
||||
if (versionQuery.Length > 0)
|
||||
{
|
||||
if (versionQuery.StartsWith("v", StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
versionQuery = versionQuery.Substring(1);
|
||||
}
|
||||
|
||||
if (!int.TryParse(versionQuery, null, out version))
|
||||
{
|
||||
throw new ArgumentException("Could not determine requested GUID version");
|
||||
}
|
||||
}
|
||||
|
||||
if (version == 3 || version == 5)
|
||||
{
|
||||
string[] sParameters = content.Split(" ");
|
||||
|
||||
if (sParameters.Length != 2)
|
||||
{
|
||||
throw new ArgumentException("GUID versions 3 and 5 require 2 parameters - a namespace GUID and a name");
|
||||
}
|
||||
|
||||
string namespaceParameter = sParameters[0];
|
||||
string nameParameter = sParameters[1];
|
||||
|
||||
request = new GUIDRequest(version, namespaceParameter, nameParameter);
|
||||
}
|
||||
else
|
||||
{
|
||||
request = new GUIDRequest(version);
|
||||
}
|
||||
}
|
||||
else if (command.ToLower(null) == "base64")
|
||||
{
|
||||
int commandIndex = query.RawUserQuery.IndexOf(command, StringComparison.InvariantCultureIgnoreCase);
|
||||
string content = query.RawUserQuery.Substring(commandIndex + command.Length).Trim();
|
||||
request = new Base64Request(Encoding.UTF8.GetBytes(content));
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new FormatException($"Invalid Query: {query.RawUserQuery}");
|
||||
}
|
||||
|
||||
return request;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,156 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading;
|
||||
using System.Windows;
|
||||
using Community.PowerToys.Run.Plugin.ValueGenerator.Properties;
|
||||
using ManagedCommon;
|
||||
using Wox.Plugin;
|
||||
using Wox.Plugin.Logger;
|
||||
|
||||
namespace Community.PowerToys.Run.Plugin.ValueGenerator
|
||||
{
|
||||
public class Main : IPlugin, IPluginI18n, IDisposable
|
||||
{
|
||||
public string Name => Resources.plugin_name;
|
||||
|
||||
public string Description => Resources.plugin_description;
|
||||
|
||||
private PluginInitContext _context;
|
||||
private static bool _isLightTheme = true;
|
||||
private bool _disposed;
|
||||
private static InputParser _inputParser = new InputParser();
|
||||
|
||||
public void Init(PluginInitContext context)
|
||||
{
|
||||
context = context ?? throw new ArgumentNullException(paramName: nameof(context));
|
||||
|
||||
_context = context;
|
||||
_context.API.ThemeChanged += OnThemeChanged;
|
||||
UpdateIconPath(_context.API.GetCurrentTheme());
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(disposing: true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
private void OnThemeChanged(Theme currentTheme, Theme newTheme)
|
||||
{
|
||||
UpdateIconPath(newTheme);
|
||||
}
|
||||
|
||||
private static void UpdateIconPath(Theme theme)
|
||||
{
|
||||
if (theme == Theme.Light || theme == Theme.HighContrastWhite)
|
||||
{
|
||||
_isLightTheme = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
_isLightTheme = false;
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (!_disposed)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
if (_context != null && _context.API != null)
|
||||
{
|
||||
_context.API.ThemeChanged -= OnThemeChanged;
|
||||
}
|
||||
|
||||
_disposed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public string GetTranslatedPluginDescription()
|
||||
{
|
||||
return Resources.plugin_description;
|
||||
}
|
||||
|
||||
public string GetTranslatedPluginTitle()
|
||||
{
|
||||
return Resources.plugin_name;
|
||||
}
|
||||
|
||||
public List<Result> Query(Query query)
|
||||
{
|
||||
if (query == null)
|
||||
{
|
||||
throw new ArgumentNullException(paramName: nameof(query));
|
||||
}
|
||||
|
||||
var results = new List<Result>();
|
||||
try
|
||||
{
|
||||
IComputeRequest computeRequest = _inputParser.ParseInput(query);
|
||||
results.Add(GetResult(computeRequest));
|
||||
}
|
||||
catch (ArgumentException e)
|
||||
{
|
||||
results.Add(GetErrorResult(e.Message));
|
||||
}
|
||||
catch (FormatException e)
|
||||
{
|
||||
Log.Debug(GetTranslatedPluginTitle() + ": " + e.Message, GetType());
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
private Result GetResult(IComputeRequest request)
|
||||
{
|
||||
request.Compute();
|
||||
|
||||
return new Result
|
||||
{
|
||||
ContextData = request.Result,
|
||||
Title = request.ResultToString(),
|
||||
IcoPath = _isLightTheme ? "Images/ValueGenerator.dark.png" : "Images/ValueGenerator.light.png",
|
||||
Score = 300,
|
||||
SubTitle = request.Description,
|
||||
Action = c =>
|
||||
{
|
||||
var ret = false;
|
||||
var thread = new Thread(() =>
|
||||
{
|
||||
try
|
||||
{
|
||||
Clipboard.SetText(request.ResultToString());
|
||||
ret = true;
|
||||
}
|
||||
catch (ExternalException)
|
||||
{
|
||||
MessageBox.Show(Properties.Resources.copy_failed);
|
||||
}
|
||||
});
|
||||
thread.SetApartmentState(ApartmentState.STA);
|
||||
thread.Start();
|
||||
thread.Join();
|
||||
return ret;
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
private Result GetErrorResult(string errorMessage)
|
||||
{
|
||||
return new Result
|
||||
{
|
||||
Title = Resources.error_title,
|
||||
SubTitle = errorMessage,
|
||||
IcoPath = _isLightTheme ? "Images/Warning.light.png" : "Images/Warning.dark.png",
|
||||
Action = _ => { return true; },
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.42000
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace Community.PowerToys.Run.Plugin.ValueGenerator.Properties {
|
||||
using System;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// A strongly-typed resource class, for looking up localized strings, etc.
|
||||
/// </summary>
|
||||
// This class was auto-generated by the StronglyTypedResourceBuilder
|
||||
// class via a tool like ResGen or Visual Studio.
|
||||
// To add or remove a member, edit your .ResX file then rerun ResGen
|
||||
// with the /str option, or rebuild your VS project.
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
public class Resources {
|
||||
|
||||
private static global::System.Resources.ResourceManager resourceMan;
|
||||
|
||||
private static global::System.Globalization.CultureInfo resourceCulture;
|
||||
|
||||
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||
internal Resources() {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the cached ResourceManager instance used by this class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
public static global::System.Resources.ResourceManager ResourceManager {
|
||||
get {
|
||||
if (object.ReferenceEquals(resourceMan, null)) {
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Community.PowerToys.Run.Plugin.ValueGenerator.Properties.Resources", typeof(Resources).Assembly);
|
||||
resourceMan = temp;
|
||||
}
|
||||
return resourceMan;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Overrides the current thread's CurrentUICulture property for all
|
||||
/// resource lookups using this strongly typed resource class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
public static global::System.Globalization.CultureInfo Culture {
|
||||
get {
|
||||
return resourceCulture;
|
||||
}
|
||||
set {
|
||||
resourceCulture = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Copy failed.
|
||||
/// </summary>
|
||||
public static string copy_failed {
|
||||
get {
|
||||
return ResourceManager.GetString("copy_failed", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Copy {0} to clipboard.
|
||||
/// </summary>
|
||||
public static string copy_to_clipboard {
|
||||
get {
|
||||
return ResourceManager.GetString("copy_to_clipboard", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Value Generator Error.
|
||||
/// </summary>
|
||||
public static string error_title {
|
||||
get {
|
||||
return ResourceManager.GetString("error_title", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to A plugin to calculate hashes and generate values..
|
||||
/// </summary>
|
||||
public static string plugin_description {
|
||||
get {
|
||||
return ResourceManager.GetString("plugin_description", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Value Generator.
|
||||
/// </summary>
|
||||
public static string plugin_name {
|
||||
get {
|
||||
return ResourceManager.GetString("plugin_name", resourceCulture);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="copy_failed" xml:space="preserve">
|
||||
<value>Copy failed</value>
|
||||
</data>
|
||||
<data name="copy_to_clipboard" xml:space="preserve">
|
||||
<value>Copy {0} to clipboard</value>
|
||||
</data>
|
||||
<data name="error_title" xml:space="preserve">
|
||||
<value>Value Generator Error</value>
|
||||
</data>
|
||||
<data name="plugin_description" xml:space="preserve">
|
||||
<value>A plugin to calculate hashes and generate values.</value>
|
||||
</data>
|
||||
<data name="plugin_name" xml:space="preserve">
|
||||
<value>Value Generator</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"ID": "a26b1bb4dbd911edafa10242ac120002",
|
||||
"ActionKeyword": "#",
|
||||
"isGlobal": false,
|
||||
"Name": "ValueGenerator",
|
||||
"Description": "A plugin to calculate hashes and generate values",
|
||||
"Author": "IHorvalds",
|
||||
"Version": "1.0.0",
|
||||
"Language": "csharp",
|
||||
"Website": "https://github/com/IHorvalds",
|
||||
"IcoPathDark": "Images\\ValueGenerator.dark.png",
|
||||
"IcoPathLight": "Images\\ValueGenerator.light.png",
|
||||
"ExecuteFileName": "Community.PowerToys.Run.Plugin.ValueGenerator.dll"
|
||||
}
|
||||
@@ -118,6 +118,9 @@ namespace Wox.Plugin.Common.Win32
|
||||
|
||||
[DllImport("shell32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
|
||||
public static extern int SHCreateItemFromParsingName([MarshalAs(UnmanagedType.LPWStr)] string path, IntPtr pbc, ref Guid riid, [MarshalAs(UnmanagedType.Interface)] out IShellItem shellItem);
|
||||
|
||||
[DllImport("rpcrt4.dll")]
|
||||
public static extern int UuidCreateSequential(out GUIDDATA Uuid);
|
||||
}
|
||||
|
||||
[SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "These are the names used by win32.")]
|
||||
@@ -143,6 +146,16 @@ namespace Wox.Plugin.Common.Win32
|
||||
/// Closes the window
|
||||
/// </summary>
|
||||
public const int SC_CLOSE = 0xF060;
|
||||
|
||||
/// <summary>
|
||||
/// RPC call succeeded
|
||||
/// </summary>
|
||||
public const int RPC_S_OK = 0;
|
||||
|
||||
/// <summary>
|
||||
/// The UUID is guaranteed to be unique to this computer only.
|
||||
/// </summary>
|
||||
public const int RPC_S_UUID_LOCAL_ONLY = 0x720;
|
||||
}
|
||||
|
||||
public static class ShellItemTypeConstants
|
||||
@@ -618,6 +631,16 @@ namespace Wox.Plugin.Common.Win32
|
||||
AllAccess = StandardRightsRequired | Synchronize | 0xFFFF,
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct GUIDDATA
|
||||
{
|
||||
public int Data1;
|
||||
public short Data2;
|
||||
public short Data3;
|
||||
[System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst = 8)]
|
||||
public byte[] Data4;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Contains information about the placement of a window on the screen.
|
||||
/// </summary>
|
||||
|
||||
@@ -44,6 +44,18 @@ namespace Wox.Plugin
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the query as entered by the user.
|
||||
/// You should only use this property if you need to process the raw text directly.
|
||||
/// </summary>
|
||||
public string RawUserQuery
|
||||
{
|
||||
get
|
||||
{
|
||||
return _query;
|
||||
}
|
||||
}
|
||||
|
||||
private string _search;
|
||||
|
||||
/// <summary>
|
||||
|
||||
Reference in New Issue
Block a user