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

Install-StartMenu Helper #395

Open
saneki opened this issue Aug 23, 2015 · 23 comments
Open

Install-StartMenu Helper #395

saneki opened this issue Aug 23, 2015 · 23 comments

Comments

@saneki
Copy link

saneki commented Aug 23, 2015

Some of the packages I plan on maintaining provide GUI programs but don't have installers, so there's no easy way to add (or remove) shortcuts of them to/from the CommonPrograms directory so that they appear in the start menu (on Win 7 / Win Server 2008 at least, not sure about newer versions). I ended up writing functions to add/remove shortcuts to/from the start menu for one of my packages.

It would be convenient if chocolatey had helpers for similar functionality, considering the start menu is the typical place GUI programs show up after being installed.

@aronovgj
Copy link

one of my packages installing (and uninstalling) a start menu shortcut:

https://chocolatey.org/packages/crystaldiskinfo/6.5.2

@saneki
Copy link
Author

saneki commented Aug 23, 2015

@aronovgj Wouldn't something like Install-ChocolateyStartMenu -File "DiskInfo.exe" -As "CrystalDiskInfo.lnk" be so much easier/more portable though?

For my dnSpy package, it might look something like this:

Install-ChocolateyStartMenu -Path "dnSpy" -File "dnSpy.exe", "dnSpy-x64.exe"
# ...
Uninstall-ChocolateyStartMenu -Path "dnSpy"

Forgive me if my powershell is off, I'm rather new to it.

@aronovgj
Copy link

Install-ChocolateyShortcut is a one-liner. the definition of the variables is just for readability. you will need to define the name of the .exe manually, because there may be several exe files, the path to the .exe (because how would you know whether it is in program files or program files (86) or \lib\packagename) and you will need to define how you want the link to be placed in the start menu (\Start Menu\Programs\package.lnk? \Start Menu\Programs\packagename\package.lnk?)

for the uninstaller you would also need the .lnk name and the path.

don't think it can get any easier

@saneki
Copy link
Author

saneki commented Aug 23, 2015

Of course someone might want to have a more complicated start menu setup, in which case it can be done manually, but just looking through my own start menu most of the subdirectories are very simple and only a few have child directories themselves.

You say it can't get any easier but I just gave an example of it being easier (reducing 4 lines to 1), though I should have specified a "base" directory option: Install-ChocolateyStartMenu -Base $destdir -File "DiskInfo.exe" -As "CrystalDiskInfo.lnk"

@aronovgj
Copy link

You say it can't get any easier but I just gave an example of it being easier (reducing 4 lines to 1)

And I explained to you that those 4 lines are actually one line.
Install-ChocolateyShortcut -shortcutFilePath (Join-Path [environment]::GetFolderPath([environment+specialfolder]::Programs) "CrystalDiskInfo.lnk") -targetPath (Join-Path $(Split-Path -parent $MyInvocation.MyCommand.Definition) "DiskInfo.exe" )

untested though...

@saneki
Copy link
Author

saneki commented Aug 23, 2015

That's rather cumbersome, and (I believe) makes the assumption that the destination's parent directory exists, which would affect it if CrystalDiskInfo.lnk was in a subdirectory. Also, that example wouldn't translate well to shortcut-ing multiple files.

Although I'm proposing a start menu helper, I'm not proposing that it be the only way to manipulate the start menu. I just figured that manipulating the start menu is something a lot of packages would be interested in doing, so there might as well be an optional helper to make it as easy as possible. Isn't that the purpose of a helper anyways? Why even bother having Install-ChocolateyShortcut when you could just use this?

@aronovgj
Copy link

valid arguments. lets see what @ferventcoder thinks

@ferventcoder
Copy link
Member

Related to #344, but still different.

I like the idea, but I was thinking less of a helper, and more of a preference on the user end. The idea for helpers is still there and making a helper that works on top of Install-ChocolateyShortcut just passing the right things so you can just Install-StartMenu and not have to know that it goes to Common Programs directory on some operating systems and other places on other OS versions would be nice.

@ferventcoder ferventcoder changed the title [Enhancement] Helper for creating/removing shortcuts in (Common)Programs directory Install-StartMenu Helper Aug 24, 2015
@qzo
Copy link

qzo commented Aug 26, 2015

I'd like for the helper to allow creating (and naming) multiple shortcuts, maybe like this (I'm no PowerShell expert):

Install-ChocolateyStartMenu -Path "Some application" -Items @('app1.exe', @{'File' = 'app2.exe'; 'Name' = 'Application 2'}, 'app3.exe')

I assume Auto uninstaller would remove the Start Menu directory, so Uninstall-ChocolateyStartMenu might not be needed eventually.

In my case that would save quite a lot of code (see CreateStartMenuShortcuts function), making the install script shorter, which might help the moderators and others who want to review what it does:
https://github.com/qzo/chocolatey-packages/blob/6b892168b853ce537cf9f1b25aa2009f5f266a5a/packages/manual/higan/tools/chocolateyinstall.ps1

@DarwinJS
Copy link
Contributor

How about if I role this into #519 as follows:

If shortcut path comes in without a ":" in it, assume it might be a special folder value path in the form "CommonStartMenu\shortcutname.lnk"

Parse the special folder value ("CommonStratMenu" in the example) and validate it against the list returned by [Environment+SpecialFolder]::GetNames([Environment+SpecialFolder])

If it does not pass, reject the path as not a valid reference and not on the list of special folders in this user and process execution context ONLY On an error - output the values from [Environment+SpecialFolder]::GetNames([Environment+SpecialFolder]) to the log so that package builders and users don't have to create special code to try to find out what folders are available in a given special context (e.g. SYSTEM account context under SCCM on a pure 32-bit OS).

If it does pass, use [environment]::getfolderpath("CommonStartMenu") to retrieve and use the value throughout.

In the help for the ShortcutFilePath parameter detail:
*) The ability to use special folder values.
*) The most commonly used special values and which are machine vs user - like CommonStartMenu, CommonDesktopDirectory, CommonStart, CommonPrograms, StartMenu (user), DesktopDirectory (user), Programs (user), SendTo (user)
*) That the user can enumerate the available special folders for a given user / process context with [Environment+SpecialFolder]::GetNames([Environment+SpecialFolder])

@DarwinJS
Copy link
Contributor

Here is the working code:

$ShortcutFilePath = "CommonDesktopdirectory\abc.lnk"

If ($ShortCutFilePath -inotlike "_:_")
{
$SpecialFolderCandidate = ($shortcutfilepath.split(""))[0]
If (@([Environment+SpecialFolder]::GetNames([Environment+SpecialFolder])) -icontains $SpecialFolderCandidate)
{
$shortcutfilepath = $shortcutfilepath.replace($SpecialFolderCandidate,[environment]::getfolderpath($SpecialFolderCandidate))
}
Else
{# Error
Write-error "$SpecialFolderCandidate is not a valid path reference and is not on the list"
Write-error "of special folders available in this process and user context, available folders are:"
([Environment+SpecialFolder]::GetNames([Environment+SpecialFolder])) | out-string | out-default
}
}
Write-output "`$shortcutfilepath is: $shortcutfilepath"

@ferventcoder
Copy link
Member

@DarwinJS that's a good start. I think folks also want an easy function they can call as well.

@DarwinJS
Copy link
Contributor

Sure I could put this in the Install-ChocolateyShortcut and create a set of encapsulating functions.

It looks like the rule is one function per *.ps1 ?

Which shortcut areas merit their own function - just the Machine Start Menu? Also by Machine Start menu I assume you all probably mean under the "Programs" folder of the start menu?

Should the easy function allow the specification of a sub folder?

Rob - I am thinking that maybe Install-ChocolateyShortcut should auto-create create any non-existent folder levels in the target shortcut path so that there does not have to be a separate step to create a sub-menu folder?

@ferventcoder
Copy link
Member

It would be nice if it was smart enough to create missing folder structure.

@alexchandel
Copy link

alexchandel commented Jun 1, 2016

All of these hacks for Install-ChocolateyShortcut that involve [environment]::GetFolderPath are hideous not pretty code. The (API) consumer shouldn't have to do all of that to perform such a common task.

For example, from the ConsoleZ package, something like this:

Install-ChocolateyStartMenu -Path "ConsoleZ" -Name "Console" -Target "tools/Console.exe"

should create a shortcut at /ProgramData/Microsoft/Windows/Start Menu/Programs/Chocolatey/ConsoleZ/Console.lnk that points to /ProgramData/chocolatey/lib/ConsoleZ/tools/Console.exe, creating both the Chocolatey folder and the ConsoleZ folder if necessary.

And something like this:

Install-ChocolateyStartMenu -Name "ConsoleZ" -Target "tools/Console.exe"

should create a shortcut at /ProgramData/Microsoft/Windows/Start Menu/Programs/Chocolatey/ConsoleZ.lnk that points to /ProgramData/chocolatey/lib/ConsoleZ/tools/Console.exe.

Shortcut folders should be within /ProgramData/Microsoft/Windows/Start Menu/Programs/Chocolatey/ by default to avoid collisions with other installers, and because Chocolatey is simply a different means of installation.

And chocolatey should track and automatically remove such shortcuts when uninstalling (per #711).

@ferventcoder
Copy link
Member

@alexchandel None of these are consumer-centric - they are package-centric.

@alexchandel
Copy link

@ferventcoder That's what I mean. The consumer of the API.

@ferventcoder
Copy link
Member

I'm not following - expecting a package creator to use PowerShell is normal. So the word "hideous" throws me because package consumers (those using Chocolatey) don't see any of this for the most part.

@rgl
Copy link

rgl commented May 3, 2017

Has this landed on choco in some form?

@rgl
Copy link

rgl commented May 3, 2017

FWIW, I ended up using the following at rgl/liteide-chocolatey-package:

Install-ChocolateyShortcut `
  -ShortcutFilePath "$([Environment]::GetFolderPath('CommonStartMenu'))\Programs\LiteIDE.lnk" `
  -TargetPath "$installPath\liteide\bin\liteide.exe"

@ferventcoder ferventcoder modified the milestone: 0.10.9 Aug 27, 2017
@ferventcoder ferventcoder modified the milestones: 0.10.10, 0.10.9 Aug 29, 2017
@ferventcoder ferventcoder modified the milestones: 0.10.10, 0.10.12 Mar 27, 2018
@ferventcoder ferventcoder modified the milestones: 0.10.12, 0.10.13 May 3, 2018
@ferventcoder ferventcoder modified the milestones: 0.10.13, 0.10.14, 0.10.15 Mar 9, 2019
@ferventcoder ferventcoder modified the milestones: 0.10.15, 0.10.16 Apr 1, 2019
@gep13 gep13 modified the milestones: 0.10.16, 0.10.17 May 31, 2019
@ferventcoder ferventcoder modified the milestones: 0.10.17, 0.10.18 Jan 14, 2020
@cmorty
Copy link

cmorty commented Aug 2, 2020

I'd really love to see this. Especially with zip-Packages this would make life easier as it would allow getting rid of the chocolateyUninstall.ps1 in many cases. This would also allow to make things even more generic and allow using global flags like /noStartmenu (assuming most people want a start menu entry) and /Desktopshortcut (assuming most people, don't want their desktop littered).

@cmorty
Copy link

cmorty commented Aug 2, 2020

I even found two coreteam packages that would profit from a helper that also automatically removes the shortcut when uninstalling:

I'm sure there are many more out there..... :)

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

No branches or pull requests

9 participants