Skip to content

Commit a5df28c

Browse files
committed
Fix #15: Ensure reliable vscode focus
1 parent 2e0e1b3 commit a5df28c

File tree

9 files changed

+146
-1
lines changed

9 files changed

+146
-1
lines changed
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
using System.Diagnostics;
2+
3+
if (args.Length == 0)
4+
{
5+
Console.Error.WriteLine("Error: No executable specified.");
6+
return 1;
7+
}
8+
9+
try
10+
{
11+
string targetExe = args[0].Trim('"');
12+
string executableName = Path.GetFileName(targetExe);
13+
if (!string.Equals(executableName, "Code.exe", StringComparison.OrdinalIgnoreCase))
14+
{
15+
Console.Error.WriteLine($"Error: This launcher only supports executing Code.exe for VisualStudioCodeForCommandPalette extension. Attempted to run: {executableName}");
16+
return 1;
17+
}
18+
string arguments = args.Length > 1 ? string.Join(" ", args, 1, args.Length - 1) : "";
19+
var startInfo = new ProcessStartInfo
20+
{
21+
FileName = targetExe,
22+
Arguments = arguments,
23+
UseShellExecute = true,
24+
WindowStyle = ProcessWindowStyle.Hidden,
25+
CreateNoWindow = true
26+
};
27+
28+
Process.Start(startInfo);
29+
return 0;
30+
}
31+
catch (Exception ex)
32+
{
33+
Console.Error.WriteLine($"Failed to launch process: {ex}");
34+
return 1;
35+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<!-- https://go.microsoft.com/fwlink/?LinkID=208121. -->
3+
<Project>
4+
<PropertyGroup>
5+
<Configuration>Release</Configuration>
6+
<Platform>ARM64</Platform>
7+
<PublishDir>bin\ARM64\Release\net8.0\publish</PublishDir>
8+
<PublishProtocol>FileSystem</PublishProtocol>
9+
<_TargetId>Folder</_TargetId>
10+
<TargetFramework>net8.0</TargetFramework>
11+
<RuntimeIdentifier>win-arm64</RuntimeIdentifier>
12+
<SelfContained>true</SelfContained>
13+
<PublishSingleFile>false</PublishSingleFile>
14+
<PublishReadyToRun>false</PublishReadyToRun>
15+
</PropertyGroup>
16+
</Project>
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<!-- https://go.microsoft.com/fwlink/?LinkID=208121. -->
3+
<Project>
4+
<PropertyGroup>
5+
<Configuration>Release</Configuration>
6+
<Platform>x64</Platform>
7+
<PublishDir>bin\x64\Release\net8.0\publish</PublishDir>
8+
<PublishProtocol>FileSystem</PublishProtocol>
9+
<_TargetId>Folder</_TargetId>
10+
<TargetFramework>net8.0</TargetFramework>
11+
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
12+
<SelfContained>true</SelfContained>
13+
<PublishSingleFile>false</PublishSingleFile>
14+
<PublishReadyToRun>false</PublishReadyToRun>
15+
</PropertyGroup>
16+
</Project>
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<OutputType>Exe</OutputType>
5+
<TargetFramework>net8.0</TargetFramework>
6+
<ImplicitUsings>enable</ImplicitUsings>
7+
<Nullable>enable</Nullable>
8+
<PublishAot>true</PublishAot>
9+
<InvariantGlobalization>true</InvariantGlobalization>
10+
<PublishTrimmed>true</PublishTrimmed>
11+
<TrimMode>link</TrimMode>
12+
<DebuggerSupport>false</DebuggerSupport>
13+
<DebugType>none</DebugType>
14+
<OptimizationPreference>Size</OptimizationPreference>
15+
</PropertyGroup>
16+
17+
</Project>

WorkspaceLauncherForVSCode.sln

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ VisualStudioVersion = 17.13.35507.96
44
MinimumVisualStudioVersion = 10.0.40219.1
55
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WorkspaceLauncherForVSCode", "WorkspaceLauncherForVSCode\WorkspaceLauncherForVSCode.csproj", "{DBDA4F4C-D6F6-414C-A521-6B4031F8D15A}"
66
EndProject
7+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VisualStudioCodeForCommandPaletteLauncher", "VisualStudioCodeForCommandPaletteLauncher\VisualStudioCodeForCommandPaletteLauncher.csproj", "{9237B5EF-9F2D-44B8-BBAA-E4DC8488B122}"
8+
EndProject
79
Global
810
GlobalSection(SolutionConfigurationPlatforms) = preSolution
911
Debug|ARM64 = Debug|ARM64
@@ -32,6 +34,18 @@ Global
3234
{DBDA4F4C-D6F6-414C-A521-6B4031F8D15A}.Release|x86.ActiveCfg = Release|x86
3335
{DBDA4F4C-D6F6-414C-A521-6B4031F8D15A}.Release|x86.Build.0 = Release|x86
3436
{DBDA4F4C-D6F6-414C-A521-6B4031F8D15A}.Release|x86.Deploy.0 = Release|x86
37+
{9237B5EF-9F2D-44B8-BBAA-E4DC8488B122}.Debug|ARM64.ActiveCfg = Debug|ARM64
38+
{9237B5EF-9F2D-44B8-BBAA-E4DC8488B122}.Debug|ARM64.Build.0 = Debug|ARM64
39+
{9237B5EF-9F2D-44B8-BBAA-E4DC8488B122}.Debug|x64.ActiveCfg = Debug|x64
40+
{9237B5EF-9F2D-44B8-BBAA-E4DC8488B122}.Debug|x64.Build.0 = Debug|x64
41+
{9237B5EF-9F2D-44B8-BBAA-E4DC8488B122}.Debug|x86.ActiveCfg = Debug|x64
42+
{9237B5EF-9F2D-44B8-BBAA-E4DC8488B122}.Debug|x86.Build.0 = Debug|x64
43+
{9237B5EF-9F2D-44B8-BBAA-E4DC8488B122}.Release|ARM64.ActiveCfg = Release|ARM64
44+
{9237B5EF-9F2D-44B8-BBAA-E4DC8488B122}.Release|ARM64.Build.0 = Release|ARM64
45+
{9237B5EF-9F2D-44B8-BBAA-E4DC8488B122}.Release|x64.ActiveCfg = Release|x64
46+
{9237B5EF-9F2D-44B8-BBAA-E4DC8488B122}.Release|x64.Build.0 = Release|x64
47+
{9237B5EF-9F2D-44B8-BBAA-E4DC8488B122}.Release|x86.ActiveCfg = Release|x64
48+
{9237B5EF-9F2D-44B8-BBAA-E4DC8488B122}.Release|x86.Build.0 = Release|x64
3549
EndGlobalSection
3650
GlobalSection(SolutionProperties) = preSolution
3751
HideSolutionNode = FALSE

WorkspaceLauncherForVSCode/Classes/SettingsManager.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,12 @@ public class SettingsManager : JsonSettingsManager
8383
"Enable Logging",
8484
"Enables diagnostic logging for troubleshooting.",
8585
false);
86+
87+
private readonly ToggleSetting _useHelperLauncher = new(
88+
Namespaced(nameof(UseHelperLauncher)),
89+
"Use Helper Launcher",
90+
"Launches Visual Studio Code via a helper executable (VisualStudioCodeForCommandPaletteLauncher.exe). Enable this if Visual Studio Code doesn't come to the foreground when opened. This workaround is needed on some PCs because Windows can prevent background processes (like this extension) from 'stealing' focus.",
91+
false);
8692

8793
private readonly ToggleSetting _showTypeTag = new(
8894
Namespaced(nameof(_showTypeTag)),
@@ -206,6 +212,7 @@ public SortBy SortBy
206212
}
207213

208214
public bool EnableLogging => _enableLogging.Value;
215+
public bool UseHelperLauncher => _useHelperLauncher.Value;
209216
public bool EnableVisualStudio => _enableVisualStudio.Value;
210217
public bool EnableWorkspaceWatcher => _enableWorkspaceWatcher.Value;
211218
public bool ClearSearchOnExecute => _clearSearchOnExecute.Value;
@@ -328,6 +335,7 @@ public SettingsManager()
328335
Settings.Add(_vsSecondaryCommand);
329336
Settings.Add(_vscodeSecondaryCommand);
330337
Settings.Add(_clearSearchOnExecute);
338+
Settings.Add(_useHelperLauncher);
331339
// Settings.Add(_enableWorkspaceWatcher);
332340
#if DEBUG
333341
Settings.Add(_enableLogging);

WorkspaceLauncherForVSCode/Commands/OpenVisualStudioCodeCommand.cs

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
// Modifications copyright (c) 2025 tanchekwei
22
// Licensed under the MIT License. See the LICENSE file in the project root for details.
33
using System;
4+
using System.Diagnostics;
5+
using System.IO;
46
using System.Threading.Tasks;
57
using Microsoft.CmdPal.Ext.System.Helpers;
68
using Microsoft.CommandPalette.Extensions.Toolkit;
@@ -90,7 +92,30 @@ public override CommandResult Invoke()
9092
arguments = $"--folder-uri \"{Workspace.Path}\"";
9193
}
9294

93-
OpenInShellHelper.OpenInShell(Workspace.VSCodeInstance.ExecutablePath, arguments, runAs: _elevated ? OpenInShellHelper.ShellRunAsType.Administrator : OpenInShellHelper.ShellRunAsType.None);
95+
if (page.SettingsManager.UseHelperLauncher)
96+
{
97+
var launcherPath = Path.Combine(AppContext.BaseDirectory, "VisualStudioCodeForCommandPaletteLauncher.exe");
98+
var launcherArgs = $"\"{Workspace.VSCodeInstance.ExecutablePath}\" {arguments}";
99+
100+
var startInfo = new ProcessStartInfo(launcherPath, launcherArgs)
101+
{
102+
UseShellExecute = false,
103+
CreateNoWindow = true,
104+
WindowStyle = ProcessWindowStyle.Hidden,
105+
};
106+
107+
if (_elevated)
108+
{
109+
startInfo.Verb = "runas";
110+
startInfo.UseShellExecute = true;
111+
}
112+
113+
Process.Start(startInfo);
114+
}
115+
else
116+
{
117+
OpenInShellHelper.OpenInShell(Workspace.VSCodeInstance.ExecutablePath, arguments, runAs: _elevated ? OpenInShellHelper.ShellRunAsType.Administrator : OpenInShellHelper.ShellRunAsType.None);
118+
}
94119

95120
Task.Run(() => page.UpdateFrequencyAsync(Workspace.Path));
96121

WorkspaceLauncherForVSCode/Listeners/SettingsListener.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ public class SettingsListener
1818
private TagType _previousTagTypes;
1919
private SortBy _previousSortBy;
2020
private bool _prevEnableWorkspaceWatcher;
21+
private bool _previousUseHelperLauncher;
2122

2223
public event EventHandler? InstanceSettingsChanged;
2324
public event EventHandler? PageSettingsChanged;
@@ -36,6 +37,7 @@ public SettingsListener(SettingsManager settingsManager)
3637
_previousTagTypes = _settingsManager.TagTypes;
3738
_previousSortBy = _settingsManager.SortBy;
3839
_prevEnableWorkspaceWatcher = _settingsManager.EnableWorkspaceWatcher;
40+
_previousUseHelperLauncher = _settingsManager.UseHelperLauncher;
3941
_settingsManager.Settings.SettingsChanged += OnSettingsChanged;
4042
}
4143
catch (Exception ex)
@@ -61,6 +63,7 @@ private void OnSettingsChanged(object? sender, Settings e)
6163
var currentTagTypes = _settingsManager.TagTypes;
6264
var currentSortBy = _settingsManager.SortBy;
6365
var currentEnableWorkspaceWatcher = _settingsManager.EnableWorkspaceWatcher;
66+
var currentUseHelperLauncher = _settingsManager.UseHelperLauncher;
6467

6568
if (currentEditions != _previousEditions || currentVsSecondaryCommand != _previousVsSecondaryCommand || currentVscodeSecondaryCommand != _previousVscodeSecondaryCommand || currentTagTypes != _previousTagTypes)
6669
{
@@ -91,6 +94,11 @@ private void OnSettingsChanged(object? sender, Settings e)
9194
InstanceSettingsChanged?.Invoke(this, EventArgs.Empty);
9295
_previousEnableVisualStudio = currentEnableVisualStudio;
9396
}
97+
98+
if (currentUseHelperLauncher != _previousUseHelperLauncher)
99+
{
100+
_previousUseHelperLauncher = currentUseHelperLauncher;
101+
}
94102
}
95103
catch (Exception ex)
96104
{

WorkspaceLauncherForVSCode/WorkspaceLauncherForVSCode.csproj

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,12 @@
8383
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
8484
</Content>
8585
</ItemGroup>
86+
<ItemGroup>
87+
<Content Include="..\VisualStudioCodeForCommandPaletteLauncher\bin\$(Platform)\release\net8.0\publish\VisualStudioCodeForCommandPaletteLauncher.exe">
88+
<Link>VisualStudioCodeForCommandPaletteLauncher.exe</Link>
89+
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
90+
</Content>
91+
</ItemGroup>
8692
<ItemGroup>
8793
<EmbeddedResource Update="Properties\Resource.resx">
8894
<Generator>ResXFileCodeGenerator</Generator>

0 commit comments

Comments
 (0)