Scoop
Scoop copied to clipboard
Support shims to both console and GUI apps
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.
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.
@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?
A symbolic link would suffice. BTW, why do we need a shim.exe
?
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.
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 .dll
s.
@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
why do we need a
shim.exe
?I think the intent of
scoop/shims/*.exe
is used to help prevent pollution of thePATH
.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
@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
)
Ah yes, thank you, just noticed your answer on stackoverflow too :)
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 likefunction shim
withincore.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.
@excitoon how would this console/GUI check look like? Is that possible?
@r15ch13 I just made a PR for that.
As for second part, icon for shim, there are two ways doing it:
- make shell handler which would set proper icon for a file (quite system-intrusive);
- simply copy icon from executable into shim (PE format is well described and static).
Can it add a parameter? ex scoop install aaa --gui
, then it create shims as a gui app.
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
@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. :)
@yelkarama Link you posted is only a readme and issue list.
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...
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!
I guess this still is an issue for example if you install and run https://wezfurlong.org/wezterm/install/windows.html
seems to be still an 'issue' as of July, e.g., with notepad++ when using win+r ('run')
I guess this still is an issue for example if you install and run https://wezfurlong.org/wezterm/install/windows.html
Why do I get this error when running both of these commands?
scoop config shim kiennq scoop reset *
scoop config shim 71 scoop reset *
@syncrodazt try doing
scoop update -f 7zip
And speaking of the feature itself. I very much like it. I am a new scoop user and it bothered me when i went windows key -> type 'git bash' -> have cmd and git bash open up.
It's been like this with most apps ran through windows quick access. With the shim config it's solid now.
I'm seeing this issue again since a recent update on sumatrapdf
Multiple of the apps I have installed still show the blank cmd windows when I run the shim executables. Ones that are console anyway will use that console window, but ones that are GUI, this console window does nothing, and closing it closes the app.
Notably, git-gui and Blender (I think Blender runs DeallocConsole though to get rid of it, because opening a console first is Blender's default behaviour) work fine, while some examples like notepad2 do not. Also, the ones that create entries in the start menu through the "scoop apps" folder are also fine, but those don't use the shim exeuctable anyway. Those GUI apps that don't make such an entry, those will be the ones directly found by the executable in start menu search and those still suffer for me.
Which shim executable are you using? Can you run this and try again?
scoop config shim kiennq
scoop update
scoop reset *
It seems I forgot to write after all that I did try both kiennq and 71. I even deleted the entire shim folder and let the reset reinitialize it (leaving the shim for scoop itself intact). I also verified that with those shims, there wasn't a cmd and ps1 for every executable anymore, it was all exe and ".shim" files that contain the path to the executable in the case of kiennq.
So i think I did my due diligence, did I miss anything?
Ah okay I think I understand the issue now. The shim executable is a console program, so it will always open a console regardless of whether the target executable is a console program or a GUI program. Note that this is a peculiarity of Windows itself, all programs need to declare what subsystem they belong to (either CONSOLE or WINDOWS) before compilation and there's no way to work around this.
Programs which have a GUI should create shortcuts for themselves in the manifest. Using the shim for them is not recommended, the shim is only supposed to be used from the shell/terminal.
Well, there are solutions I can personally think of.
I know for console apps you can't just not wait for execution to end (or else the console will dealloc), and for it to stay in the same console session, you have to execute the app in your own console session... I get that this is why scoop does it this way.
I can see a few solutions to this.
First, actually read the PE info of the executable and ShellExecuteEx it if it's a gui app (then don't wait and the shim will pop up a console but at least disappear).
Other solutions I havd would need the manifest to include information about the nature of the app though...
Here, I can see generating different shims whether or not the app is a gui app - something like Blender would say it's a console app (because it does always start up with a console first), for example. A gui shim is a gui executable, while a console shim is as now. Make the default console and you only have to update the gui apps (least destructive way).
Second, use the ".shim" file to determine this state, then the shim, when reading that, decides to DeallocConsole at runtime or, here, again, ShellExecuteEx the executable instead.
Since we're on Windows, unlike on Linux, the parent process can die without taking its children with it.
I mean I understand there are workarounds for it (which will require a lot of hard work and special casing, for e.g. not all target executables are .exe files etc.), but I still don't understand the point of this effort. GUI apps have shortcuts already (which directly target the app executable), why would you want to launch them using a shim, and that too directly from Start Menu (where the said shortcuts exist)? Shims are a CLI tool by definition: they should be used only from the CLI.
Well, the use case is that some (gui) applications are very good to run from a console or the "RUN" field, like notepad++ or notepad2. The console blocking on that is actually kind of annoying here.
Of course, assigning the filetype to that app also works, but you can only have one app assigned to a file type.
I get some apps actually use bat/cmd and not exe. In that case, the special case is just this: If exe, do PE introspection, if not, do nothing at all and behave like before.
As for the analysis though, I have done some Google-Fu, and there is a class for PE Headers in... dotnet v6. Since scoop needs to run on the basic windows included Powershell, that's out. There is a c# library that should fit in the requires versions, but yeah, it's a lot more work than I thought to do the analysis here. https://github.com/secana/PeNet
With the dotnet v6 class it would be a handful of lines to find the subsystem type in the PE header.