Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support shims to both console and GUI apps #1606

Closed
prasannavl opened this issue Jul 18, 2017 · 79 comments · Fixed by #5424
Closed

Support shims to both console and GUI apps #1606

prasannavl opened this issue Jul 18, 2017 · 79 comments · Fixed by #5424

Comments

@prasannavl
Copy link

prasannavl commented Jul 18, 2017

When using any tools, like sysinternals for example, an empty command window (the shim) is open, and has to be manually closed.

The ideal way would be that the shim itself be a "win32" app. Currently all shims are console programs. i.e, not linked as "win32" apps for gui mode.

EDIT:
Suggestion, allow for properties in the manifest to configure which binaries are gui shims, and which should be commandline shims, and use shims accordingly.

@prasannavl prasannavl changed the title empty command window shims shims are console only - doesn't support win32 gui apps Jul 29, 2017
@SimplyKnownAsG
Copy link
Contributor

would it be possible to add a flag in the json (then in the .shim) indicating that shim.exe should not wait indefinitely? Something like

bool fork = bool.Parse(Get("fork", config) ?? "false");
if(fork) {
    return 0;
}
else {
    WaitForSingleObject(pi.hProcess, INFINITE);

    uint exit_code = 0;
    GetExitCodeProcess(pi.hProcess, out exit_code);

    // Close process and thread handles.
    CloseHandle(pi.hProcess);
    CloseHandle(pi.hThread);

    return (int)exit_code;
}

I'm not sure how one might specify this in the app.json, and currently it looks like function shim within core.ps1 would need to accept another argument. It might make sense (for future concerns) to allow $arg to be a dict of key/vals that can be dumped to the .shim file for loading. Not to get ahead of this current problem.

@rasa rasa changed the title shims are console only - doesn't support win32 gui apps Support shims to both console and GUI apps Mar 12, 2018
@SimplyKnownAsG
Copy link
Contributor

@r15ch13 is there a way you think this should be accomplished? i'd be happy to close #2006 if there were another way around it. I suppose we could also change GUIs to just add the path rather than creating a shim. is there a preference of adding to path vs creating a shim?

@Congee
Copy link
Contributor

Congee commented May 25, 2018

A symbolic link would suffice. BTW, why do we need a shim.exe?

@rasa
Copy link
Member

rasa commented May 25, 2018

A symbolic link doesn't work, as the exe that is the symlink's target cannot find its related .dlls, as the "exe's directory" is the directory the symlink is in, not where the target lives.

@SimplyKnownAsG
Copy link
Contributor

Windows isn't very friendly about symbolic links, but hard links are more accessible for those who do not have admin rights. However, I think that @rasa is correct about .dlls.

@Congee, I'm not sure I understand the question:

why do we need a shim.exe?

I think the intent of scoop/shims/*.exe is used to help prevent pollution of the PATH. shim.exe is a fancy/funky symlink

@fritzmg
Copy link

fritzmg commented Nov 22, 2018

why do we need a shim.exe?

I think the intent of scoop/shims/*.exe is used to help prevent pollution of the PATH. shim.exe is a fancy/funky symlink

Additionally, if you create file assocations or any other reference for an application that is installed via scoop, they would not work anymore if the application gets updated (since the folder name would change within apps/).

Btw. it appears that icons from the "shim"ed (?) executable also do not work: https://stackoverflow.com/questions/53430845/scoop-installed-git-bash-open-git-bash-here-context-menu

@r15ch13
Copy link
Member

r15ch13 commented Nov 22, 2018

@fritzmg the actual shim.exe doesn't have an icon, so it can't be displayed.
In this case, it's recommended to use the current version path. (e.g. ~\scoop\apps\git\current\git-bash.exe)

@fritzmg
Copy link

fritzmg commented Nov 23, 2018

Ah yes, thank you, just noticed your answer on stackoverflow too :)

@excitoon
Copy link
Contributor

excitoon commented Dec 20, 2018

would it be possible to add a flag in the json (then in the .shim) indicating that shim.exe should not wait indefinitely? Something like

bool fork = bool.Parse(Get("fork", config) ?? "false");
if(fork) {
    return 0;
}
else {
    WaitForSingleObject(pi.hProcess, INFINITE);

    uint exit_code = 0;
    GetExitCodeProcess(pi.hProcess, out exit_code);

    // Close process and thread handles.
    CloseHandle(pi.hProcess);
    CloseHandle(pi.hThread);

    return (int)exit_code;
}

I'm not sure how one might specify this in the app.json, and currently it looks like function shim within core.ps1 would need to accept another argument. It might make sense (for future concerns) to allow $arg to be a dict of key/vals that can be dumped to the .shim file for loading. Not to get ahead of this current problem.

Totally agree. Even more, it is easy to check if the application is console or not even without a flag.

@r15ch13
Copy link
Member

r15ch13 commented Dec 20, 2018

@excitoon how would this console/GUI check look like? Is that possible?

@excitoon
Copy link
Contributor

excitoon commented Dec 20, 2018

@r15ch13 I just made a PR for that.

@excitoon
Copy link
Contributor

As for second part, icon for shim, there are two ways doing it:

  1. make shell handler which would set proper icon for a file (quite system-intrusive);
  2. simply copy icon from executable into shim (PE format is well described and static).

@fcying
Copy link

fcying commented Feb 4, 2019

Can it add a parameter? ex scoop install aaa --gui, then it create shims as a gui app.

@yelkarama
Copy link

Hi
Chocolatey is also using the same shim technique to (I believe) avoid polluting the path and it doesn't have this issue.
Here is their github repo:
https://github.com/chocolatey/shimgen

@chawyehsu
Copy link
Member

chawyehsu commented Apr 26, 2019

@yelkarama shimgen of chocolatey is a closed source proprietary software, though they say it's an open source feature in their docs title, kinda funny.

https://github.com/chocolatey/choco/blob/master/src/chocolatey.resources/tools/shimgen.license.txt

You know that Scoop is a personal project of luke, while Chocolatey is a commercial software, though it has community version. The distribution or use of shimgen outside of Chocolatey without permission is prohibited. The shimming system is a critical piece of Scoop/Chocolatey, obviously. Scoop community developers will always be interested in improve the project, but as you know it's still a community maintained project, thus it can take more time. :)

@excitoon
Copy link
Contributor

excitoon commented Apr 26, 2019

@yelkarama Link you posted is only a readme and issue list.

@niheaven
Copy link
Member

I want to use shimgen outside of Chocolatey.

If your project is FOSS, please contact us for a grant of a free license to do so. > If your project is commercial, please contact Chocolatey Software for a quote.

shimgen is closed source proprietary software, while generated shim is under MS-RSL...

@rasa
Copy link
Member

rasa commented Dec 23, 2020

This issue should be fixed in #3998, which was merged into master. To use, type:

scoop config shim kiennq
scoop reset *

or

scoop config shim 71
scoop reset *

Eventually, one of those shims (probably kiennq) will be made the default.

If this issue is still a problem after trying both solutions above, please reopen this issue. Thanks!

@SpacewaIker
Copy link

@spider2048 your changes in #5559 and #5684 don't seem to work on my computer. I switched to the develop branch and tested with both neovide and nvim-qt, both stay attached to the terminal. (I do get the message that a GUI application was detected when installing)

@spider2048
Copy link
Contributor

spider2048 commented Jan 17, 2024

@SpacewaIker I was able to reproduce your problem only in nushell (from here) and I would say that is the culprit. nushell blocks the prompt until the child process terminates. Also, this is not because of scoop because if an application is started with its actual executable instead of its shim, nushell would wait till the process exits. I would like to hear if my commits don't work in pwsh or any other shell which doesn't behave this way.

@SpacewaIker
Copy link

It seems that you're right, it works as expected in powershell and CMD. However it worked fine with nushell and previous versions of neovide... So now I don't know if the issue is with neovide or nushell, since it doesn't seem to come from scoop.

@spider2048
Copy link
Contributor

@SpacewaIker I think the issue is with nushell and not with neovide as I see a wait in its code.

@Roemer
Copy link

Roemer commented Feb 5, 2024

It seems that shims for GUI applications build with go/fyne-framework also open a terminal which needs to stay open. Is this also adressed with this issue?
It can be tested for example with https://github.com/Roemer/disk-tree and a following local manifest saved as disk-tree.json:

{
    "version": "0.2.0",
    "url": "https://github.com/Roemer/disk-tree/releases/download/v0.2.0/disk-tree-0.2.0.exe",
    "bin": "disk-tree-0.2.0.exe"
}

and then scoop install <path-to>/disk-tree.json

@spider2048
Copy link
Contributor

@Roemer Yes, it is also addressed with this issue. In the current develop branch (as of now), disk-tree will no longer need to have an open terminal.
I would say, if an application was a GUI app, the shim will also be GUI.

@Roemer
Copy link

Roemer commented Feb 5, 2024

Any idea when this might find its way into a release? Been a while since the last release.

@goyalyashpal
Copy link

A symbolic link doesn't work, as the exe that is the symlink's target cannot find its related .dlls, as the "exe's directory" is the directory the symlink is in, not where the target lives.
- @ rasa at #1606 (comment)

i wonder how the wonderful pipx uses symlinks then?
pipx allows to run "python packages with entry points" as standalone isolated apps.

following is a screenshot for the directory used by pipx to store the symlinks of the executables

@pfmoore
Copy link

pfmoore commented Mar 20, 2024

The executables in pipx don't locate any of their resources or DLLs using paths relative to the executable, so the problem referred to doesn't arise.

@gerardog
Copy link
Contributor

The executables in pipx don't locate any of their resources or DLLs using paths relative to the executable, so the problem referred to doesn't arise.

Exactly. As another example, gsudo (and possible any .net app) when built for .net framework 4.x fails to load it's .dlls if invoked from a symlink. A special workaround in code fixed that. When I later rebuilt it with .net 7 NativeAOT, the workaround was no longer needed.

@goyalyashpal
Copy link

so, can this be considered as lack of convention in windows applications to resolve the paths to destination (assuming that it is possible to resolve in the first place).

as from my surfacial knowledge, in linux the executables are moved to the bin folder away from directory on install right away. but yeah, in there, they likely don't have to resolve their install location, but the location of system-wide libs

@pfmoore
Copy link

pfmoore commented Mar 20, 2024

so, can this be considered as lack of convention in windows applications to resolve the paths to destination (assuming that it is possible to resolve in the first place).

Not really. My understanding is that in Linux, shared libraries and resources are typically located in fixed absolute locations. So executables can be run from anywhere, but shared libraries and resources can't be safely moved. Conversely, in Windows the common practice is to store all application DLLs and resources in the application directory. This means you can move the application as a whole, but can't move components relative to each other.

The semantics of a symlink make it equivalent to moving the executable to another place. As the above demonstrates, this works for typical Linux applications, but doesn't work for typical Windows applications.

Applications can be written in such a way that this isn't an issue in practice (pipx shims hard-code the absolute path to the Python interpreter that gets run, but everything else in the app is relative to that, so you can move or symlink the shim, but not any other part of the app). But in general symlinking an application exe is less likely to work on Windows than Linux, because of the different conventions.

@goyalyashpal

This comment was marked as resolved.

@29039
Copy link

29039 commented Mar 23, 2024

For anyone playing at home who can't wait for a new release, you can access the new shim from https://github.com/ScoopInstaller/Scoop/tree/develop/supporting/shims/kiennq

@brian6932
Copy link

brian6932 commented Mar 24, 2024

5153d73 seems to break this for me

❯ streamlink

❯ & (scoop which streamlink)
usage: streamlink [OPTIONS] <URL> [STREAM]

Use -h/--help to see the available options or read the manual at https://streamlink.github.io

manifests reproduced/tested on
https://github.com/brian6932/dank-scoop/blob/master/bucket/streamlink-nightly-lean-ttv-lol.json
https://github.com/brian6932/dank-scoop/blob/master/bucket/streamlink-nightly-lean.json

@spider2048
Copy link
Contributor

spider2048 commented Mar 24, 2024

I was able to run streamlink with no issues using scoopcs.

scoop config shim scoopcs
scoop reset streamlink

and

$ streamlink
usage: streamlink [OPTIONS] <URL> [STREAM]

Use -h/--help to see the available options or read the manual at https://streamlink.github.io

And now that #5721 is merged, we can use the scoopcs shim type to handle GUI+CLI shims effectively.

Ideally, we can make a switch from kiennq to scoopcs reducing the binary size and solving issues.

Edit: It seems that kiennq shim faces issues handling the arguments (130+ characters) in the shim manifest, which results in an exception with reason invalid string position.

@brian6932
Copy link

I understand that the old shimgen can be used, but that's not really a solution, isn't the old shimgen slower anyway, the C(++) one should just be fixed.

@spider2048
Copy link
Contributor

How slow is the old shim? I don't really see much differences in their launch times. It's not part of my hot path, anyway.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.