nsIWindowsShellService.idl (16877B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 #include "imgIContainer.idl" 6 #include "nsIShellService.idl" 7 8 interface nsIFile; 9 10 [scriptable, uuid(fb9b59db-5a91-4e67-92b6-35e7d6e6d3fd)] 11 interface nsIWindowsShellService : nsIShellService 12 { 13 /* 14 * Creates a new shortcut (.lnk) file. This shortcut will be recorded in 15 * a new shortcuts log file located in %PROGRAMDATA%\Mozilla-1de4eec8-1241-4177-a864-e594e8d1fb38 16 * that is named after the currently running application and current user, eg: 17 * Firefox_user123_shortcuts.ini. 18 * 19 * For reasons that we haven't been able to pin down, these shortcuts get created with 20 * extra metadata on them (KnownFolderDataBlock, SpecialFolderDataBlock) that cause 21 * the Windows ShellLink classes to improperly read their target path with certain 22 * parameters. This causes any 32-bit programs that read the links (such as our 23 * installer and uninstaller) to think that 64-bit installs are located in the 32-bit 24 * Program Files directory. 25 * See https://social.msdn.microsoft.com/Forums/windowsdesktop/en-US/6f2e7920-50a9-459d-bfdd-316e459e87c0/ishelllink-getpath-returns-wrong-folder-for-64-bit-application-when-called-from-32-bit-application 26 * for some additional discussion of this. 27 * 28 * @param aBinary Target file of the shortcut. 29 * @param aArguments Arguments to set for the shortcut. May be empty. 30 * @param aDescription The description of the shortcut. The string used here 31 * shows up as the hover text of the shortcut in Explorer and on the 32 * Taskbar (if the shortcut is pinned there). 33 * @param aIconFile The file containing the desired icon for the shortcut. This 34 * can be the same file as aBinary. 35 * @param aIconIndex The index of the in aIconFile. Note that this is 0 based index 36 * that IShellLinkW requires, _not_ a Resource ID that is sometimes used 37 * for icons. 38 * @param aAppUserModelId The App User Model ID to set for the shortcut. This will 39 * affect which icon on the Taskbar the application groups with when first 40 * launched. 41 * @param aShortcutFolder The special Windows folder to create the shortcut in. Must be 42 * either "Programs" or "Desktop". 43 * @param aShortcutRelativePath The relative path of the shortcut from the shortcut 44 * folder. 45 * @return The full native path to the created shortcut. 46 * 47 * @throws NS_ERROR_INVALID_ARG if an invalid shortcut folder is passed 48 * @throws NS_ERROR_FILE_NOT_FOUND if the shortcut file or shortcuts log cannot be 49 * created or accessed 50 * @throws NS_ERROR_FAILURE for other types of failures 51 */ 52 [implicit_jscontext] 53 Promise createShortcut(in nsIFile aBinary, in Array<AString> aArguments, 54 in AString aDescription, in nsIFile aIconFile, in unsigned short aIconIndex, 55 in AString aAppUserModelId, in AString aShortcutFolder, 56 in AString aShortcutRelativePath); 57 58 /* 59 * Deletes the provided shortcut path relative to the shortcut folder, and removes it 60 * from the uninstaller's log file. 61 * 62 * @param aShortcutFolder The special Windows folder to create the shortcut in. 63 * Should be either Desktop or StartMenu. 64 * @param aShortcutRelativePath The relative path to the shortcut file from the folder. 65 * 66 * @throws NS_ERROR_INVALID_ARG if an invalid shortcut folder is passed 67 */ 68 [implicit_jscontext] 69 Promise deleteShortcut(in AString aShortcutFolder, in AString aShortcutRelativePath); 70 71 /* 72 * Searches the %USERPROFILE%\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup 73 * folder and returns an array with the path of all shortcuts with a target matching the 74 * current Firefox install location. The AUMID isn't required here as we are only looking 75 * for the currently running binary, whether that's firefox.exe or the private browsing 76 * proxy executable. 77 * 78 * It is possible to return an empty array if no shortcuts are found. 79 * 80 * @return An array of paths for all launch on login shortcuts.s 81 * 82 * @throws NS_ERROR_ABORT 83 * if instance cannot be created. 84 * @throws NS_ERROR_FILE_NOT_FOUND 85 * if %USERPROFILE%\AppData\Roaming\ cannot be opened. 86 * @throws NS_ERROR_FAILURE 87 * if the executable file cannot be found. 88 * @throws NS_ERROR_FILE_UNRECOGNIZED_PATH 89 * if the executable file cannot be converted into a string. 90 */ 91 92 Array<AString> getLaunchOnLoginShortcuts(); 93 94 /* 95 * Pins the current application to the Windows Start Menu 96 * 97 * The APIs used within this function are MSIX only and 98 * will also not work on MINGW. 99 * 100 * @param aCheckOnly If only testing whether pinning is possible 101 * 102 * @return True if the application was successfully pinned 103 * to the Start Menu. 104 * 105 * @throws NS_ERROR_NOT_AVAILABLE 106 * If used on a non-MSIX build 107 * @throws NS_ERROR_NOT_IMPLEMENTED 108 * If used on a MinGW build 109 * @throws NS_ERROR_NOT_SAME_THREAD 110 * If called off main thread 111 * @throws NS_ERROR_FAILURE 112 * For Windows API failures 113 */ 114 [implicit_jscontext] 115 Promise pinCurrentAppToStartMenuAsync(in boolean aCheckOnly); 116 117 /* 118 * Whether the current app is among Windows Start Menu pins 119 * 120 * @return True if pinned, false otherwise 121 * 122 * The APIs used within this function are MSIX only and 123 * will also not work on MINGW. 124 * 125 * @throws NS_ERROR_NOT_AVAILABLE 126 * If used on a non-MSIX build 127 * @throws NS_ERROR_NOT_IMPLEMENTED 128 * If used on a MinGW build 129 * @throws NS_ERROR_NOT_SAME_THREAD 130 * If called off main thread 131 * @throws NS_ERROR_FAILURE 132 * For Windows API failures 133 */ 134 [implicit_jscontext] 135 Promise isCurrentAppPinnedToStartMenuAsync(); 136 137 /* 138 * Disables the startup task corresponding to the provided taskId 139 * to launch upon OS login. The startup task is declared 140 * within the App Manifest. 141 * 142 * If the task was previously disabled by the user this function 143 * will not re-enable it. 144 * 145 * The APIs used within this function are MSIX only and 146 * will also not work on MINGW. 147 * 148 * @param aTaskId Target taskId to enable 149 * 150 * @return True if the application was successfully set up to 151 * launch on OS login. 152 * 153 * @throws NS_ERROR_NOT_AVAILABLE 154 * If used on a non-MSIX build 155 * @throws NS_ERROR_NOT_IMPLEMENTED 156 * If used on a MinGW build 157 * @throws NS_ERROR_NOT_SAME_THREAD 158 * If called off main thread 159 * @throws NS_ERROR_FAILURE 160 * For other types of failures 161 */ 162 [implicit_jscontext] 163 Promise enableLaunchOnLoginMSIXAsync(in AString aTaskId); 164 165 /* 166 * Disables the startup task corresponding to the provided taskId 167 * to launch upon OS login. The startup task is declared 168 * within the App Manifest. 169 * 170 * The APIs used within this function are MSIX only and 171 * will also not work on MINGW. 172 * 173 * @param aTaskId Target taskId to disable 174 * 175 * @return True if the application was successfully disabled from 176 * launching on OS login. 177 * 178 * @throws NS_ERROR_NOT_AVAILABLE 179 * If used on a non-MSIX build 180 * @throws NS_ERROR_NOT_IMPLEMENTED 181 * If used on a MinGW build 182 * @throws NS_ERROR_NOT_SAME_THREAD 183 * If called off main thread 184 * @throws NS_ERROR_FAILURE 185 * For other types of failures 186 */ 187 [implicit_jscontext] 188 Promise disableLaunchOnLoginMSIXAsync(in AString aTaskId); 189 190 /* 191 * Determines if the startup task corresponding to the provided taskId to 192 * launch upon OS login is enabled. The startup task is declared 193 * within the App Manifest. The APIs used within this function are MSIX 194 * only and will also not work on MINGW. 195 * 196 * If the user has disabled the application from launching on login, it 197 * cannot be re-enabled by the application. 198 * 199 * @param aTaskId Target taskId to check status of 200 * 201 * @return 0/1/2/3 if the application's OS launch on login is 202 disabled in settings / disabled / enabled / enabled by policy 203 * 204 * @throws NS_ERROR_NOT_AVAILABLE 205 * If used on a non-MSIX build 206 * @throws NS_ERROR_NOT_IMPLEMENTED 207 * If used on a MinGW build 208 * @throws NS_ERROR_NOT_SAME_THREAD 209 * If called off main thread 210 * @throws NS_ERROR_FAILURE 211 * For other types of failures 212 */ 213 214 cenum LaunchOnLoginEnabledEnumerator : 8 { 215 LAUNCH_ON_LOGIN_DISABLED_BY_SETTINGS = 0, 216 LAUNCH_ON_LOGIN_DISABLED = 1, 217 LAUNCH_ON_LOGIN_ENABLED = 2, 218 LAUNCH_ON_LOGIN_ENABLED_BY_POLICY = 3, 219 }; 220 221 [implicit_jscontext] 222 Promise getLaunchOnLoginEnabledMSIXAsync(in AString aTaskId); 223 224 /* 225 * Pin the current app to the taskbar. If aPrivateBrowsing is true, the 226 * Private Browsing version of the app (with a different icon and launch 227 * arguments) will be pinned instead. 228 * 229 * This MUST only be used in response to an active request from the user. 230 * 231 * If it exists, uses an existing shortcut on the Desktop or Start Menu, 232 * which would have been created by the installer (for All Users or 233 * Current User). If none can be found, one will be created with the correct 234 * AUMID for proper launching and grouping. 235 * 236 * NOTE: It is possible for the shortcut match to fail even when a 237 * shortcut refers to the current executable, if the paths differ due 238 * to e.g. symlinks. This should be rare. 239 * 240 * This will definitely fail on an OS before Windows 10 build 1809 241 * (October 2018 Update). 242 * 243 * NOTE: Can only run on the main thread, but the actual work occurs on a 244 * background thread. 245 * 246 * @throws NS_ERROR_NOT_SAME_THREAD 247 * if called off main thread. 248 * @throws NS_ERROR_NOT_AVAILABLE 249 * if OS is not at least Windows 10 build 1809, or if creating the 250 * Taskband Pin object fails 251 * @throws NS_ERROR_FAILURE 252 * for unexpected errors 253 * 254 * @rejects NS_ERROR_FILE_NOT_FOUND 255 * if a shortcut matching this app's AUMID and exe path wasn't found 256 * 257 * @returns {Promise<void>} A promise that resolves to |undefined| if 258 * successful or rejects with an nserror. 259 */ 260 [implicit_jscontext] 261 Promise pinCurrentAppToTaskbarAsync(in boolean aPrivateBrowsing); 262 263 /* 264 * Do a dry run of pinCurrentAppToTaskbar(). 265 * 266 * NOTE: Can only be run on the main thread, but the actual work occurs on a 267 * background thread. 268 * 269 * This does all the same checks and setup, throws the same errors, but doesn't 270 * do the final step of creating the pin. 271 * 272 * @throws same as pinCurrentAppToTaskbarAsync() 273 * @rejects same as pinCurrentAppToTaskbarAsync() 274 * @returns same as pinCurrentAppToTaskbarAsync() 275 */ 276 [implicit_jscontext] 277 Promise checkPinCurrentAppToTaskbarAsync(in boolean aPrivateBrowsing); 278 279 /* 280 * Search for the current executable among taskbar pins 281 * 282 * NOTE: Can only be run on the main thread, but the actual work occurs on a 283 * background thread. 284 * 285 * NOTE: It is possible for the check to fail even when a taskbar pin refers 286 * to this executable, if the paths differ due to e.g. symlinks. 287 * It is also possible for the check to succeed with a shortcut that doesn't 288 * actually appear on the taskbar. 289 * These cases should be rare. 290 * 291 * @return Promise that always resolves, true if pinned, false otherwise 292 * @throws NS_ERROR_NOT_SAME_THREAD if not run on the main thread 293 * 294 */ 295 [implicit_jscontext] 296 Promise isCurrentAppPinnedToTaskbarAsync(in AString aumid); 297 298 /* 299 * Similar to createShortcut except it removes most of the checking in that 300 * function that ensures we are pinning a Firefox executable instead allowing 301 * any shortcut to be pinned. 302 * 303 * This function should not be called unless it is certain that it's 304 * necessary given how few checks there are within. 305 * @param aAppUserModelId 306 * The aumid to be contained in the .lnk file 307 * @param aShortcutFolder The special Windows folder to create the shortcut 308 * in. Must be either "Programs" or "Desktop". 309 * @param aShortcutRelativePath 310 * The path to the .lnk file that should be pinned to the taskbar, 311 * relative to aShortcutFolder. 312 */ 313 [implicit_jscontext] 314 Promise pinShortcutToTaskbar( 315 in AString aAppUserModelId, 316 in AString aShortcutFolder, 317 in AString aShortcutRelativePath 318 ); 319 320 /* This function can be used to convert compatible image formats into .ico 321 * files to be used for .lnk files (see createShortcut). 322 * 323 * @param aFile 324 * Output file to be written 325 * @param aContainer 326 * The graphics container 327 */ 328 [implicit_jscontext] 329 Promise createWindowsIcon( 330 in nsIFile aFile, 331 in imgIContainer aContainer 332 ); 333 334 /* 335 * This function is a counterpart to pinShortcutToTaskbar and allows 336 * the unpinning of any shortcut, including non-Firefox executables, 337 * without the checks of createShortcut. 338 * 339 * This function should not be called unless it is certain that it's 340 * necessary given how few checks there are within. 341 * @param aShortcutFolder The special Windows folder that the shortcut 342 * is in. Must be either "Programs" or "Desktop". 343 * @param aShortcutRelativePath 344 * The path to the .lnk file that should be unpinned, relative 345 * to aShortcutFolder. 346 * @throws NS_ERROR_FAILURE 347 * If the COM service could not be initialized 348 * @throws NS_ERROR_FILE_NOT_FOUND 349 * If aShortcutPath cannot be found 350 * @throws NS_ERROR_NOT_AVAILABLE 351 * If the taskbar pinning service cannot be initialized 352 * @throws NS_ERROR_FILE_ACCESS_DENIED 353 * If the taskbar pins cannot be modified 354 */ 355 void unpinShortcutFromTaskbar( 356 in AString aShortcutFolder, 357 in AString aShortcutRelativePath 358 ); 359 360 /* 361 * Determine where a given shortcut likely appears in the shell. 362 * 363 * Returns one of: 364 * - "StartMenu" or "StartMenuPrivate", Current User or All Users Start 365 * Menu, including pins 366 * - "Desktop" or "DesktopPrivate", Current User or All Users Desktop 367 * - "Taskbar" or "TaskbarPrivate", Taskbar Pins 368 * - "" otherwise 369 * 370 * If a Private Browsing shortcut was used to launch, the "Private" 371 * variant of one of the above entries will be returned. 372 * 373 * NOTE: This tries to avoid I/O, so paths are compared directly as 374 * strings, which may not be accurate in all cases. It is intended 375 * for noncritical telemetry use. 376 */ 377 AString classifyShortcut(in AString aPath); 378 379 /* 380 * Determine whether a pinnable shortcut with matching AUMID is present. 381 * 382 * @param aAUMID 383 * AUMID of the shortcut to find. 384 * @param aPrivateBrowsing 385 * `true` to have the private browsing suffix added to `aAUMID`. 386 * 387 * @returns {Promise<void>} Always resolves with boolean, true if a pinnable 388 * shortcut exists. 389 */ 390 [implicit_jscontext] 391 Promise hasPinnableShortcut(in AString aAUMID, in boolean aPrivateBrowsing); 392 393 /* 394 * Check if setDefaultBrowserUserChoice() is expected to succeed. 395 * 396 * This checks the ProgIDs for this installation, and the hash of the existing 397 * UserChoice association. 398 * 399 * @return true if the check succeeds, false otherwise. 400 */ 401 boolean canSetDefaultBrowserUserChoice(); 402 403 /* 404 * checkAllProgIDsExist() and checkBrowserUserChoiceHashes() are components 405 * of canSetDefaultBrowserUserChoice(), broken out for telemetry purposes. 406 * 407 * @return true if the check succeeds, false otherwise. 408 */ 409 boolean checkAllProgIDsExist(); 410 boolean checkBrowserUserChoiceHashes(); 411 412 /* 413 * Retrieves the application-defined, explicit Application User Model ID 414 * for the current process. This function is only to be used on 415 * Windows for testing purposes 416 * 417 * @return string AUMID 418 * @throws NS_ERROR_FAILURE when the AUMID cannot be fetched 419 */ 420 AString checkCurrentProcessAUMIDForTesting(); 421 422 /* 423 * Determines whether or not Firefox is the "Default Handler", i.e., 424 * is registered to handle, the given file extension (like ".pdf") 425 * or protocol (like "https"). 426 */ 427 boolean isDefaultHandlerFor(in AString aFileExtensionOrProtocol); 428 429 430 /* 431 * Return the Windows ProgID currently registered to handle the gven 432 * file extension (like ".pdf") or protocol (like "https"). 433 * 434 * @return string ProgID, or "" when no association is registered. 435 * @throws NS_ERROR_FAILURE when the file extension or protocol 436 * cannot be determined. 437 */ 438 AString queryCurrentDefaultHandlerFor(in AString aFileExtensionOrProtocol); 439 };