chocolatey / choco

Chocolatey - the package manager for Windows
https://chocolatey.org
Other
10.35k stars 903 forks source link

Use application registration besides shimming. #1072

Open majkinetor opened 7 years ago

majkinetor commented 7 years ago

This is a general problem with many packages - they don't provide easy access that is typical in Linux world. Shimming solves only part of it in an IMO not a good way: more then I would like I have weird situations around shimmed apps.

That is one of the reasons I created Register-Application so that GUI apps are available both in WIN + R, windows start menu search and PowerShell console with profile script Set-AppKeyAliases.ps1.

Application Registration is an offical way provided by MS instead of PATH due to its limitations (see Repair-Path for details on those). I generally use PATH if there are more then few apps (sysinternals, nirlauncher etc.) and shim for 1 or 2 apps in a package.

Appliation Registration can completelly replace shims with few simple tricks.

Currently with above mentioned PowerShell profile script registered apps work in Posh:

PS> Set-AppKeyAliases -Verbose

VERBOSE: 7zFM = C:\Program Files\7-Zip\7zFM.exe
VERBOSE: Ahk2Exe = C:\Program Files\AutoHotkey\Compiler\Ahk2Exe.exe
VERBOSE: AutoHotkey = C:\Program Files\AutoHotkey\AutoHotkey.exe
VERBOSE: Blend = C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\Blend.exe
VERBOSE: chrome = C:\Program Files (x86)\Google\Chrome\Application\chrome.exe
VERBOSE: clementine = C:\Program Files (x86)\Clementine\clementine.exe
WARNING: Ignoring invalid path for 'cmmgr32' : ''
VERBOSE: ConEmu64 = C:\Program Files\ConEmu\ConEmu64.exe
VERBOSE: devenv = C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\devenv.exe
WARNING: Ignoring invalid path for 'dfshim.dll' : ''
VERBOSE: dnGREP = C:\Program Files\dnGREP\dnGREP.exe
VERBOSE: excel = C:\PROGRA~1\MICROS~1\Office16\EXCEL.EXE
VERBOSE: firefox = C:\Program Files\Mozilla Firefox\firefox.exe
VERBOSE: foxitreader = C:\Program Files (x86)\Foxit Software\Foxit Reader\FoxitReader.exe
WARNING: Ignoring invalid path for 'fsquirt' : ''
VERBOSE: IEDIAG = C:\Program Files\Internet Explorer\IEDIAGCMD.EXE
VERBOSE: IEDIAGCMD = C:\Program Files\Internet Explorer\IEDIAGCMD.EXE
VERBOSE: IEXPLORE = C:\Program Files\Internet Explorer\IEXPLORE.EXE
WARNING: Ignoring invalid path for 'install' : ''
VERBOSE: licensemanagershellext = C:\Windows\System32\licensemanagershellext.exe
WARNING: Ignoring invalid path for 'LogiLDA.dll' : ''
VERBOSE: mfbclient = C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\mfbclient.exe
VERBOSE: mip = C:\Program Files\Common Files\Microsoft Shared\Ink\mip.exe
VERBOSE: mplayer2 = C:\Program Files (x86)\Windows Media Player\wmplayer.exe
VERBOSE: MSACCESS = C:\PROGRA~1\MICROS~1\Office16\MSACCESS.EXE
WARNING: Ignoring invalid path for 'MsoHtmEd' : ''
VERBOSE: msoxmled = C:\Program Files\Common Files\Microsoft Shared\OFFICE16\MSOXMLED.EXE
VERBOSE: mtm = C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\mtm.exe
VERBOSE: nirlauncher = C:\tools\NirLauncher\nirlauncher.exe
VERBOSE: notepad++ = C:\Program Files\Notepad++\notepad++.exe
VERBOSE: ntp = C:\Windows\notepad.exe
VERBOSE: pbrush = C:\Windows\System32\mspaint.exe
VERBOSE: powerpnt = C:\PROGRA~1\MICROS~1\Office16\POWERPNT.EXE
VERBOSE: PowerShell = C:\Windows\system32\WindowsPowerShell\v1.0\PowerShell.exe
WARNING: Ignoring invalid path for 'setup' : ''
VERBOSE: smplayer = C:\Program Files\SMPlayer\smplayer.exe
VERBOSE: SnippingTool = C:\Windows\system32\SnippingTool.exe
VERBOSE: srptool = c:\Program Files\Git\mingw64\bin\srptool.exe
WARNING: Ignoring invalid path for 'table30' : ''
VERBOSE: TabTip = C:\Program Files\Common Files\microsoft shared\ink\TabTip.exe
VERBOSE: tixati = C:\Program Files\tixati\tixati.exe
VERBOSE: vbox = C:\Program Files\Oracle\VirtualBox\virtualbox.exe
VERBOSE: virtualbox = C:\Program Files\Oracle\VirtualBox\virtualbox.exe
WARNING: Ignoring invalid path for 'vstoee.dll' : ''
VERBOSE: wab = C:\Program Files\Windows Mail\wab.exe
VERBOSE: wabmig = C:\Program Files\Windows Mail\wabmig.exe
VERBOSE: WinMerge = C:\Program Files (x86)\WinMerge\WinMergeU.exe
VERBOSE: WinMergeU = C:\Program Files (x86)\WinMerge\WinMergeU.exe
VERBOSE: Winword = C:\PROGRA~1\MICROS~1\Office16\WINWORD.EXE
VERBOSE: wmplayer = C:\Program Files (x86)\Windows Media Player\wmplayer.exe
VERBOSE: WORDPAD = C:\Program Files\Windows NT\Accessories\WORDPAD.EXE
VERBOSE: WRITE = C:\Program Files\Windows NT\Accessories\WORDPAD.EXE
WARNING: Alias not writable: WRITE

To have the same effect in cmd.exe (which is finally not default shell anymore) one can use doskey, a la:

doskey srptool="c:\Program Files\Git\mingw64\bin\srptool.exe"

If chocolatey profile contains the said script and chocolatey installer adds cmd.exe startup script in registry that does the doskey stuff, we will cover all 3 worlds - powershell, cmd and Explorer. Furthermore, both mechanisms can exist at the same time so package maintainer can choose. Furthermore at least 50% of apps actually register application during installation so there is actually nothing to be done half of the time, it just works with profile scripts set.

Management of this stuff is also easier - even ccleaner and friends would remove invalid enteries while leftover shims will be deleted by no tool. You also can't know if shim actually shims correct application until you check it out personally in detail.

On linux the sistuation is the same - almost all apps, GUI or CLI register in console. Unified experience on multiple platforms is great feature.

I think this is valuable. Implementing such a change is trivial. Stuff is already implemented. Action plan would be

cc @AdmiringWorm @gep13

jberezanski commented 7 years ago

There are two huge drawbacks of using App Paths: 1) such registrations are not discoverable using established mechanisms, namely where.exe and the Get-Command cmdlet, 2) they are not taken into account by the CreateProcess API (only by ShellExecute), so applications that start other applications directly (instead of relying on the Shell, i.e. Explorer to do so), will not work correctly.

And no, I do not believe polluting the PowerShell alias namespace with a ton of aliases is the right approach. Like desktop shortcuts, pinned taskbar and Start items, I believe the user should remain in full control over what gets put there. In fact, I also frown upon modifying the user's $profile.

Last remark: all mechanisms based on modifying $profile fall apart when the user account used for installing applications is different from the end user, as is common in companies (where a technical account is used for automating workstation setup, or a workstation admin does that manually), but also for more security-conscious home users (who have a dedicated admin account, not used for day-to-day tasks).

majkinetor commented 7 years ago

Such registrations are not discoverable using established mechanisms, namely where.exe and the Get-Command cmdlet,

Yes they are in powershellworld with Get-Command. This is the native way, which isnt. [EDITED, sorry, where.exe is native, mistake, outdated however].

they are not taken into account by the CreateProcess API

This is very small problem, but shims can and DOES fail too, all the time, I don't see how this is different.

And no, I do not believe polluting the PowerShell alias namespace with a ton of aliases is the right approach.

And populating it with shims is OK ?

Like desktop shortcuts, pinned taskbar and Start items, I believe the user should remain in full control over what gets put there. In fact, I also frown upon modifying the user's $profile.

Chocolatey already does this (refreshenv?) you are talking about something different entirelly.

Last remark: all mechanisms based on modifying $profile fall apart when the user account used for installing applications is different from the end user, as is common in companies (where a technical account is used for automating workstation setup, or a workstation admin does that manually), but also for more security-conscious home users (who have a dedicated admin account, not used for day-to-day tasks).

No, you have global and local registration so global will work for all users. You also have global and local profile for Posh.

Also, did you miss the point that we can have both ? There is no loose only gain, and we can see which method will users eventually be happy with.

To recap, those might be some problems but are IMO smaller then those of shims.

jberezanski commented 7 years ago

Yes they are in powershellworld with Get-Command

On my Windows 8.1 with PowerShell 4.0:

C:\> $psversiontable.PSVersion; (Get-CimInstance -ClassName Win32_OperatingSystem).Version

Major  Minor  Build  Revision
-----  -----  -----  --------
4      0      -1     -1
6.3.9600

C:\> Get-Command -Name pbrush.exe
Get-Command : The term 'pbrush.exe' is not recognized as the name of a cmdlet, function, script file, or operable program. (...)

C:\> Get-Command -Name pbrush
Get-Command : The term 'pbrush' is not recognized as the name of a cmdlet, function, script file, or operable program. (...)

C:\> Get-Item -Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\pbrush.exe'

    Hive: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths

Name                           Property
----                           --------
pbrush.exe                     (default) : C:\Windows\System32\mspaint.exe
                               Path      : C:\Windows\System32

This is the native way, which isnt.

where is the native way from cmd.exe.

they are not taken into account by the CreateProcess API

This is very small problem

Not if you rely on such tools.

shims can and DOES fail too, all the time

How is that? Is there any concrete evidence of a mass of users reporting problems with shims?

As for maintaining shims and removing invalid ones, that should be the job of Chocolatey.

And populating it with shims is OK ?

Shims do not pollute the alias namespace. Besides, adding a file to a directory that is already on PATH (and dedicated to storing shims) is not polluting anything.

Like desktop shortcuts, pinned taskbar and Start items, I believe the user should remain in full control over what gets put there. In fact, I also frown upon modifying the user's $profile.

Chocolatey already does this (refreshenv?) you are talking about something different entirelly.

I don't see the relation between refreshenv and modifying $profile.

You also have global and local profile for Posh.

And modifying or creating the global profile may have nasty machine-wide repercussions - I recall a recent discussion about the presence of a profile breaking Vagrant provisioning, for example.

Also, did you miss the point that we can have both ? There is no loose only gain, and we can see which method will users eventually be happy with.

Ah, the pitfall of adding yet another configuration setting. In this case, it also has the potential of complicating Chocolatey maintenance and making diagnosing user issues harder.

Don't get me wrong, I'm largely playing devil's advocate here. I'm not a fan of shims myself (in fact, I had suggested App Paths to @ferventcoder a long while ago), but I want us to fully understand the pros and cons.

majkinetor commented 7 years ago

Yeah, there is no exe in alias: gcm pbrush If that is the problem 2 aliases can be created pbrush and pbrush.exe although its ridiculous.

How is that? Is there any concrete evidence of a mass of users reporting problems with shims?

Mass of users do not report it as mass of users do not use CLI. I never use desktop and it happens to me all the time but it happens in specific contexts. Recently I was testing nirlauncher for sysinternals tools and all tools had the problem with it. Outside of it tools worked normally. Will see to document it in the future when it arises.

As for maintaining shims and removing invalid ones, that should be the job of Chocolatey.

Yes for portable packages. No for other pakcages, its a maintainer responsibility.

Besides, adding a file to a directory that is already on PATH (and dedicated to storing shims) is not polluting anything.

It is polluting file system. It also provides aditional commands that can spoil exisiting scripts. You can't actually distinguish them from normal programs while you can safely ignore aliases if you want.

And modifying or creating the global profile may have nasty machine-wide repercussions - I recall a recent discussion about the presence of a profile breaking Vagrant provisioning, for example.

Lets not add generalizations here, modfying anything can have nasty machine wide reprecussions. Context is important. About vagrant, that is probably upstream problem ( I have it and I solve it by not adding commands directly in profile but creating a function that I call ad hock).

In this case, it also has the potential of complicating Chocolatey maintenance and making diagnosing user issues harder.

So lets return to ketarin then, AU just added more complexity, no ? Context, again, no generalizations.

Don't get me wrong, I'm largely playing devil's advocate here.

I like people questioning me with good arguments. That will never be the problem. Your current arguments are valid but we need to have a perspective on pros and cons.

majkinetor commented 7 years ago

but I want us to fully understand the pros and cons.

I use this system in Powershell for over a year. It never produced any problem. I add Register-Application to all packages that do not register and sometimes to those that do (its easier to type vbox then virtualbox for example).

This system is good because pros are many and cons are low. Especially given that almost all of the cons are in the CLI which majority of folks do not use. However, we have engineering commune to think about.

Besides, we don't have to add anything in profile. The one can call Set-AppKeyAliases manually when he needs it in specific shell so it should be available via chocolatey profile but it doesn't have to be executed on start)

jberezanski commented 7 years ago

Yeah, there is no exe in alias: gcm pbrush

I was demonstrating the effect of adding to App Paths only, without any other modifications to the system (specifically, no aliases). I've actually executed gcm without .exe (third command; the presence of ".exe" in error message was my editing mistake when pasting the output here; fixed now).

Yes for portable packages. No for other pakcages, its a maintainer responsibility.

The entire $Env:ChocolateyInstall\bin directory falls under Chocolatey governance, no exceptions. Shimming there is a feature of Chocolatey, so Chocolatey should keep that directory healthy.

You can't actually distinguish [shims] from normal programs while you can safely ignore aliases if you want.

That I perceive as an advantage. In my own scripts, to make them as robust as possible, I look for executables using e.g. Get-Command -Name diskspd -CommandType Application, to make sure I invoke the real application instead of a function or alias someone might have created for their use.

So lets return to ketarin then, AU just added more complexity, no ?

Here I was talking about providing both options and allowing the user to choose. Two possible configurations, so twice the numer of test cases and two cases to consider when diagnosing user issues.

As for AU, I don't think that's a good example. In itself, AU does not increase, but greatly reduces the complexity. It is also an external tool from the point of view of Chocolatey, same as Ketarin, and the Chocolatey team has no obligation to support either of them.

Besides, we don't have to add anything in profile.

That I agree with fully. Not only "don't have to", but even "should not", I think.

majkinetor commented 7 years ago

Here I was talking about providing both options and allowing the user to choose. Two possible configurations, so twice the numer of test cases and two cases to consider when diagnosing user issues.

No, the same command returns answer for both questions and shows the type of application (alias vs application).

People always think their ways are the standard and other stuff are exceptions. Good solution should support all variants if it doesn't introduce too much complexity. In this case, nothing changes

That I perceive as an advantage

In your case it is, in different case it might be not. Why should you use rm.exe if I provided alias that deletes to recycle bin for example (hypoteically speaking)>

This allows an option to choose what you want or don't care.

In itself, AU does not increase, but greatly reduces the complexity.

It didn't to @dtgm for example. He didn't want to use it as it increased complexity in his system. Also, currently, while both are kept in transition, it only increases complexity.

majkinetor commented 7 years ago

BUT lets not be theoretical.

Do you actually think those mentioned problem are show stoppers ? That benefits are not so big as cons?

Or you just want to brainstorm anything that is possible ?

Perspective is needed.

majkinetor commented 7 years ago

cc @darwinjs, I actually got the registration part from his code.

DarwinJS commented 7 years ago

@jberezanski has many valid points (skim read) (that may counter anything I've posted about AppPaths being a possible substitution for shims.)

@majkinetor - I think this statement in your originally posted issue "Appliation Registration can completelly replace shims with few simple tricks." is what @jberezanski is taking issue with.

Maybe you could propose this as an enhancement to allow shimmed items to also be found on the start menu, rather than a replacment for shimming.

Also, maybe packagers "opt-in" if they want it, rather than have it be automatic? The way to publicize the capability might be to work it into the template for "choco new"?

jberezanski commented 7 years ago

Why should you use rm.exe if I provided alias that deletes to recycle bin for example (hypoteically speaking)

Because I want my script to be reliable and dependable in its behavior, which is why I currently explicitly look only for CommandType Application. I can adapt, of course, but then the transition will not be seamless (and I imagine I'm not the only one writing scripts that way).

Do you actually think those mentioned problem are show stoppers ? That benefits are not so big as cons?

I'm not sure yet, that's why I engage in this discussion. Also, I want to discourage implementing behavior I disagree with, such as automatic modification of PowerShell profiles.

majkinetor commented 7 years ago

I wrote in title of this issue besides. That they can replace shims is just observation.

majkinetor commented 7 years ago

Also, I want to discourage implementing behavior I disagree with, such as automatic modification of PowerShell profiles.

I totally agree here. This was a BAD decision and should be removed while its still fresh. This should have been done by installing appropriate Powershell module. The same thing would work with Set-AppKeyAliases and left to the users to utilize it with clever choco message tips or even a feature (enable_appkeyaliases for example would modify user profile on its demand).

ferventcoder commented 7 years ago

This is a fantastic discussion. I don't want to remove from the convo, so I will only add a couple of additional points for consideration.

Considerations to points made so far:

So here are some of the additional points I wanted to bring an awareness to:

dragon788 commented 7 years ago

Possibly relevant, I think there was some recently some talk on Gitter about how modifying the $env:PSModulePath might avoid touching the profile while still making helpers available by adding/removing from that path (which Microsoft actually does themselves). This could be used for an Install-PowerShellModule command without touching the $profile or the sensitive (admin required) $somepath\PowerShell\1.0\modules directory.

jberezanski commented 7 years ago

@ferventcoder

No Administrative Permissions - The other issue to consider here is that shimgen requires no administrative permissions to create these shim

That's right, but placing the shims in $Env:ChocolateyInstall\bin does require admin rights (in a default install). Which is a good thing, because it would be a security hole otherwise.

All in all, I'm all for implementing the addition to App Paths, but in addition to shims (and subject to the same control mechanisms, i.e. respecting *.exe.ignore files), not as a replacement (in the default configuration). We could provide feature toggles to control enabling/disabling of both mechanisms, for those adventurous enough to try the App Paths-only approach.

No automatic tampering with aliases or cmd.exe startup scripts, however. As @majkinetor suggested, we might provide functions in the Chocolatey PowerShell module (the one that does autocompletion) to install both hooks, but leave it to the user to use them at their discretion.

majkinetor commented 7 years ago

We could provide feature toggles to control enabling/disabling of both mechanisms, for those adventurous enough to try the App Paths-only approach.

This would be the best approach along with chocolatey Posh module.

ferventcoder commented 7 years ago

That's right, but placing the shims in $Env:ChocolateyInstall\bin does require admin rights (in a default install). Which is a good thing, because it would be a security hole otherwise.

In the default install, yes. 👍 The point is still allowing the ability for non-admins to be able to use some parts of Chocolatey.