45

I had installed Zotero using winget install Zotero.Zotero and it installed fine in C:\Program Files (x86)\Zotero. But when I run winget upgrade, it shows two Zotero versions, like so:

Name   Id            Version Available Source
---------------------------------------------
Zotero Zotero.Zotero 6.0.10  6.0.13    winget
Zotero Zotero.Zotero 6.0.9   6.0.13    winget
2 upgrades available.

I have verified that the currently installed Zotero version is 6.0.13. Since I have had prior installations of Zotero with and without winget, I think, these entries might reflect those installations. So, I wanted to uninstall / remove these without removing version 6.0.13, currently installed at C:\Program Files (x86)\Zotero.

My question is, how do I make winget show the installation directories for these two versions, so that I can manually remove them?

ᄂ ᄀ
  • 4,187
P_0
  • 551

4 Answers4

28

Update 2023-04-17

It seems winget version v1.5.1081-preview and above (those including PR3128), include info on default directories by running winget --info.

output from winget --info

There's also an open issue to be able to list the directories per app (Issue 2298).

Regarding Zotero itself, I couldn't find a package with ID Zotero.Zotero, but did find DigitalScholar.Zotero. That shows that the default installer's used, so the default path would be the same as the app's (from hunting around their docs this seems to be C:\Program Files (x86)\Zotero, though I've not seen anything explicit).

Note: It's possible that your additional version of Zotero.Zotero doesn't exist on disk; but only exists in WinGet's database (e.g. if it were installed then the path deleted without WinGet being aware). See "Failed Attempt to Hunt Out Metadata" for info on how to query that database).


Original Answer

The exact location depends on the package & so far as I can tell there's currently no way to fetch that info for all installed winget packages.

For those which don't have installers, but are just files downloaded, they're put under a folder under: %localappdata%\microsoft\winget\packages

Where there's an exe with a portable command alias (i.e. to avoid having to add each exe's path to your PATH variable), a symlink is created. That symlink is held in %localappdata%\Microsoft\WinGet\Links\.

Note: Some apps' manifests may specificy a default install directory. That's given in their InstallLocation property (see schema).


Failed Attempt to Hunt Out Metadata

I wondered if you could find the path under which WinGet stores the metadata of packages installed... I couldn't - but notes below in case this helps others hunt deeper (my conclusion is that WinGet doesn't remember where it installs things, only that it has installed them / what version it installed; everything else is left to the default installer).

You can get the path for its settings file by running winget settings then looking at the path of the settings.json file that this opens. For me this was: C:\Users\myUsername\AppData\Local\Packages\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe\LocalState\settings.json

By poking around in that directory I found a SQLLite DB: C:\Users\myUsername\AppData\Local\Packages\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe\LocalState\Microsoft.Winget.Source_8wekyb3d8bbwe\installed.db.

We can query this file/database using the below PowerShell:

# Load the System.Data.SQLite.dll assembly.  This is likely already somewhere on your machine, but if you can't find it, see https://system.data.sqlite.org/index.html/doc/trunk/www/downloads.wiki
Add-Type -Path 'C:\Program Files\Microsoft Visual Studio\2022\Professional\Common7\IDE\PrivateAssemblies\System.Data.SQLite.dll'

Update this path with your install.db path

$installDbPath = 'C:\Users\myUsername\AppData\Local\Packages\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe\LocalState\Microsoft.Winget.Source_8wekyb3d8bbwe\installed.db'

create a connection to this db

$con = [System.Data.SQLite.SQLiteConnection]::new("Data Source=$installDbPath") $con.Open()

Create and execute a query to list all tables (thanks to https://stackoverflow.com/a/14623907/361842 for the SQL)

$command = $con.CreateCommand() $command.CommandText = @" SELECT name FROM sqlite_master WHERE type IN ('table','view') AND name NOT LIKE 'sqlite_%' UNION ALL SELECT name FROM sqlite_temp_master WHERE type IN ('table','view') ORDER BY 1; "@ $data = [System.Data.DataSet]::new() $adapter = [System.Data.SQLite.SQLiteDataAdapter]::new($command) $adapter.Fill($data) | Out-Null $data.Tables.Rows

channels

commands

commands_map

ids

manifest

manifest_metadata

metadata

monikers

names

norm_names

norm_names_map

norm_publishers

norm_publishers_map

pathparts

pfns

pfns_map

productcodes

productcodes_map

tags

tags_map

versions

Now repeat over the IDs table to give the IDs of all installed packages

$command.CommandText = "SELECT * FROM ids" $data = [System.Data.DataSet]::new() # reset this to avoid appending $adapter.Fill($data) #note: adapter has a reference to $command, so by updating the command text the adapter's command is automatically updated $data.Tables.Rows | ft -AutoSize

sadly I hunted through all the other tables but couldn't find any hint of an installation directory being stored here

1

To the ones still looking for an answer, this works for me:

winget list -q $id | Out-Null
if ($?) {  echo "$id installed" }
1

I have installed hurl with winget install hurl

To find where it has been installed, I have done the next

  1. winget uninstall hurl
  2. have seen warning about changes (that may be dependent on CLI used)
  3. have seen uninstall popup where I was able to see path

That is an uninstall popup: uninstall popup

Nikita
  • 133
0

I couldn't find anything matching among winget command line options.

But a partial workaround is to use where command to search by executable name.

Like where zotero

Vadzim
  • 1,342