[Run][New Plugin] VSCode Workspaces/Remote machines (#9050)

* vscode workspaces plugin for Powertoys Run

* reduce score

* make vscode workspaces dynamic instead of string to prevent exceptions

* change icons again

* remove unused images and PreserveNewest during build

* code refactoring

* show vscode ssh remote machines

* update score workspaces

* vscode workspaces plugin for Powertoys Run

* remove unused images and PreserveNewest during build

* code refactoring

* remove unused packages

* get ExecutablePath from AppData and use shell to vscode process

* ' instead of \"

* try using ((char)34) instead of '

* add comments

* translate windows paths

* remove unused code

* add vscodeworkspace to installer

* use the new naming convention for plugins

* sign VSCodeWorkspaces.dll

* reimplement ssh-config parser

* update spell-check

* use the new naming convention for community plugins

* minor adjustments

* add actionKeyword {

* prevent copyright

* add localization

* add github link

* bug fix after localization

* --new-window --enable-proposed-api ms-vscode-remote.remote-ssh

* change order by

* Update src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Calculator/Properties/Resources.Designer.cs

* Update src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Calculator/Properties/Resources.Designer.cs

* Update src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Calculator/Properties/Resources.Designer.cs

* Update src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Calculator/Properties/Resources.Designer.cs

* Update src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Calculator/Properties/Resources.Designer.cs

* Update src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Calculator/Properties/Resources.Designer.cs

* Update src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Calculator/Properties/Resources.Designer.cs

* Update src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Calculator/Properties/Resources.Designer.cs

* Update src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Calculator/Properties/Resources.Designer.cs

* Update src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Calculator/Properties/Resources.Designer.cs

* Update src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Calculator/Properties/Resources.Designer.cs

* Update src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.VSCodeWorkspaces/Properties/Resources.resx

* Update src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.VSCodeWorkspaces/Properties/Resources.resx

* Update src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.VSCodeWorkspaces/Properties/Resources.resx

* Update src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.VSCodeWorkspaces/Properties/Resources.resx

* Update src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.VSCodeWorkspaces/Properties/Resources.resx

* fix powertoys run settings not working

* update plugin description

Co-authored-by: ricar <ricar@ASUS>
Co-authored-by: Enrico Giordani <enricogior@users.noreply.github.com>
This commit is contained in:
ricardosantos9521 2021-03-04 17:15:49 +00:00 committed by GitHub
parent f648ac44b2
commit 7e5fb876bb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 1153 additions and 5 deletions

View File

@ -276,6 +276,7 @@ codecvt
codeofconduct
codeql
codereview
Codespaces
COINIT
colorconv
colorhistory
@ -1808,6 +1809,7 @@ rgelt
Rgn
rgs
rhs
ricardosantos
Riched
Richtext
RIGHTSCROLLBAR
@ -2005,6 +2007,7 @@ srre
srw
srwlock
ssf
ssh
sstream
STACKFRAME
stackoverflow
@ -2224,6 +2227,7 @@ uncompilable
UNCPRIORITY
undef
UNDNAME
unescape
Ungroup
unicode
Unindent
@ -2320,8 +2324,10 @@ VOS
VREDRAW
VSC
VSCBD
vscode
VSCROLL
vse
vsonline
vstemplate
VSTHRD
VSTS
@ -2432,6 +2438,7 @@ wofstream
wordpad
workaround
workflow
workspaces
wostream
wox
wparam
@ -2444,6 +2451,7 @@ WResize
wrl
wsf
wsh
wsl
wss
wstr
wstring

View File

@ -131,6 +131,7 @@ build:
- 'modules\launcher\Plugins\Microsoft.Plugin.WindowWalker\Wox.Infrastructure.dll'
- 'modules\launcher\Plugins\Microsoft.Plugin.WindowWalker\Wox.Plugin.dll'
- 'modules\launcher\Plugins\Microsoft.Plugin.WindowWalker\Telemetry.dll'
- 'modules\launcher\Plugins\VSCodeWorkspaces\Community.PowerToys.Run.Plugin.VSCodeWorkspaces.dll'
- 'modules\launcher\Plugins\Service\Microsoft.PowerToys.Run.Plugin.Service.dll'
- 'modules\launcher\Plugins\System\Microsoft.PowerToys.Run.Plugin.System.dll'
- 'modules\launcher\PowerLauncher.dll'

View File

@ -128,6 +128,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Plugins", "Plugins", "{4AFC
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.PowerToys.Run.Plugin.Calculator", "src\modules\launcher\Plugins\Microsoft.PowerToys.Run.Plugin.Calculator\Microsoft.PowerToys.Run.Plugin.Calculator.csproj", "{59BD9891-3837-438A-958D-ADC7F91F6F7E}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Community.PowerToys.Run.Plugin.VSCodeWorkspaces", "src\modules\launcher\Plugins\Community.PowerToys.Run.Plugin.VSCodeWorkspaces\Community.PowerToys.Run.Plugin.VSCodeWorkspaces.csproj", "{4D971245-7A70-41D5-BAA0-DDB5684CAF51}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Plugin.WindowWalker", "src\modules\launcher\Plugins\Microsoft.Plugin.WindowWalker\Microsoft.Plugin.WindowWalker.csproj", "{74F1B9ED-F59C-4FE7-B473-7B453E30837E}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Plugin.Program", "src\modules\launcher\Plugins\Microsoft.Plugin.Program\Microsoft.Plugin.Program.csproj", "{FDB3555B-58EF-4AE6-B5F1-904719637AB4}"
@ -418,6 +420,10 @@ Global
{59BD9891-3837-438A-958D-ADC7F91F6F7E}.Debug|x64.Build.0 = Debug|x64
{59BD9891-3837-438A-958D-ADC7F91F6F7E}.Release|x64.ActiveCfg = Release|x64
{59BD9891-3837-438A-958D-ADC7F91F6F7E}.Release|x64.Build.0 = Release|x64
{4D971245-7A70-41D5-BAA0-DDB5684CAF51}.Debug|x64.ActiveCfg = Debug|x64
{4D971245-7A70-41D5-BAA0-DDB5684CAF51}.Debug|x64.Build.0 = Debug|x64
{4D971245-7A70-41D5-BAA0-DDB5684CAF51}.Release|x64.ActiveCfg = Release|x64
{4D971245-7A70-41D5-BAA0-DDB5684CAF51}.Release|x64.Build.0 = Release|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}.Release|x64.ActiveCfg = Release|x64
@ -665,6 +671,7 @@ Global
{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}
{4D971245-7A70-41D5-BAA0-DDB5684CAF51} = {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}

View File

@ -245,6 +245,10 @@
<Directory Id="UriImagesFolder" Name="Images" />
<Directory Id="UriLanguagesFolder" Name="Languages" />
</Directory>
<Directory Id="VSCodeWorkspacePluginFolder" Name="VSCodeWorkspace">
<Directory Id="VSCodeWorkspaceImagesFolder" Name="Images" />
<Directory Id="VSCodeWorkspaceLanguagesFolder" Name="Languages" />
</Directory>
<Directory Id="WindowWalkerPluginFolder" Name="Microsoft.Plugin.WindowWalker">
<Directory Id="WindowWalkerImagesFolder" Name="Images" />
<Directory Id="WindowWalkerLanguagesFolder" Name="Languages" />
@ -818,7 +822,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;CalculatorPluginFolder;FolderPluginFolder;ProgramPluginFolder;ShellPluginFolder;IndexerPluginFolder;UriPluginFolder;WindowWalkerPluginFolder;RegistryPluginFolder;ServicePluginFolder?>
<?foreach ParentDirectory in LauncherInstallFolder;FancyZonesInstallFolder;ImageResizerInstallFolder;ColorPickerInstallFolder;FileExplorerPreviewInstallFolder;CalculatorPluginFolder;FolderPluginFolder;ProgramPluginFolder;ShellPluginFolder;IndexerPluginFolder;UriPluginFolder;WindowWalkerPluginFolder;RegistryPluginFolder;VSCodeWorkspacePluginFolder;ServicePluginFolder?>
<DirectoryRef Id="$(var.ParentDirectory)">
<!-- Resource file directories -->
<?foreach Language in $(var.LocLanguageList)?>
@ -894,6 +898,9 @@
<Component Id="Launcher_Uri_$(var.IdSafeLanguage)_Component" Directory="Resource$(var.IdSafeLanguage)UriPluginFolder">
<File Id="Launcher_Uri_$(var.IdSafeLanguage)_File" Source="$(var.BinX64Dir)modules\launcher\Plugins\Microsoft.Plugin.Uri\$(var.Language)\Microsoft.Plugin.Uri.resources.dll" />
</Component>
<Component Id="Launcher_VSCodeWorkspaces_$(var.IdSafeLanguage)_Component" Directory="Resource$(var.IdSafeLanguage)VSCodeWorkspacesPluginFolder">
<File Id="Launcher_VSCodeWorkspaces_$(var.IdSafeLanguage)_File" Source="$(var.BinX64Dir)modules\launcher\Plugins\VSCodeWorkspaces\$(var.Language)\Community.PowerToys.Run.Plugin.VSCodeWorkspaces.resources.dll" />
</Component>
<Component Id="Launcher_WindowWalker_$(var.IdSafeLanguage)_Component" Directory="Resource$(var.IdSafeLanguage)WindowWalkerPluginFolder">
<File Id="Launcher_WindowWalker_$(var.IdSafeLanguage)_File" Source="$(var.BinX64Dir)modules\launcher\Plugins\Microsoft.Plugin.WindowWalker\$(var.Language)\Microsoft.Plugin.WindowWalker.resources.dll" />
</Component>
@ -1006,7 +1013,20 @@
<File Id="UriLightIcon" Source="$(var.BinX64Dir)modules\launcher\Plugins\Microsoft.Plugin.Uri\Images\Uri.light.png" />
</Component>
<!-- WindowWalker Plugin -->
<!-- VSCodeWorkspaces Plugin -->
<Component Id="VSCodeWorkspacesComponent" Directory="VSCodeWorkspacePluginFolder" Guid="78363DBD-7E38-4D5F-8987-9963DF609B94">
<File Id="VSCodeWorkspaceFolder_deps" Source="$(var.BinX64Dir)modules\launcher\Plugins\VSCodeWorkspaces\Community.PowerToys.Run.Plugin.VSCodeWorkspaces.deps.json" />
<?foreach File in plugin.json;Community.PowerToys.Run.Plugin.VSCodeWorkspaces.dll?>
<File Id="VSCodeWorkspaces_$(var.File)" Source="$(var.BinX64Dir)modules\launcher\Plugins\VSCodeWorkspaces\$(var.File)" />
<?endforeach?>
</Component>
<Component Id="VSCodeWorkspacesImagesComponent" Directory="VSCodeWorkspaceImagesFolder" Guid="6F3C0CF1-7024-4333-BFA1-850D340AEE69">
<File Id="VSCodeWorkspacePluginIcon" Source="$(var.BinX64Dir)modules\launcher\Plugins\VSCodeWorkspaces\Images\vscode_plugin.png" />
<File Id="VSCodeWorkspaceFolder" Source="$(var.BinX64Dir)modules\launcher\Plugins\VSCodeWorkspaces\Images\folder.png" />
<File Id="VSCodeWorkspaceRemote" Source="$(var.BinX64Dir)modules\launcher\Plugins\VSCodeWorkspaces\Images\monitor.png" />
</Component>
<!-- WindowWalker Plugin -->
<Component Id="WindowWalkerComponent" Directory="WindowWalkerPluginFolder" Guid="EB1391C9-B701-421F-80FC-ABB2FEDFAD19">
<?foreach File in plugin.json;Microsoft.Plugin.WindowWalker.deps.json;Microsoft.Plugin.WindowWalker.dll;ManagedTelemetry.dll?>
<File Id="WindowWalker_$(var.File)" Source="$(var.BinX64Dir)modules\launcher\Plugins\Microsoft.Plugin.WindowWalker\$(var.File)" />

View File

@ -0,0 +1,90 @@
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
<Import Project="..\..\..\..\Version.props" />
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<ProjectGuid>{4D971245-7A70-41D5-BAA0-DDB5684CAF51}</ProjectGuid>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Community.PowerToys.Run.Plugin.VSCodeWorkspaces</RootNamespace>
<AssemblyName>Community.PowerToys.Run.Plugin.VSCodeWorkspaces</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\VSCodeWorkspaces\</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\VSCodeWorkspaces\</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>
<PackageReference Include="JetBrains.Annotations" Version="2020.1.0" />
<PackageReference Include="System.Runtime" Version="4.3.1" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
</ItemGroup>
<ItemGroup>
<Reference Include="Windows.Foundation.UniversalApiContract">
<HintPath>C:\Program Files (x86)\Windows Kits\10\References\10.0.18362.0\Windows.Foundation.UniversalApiContract\8.0.0.0\Windows.Foundation.UniversalApiContract.winmd</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Update="Properties\Resources.Designer.cs">
<DependentUpon>Resources.resx</DependentUpon>
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
</Compile>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Update="Properties\Resources.resx">
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
<Generator>ResXFileCodeGenerator</Generator>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<None Update="Images\folder.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Images\monitor.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Images\vscode_plugin.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

View File

@ -0,0 +1,14 @@
{
"Projects": [
{
"LanguageSet": "Azure_Languages",
"LocItems": [
{
"SourceFile": "src\\modules\\launcher\\Plugins\\VSCodeWorkspaces\\Properties\\Resources.resx",
"CopyOption": "LangIDOnName",
"OutputPath": "src\\modules\\launcher\\Plugins\\VSCodeWorkspaces\\Properties"
}
]
}
]
}

View File

@ -0,0 +1,176 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Windows.Controls;
using Community.PowerToys.Run.Plugin.VSCodeWorkspaces.Properties;
using Community.PowerToys.Run.Plugin.VSCodeWorkspaces.RemoteMachinesHelper;
using Community.PowerToys.Run.Plugin.VSCodeWorkspaces.VSCodeHelper;
using Community.PowerToys.Run.Plugin.VSCodeWorkspaces.WorkspacesHelper;
using Microsoft.PowerToys.Settings.UI.Library;
using Wox.Plugin;
namespace Community.PowerToys.Run.Plugin.VSCodeWorkspaces
{
public class Main : IPlugin, IPluginI18n
{
public PluginInitContext _context { get; private set; }
public string Name => GetTranslatedPluginTitle();
public string Description => GetTranslatedPluginDescription();
public Main()
{
VSCodeInstances.LoadVSCodeInstances();
}
public readonly VSCodeWorkspacesApi _workspacesApi = new VSCodeWorkspacesApi();
public readonly VSCodeRemoteMachinesApi _machinesApi = new VSCodeRemoteMachinesApi();
public List<Result> Query(Query query)
{
var results = new List<Result>();
if (query != null)
{
// Search opened workspaces
_workspacesApi.Workspaces.ForEach(a =>
{
var title = $"{a.FolderName}";
var typeWorkspace = a.WorkspaceTypeToString();
if (a.TypeWorkspace == TypeWorkspace.Codespaces)
{
title += $" - {typeWorkspace}";
}
else if (a.TypeWorkspace != TypeWorkspace.Local)
{
title += $" - {(a.ExtraInfo != null ? $"{a.ExtraInfo} ({typeWorkspace})" : typeWorkspace)}";
}
results.Add(new Result
{
Title = title,
SubTitle = $"{Resources.Workspace}{(a.TypeWorkspace != TypeWorkspace.Local ? $" {Resources.In} {typeWorkspace}" : "")}: {SystemPath.RealPath(a.RelativePath)}",
Icon = a.VSCodeInstance.WorkspaceIcon,
Action = c =>
{
bool hide;
try
{
var process = new ProcessStartInfo
{
FileName = a.VSCodeInstance.ExecutablePath,
UseShellExecute = true,
Arguments = $"--folder-uri {a.Path}",
WindowStyle = ProcessWindowStyle.Hidden
};
Process.Start(process);
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;
},
ContextData = a,
});
});
// Search opened remote machines
_machinesApi.Machines.ForEach(a =>
{
var title = $"{a.Host}";
if (a.User != null && a.User != String.Empty && a.HostName != null && a.HostName != String.Empty)
{
title += $" [{a.User}@{a.HostName}]";
}
results.Add(new Result
{
Title = title,
SubTitle = Resources.SSHRemoteMachine,
Icon = a.VSCodeInstance.RemoteIcon,
Action = c =>
{
bool hide;
try
{
var process = new ProcessStartInfo()
{
FileName = a.VSCodeInstance.ExecutablePath,
UseShellExecute = true,
Arguments = $"--new-window --enable-proposed-api ms-vscode-remote.remote-ssh --remote ssh-remote+{((char)34) + a.Host + ((char)34)}",
WindowStyle = ProcessWindowStyle.Hidden,
};
Process.Start(process);
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;
},
ContextData = a,
});
});
}
results.ForEach(x =>
{
if (x.Score == 0)
{
x.Score = 100;
}
//if is a remote machine give it 12 extra points
if (x.ContextData is VSCodeRemoteMachine)
{
x.Score = x.Score + (query.Search.Count() * 5);
}
//intersect the title with the query
var intersection = x.Title.ToLower().Intersect(query.Search.ToLower()).Count();
x.Score = x.Score - (Convert.ToInt32(((x.Title.Count() - intersection) *2.5)));
});
results = results.OrderBy(x => x.Title).ToList();
if (query.ActionKeyword == String.Empty || (query.ActionKeyword != String.Empty && query.Search != String.Empty))
{
results = results.Where(a => a.Title.ToLower().Contains(query.Search.ToLower())).ToList();
}
return results;
}
public void Init(PluginInitContext context)
{
_context = context;
}
public string GetTranslatedPluginTitle()
{
return Resources.PluginTitle;
}
public string GetTranslatedPluginDescription()
{
return Resources.PluginDescription;
}
}
}

View File

@ -0,0 +1,126 @@
//------------------------------------------------------------------------------
// <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.VSCodeWorkspaces.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", "16.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal 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)]
internal 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.VSCodeWorkspaces.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)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
/// <summary>
/// Looks up a localized string similar to in.
/// </summary>
internal static string In {
get {
return ResourceManager.GetString("In", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Open VSCode previously opened workspaces, remote machines (SSH or Codespaces) and containers..
/// </summary>
internal static string PluginDescription {
get {
return ResourceManager.GetString("PluginDescription", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to VSCode Workspaces.
/// </summary>
internal static string PluginTitle {
get {
return ResourceManager.GetString("PluginTitle", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to SSH remote machine.
/// </summary>
internal static string SSHRemoteMachine {
get {
return ResourceManager.GetString("SSHRemoteMachine", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Container.
/// </summary>
internal static string TypeWorkspaceContainer {
get {
return ResourceManager.GetString("TypeWorkspaceContainer", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Local.
/// </summary>
internal static string TypeWorkspaceLocal {
get {
return ResourceManager.GetString("TypeWorkspaceLocal", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Workspace.
/// </summary>
internal static string Workspace {
get {
return ResourceManager.GetString("Workspace", resourceCulture);
}
}
}
}

View File

@ -0,0 +1,145 @@
<?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="PluginTitle" xml:space="preserve">
<value>VSCode Workspaces</value>
</data>
<data name="In" xml:space="preserve">
<value>in</value>
<comment>Used to indicate the location where something is</comment>
</data>
<data name="PluginDescription" xml:space="preserve">
<value>Open VSCode previously opened workspaces, remote machines (SSH or Codespaces) and containers.</value>
</data>
<data name="SSHRemoteMachine" xml:space="preserve">
<value>SSH remote machine</value>
</data>
<data name="TypeWorkspaceContainer" xml:space="preserve">
<value>Container</value>
<comment>As in "Visual Studio Code workspace container type</comment>
</data>
<data name="TypeWorkspaceLocal" xml:space="preserve">
<value>Local</value>
<comment>As in "The workspace is on the local machine"</comment>
</data>
<data name="Workspace" xml:space="preserve">
<value>Workspace</value>
<comment>It refers to the "Visual Studio Code workspace"</comment>
</data>
</root>

View File

@ -0,0 +1,23 @@
using System;
using System.Text.RegularExpressions;
namespace Community.PowerToys.Run.Plugin.VSCodeWorkspaces
{
class SystemPath
{
private static readonly Regex WindowsPath = new Regex(@"^([a-zA-Z]:)", RegexOptions.Compiled);
public static string RealPath(string path)
{
if (WindowsPath.IsMatch(path))
{
String windowsPath = path.Replace("/", "\\");
return $"{windowsPath[0]}".ToUpper() + windowsPath.Remove(0,1);
}
else
{
return path;
}
}
}
}

View File

@ -0,0 +1,15 @@
using Community.PowerToys.Run.Plugin.VSCodeWorkspaces.VSCodeHelper;
namespace Community.PowerToys.Run.Plugin.VSCodeWorkspaces.RemoteMachinesHelper
{
public class VSCodeRemoteMachine
{
public string Host { get; set; }
public string User { get; set; }
public string HostName { get; set; }
public VSCodeInstance VSCodeInstance { get; set; }
}
}

View File

@ -0,0 +1,64 @@
using Community.PowerToys.Run.Plugin.VSCodeWorkspaces.SshConfigParser;
using Community.PowerToys.Run.Plugin.VSCodeWorkspaces.VSCodeHelper;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using Wox.Plugin.Logger;
namespace Community.PowerToys.Run.Plugin.VSCodeWorkspaces.RemoteMachinesHelper
{
public class VSCodeRemoteMachinesApi
{
public VSCodeRemoteMachinesApi() { }
public List<VSCodeRemoteMachine> Machines
{
get
{
var results = new List<VSCodeRemoteMachine>();
foreach (var vscodeInstance in VSCodeInstances.instances)
{
// settings.json contains path of ssh_config
var vscode_settings = Path.Combine(vscodeInstance.AppData, "User\\settings.json");
if (File.Exists(vscode_settings))
{
var fileContent = File.ReadAllText(vscode_settings);
try
{
dynamic vscodeSettingsFile = JsonConvert.DeserializeObject<dynamic>(fileContent);
if (vscodeSettingsFile.ContainsKey("remote.SSH.configFile"))
{
var path = vscodeSettingsFile["remote.SSH.configFile"];
if (File.Exists(path.Value))
{
foreach (SshHost h in SshConfig.ParseFile(path.Value))
{
var machine = new VSCodeRemoteMachine();
machine.Host = h.Host;
machine.VSCodeInstance = vscodeInstance;
machine.HostName = h.HostName != null ? h.HostName : String.Empty;
machine.User = h.User != null ? h.User : String.Empty;
results.Add(machine);
}
}
}
}
catch (Exception ex)
{
var message = $"Failed to deserialize ${vscode_settings}";
Log.Exception(message, ex, GetType());
}
}
}
return results;
}
}
}
}

View File

@ -0,0 +1,39 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
namespace Community.PowerToys.Run.Plugin.VSCodeWorkspaces.SshConfigParser
{
public class SshConfig
{
private static readonly Regex SSH_CONFIG = new Regex(@"^(\w[\s\S]*?\w)$(?=(?:\s+^\w|\z))", RegexOptions.Multiline);
private static readonly Regex KEY_VALUE = new Regex(@"(\w+\s\S+)", RegexOptions.Multiline);
public static IEnumerable<SshHost> ParseFile(string path)
{
return Parse(File.ReadAllText(path));
}
public static IEnumerable<SshHost> Parse(string str)
{
str = str.Replace("\r", "");
var list = new List<SshHost>();
foreach (Match match in SSH_CONFIG.Matches(str))
{
var sshHost = new SshHost();
string content = match.Groups.Values.ToList()[0].Value;
foreach (Match match1 in KEY_VALUE.Matches(content))
{
var split = match1.Value.Split(" ");
var key = split[0];
var value = split[1];
sshHost.Properties[key] = value;
}
list.Add(sshHost);
}
return list;
}
}
}

View File

@ -0,0 +1,53 @@
using System.Collections.Generic;
namespace Community.PowerToys.Run.Plugin.VSCodeWorkspaces.SshConfigParser
{
public class SshHost
{
public string IdentityFile
{
get => this[nameof(IdentityFile)]?.ToString();
set => this[nameof(IdentityFile)] = value;
}
public string Host
{
get => this[nameof(Host)]?.ToString();
set => this[nameof(Host)] = value;
}
public string HostName
{
get => this[nameof(HostName)]?.ToString();
set => this[nameof(HostName)] = value;
}
public string User {
get => this[nameof(User)]?.ToString();
set => this[nameof(User)] = value;
}
public string ForwardAgent {
get => this[nameof(ForwardAgent)]?.ToString();
set => this[nameof(ForwardAgent)] = value;
}
internal Dictionary<string, object> Properties { get; } = new Dictionary<string, object>();
public object this[string key]
{
get
{
if (Properties.TryGetValue(key, out var value))
{
return value;
}
return null;
}
set { Properties[key] = value; }
}
public IEnumerable<string> Keys => Properties.Keys;
}
}

View File

@ -0,0 +1,30 @@
using System;
using System.Windows.Media;
using System.Windows.Media.Imaging;
namespace Community.PowerToys.Run.Plugin.VSCodeWorkspaces.VSCodeHelper
{
public enum VSCodeVersion
{
Stable = 1,
Insiders = 2,
Exploration = 3
}
public class VSCodeInstance
{
public VSCodeVersion VSCodeVersion { get; set; }
public string ExecutablePath { get; set; } = String.Empty;
public string AppData { get; set; } = String.Empty;
public ImageSource WorkspaceIcon(){ return WorkspaceIconBitMap; }
public ImageSource RemoteIcon(){ return RemoteIconBitMap; }
public BitmapImage WorkspaceIconBitMap { get; set; }
public BitmapImage RemoteIconBitMap { get; set; }
}
}

View File

@ -0,0 +1,133 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Windows;
using System.Windows.Interop;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
namespace Community.PowerToys.Run.Plugin.VSCodeWorkspaces.VSCodeHelper
{
static class VSCodeInstances
{
private static readonly string PathUserAppData = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
private static string _systemPath = String.Empty;
private static string _userAppDataPath = Environment.GetEnvironmentVariable("AppData");
public static List<VSCodeInstance> instances = new List<VSCodeInstance>();
private static BitmapImage Bitmap2BitmapImage(Bitmap bitmap)
{
using (var memory = new MemoryStream())
{
bitmap.Save(memory, ImageFormat.Png);
memory.Position = 0;
var bitmapImage = new BitmapImage();
bitmapImage.BeginInit();
bitmapImage.StreamSource = memory;
bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
bitmapImage.EndInit();
bitmapImage.Freeze();
return bitmapImage;
}
}
public static Bitmap bitmapOverlayToCenter(Bitmap bitmap1, Bitmap overlayBitmap)
{
int bitmap1Width = bitmap1.Width;
int bitmap1Height = bitmap1.Height;
Bitmap overlayBitmapResized = new Bitmap(overlayBitmap, new System.Drawing.Size(bitmap1Width / 2, bitmap1Height / 2));
float marginLeft = (float)(bitmap1Width * 0.7 - overlayBitmapResized.Width * 0.5);
float marginTop = (float)(bitmap1Height * 0.7 - overlayBitmapResized.Height * 0.5);
Bitmap finalBitmap = new Bitmap(bitmap1Width, bitmap1Height);
using (Graphics g = Graphics.FromImage(finalBitmap))
{
g.DrawImage(bitmap1, System.Drawing.Point.Empty);
g.DrawImage(overlayBitmapResized, marginLeft, marginTop);
}
return finalBitmap;
}
// Gets the executablePath and AppData foreach instance of VSCode
public static void LoadVSCodeInstances()
{
if (_systemPath != Environment.GetEnvironmentVariable("PATH"))
{
instances = new List<VSCodeInstance>();
_systemPath = Environment.GetEnvironmentVariable("PATH");
var paths = _systemPath.Split(";");
paths = paths.Where(x => x.Contains("VS Code")).ToArray();
foreach (var path in paths)
{
if (Directory.Exists(path))
{
var files = Directory.GetFiles(path);
var iconPath = Path.GetDirectoryName(path);
files = files.Where(x => x.Contains("code") && !x.EndsWith(".cmd")).ToArray();
if (files.Length > 0)
{
var file = files[0];
var version = String.Empty;
var instance = new VSCodeInstance
{
ExecutablePath = file,
};
if (file.EndsWith("code"))
{
version = "Code";
instance.VSCodeVersion = VSCodeVersion.Stable;
}
else if (file.EndsWith("code-insiders"))
{
version = "Code - Insiders";
instance.VSCodeVersion = VSCodeVersion.Insiders;
}
else if (file.EndsWith("code-exploration"))
{
version = "Code - Exploration";
instance.VSCodeVersion = VSCodeVersion.Exploration;
}
if (version != String.Empty)
{
instance.AppData = Path.Combine(_userAppDataPath, version);
var iconVSCode = Path.Join(iconPath, $"{version}.exe");
var bitmapIconVscode = Icon.ExtractAssociatedIcon(iconVSCode).ToBitmap();
//workspace
var folderIcon = (Bitmap)System.Drawing.Image.FromFile(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + "//Images//folder.png");
instance.WorkspaceIconBitMap = Bitmap2BitmapImage(bitmapOverlayToCenter(folderIcon, bitmapIconVscode));
//remote
var monitorIcon = (Bitmap)System.Drawing.Image.FromFile(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + "//Images//monitor.png");
instance.RemoteIconBitMap = Bitmap2BitmapImage(bitmapOverlayToCenter(monitorIcon, bitmapIconVscode));
instances.Add(instance);
}
}
}
}
}
}
}
}

View File

@ -0,0 +1,58 @@
using System;
using System.Text.RegularExpressions;
namespace Community.PowerToys.Run.Plugin.VSCodeWorkspaces.WorkspacesHelper
{
public class ParseVSCodeUri
{
private static readonly Regex LocalWorkspace = new Regex("^file:///(.+)$", RegexOptions.Compiled);
private static readonly Regex RemoteSSHWorkspace = new Regex(@"^vscode-remote://ssh-remote\+(.+?(?=\/))(.+)$", RegexOptions.Compiled);
private static readonly Regex RemoteWSLWorkspace = new Regex(@"^vscode-remote://wsl\+(.+?(?=\/))(.+)$", RegexOptions.Compiled);
private static readonly Regex CodespacesWorkspace = new Regex(@"^vscode-remote://vsonline\+(.+?(?=\/))(.+)$", RegexOptions.Compiled);
public static (TypeWorkspace? TypeWorkspace, String MachineName, String Path) GetTypeWorkspace(string uri)
{
if (LocalWorkspace.IsMatch(uri))
{
var match = LocalWorkspace.Match(uri);
if (match.Groups.Count > 1)
{
return (TypeWorkspace.Local, null, match.Groups[1].Value);
}
}
else if (RemoteSSHWorkspace.IsMatch(uri))
{
var match = RemoteSSHWorkspace.Match(uri);
if (match.Groups.Count > 1)
{
return (TypeWorkspace.RemoteSSH, match.Groups[1].Value, match.Groups[2].Value);
}
}
else if (RemoteWSLWorkspace.IsMatch(uri))
{
var match = RemoteWSLWorkspace.Match(uri);
if (match.Groups.Count > 1)
{
return (TypeWorkspace.RemoteWSL, match.Groups[1].Value, match.Groups[2].Value);
}
}
else if (CodespacesWorkspace.IsMatch(uri))
{
var match = CodespacesWorkspace.Match(uri);
if (match.Groups.Count > 1)
{
return (TypeWorkspace.Codespaces, String.Empty, match.Groups[2].Value);
}
}
return (null, null, null);
}
}
}

View File

@ -0,0 +1,14 @@
using System.Collections.Generic;
namespace Community.PowerToys.Run.Plugin.VSCodeWorkspaces.WorkspacesHelper
{
public class VSCodeStorageFile
{
public openedPathsList openedPathsList { get; set; }
}
public class openedPathsList
{
public List<dynamic> workspaces3 { get; set; }
}
}

View File

@ -0,0 +1,43 @@
using Community.PowerToys.Run.Plugin.VSCodeWorkspaces.Properties;
using Community.PowerToys.Run.Plugin.VSCodeWorkspaces.VSCodeHelper;
namespace Community.PowerToys.Run.Plugin.VSCodeWorkspaces.WorkspacesHelper
{
public class VSCodeWorkspace
{
public string Path { get; set; }
public string RelativePath { get; set; }
public string FolderName { get; set; }
public string ExtraInfo { get; set; }
public TypeWorkspace TypeWorkspace { get; set; }
public VSCodeInstance VSCodeInstance { get; set; }
public string WorkspaceTypeToString()
{
switch (TypeWorkspace)
{
case TypeWorkspace.Local: return Resources.TypeWorkspaceLocal;
case TypeWorkspace.Codespaces: return "Codespaces";
case TypeWorkspace.RemoteContainers: return Resources.TypeWorkspaceContainer;
case TypeWorkspace.RemoteSSH: return "SSH";
case TypeWorkspace.RemoteWSL: return "WSL";
}
return string.Empty;
}
}
public enum TypeWorkspace
{
Local = 1,
Codespaces = 2,
RemoteWSL = 3,
RemoteSSH = 4,
RemoteContainers = 5
}
}

View File

@ -0,0 +1,74 @@
using Community.PowerToys.Run.Plugin.VSCodeWorkspaces.VSCodeHelper;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using Wox.Plugin.Logger;
namespace Community.PowerToys.Run.Plugin.VSCodeWorkspaces.WorkspacesHelper
{
public class VSCodeWorkspacesApi
{
public VSCodeWorkspacesApi() { }
public List<VSCodeWorkspace> Workspaces
{
get
{
var results = new List<VSCodeWorkspace>();
foreach (var vscodeInstance in VSCodeInstances.instances)
{
// storage.json contains opened Workspaces
var vscode_storage = Path.Combine(vscodeInstance.AppData, "storage.json");
if (File.Exists(vscode_storage))
{
var fileContent = File.ReadAllText(vscode_storage);
try
{
VSCodeStorageFile vscodeStorageFile = JsonConvert.DeserializeObject<VSCodeStorageFile>(fileContent);
if (vscodeStorageFile != null)
{
foreach (var workspaceUri in vscodeStorageFile.openedPathsList.workspaces3)
{
if (workspaceUri != null && workspaceUri is String)
{
string unescapeUri = Uri.UnescapeDataString(workspaceUri);
var typeWorkspace = ParseVSCodeUri.GetTypeWorkspace(unescapeUri);
if (typeWorkspace.TypeWorkspace.HasValue)
{
var folderName = Path.GetFileName(unescapeUri);
results.Add(new VSCodeWorkspace()
{
Path = workspaceUri,
RelativePath = typeWorkspace.Path,
FolderName = folderName,
ExtraInfo = typeWorkspace.MachineName,
TypeWorkspace = typeWorkspace.TypeWorkspace.Value,
VSCodeInstance = vscodeInstance
});
}
}
}
}
}
catch (Exception ex)
{
var message = $"Failed to deserialize ${vscode_storage}";
Log.Exception(message, ex, GetType());
}
}
}
return results;
}
}
}
}

View File

@ -0,0 +1,14 @@
{
"ID": "525995402BEF4A8CA860D92F6D108092",
"ActionKeyword": "{",
"Name": "VSCode Workspaces",
"Description": "Opened VSCode Workspaces",
"Author": "ricardosantos9521",
"Version": "1.0.0",
"Language": "csharp",
"Website": "https://github.com/ricardosantos9521/PowerToys/",
"ExecuteFileName": "Community.PowerToys.Run.Plugin.VSCodeWorkspaces.dll",
"IsGlobal": false,
"IcoPathDark": "Images\\vscode_plugin.png",
"IcoPathLight": "Images\\vscode_plugin.png"
}

View File

@ -45,7 +45,7 @@ namespace Microsoft.PowerToys.Run.Plugin.Calculator.Properties {
return resourceMan;
}
}
/// <summary>
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
@ -68,7 +68,7 @@ namespace Microsoft.PowerToys.Run.Plugin.Calculator.Properties {
return ResourceManager.GetString("wox_plugin_calculator_copy_failed", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Copy this number to the clipboard.
/// </summary>
@ -95,6 +95,7 @@ namespace Microsoft.PowerToys.Run.Plugin.Calculator.Properties {
return ResourceManager.GetString("wox_plugin_calculator_not_a_number", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Does mathematical calculations (e.g. 5*3-2)..
@ -104,7 +105,7 @@ namespace Microsoft.PowerToys.Run.Plugin.Calculator.Properties {
return ResourceManager.GetString("wox_plugin_calculator_plugin_description", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Calculator.
/// </summary>