Functions/GenXdev.Queries.Webbrowser/Open-StackOverflowQuery.ps1
################################################################################ <# .SYNOPSIS Opens Stack Overflow search queries in a web browser. .DESCRIPTION Opens one or more Stack Overflow search queries in a web browser with comprehensive browser and display configuration options. This function provides an advanced wrapper around Stack Overflow search functionality with extensive options for window positioning, browser selection, and behavior customization. Key features: - Multiple search query support with pipeline input - Smart browser detection and selection (Edge, Chrome, Firefox, all browsers) - Advanced window positioning (left, right, top, bottom, centered, fullscreen) - Multi-monitor support with automatic or manual monitor selection - Private/incognito browsing mode support - Application mode for distraction-free browsing - Language localization support for international search results - Extension and popup blocking options - Focus management and window manipulation - Keystroke automation to browser windows - URL return options for automation workflows The function automatically detects system capabilities and adjusts behavior accordingly. For browsers not installed on the system, operations are silently skipped without errors. .PARAMETER Queries The search queries to perform on Stack Overflow. Accepts pipeline input and supports multiple queries in a single operation. Each query is URL-encoded and submitted as a separate Stack Overflow search. .PARAMETER Language The language of the returned search results. Accepts a comprehensive list of languages and automatically sets the appropriate Accept-Language header for localized search results. .PARAMETER Monitor The monitor to display results on: - 0 = Primary monitor - -1 = Discard positioning (no window positioning) - -2 = Configured secondary monitor (uses $Global:DefaultSecondaryMonitor) - 1+ = Specific monitor number .PARAMETER Width The initial width of the browser window in pixels. When not specified, uses the monitor's working area width or half-width for side positioning. .PARAMETER Height The initial height of the browser window in pixels. When not specified, uses the monitor's working area height or half-height for top/bottom positioning. .PARAMETER X The initial X position of the browser window. When not specified, uses the monitor's left edge. Can be specified relative to the selected monitor. .PARAMETER Y The initial Y position of the browser window. When not specified, uses the monitor's top edge. Can be specified relative to the selected monitor. .PARAMETER AcceptLang Set the browser accept-lang http header. Overrides the Language parameter when both are specified. .PARAMETER KeysToSend Keystrokes to send to the browser window after opening. Uses the same format as the GenXdev.Windows\Send-Key cmdlet for automation scenarios. .PARAMETER Private Opens in incognito/private browsing mode. Uses InPrivate for Edge and incognito for Chrome. .PARAMETER Force Force enable debugging port, stopping existing browsers if needed. Useful when browser debugging features are required. .PARAMETER Edge Opens in Microsoft Edge browser specifically. .PARAMETER Chrome Opens in Google Chrome browser specifically. .PARAMETER Chromium Opens in Microsoft Edge or Google Chrome, depending on what the default browser is. Prefers Chromium-based browsers. .PARAMETER Firefox Opens in Firefox browser specifically. .PARAMETER All Opens in all registered modern browsers simultaneously. .PARAMETER FullScreen Opens in fullscreen mode using F11 key simulation. .PARAMETER Left Place browser window on the left side of the screen. .PARAMETER Right Place browser window on the right side of the screen. .PARAMETER Top Place browser window on the top side of the screen. .PARAMETER Bottom Place browser window on the bottom side of the screen. .PARAMETER Centered Place browser window in the center of the screen. .PARAMETER ApplicationMode Hide the browser controls for a distraction-free search experience. .PARAMETER NoBrowserExtensions Prevent loading of browser extensions during the search session. .PARAMETER DisablePopupBlocker Disable the popup blocker to allow search-related popups. .PARAMETER FocusWindow Focus the browser window after opening the search. .PARAMETER SetForeground Set the browser window to foreground after opening. .PARAMETER Maximize Maximize the window after positioning for full-screen search experience. .PARAMETER RestoreFocus Restore PowerShell window focus after opening the browser. .PARAMETER NewWindow Don't re-use existing browser window, instead, create a new one for each search query. .PARAMETER PassThru Returns a [System.Diagnostics.Process] object of the browser process for further automation or monitoring. .PARAMETER ReturnURL Don't open webbrowser, just return the formatted Stack Overflow search URL for the query without launching any browser. .PARAMETER ReturnOnlyURL After opening webbrowser, return the formatted Stack Overflow search URL. Useful for logging or further processing. .PARAMETER SendKeyEscape Escape control characters when sending keystrokes to the browser window. .PARAMETER SendKeyHoldKeyboardFocus Prevent returning keyboard focus to PowerShell after sending keystrokes to the browser window. .PARAMETER SendKeyUseShiftEnter Send Shift+Enter instead of regular Enter for line breaks when sending keystrokes to the browser. .PARAMETER SendKeyDelayMilliSeconds Delay between sending different key sequences in milliseconds. Useful for slower systems or complex automation scenarios. .EXAMPLE Open-StackOverflowQuery -Queries "powershell array" -Monitor 0 Opens a Stack Overflow search for "powershell array" on the primary monitor. .EXAMPLE qso "powershell array" -mon 0 Opens a Stack Overflow search using the alias with monitor positioning. .EXAMPLE "powershell", "array manipulation" | Open-StackOverflowQuery -Language "English" -Chrome Opens multiple Stack Overflow searches in Chrome with English language preference. .EXAMPLE Open-StackOverflowQuery -Queries "c# linq" -ReturnURL Returns the Stack Overflow search URL without opening a browser. #> ################################################################################ function Open-StackOverflowQuery { [CmdletBinding()] [Alias('qso')] param( ######################################################################## [Alias('q', 'Name', 'Text', 'Query')] [Parameter( Mandatory = $true, Position = 0, ValueFromRemainingArguments = $false, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true, HelpMessage = 'The search queries to perform on Stack Overflow' )] [string[]] $Queries, ######################################################################## [ValidateSet( 'Afrikaans', 'Akan', 'Albanian', 'Amharic', 'Arabic', 'Armenian', 'Azerbaijani', 'Basque', 'Belarusian', 'Bemba', 'Bengali', 'Bihari', 'Bork, bork, bork!', 'Bosnian', 'Breton', 'Bulgarian', 'Cambodian', 'Catalan', 'Cherokee', 'Chichewa', 'Chinese (Simplified)', 'Chinese (Traditional)', 'Corsican', 'Croatian', 'Czech', 'Danish', 'Dutch', 'Elmer Fudd', 'English', 'Esperanto', 'Estonian', 'Ewe', 'Faroese', 'Filipino', 'Finnish', 'French', 'Frisian', 'Ga', 'Galician', 'Georgian', 'German', 'Greek', 'Guarani', 'Gujarati', 'Hacker', 'Haitian Creole', 'Hausa', 'Hawaiian', 'Hebrew', 'Hindi', 'Hungarian', 'Icelandic', 'Igbo', 'Indonesian', 'Interlingua', 'Irish', 'Italian', 'Japanese', 'Javanese', 'Kannada', 'Kazakh', 'Kinyarwanda', 'Kirundi', 'Klingon', 'Kongo', 'Korean', 'Krio (Sierra Leone)', 'Kurdish', 'Kurdish (Soranî)', 'Kyrgyz', 'Laothian', 'Latin', 'Latvian', 'Lingala', 'Lithuanian', 'Lozi', 'Luganda', 'Luo', 'Macedonian', 'Malagasy', 'Malay', 'Malayalam', 'Maltese', 'Maori', 'Marathi', 'Mauritian Creole', 'Moldavian', 'Mongolian', 'Montenegrin', 'Nepali', 'Nigerian Pidgin', 'Northern Sotho', 'Norwegian', 'Norwegian (Nynorsk)', 'Occitan', 'Oriya', 'Oromo', 'Pashto', 'Persian', 'Pirate', 'Polish', 'Portuguese (Brazil)', 'Portuguese (Portugal)', 'Punjabi', 'Quechua', 'Romanian', 'Romansh', 'Runyakitara', 'Russian', 'Scots Gaelic', 'Serbian', 'Serbo-Croatian', 'Sesotho', 'Setswana', 'Seychellois Creole', 'Shona', 'Sindhi', 'Sinhalese', 'Slovak', 'Slovenian', 'Somali', 'Spanish', 'Spanish (Latin American)', 'Sundanese', 'Swahili', 'Swedish', 'Tajik', 'Tamil', 'Tatar', 'Telugu', 'Thai', 'Tigrinya', 'Tonga', 'Tshiluba', 'Tumbuka', 'Turkish', 'Turkmen', 'Twi', 'Uighur', 'Ukrainian', 'Urdu', 'Uzbek', 'Vietnamese', 'Welsh', 'Wolof', 'Xhosa', 'Yiddish', 'Yoruba', 'Zulu')] [parameter( Mandatory = $false, Position = 1, HelpMessage = ('The language of the returned search results for ' + 'localized Stack Overflow content') )] [string] $Language, ######################################################################## [Alias('m', 'mon')] [Parameter( Mandatory = $false, HelpMessage = ('The monitor to use, 0 = default, -1 is discard, ' + '-2 = Configured secondary monitor, defaults to -1, no positioning') )] [int] $Monitor = -1, ######################################################################## [Parameter( Mandatory = $false, HelpMessage = 'The initial width of the webbrowser window' )] [int] $Width = -1, ######################################################################## [Parameter( Mandatory = $false, HelpMessage = 'The initial height of the webbrowser window' )] [int] $Height = -1, ######################################################################## [Parameter( Mandatory = $false, HelpMessage = 'The initial X position of the webbrowser window' )] [int] $X = -999999, ######################################################################## [Parameter( Mandatory = $false, HelpMessage = 'The initial Y position of the webbrowser window' )] [int] $Y = -999999, ######################################################################## [Alias('lang', 'locale')] [Parameter( Mandatory = $false, HelpMessage = 'Set the browser accept-lang http header' )] [string] $AcceptLang, ######################################################################## [Parameter( Mandatory = $false, HelpMessage = ('Keystrokes to send to the Browser window, ' + 'see documentation for cmdlet GenXdev.Windows\Send-Key') )] [string[]] $KeysToSend, ######################################################################## [Parameter( Mandatory = $false, HelpMessage = 'Opens in incognito/private browsing mode' )] [Alias('incognito', 'inprivate')] [switch] $Private, ######################################################################## [Parameter( Mandatory = $false, HelpMessage = ('Force enable debugging port, stopping existing ' + 'browsers if needed') )] [switch] $Force, ######################################################################## [Alias('e')] [Parameter( Mandatory = $false, HelpMessage = 'Opens in Microsoft Edge' )] [switch] $Edge, ######################################################################## [Alias('ch')] [Parameter( Mandatory = $false, HelpMessage = 'Opens in Google Chrome' )] [switch] $Chrome, ######################################################################## [Alias('c')] [Parameter( Mandatory = $false, HelpMessage = ('Opens in Microsoft Edge or Google Chrome, ' + 'depending on what the default browser is') )] [switch] $Chromium, ######################################################################## [Alias('ff')] [Parameter( Mandatory = $false, HelpMessage = 'Opens in Firefox' )] [switch] $Firefox, ######################################################################## [Parameter( Mandatory = $false, HelpMessage = 'Opens in all registered modern browsers' )] [switch] $All, ######################################################################## [Alias('fs', 'f')] [Parameter( Mandatory = $false, HelpMessage = 'Opens in fullscreen mode' )] [switch] $FullScreen, ######################################################################## [Parameter( Mandatory = $false, HelpMessage = 'Place browser window on the left side of the screen' )] [switch] $Left, ######################################################################## [Parameter( Mandatory = $false, HelpMessage = 'Place browser window on the right side of the screen' )] [switch] $Right, ######################################################################## [Parameter( Mandatory = $false, HelpMessage = 'Place browser window on the top side of the screen' )] [switch] $Top, ######################################################################## [Parameter( Mandatory = $false, HelpMessage = 'Place browser window on the bottom side of the screen' )] [switch] $Bottom, ######################################################################## [Parameter( Mandatory = $false, HelpMessage = 'Place browser window in the center of the screen' )] [switch] $Centered, ######################################################################## [Alias('a', 'app', 'appmode')] [Parameter( Mandatory = $false, HelpMessage = 'Hide the browser controls' )] [switch] $ApplicationMode, ######################################################################## [Alias('de', 'ne', 'NoExtensions')] [Parameter( Mandatory = $false, HelpMessage = 'Prevent loading of browser extensions' )] [switch] $NoBrowserExtensions, ######################################################################## [Parameter( Mandatory = $false, HelpMessage = 'Disable the popup blocker' )] [Alias('allowpopups')] [switch] $DisablePopupBlocker, ######################################################################## [Parameter( Mandatory = $false, HelpMessage = 'Focus the browser window after opening' )] [Alias('fw','focus')] [switch] $FocusWindow, ######################################################################## [Parameter( Mandatory = $false, HelpMessage = 'Set the browser window to foreground after opening' )] [Alias('fg')] [switch] $SetForeground, ######################################################################## [Parameter( Mandatory = $false, HelpMessage = 'Maximize the window after positioning' )] [switch] $Maximize, ######################################################################## [Parameter( Mandatory = $false, HelpMessage = 'Restore PowerShell window focus' )] [Alias('rf', 'bg')] [switch] $RestoreFocus, ######################################################################## [Alias('nw', 'new')] [Parameter( Mandatory = $false, HelpMessage = ("Don't re-use existing browser window, instead, " + 'create a new one') )] [switch] $NewWindow, ######################################################################## [Parameter( Mandatory = $false, HelpMessage = ('Returns a [System.Diagnostics.Process] object of ' + 'the browserprocess') )] [Alias('pt')] [switch] $PassThru, ######################################################################## [parameter( Mandatory = $false, HelpMessage = "Don't open webbrowser, just return the url" )] [switch] $ReturnURL, ######################################################################## [parameter( Mandatory = $false, HelpMessage = 'After opening webbrowser, return the url' )] [switch] $ReturnOnlyURL, ######################################################################## [Parameter( Mandatory = $false, HelpMessage = 'Escape control characters when sending keys' )] [Alias('Escape')] [switch] $SendKeyEscape, ######################################################################## [Parameter( Mandatory = $false, HelpMessage = ('Prevent returning keyboard focus to PowerShell ' + 'after sending keys') )] [Alias('HoldKeyboardFocus')] [switch] $SendKeyHoldKeyboardFocus, ######################################################################## [Parameter( Mandatory = $false, HelpMessage = ('Send Shift+Enter instead of regular Enter for ' + 'line breaks') )] [Alias('UseShiftEnter')] [switch] $SendKeyUseShiftEnter, ######################################################################## [Parameter( Mandatory = $false, HelpMessage = ('Delay between sending different key sequences ' + 'in milliseconds') )] [Alias('DelayMilliSeconds')] [int] $SendKeyDelayMilliSeconds, ######################################################################## [Parameter( Mandatory = $false, HelpMessage = 'Removes the borders of the browser window.' )] [Alias('nb')] [switch] $NoBorders, ######################################################################## [Parameter( Mandatory = $false, HelpMessage = ('Use alternative settings stored in session for ' + 'Stack Overflow search preferences') )] [switch] $SessionOnly, ######################################################################## [Parameter( Mandatory = $false, HelpMessage = ('Clear alternative settings stored in session for ' + 'Stack Overflow search preferences') )] [switch] $ClearSession, ######################################################################## [Parameter( Mandatory = $false, HelpMessage = ('Store settings only in persistent preferences without ' + 'affecting session for Stack Overflow search') )] [Alias('FromPreferences')] [switch] $SkipSession, ######################################################################## [Parameter( Mandatory = $false, HelpMessage = 'Position browser window either fullscreen on different monitor than PowerShell, or side by side with PowerShell on the same monitor.' )] [Alias('sbs')] [switch] $SideBySide ######################################################################## ) begin { # copy identical parameter values from this function to open-webbrowser $invocationArguments = GenXdev.Helpers\Copy-IdenticalParamValues ` -BoundParameters $PSBoundParameters ` -FunctionName 'GenXdev.Webbrowser\Open-Webbrowser' ` -DefaultValues (Microsoft.PowerShell.Utility\Get-Variable ` -Scope Local ` -ErrorAction SilentlyContinue) # process language parameter if specified by user if (-not [string]::IsNullOrWhiteSpace($Language)) { # retrieve the language code from the language dictionary $code = (GenXdev.Helpers\Get-WebLanguageDictionary)[$Language] # set accept-lang header if not already explicitly specified if (-not $PSBoundParameters.ContainsKey('AcceptLang')) { $null = $invocationArguments.AcceptLang = $code } } } process { # process each search query provided by the user foreach ($query in $Queries) { # output verbose information about the query being processed Microsoft.PowerShell.Utility\Write-Verbose "Processing query: $query" # construct the complete stack overflow search url with encoded query $invocationArguments.'Url' = 'https://stackoverflow.com/search?q=' + [Uri]::EscapeUriString($query) # handle return url only scenario without opening browser if ($ReturnOnlyURL) { # return the constructed url directly to the output stream Microsoft.PowerShell.Utility\Write-Output ( $invocationArguments.Url ) # skip to next query without opening browser continue } # launch browser with the constructed search url GenXdev.Webbrowser\Open-Webbrowser @invocationArguments # return url if requested by user after opening browser if ($ReturnURL) { # output the constructed url to the output stream Microsoft.PowerShell.Utility\Write-Output ( $invocationArguments.Url ) } } } end { } } ################################################################################ |