ResultHelper.cs
  1  // Copyright (c) Microsoft Corporation
  2  // The Microsoft Corporation licenses this file to you under the MIT license.
  3  // See the LICENSE file in the project root for more information.
  4  using System;
  5  using System.Collections.Generic;
  6  using System.Linq;
  7  
  8  using Microsoft.Plugin.WindowWalker.Properties;
  9  using Wox.Infrastructure;
 10  using Wox.Plugin;
 11  
 12  namespace Microsoft.Plugin.WindowWalker.Components
 13  {
 14      /// <summary>
 15      /// Helper class to work with results
 16      /// </summary>
 17      internal static class ResultHelper
 18      {
 19          /// <summary>
 20          /// Returns a list of all results for the query.
 21          /// </summary>
 22          /// <param name="searchControllerResults">List with all search controller matches</param>
 23          /// <param name="icon">The path to the result icon</param>
 24          /// <returns>List of results</returns>
 25          internal static List<Result> GetResultList(List<SearchResult> searchControllerResults, bool isKeywordSearch, string icon, string infoIcon)
 26          {
 27              if (searchControllerResults == null || searchControllerResults.Count == 0)
 28              {
 29                  return new List<Result>();
 30              }
 31  
 32              List<Result> resultsList = new List<Result>(searchControllerResults.Count);
 33              bool addExplorerInfo = searchControllerResults.Any(x =>
 34                  string.Equals(x.Result.Process.Name, "explorer.exe", StringComparison.OrdinalIgnoreCase) &&
 35                  x.Result.Process.IsShellProcess);
 36  
 37              // Process each SearchResult to convert it into a Result.
 38              // Using parallel processing if the operation is CPU-bound and the list is large.
 39              resultsList = searchControllerResults
 40                  .AsParallel()
 41                  .Select(x => CreateResultFromSearchResult(x, icon))
 42                  .ToList();
 43  
 44              if (addExplorerInfo && isKeywordSearch && !WindowWalkerSettings.Instance.HideExplorerSettingInfo)
 45              {
 46                  resultsList.Add(GetExplorerInfoResult(infoIcon));
 47              }
 48  
 49              return resultsList;
 50          }
 51  
 52          /// <summary>
 53          /// Creates a Result object from a given SearchResult.
 54          /// </summary>
 55          /// <param name="searchResult">The SearchResult object to convert.</param>
 56          /// <param name="icon">The path to the icon that should be used for the Result.</param>
 57          /// <returns>A Result object populated with data from the SearchResult.</returns>
 58          private static Result CreateResultFromSearchResult(SearchResult searchResult, string icon)
 59          {
 60              return new Result
 61              {
 62                  Title = searchResult.Result.Title,
 63                  IcoPath = icon,
 64                  SubTitle = GetSubtitle(searchResult.Result),
 65                  ContextData = searchResult.Result,
 66                  Action = c =>
 67                  {
 68                      searchResult.Result.SwitchToWindow();
 69                      return true;
 70                  },
 71                  Score = searchResult.Score,
 72  
 73                  // For debugging you can set the second parameter to true to see more information.
 74                  ToolTipData = GetToolTip(searchResult.Result, false),
 75              };
 76          }
 77  
 78          /// <summary>
 79          /// Returns the subtitle for a result
 80          /// </summary>
 81          /// <param name="window">The window properties of the result</param>
 82          /// <returns>String with the subtitle</returns>
 83          private static string GetSubtitle(Window window)
 84          {
 85              if (window == null || !(window is Window))
 86              {
 87                  return string.Empty;
 88              }
 89  
 90              string subtitleText = Resources.wox_plugin_windowwalker_Running + ": " + window.Process.Name;
 91  
 92              if (WindowWalkerSettings.Instance.SubtitleShowPid)
 93              {
 94                  subtitleText += $" ({window.Process.ProcessID})";
 95              }
 96  
 97              if (!window.Process.IsResponding)
 98              {
 99                  subtitleText += $" [{Resources.wox_plugin_windowwalker_NotResponding}]";
100              }
101  
102              if (WindowWalkerSettings.Instance.SubtitleShowDesktopName && Main.VirtualDesktopHelperInstance.GetDesktopCount() > 1)
103              {
104                  subtitleText += $" - {Resources.wox_plugin_windowwalker_Desktop}: {window.Desktop.Name}";
105              }
106  
107              return subtitleText;
108          }
109  
110          /// <summary>
111          /// Returns the tool tip for a result
112          /// </summary>
113          /// <param name="window">The window properties of the result</param>
114          /// <param name="debugToolTip">Value indicating if a detailed debug tooltip should be returned</param>
115          /// <returns>Tooltip for the result or null of failure</returns>
116          private static ToolTipData GetToolTip(Window window, bool debugToolTip)
117          {
118              if (window == null || !(window is Window))
119              {
120                  return null;
121              }
122  
123              if (!debugToolTip)
124              {
125                  string text = $"{Resources.wox_plugin_windowwalker_Process}: {window.Process.Name}";
126                  text += $"\n{Resources.wox_plugin_windowwalker_ProcessId}: {window.Process.ProcessID}";
127  
128                  if (Main.VirtualDesktopHelperInstance.GetDesktopCount() > 1)
129                  {
130                      text += $"\n{Resources.wox_plugin_windowwalker_Desktop}: {window.Desktop.Name}";
131  
132                      if (!window.Desktop.IsAllDesktopsView)
133                      {
134                          text += $" ({Resources.wox_plugin_windowwalker_Number} {window.Desktop.Number})";
135                      }
136                  }
137  
138                  return new ToolTipData(window.Title, text);
139              }
140              else
141              {
142                  string text = $"hWnd: {window.Hwnd}\n" +
143                      $"Window class: {window.ClassName}\n" +
144                      $"Process ID: {window.Process.ProcessID}\n" +
145                      $"Thread ID: {window.Process.ThreadID}\n" +
146                      $"Process: {window.Process.Name}\n" +
147                      $"Process exists: {window.Process.DoesExist}\n" +
148                      $"Is full access denied: {window.Process.IsFullAccessDenied}\n" +
149                      $"Is uwp app: {window.Process.IsUwpApp}\n" +
150                      $"Is ShellProcess: {window.Process.IsShellProcess}\n" +
151                      $"Is window cloaked: {window.IsCloaked}\n" +
152                      $"Window cloak state: {window.GetWindowCloakState()}\n" +
153                      $"Desktop id: {window.Desktop.Id}\n" +
154                      $"Desktop name: {window.Desktop.Name}\n" +
155                      $"Desktop number: {window.Desktop.Number}\n" +
156                      $"Desktop is visible: {window.Desktop.IsVisible}\n" +
157                      $"Desktop position: {window.Desktop.Position}\n" +
158                      $"Is AllDesktops view: {window.Desktop.IsAllDesktopsView}\n" +
159                      $"Responding: {window.Process.IsResponding}";
160  
161                  return new ToolTipData(window.Title, text);
162              }
163          }
164  
165          /// <summary>
166          /// Returns an information result about the explorer setting
167          /// </summary>
168          /// <param name="iIcon">The path to the info icon.</param>
169          /// <returns>An object of the type <see cref="Result"/> with the information.</returns>
170          private static Result GetExplorerInfoResult(string iIcon)
171          {
172              return new Result()
173              {
174                  Title = Resources.wox_plugin_windowwalker_ExplorerInfoTitle,
175                  IcoPath = iIcon,
176                  SubTitle = Resources.wox_plugin_windowwalker_ExplorerInfoSubTitle,
177                  Action = c =>
178                  {
179                      Helper.OpenInShell("rundll32.exe", "shell32.dll,Options_RunDLL 7"); // "shell32.dll,Options_RunDLL 7" opens the view tab in folder options of explorer.
180                      return true;
181                  },
182                  Score = 100_000,
183              };
184          }
185      }
186  }