Private/ApplicationRegistry.ps1
using module ./_EntryRegistry.psm1 [NoRunspaceAffinity()] class ApplicationRegistry : EntryRegistry { $sync = [System.Collections.Hashtable]::Synchronized(@{}) $registerEntryJob = $null [System.Collections.Generic.List[PowerShellRun.SelectorEntry]] GetEntries([String[]]$categories) { $entries = [System.Collections.Generic.List[PowerShellRun.SelectorEntry]]::new() if ($this.sync.applicationEntries -and ($categories -contains 'Application')) { $entries.AddRange($this.sync.applicationEntries) } if ($this.sync.executableEntries -and ($categories -contains 'Executable')) { $entries.AddRange($this.sync.executableEntries) } return $entries } [void] InitializeEntries([String[]]$categories) { if ($script:isWindows) { $this.StartRegisterEntriesWindows($categories) } elseif ($script:isMacOs) { $this.StartRegisterEntriesMacOs($categories) } } [void] StartRegisterEntriesWindows($categories) { $actionKeys = @( [PowerShellRun.ActionKey]::new($script:globalStore.firstActionKey, 'Launch App') [PowerShellRun.ActionKey]::new($script:globalStore.secondActionKey, 'Launch App as Admin') [PowerShellRun.ActionKey]::new($script:globalStore.thirdActionKey, 'Launch App with arguments') ) $callback = { $result = $args[0].Result $path, $name = $args[0].ArgumentList if ($result.KeyCombination -eq $script:globalStore.firstActionKey) { & $script:globalStore.invokeFile $path } elseif ($result.KeyCombination -eq $script:globalStore.secondActionKey) { Start-Process $path -Verb runAs } elseif ($result.KeyCombination -eq $script:globalStore.thirdActionKey) { $argumentList, $keyCombination = $script:globalStore.GetArgumentListFor($name) if ($null -ne $argumentList) { & $script:globalStore.invokeFile $path $argumentList } } } $this.registerEntryJob = Start-ThreadJob { param ($categories, $actionKeys, $callback, $sync) $applicationEntries = [System.Collections.Generic.List[PowerShellRun.SelectorEntry]]::new() $executableEntries = [System.Collections.Generic.List[PowerShellRun.SelectorEntry]]::new() if ($categories -contains 'Application') { # Start Menu shortcuts $startMenuFolders = @( "$env:userprofile\AppData\Roaming\Microsoft\Windows\Start Menu\Programs", 'C:\ProgramData\Microsoft\Windows\Start Menu\Programs' ) $shell = New-Object -ComObject WScript.Shell foreach ($folder in $startMenuFolders) { $links = Get-ChildItem $folder -Filter '*.lnk' -Recurse foreach ($link in $links) { $shortcut = $shell.CreateShortcut($link.FullName) $entry = [PowerShellRun.SelectorEntry]::new() $entry.Icon = '🚀' $entry.Name = $link.BaseName $entry.Description = $shortcut.Description $entry.Preview = $link.FullName $entry.ActionKeys = $actionKeys $entry.UserData = @{ ScriptBlock = $callback ArgumentList = $link.FullName, $entry.Name } $applicationEntries.Add($entry) } } # Store Apps $shell = New-Object -ComObject shell.application $appsFolder = $shell.NameSpace('shell:AppsFolder') foreach ($item in $appsFolder.Items()) { if (-not $item.Path.Contains('!')) { continue } $path = 'shell:AppsFolder\{0}' -f $item.Path $entry = [PowerShellRun.SelectorEntry]::new() $entry.Icon = '🪟' $entry.Name = $item.Name $entry.Preview = $path # Store Apps don't run as admin $entry.ActionKeys = $actionKeys[0], $actionKeys[2] $entry.UserData = @{ ScriptBlock = $callback ArgumentList = $path, $entry.Name } $applicationEntries.Add($entry) } } $sync.applicationEntries = $applicationEntries # Executables in Path if ($categories -contains 'Executable') { $apps = Get-Command -CommandType Application foreach ($app in $apps) { $entry = [PowerShellRun.SelectorEntry]::new() $entry.Icon = '🔧' $entry.Name = $app.Name $entry.Preview = $app | Select-Object -Property Version, Source | Out-String $entry.ActionKeys = $actionKeys $entry.UserData = @{ ScriptBlock = $callback ArgumentList = $app.Source, $entry.Name } $executableEntries.Add($entry) } } $sync.executableEntries = $executableEntries } -ArgumentList $categories, $actionKeys, $callback, $this.sync } [void] StartRegisterEntriesMacOs($categories) { $actionKeys = @( [PowerShellRun.ActionKey]::new($script:globalStore.firstActionKey, 'Launch App') [PowerShellRun.ActionKey]::new($script:globalStore.thirdActionKey, 'Launch App with arguments') ) $callback = { $result = $args[0].Result $fullName, $name = $args[0].ArgumentList if ($result.KeyCombination -eq $script:globalStore.firstActionKey) { & $script:globalStore.invokeFile $fullName } elseif ($result.KeyCombination -eq $script:globalStore.thirdActionKey) { $argumentList, $keyCombination = $script:globalStore.GetArgumentListFor($name) if ($null -ne $argumentList) { & $script:globalStore.invokeFile $fullName $argumentList } } } $this.registerEntryJob = Start-ThreadJob { param ($categories, $actionKeys, $callback, $sync) $applicationEntries = [System.Collections.Generic.List[PowerShellRun.SelectorEntry]]::new() $executableEntries = [System.Collections.Generic.List[PowerShellRun.SelectorEntry]]::new() if ($categories -contains 'Application' ) { $folders = @( '/Applications' '/Applications/Utilities' '/System/Applications' '/System/Applications/Utilities' '/System/Library/CoreServices/Applications' ) foreach ($folder in $folders) { $apps = Get-ChildItem $folder -Filter '*.app' foreach ($app in $apps) { $entry = [PowerShellRun.SelectorEntry]::new() $entry.Icon = '🚀' $entry.Name = [System.IO.Path]::GetFileNameWithoutExtension($app.BaseName) $entry.Preview = $app.FullName # Not sure how to pass aruments to apps so only supports Launch action key. $entry.ActionKeys = $actionKeys[0] $entry.UserData = @{ ScriptBlock = $callback ArgumentList = $app.FullName, $entry.Name } $applicationEntries.Add($entry) } } } $sync.applicationEntries = $applicationEntries # Executables in Path if ($categories -contains 'Executable') { $apps = Get-Command -CommandType Application foreach ($app in $apps) { $entry = [PowerShellRun.SelectorEntry]::new() $entry.Icon = '🔧' $entry.Name = $app.Name $entry.Preview = $app | Select-Object -Property Version, Source | Out-String $entry.ActionKeys = $actionKeys $entry.UserData = @{ ScriptBlock = $callback ArgumentList = $app.Source, $entry.Name } $executableEntries.Add($entry) } } $sync.executableEntries = $executableEntries } -ArgumentList $categories, $actionKeys, $callback, $this.sync } [bool] UpdateEntries() { if ($this.registerEntryJob) { Receive-Job $this.registerEntryJob -Wait | Out-Null $this.registerEntryJob | Remove-Job $this.registerEntryJob = $null return $true } return $false } } |