diff --git a/Plugins/Flow.Launcher.Plugin.Program/Programs/ApplicationActivationHelper.cs b/Plugins/Flow.Launcher.Plugin.Program/Programs/ApplicationActivationHelper.cs
new file mode 100644
index 000000000..989995f31
--- /dev/null
+++ b/Plugins/Flow.Launcher.Plugin.Program/Programs/ApplicationActivationHelper.cs
@@ -0,0 +1,44 @@
+using System;
+using System.Diagnostics;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Text.RegularExpressions;
+
+namespace Microsoft.Plugin.Program.Programs
+{
+ public class ApplicationActivationHelper
+ {
+ // Reference : https://github.com/MicrosoftEdge/edge-launcher/blob/108e63df0b4cb5cd9d5e45aa7a264690851ec51d/MIcrosoftEdgeLauncherCsharp/Program.cs
+ public enum ActivateOptions
+ {
+ None = 0x00000000,
+ DesignMode = 0x00000001,
+ NoErrorUI = 0x00000002,
+ NoSplashScreen = 0x00000004,
+ }
+
+ /// ApplicationActivationManager
+ [ComImport, Guid("2e941141-7f97-4756-ba1d-9decde894a3d"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
+ interface IApplicationActivationManager
+ {
+ IntPtr ActivateApplication([In] String appUserModelId, [In] String arguments, [In] ActivateOptions options, [Out] out UInt32 processId);
+ IntPtr ActivateForFile([In] String appUserModelId, [In] IntPtr /*IShellItemArray* */ itemArray, [In] String verb, [Out] out UInt32 processId);
+ IntPtr ActivateForProtocol([In] String appUserModelId, [In] IntPtr /* IShellItemArray* */itemArray, [Out] out UInt32 processId);
+ }
+
+ // Application Activation Manager Class
+ [ComImport, Guid("45BA127D-10A8-46EA-8AB7-56EA9078943C")]
+ public class ApplicationActivationManager : IApplicationActivationManager
+ {
+
+ [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)/*, PreserveSig*/]
+ public extern IntPtr ActivateApplication([In] String appUserModelId, [In] String arguments, [In] ActivateOptions options, [Out] out UInt32 processId);
+
+ [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
+ public extern IntPtr ActivateForFile([In] String appUserModelId, [In] IntPtr /*IShellItemArray* */ itemArray, [In] String verb, [Out] out UInt32 processId);
+
+ [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
+ public extern IntPtr ActivateForProtocol([In] String appUserModelId, [In] IntPtr /* IShellItemArray* */itemArray, [Out] out UInt32 processId);
+ }
+ }
+}
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Programs/ShellLinkHelper.cs b/Plugins/Flow.Launcher.Plugin.Program/Programs/ShellLinkHelper.cs
new file mode 100644
index 000000000..49977393a
--- /dev/null
+++ b/Plugins/Flow.Launcher.Plugin.Program/Programs/ShellLinkHelper.cs
@@ -0,0 +1,132 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Runtime.InteropServices;
+using System.IO;
+using Accessibility;
+using System.Runtime.InteropServices.ComTypes;
+using System.Security.Policy;
+
+namespace Microsoft.Plugin.Program.Programs
+{
+ class ShellLinkHelper
+ {
+ [Flags()]
+ public enum SLGP_FLAGS
+ {
+ SLGP_SHORTPATH = 0x1,
+ SLGP_UNCPRIORITY = 0x2,
+ SLGP_RAWPATH = 0x4
+ }
+
+ [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
+ public struct WIN32_FIND_DATAW
+ {
+ public uint dwFileAttributes;
+ public long ftCreationTime;
+ public long ftLastAccessTime;
+ public long ftLastWriteTime;
+ public uint nFileSizeHigh;
+ public uint nFileSizeLow;
+ public uint dwReserved0;
+ public uint dwReserved1;
+ [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
+ public string cFileName;
+ [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 14)]
+ public string cAlternateFileName;
+ }
+
+ [Flags()]
+ public enum SLR_FLAGS
+ {
+ SLR_NO_UI = 0x1,
+ SLR_ANY_MATCH = 0x2,
+ SLR_UPDATE = 0x4,
+ SLR_NOUPDATE = 0x8,
+ SLR_NOSEARCH = 0x10,
+ SLR_NOTRACK = 0x20,
+ SLR_NOLINKINFO = 0x40,
+ SLR_INVOKE_MSI = 0x80
+ }
+
+
+ // Reference : http://www.pinvoke.net/default.aspx/Interfaces.IShellLinkW
+ /// The IShellLink interface allows Shell links to be created, modified, and resolved
+ [ComImport(), InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("000214F9-0000-0000-C000-000000000046")]
+ interface IShellLinkW
+ {
+ /// Retrieves the path and file name of a Shell link object
+ void GetPath([Out(), MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszFile, int cchMaxPath, ref WIN32_FIND_DATAW pfd, SLGP_FLAGS fFlags);
+ /// Retrieves the list of item identifiers for a Shell link object
+ void GetIDList(out IntPtr ppidl);
+ /// Sets the pointer to an item identifier list (PIDL) for a Shell link object.
+ void SetIDList(IntPtr pidl);
+ /// Retrieves the description string for a Shell link object
+ void GetDescription([Out(), MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszName, int cchMaxName);
+ /// Sets the description for a Shell link object. The description can be any application-defined string
+ void SetDescription([MarshalAs(UnmanagedType.LPWStr)] string pszName);
+ /// Retrieves the name of the working directory for a Shell link object
+ void GetWorkingDirectory([Out(), MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszDir, int cchMaxPath);
+ /// Sets the name of the working directory for a Shell link object
+ void SetWorkingDirectory([MarshalAs(UnmanagedType.LPWStr)] string pszDir);
+ /// Retrieves the command-line arguments associated with a Shell link object
+ void GetArguments([Out(), MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszArgs, int cchMaxPath);
+ /// Sets the command-line arguments for a Shell link object
+ void SetArguments([MarshalAs(UnmanagedType.LPWStr)] string pszArgs);
+ /// Retrieves the hot key for a Shell link object
+ void GetHotkey(out short pwHotkey);
+ /// Sets a hot key for a Shell link object
+ void SetHotkey(short wHotkey);
+ /// Retrieves the show command for a Shell link object
+ void GetShowCmd(out int piShowCmd);
+ /// Sets the show command for a Shell link object. The show command sets the initial show state of the window.
+ void SetShowCmd(int iShowCmd);
+ /// Retrieves the location (path and index) of the icon for a Shell link object
+ void GetIconLocation([Out(), MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszIconPath,
+ int cchIconPath, out int piIcon);
+ /// Sets the location (path and index) of the icon for a Shell link object
+ void SetIconLocation([MarshalAs(UnmanagedType.LPWStr)] string pszIconPath, int iIcon);
+ /// Sets the relative path to the Shell link object
+ void SetRelativePath([MarshalAs(UnmanagedType.LPWStr)] string pszPathRel, int dwReserved);
+ /// Attempts to find the target of a Shell link, even if it has been moved or renamed
+ void Resolve(ref Accessibility._RemotableHandle hwnd, SLR_FLAGS fFlags);
+ /// Sets the path and file name of a Shell link object
+ void SetPath([MarshalAs(UnmanagedType.LPWStr)] string pszFile);
+ }
+
+ [ComImport(), Guid("00021401-0000-0000-C000-000000000046")]
+ public class ShellLink
+ {
+ }
+
+ // To initialize the app description
+ public String description = String.Empty;
+
+
+ // Retrieve the target path using Shell Link
+ public string retrieveTargetPath(string path)
+ {
+ var link = new ShellLink();
+ const int STGM_READ = 0;
+ ((IPersistFile)link).Load(path, STGM_READ);
+ var hwnd = new _RemotableHandle();
+ ((IShellLinkW)link).Resolve(ref hwnd, 0);
+
+ const int MAX_PATH = 260;
+ StringBuilder buffer = new StringBuilder(MAX_PATH);
+
+ var data = new WIN32_FIND_DATAW();
+ ((IShellLinkW)link).GetPath(buffer, buffer.Capacity, ref data, SLGP_FLAGS.SLGP_SHORTPATH);
+ var target = buffer.ToString();
+
+ // To set the app description
+ if (!String.IsNullOrEmpty(target))
+ {
+ buffer = new StringBuilder(MAX_PATH);
+ ((IShellLinkW)link).GetDescription(buffer, MAX_PATH);
+ description = buffer.ToString();
+ }
+ return target;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs b/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs
index b8633f357..173cedd8d 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs
@@ -13,7 +13,6 @@ using System.Xml.Linq;
using Windows.ApplicationModel;
using Windows.Management.Deployment;
using AppxPackaing;
-using Shell;
using Flow.Launcher.Infrastructure;
using Flow.Launcher.Plugin.Program.Logger;
using IStream = AppxPackaing.IStream;
@@ -337,10 +336,10 @@ namespace Flow.Launcher.Plugin.Program.Programs
private async void Launch(IPublicAPI api)
{
- var appManager = new ApplicationActivationManager();
+ var appManager = new ApplicationActivationHelper.ApplicationActivationManager();
uint unusedPid;
const string noArgs = "";
- const ACTIVATEOPTIONS noFlags = ACTIVATEOPTIONS.AO_NONE;
+ const ApplicationActivationHelper.ActivateOptions noFlags = ApplicationActivationHelper.ActivateOptions.None;
await Task.Run(() =>
{
try
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Programs/Win32.cs b/Plugins/Flow.Launcher.Plugin.Program/Programs/Win32.cs
index cdea767f3..3b1da3abd 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Programs/Win32.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Programs/Win32.cs
@@ -8,13 +8,14 @@ using System.Security;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Win32;
-using Shell;
-using Flow.Launcher.Infrastructure;
-using Flow.Launcher.Plugin.Program.Logger;
-using Flow.Launcher.Plugin.SharedCommands;
+using Wox.Infrastructure;
+using Microsoft.Plugin.Program.Logger;
+using Wox.Plugin;
+using System.Reflection;
-namespace Flow.Launcher.Plugin.Program.Programs
+namespace Microsoft.Plugin.Program.Programs
{
+
[Serializable]
public class Win32 : IProgram
{
@@ -190,27 +191,21 @@ namespace Flow.Launcher.Plugin.Program.Programs
var program = Win32Program(path);
try
{
- var link = new ShellLink();
- const uint STGM_READ = 0;
- ((IPersistFile)link).Load(path, STGM_READ);
- var hwnd = new _RemotableHandle();
- link.Resolve(ref hwnd, 0);
-
const int MAX_PATH = 260;
StringBuilder buffer = new StringBuilder(MAX_PATH);
+ ShellLinkHelper _helper = new ShellLinkHelper();
+ string target = _helper.retrieveTargetPath(path);
- var data = new _WIN32_FIND_DATAW();
- const uint SLGP_SHORTPATH = 1;
- link.GetPath(buffer, buffer.Capacity, ref data, SLGP_SHORTPATH);
- var target = buffer.ToString();
if (!string.IsNullOrEmpty(target))
{
var extension = Extension(target);
if (extension == ExeExtension && File.Exists(target))
{
- buffer = new StringBuilder(MAX_PATH);
- link.GetDescription(buffer, MAX_PATH);
- var description = buffer.ToString();
+ program.LnkResolvedPath = program.FullPath;
+ program.FullPath = Path.GetFullPath(target).ToLower();
+ program.ExecutableName = Path.GetFileName(target);
+
+ var description = _helper.description;
if (!string.IsNullOrEmpty(description))
{
program.Description = description;
@@ -276,6 +271,7 @@ namespace Flow.Launcher.Plugin.Program.Programs
var files = new List();
var folderQueue = new Queue();
folderQueue.Enqueue(directory);
+
do
{
var currentDirectory = folderQueue.Dequeue();
diff --git a/Plugins/Flow.Launcher.Plugin.Program/ShObjIdlTlb.dll b/Plugins/Flow.Launcher.Plugin.Program/ShObjIdlTlb.dll
deleted file mode 100644
index 83815e40a..000000000
Binary files a/Plugins/Flow.Launcher.Plugin.Program/ShObjIdlTlb.dll and /dev/null differ
diff --git a/installer/PowerToysSetup/Product.wxs b/installer/PowerToysSetup/Product.wxs
new file mode 100644
index 000000000..868acfbf1
--- /dev/null
+++ b/installer/PowerToysSetup/Product.wxs
@@ -0,0 +1,937 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ = 17134)]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ NOT Installed
+ 1
+ NOT Installed
+ NOT Installed
+ Installed AND _REMOVE_ALL="Yes"
+ Installed AND _REMOVE_ALL="Yes"
+ Installed AND NOT (_REMOVE_ALL="Yes")
+ Installed AND NOT (_REMOVE_ALL="Yes")
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ NOT Installed and CREATESCHEDULEDTASK = 1
+
+
+
+
+ NOT Installed
+
+
+ Installed and (NOT UPGRADINGPRODUCTCODE) AND (REMOVE="ALL")
+
+
+
+ NOT Installed
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ EXISTINGPOWERRENAMEEXTPATH OR EXISTINGIMAGERESIZERPATH
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ INSTALLDESKTOPSHORTCUT
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+