Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move focus to main window of process if it's already running #49

Open
wants to merge 8 commits into
base: develop
Choose a base branch
from
32 changes: 31 additions & 1 deletion src/Jarvis.Addin.Files/FileProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,18 @@
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Media;
using Jarvis.Addin.Files.Drawing;
using Jarvis.Addin.Files.Indexing;
using Jarvis.Core;
using Jarvis.Core.Interop;
using JetBrains.Annotations;
using Spectre.System.IO;
using static Jarvis.Addin.Files.Sources.Uwp.ShellInterop;
using Path = System.IO.Path;

namespace Jarvis.Addin.Files
{
Expand Down Expand Up @@ -55,7 +59,33 @@ protected override Task ExecuteAsync(FileResult result)

if (result.Path.Scheme == "shell")
{
Process.Start(path);
var descriptionPath = result.Description.Replace("/", "\\");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using the FileResult.Description only works in some cases. Where a lnk-file has been indexed, this will be the shortcut's description.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that's what I feared.

var existingProcess = Process
.GetProcesses()
.FirstOrDefault(process =>
{
var processPath = new StringBuilder(1024);
var size = processPath.Capacity;
var processHandle = Kernel32.OpenProcess(0x1000, false, process.Id);
Kernel32.QueryFullProcessImageName(processHandle, 0, processPath, out size);
return processPath.ToString() == descriptionPath;
});

if (existingProcess != null)
{
Win32.SetForegroundWindow(existingProcess.MainWindowHandle);

var rect = new Win32.W32Rect();
Win32.GetWindowRect(existingProcess.MainWindowHandle, ref rect);
if (rect.Top < 0 && rect.Right < 0 && rect.Bottom < 0 && rect.Left < 0) // Window is minimized
{
Win32.ShowWindow(existingProcess.MainWindowHandle, 1);
}
}
else
{
Process.Start(path);
}
}
else if (result.Path.Scheme == "uwp")
{
Expand Down
15 changes: 15 additions & 0 deletions src/Jarvis.Core/Interop/Kernel32.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using System;
using System.Runtime.InteropServices;
using System.Text;

namespace Jarvis.Core.Interop
{
public static class Kernel32
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would prefer to put this in public static partial class Win32 and name the file Win32.Process or similar.

{
[DllImport("kernel32.dll")]
public static extern IntPtr OpenProcess(int access, bool inherit, int proccessId);

[DllImport("kernel32.dll")]
public static extern IntPtr QueryFullProcessImageName(IntPtr hprocess, int dwFlags, [Out] StringBuilder lpExeName, [Out] [MarshalAs(UnmanagedType.U4)] out int size);
}
}
6 changes: 6 additions & 0 deletions src/Jarvis.Core/Interop/Win32.Window.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,11 @@ public static partial class Win32

[DllImport("user32.dll")]
public static extern bool GetWindowRect(IntPtr hwnd, ref W32Rect rectangle);

[DllImport("user32.dll")]
public static extern bool SetForegroundWindow(IntPtr hwnd);

[DllImport("user32.dll")]
public static extern bool ShowWindow(IntPtr hwnd, int nCmdShow);
}
}
1 change: 1 addition & 0 deletions src/Jarvis.Core/Jarvis.Core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@
<Compile Include="Extensions\SettingStoreExtensions.cs" />
<Compile Include="IAddin.cs" />
<Compile Include="IInitializable.cs" />
<Compile Include="Interop\Kernel32.cs" />
<Compile Include="ISettings.cs" />
<Compile Include="Interop\Win32.Shell.cs" />
<Compile Include="Interop\Win32.Common.cs" />
Expand Down