U-C-S / Hurl

Choose the browser on the click of a link
MIT License
279 stars 10 forks source link

Detect Arc Browser Automatically #100

Open U-C-S opened 6 months ago

rp1231 commented 6 months ago

Is there any way to add it manually currently?

rp1231 commented 6 months ago

Found that using this path works: "ExePath": "C:\\Users\\root\\AppData\\Local\\Microsoft\\WindowsApps\\Arc.exe" but it doesn't show the icon for the arc browser.

riotrah commented 5 months ago

I just downloaded an icon and configured it to that, but I realized that it doesn't actually open any links in Arc

rp1231 commented 5 months ago

Yep I found that out later as well...... It just adds the browser to hurl........ Will have to find out if some some command flag is required to actually open urls.

donaldguy commented 4 months ago

After intensely too long this evening digging into more details about windows stuff than I wanted to know,

I managed to put together a powershell script (masquerading as a batch script so that it can be treated directly as an exe) that does open urls in Arc (whether its open or not) from Hurl

<# :
start /min "" powershell -WindowStyle hidden -NoProfile -NoLogo -ExecutionPolicy Bypass -Command "&{ $env:IncomingURL = '%1' ; Get-Content %0 | powershell -Command - }"
exit /b
#>
#
$url = $env:IncomingURL

if ($url -eq $null ) {
    $url = "https://github.com"
}

# I believe this is likely to stay consistent, but if not replace this with e.g.
# $arc = (Get-AppxPackage -Name "").PackageFamilyName
$arc = "TheBrowserCompany.Arc_ttt1ap7aakyb4"

[Windows.System.Launcher,Windows.System,ContentType=WindowsRuntime] | Out-Null

$uri = [System.Uri]::new($url)
$opts = [Windows.System.LauncherOptions]::new()
$opts.TargetApplicationPackageFamilyName = $arc

# as from https://superuser.com/a/1293303
Add-Type -AssemblyName System.Runtime.WindowsRuntime
$asTaskGeneric = ([System.WindowsRuntimeSystemExtensions].GetMethods() | ? { $_.Name -eq 'AsTask' -and $_.GetParameters().Count -eq 1 -and $_.GetParameters()[0].ParameterType.Name -eq 'IAsyncOperation`1' })[0]
Function Await($WinRtTask, $ResultType) {
    $asTask = $asTaskGeneric.MakeGenericMethod($ResultType)
    $netTask = $asTask.Invoke($null, @($WinRtTask))
    $netTask.Wait(-1) | Out-Null
    $netTask.Result
}

Await ([Windows.System.Launcher]::LaunchUriAsync($uri, $opts)) ([System.Boolean])

saved as open_in_arc.cmd in (as an example) my Downloads folder, then configured in the UserSettings.json like:

"Browsers": [
    {
     "Name": "Arc",
     "ExePath": "C:\\Users\\donald\\Downloads\\open_in_arc.cmd",
     "CustomIconPath": "C:\\Program Files\\WindowsApps\\TheBrowserCompany.Arc_1.1.1.27314_x64__ttt1ap7aakyb4\\assets\\DesktopShortcut.ico"
    },
...

That icon setting is still fragile to break on upgrade, but I need to go to sleep now 😄

donaldguy commented 4 months ago

Given that most of that is just about making Powershell work with .NET, it would be ~as-easy/easier to offer this solution directly in Hurl itself, if @U-C-S is inclined to (optionally) support this LauchUri invocation [that Arc apparently requires, but presumably should also work with other browsers]

rp1231 commented 4 months ago

@donaldguy Thanks for this! Hope you can find the time to write the updated code for the fragile icon setting as well.

rp1231 commented 4 months ago

@donaldguy The script you posted doesn't seem to be working for me..... Meanwhile I've made a feature request with the arc browser team to allow passing of urls like all other browsers on windows.

donaldguy commented 4 months ago

Sorry its not working for you :( ; I am on the Dev Insiders release channel so its possible my windows is different enough, but idk

I'd say try copying and pasting through it in a powershell (< 7) terminal and see if it works there or produces any error messages (also/first try double clicking it to see if its just the hurl config thats messing up calling it)

you can also (remove the start /min "" and -WindowStyle hidden) put some pauses before and after the body to see if error messages are showing up when Hurl is calling it

good luck

rp1231 commented 4 months ago

@donaldguy By running it in the terminal, I found out that the problem is being caused by the space character in my file path. Would you have an idea as to how I can properly escape the space character? This is the full error message:

C:\Extra Programs\Settings Backup\Hurl>powershell -NoProfile -NoLogo -ExecutionPolicy Bypass -Command "&{ $env:IncomingURL = '' ; Get-Content "C:\Extra Programs\Settings Backup\Hurl\open_in_arc.cmd" | powershell -Command - }"
Get-Content : A positional parameter cannot be found that accepts argument 'Programs\Settings'.
At line:1 char:28
+ ... gURL = '' ; Get-Content C:\Extra Programs\Settings Backup\Hurl\open_i ...
+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (:) [Get-Content], ParameterBindingException
    + FullyQualifiedErrorId : PositionalParameterNotFound,Microsoft.PowerShell.Commands.GetContentCommand
donaldguy commented 4 months ago

Change the %0 to \"%0\" (or '%0')

I probably should have done that in the first place but I was getting some issues with quoting the url and it ending up like ""https://…"" and overgeneralized the cautiousness

donaldguy commented 4 months ago

Although it looks in that message like the path is already getting quoted as passed in...

You could try moving in to a batch variable

So like above the powershell invocation put set script=%0 and replace the %0 in the line with %script%

I know enough about quoting in various unix shells that I could definitely figure it out there, but less so Windows (at least while I'm writing this from iPhone)

rp1231 commented 4 months ago

@donaldguy That didn't work, Maybe I did it incorrectly idk. I would be great if you could give it a shot once you get access to a pc.

riotrah commented 4 months ago

@donaldguy thanks for digging into this!

donaldguy commented 4 months ago

@rp1231 my second suggestion, or at least the combination of the two, works;

So:

<# :
set script=%0
start /min "" powershell -WindowStyle hidden -NoProfile -NoLogo -ExecutionPolicy Bypass -Command "&{ $env:IncomingURL = '%1' ; Get-Content '%script%' | powershell -Command - }"
exit /b
#>
#
$url = $env:IncomingURL

if ($url -eq $null ) {
    $url = "https://github.com"
}

# I believe this is likely to stay consistent, but if not replace this with e.g.
# $arc = (Get-AppxPackage -Name "").PackageFamilyName
$arc = "TheBrowserCompany.Arc_ttt1ap7aakyb4"

[Windows.System.Launcher,Windows.System,ContentType=WindowsRuntime] | Out-Null

$uri = [System.Uri]::new($url)
$opts = [Windows.System.LauncherOptions]::new()
$opts.TargetApplicationPackageFamilyName = $arc

# as from https://superuser.com/a/1293303
Add-Type -AssemblyName System.Runtime.WindowsRuntime
$asTaskGeneric = ([System.WindowsRuntimeSystemExtensions].GetMethods() | ? { $_.Name -eq 'AsTask' -and $_.GetParameters().Count -eq 1 -and $_.GetParameters()[0].ParameterType.Name -eq 'IAsyncOperation`1' })[0]
Function Await($WinRtTask, $ResultType) {
    $asTask = $asTaskGeneric.MakeGenericMethod($ResultType)
    $netTask = $asTask.Invoke($null, @($WinRtTask))
    $netTask.Wait(-1) | Out-Null
    $netTask.Result
}

Await ([Windows.System.Launcher]::LaunchUriAsync($uri, $opts)) ([System.Boolean])

and (for you, based on your previous error message, and which I copied for testing)

 {
     "Name": "Arc",
     "ExePath": "C:\\Extra Programs\\Settings Backup\\Hurl\\open_in_arc.cmd",
     "CustomIconPath": "C:\\Program Files\\WindowsApps\\TheBrowserCompany.Arc_1.1.2.27976_x64__ttt1ap7aakyb4\\assets\\DesktopShortcut.ico"
 },
rp1231 commented 4 months ago

Thanks a lot! I'll try it out.

riotrah commented 4 months ago

What are those commented directive-looking things at the beginning?

rp1231 commented 4 months ago

@donaldguy Thanks it's working now. But it doesn't seem to be working for redirected links from gmail. for eg. links starting with https://www.google.com/url?q= I get this Screenshot 2024-05-16 132646 Would you have any idea on how to solve this?

donaldguy commented 4 months ago

What are those commented directive-looking things at the beginning?

That is boilerplate to re-invoke the same file as a powershell script after it is started as a batch (essentially DOS) script. (that part is, in fact, in a multi-line powershell comment, so powershell will skip over that part. The cmd.exe doesn’t read past that part because of the exit /b on line 3 or 4)

I am doing this this way for two reasons:

  1. While powershell is much more powerful, Windows does not have any handling for treating a powershell script like an exe (but will treat a batch script like one, as whatever else you can say about Microsft, they are pretty committed to API-level backwards compatibility).

    this isn’t strictly necessary, but the alternative is to make the ExePath point at powershell.exe and have a longer set of arguments passed along to invoke the script

  2. the binding from powershell to WindowsRT is broken in current Powershell 7 (with a possible workaround if you re-import the ~Windows SDK but I think it would also need to get downloaded from the packages manager as well). But it still works in Powershell 1, which is still kicking around System32 and is what you get if you ask for powershell from a batch script (or e.g. the Run dialogue)

EDIT: 3. the start /min “” (where that last empty string is a window title) is also apparently more reliable way to keep a shell window from popping up for a split-second when this call-out occurs. (On my machine I still can catch like a flicker of an outline, but it was definitely worse without it)

donaldguy commented 4 months ago

@rp1231 whats the actual URL getting loaded?

(i.e. how much is going missing / and upon including what character[s])

There may be some sort of raw string syntax or other way to more aggressively suppress escaping, but it would definitely help to know what actual inputs are fouling it how

rp1231 commented 4 months ago

@donaldguy For example if I click on 'view on github' from a gmail desktop app that I'm using, The url supposed to be sent to arc is:

https://www.google.com/url?q=https://github.com/U-C-S/Hurl/issues/100%23issuecomment-2114860468&source=gmail&ust=1715942426883000&usg=AOvVaw3eLhKs6cFp65NqvD8rXQxU

But what's opening in Arc is:

https://www.google.com/url?q
arsalan86 commented 3 months ago

@donaldguy For example if I click on 'view on github' from a gmail desktop app that I'm using, The url supposed to be sent to arc is:

https://www.google.com/url?q=https://github.com/U-C-S/Hurl/issues/100%23issuecomment-2114860468&source=gmail&ust=1715942426883000&usg=AOvVaw3eLhKs6cFp65NqvD8rXQxU

But what's opening in Arc is:

https://www.google.com/url?q

I have the same issue. Have you been able to find any fixes for this?

donaldguy commented 3 months ago

Honestly, I had fallen entirely out of the habit of waking/using my Windows PC at all (in favor of my macbook air taking over same peripherals at my desk) for almost the entirety of the interim (before, coincidentally this morning) [also I went

I'll try to glance at it (tomorrow maybe, no real promises);

if I had to guess its gonna either be broadly a quoting issue or powershell assigning some significance to either ? or = and/so those needing a \ injected in front (or the entire url wrapped or encoded in some more aggressive way)

really the right approach would likely just be to get this logic into hurl and/or bt and avoid this runaround entirely— I've never actually worked directly with .NET or C# though, so its not top of my todo list to write those PRs

donaldguy commented 3 months ago

also honestly, thats a slightly stupid thing for github gmail [I need to go to sleep] to actually be requesting anyway (and maybe it isn't, just showing you a preview that way)

those /s should be %2Fs at the very least

and so maybe thats part of it;

but again - its probably something about how the = (probs specifically, whereas the ? looks to be making it through unscathed)

donaldguy commented 3 months ago

also (just) before I lost interest in Windows for a month or more, I did notice that The Browser Company had added a whole mess of DLLs and some metadata about binding to their AppX manifest of one of the last releases I looked at that closely

so its very possible there is a better way to do this now for someone who knows literally anything about Windows APIs (which for the record ... I really don't)

U-C-S commented 3 months ago

I will take a look at this, this week. Thanks @donaldguy