Recent

Author Topic: Getting the list of installed programs  (Read 13871 times)

lainz

  • Hero Member
  • *****
  • Posts: 4741
  • Web, Desktop & Android developer
    • https://lainz.github.io/
Re: Getting the list of installed programs
« Reply #15 on: September 23, 2016, 01:01:30 am »
Hi, here is the code https://github.com/lainz/lainzuninstall

But I need help making a proper execute command, currenly it will only do a cmd run of the command that is stored in the registry, but it seems that requires another method of execution or parsing the string, since there are very different commands to just load the data and run.

rvk

  • Hero Member
  • *****
  • Posts: 6953
Re: Getting the list of installed programs
« Reply #16 on: September 23, 2016, 09:31:13 am »
Code: Pascal  [Select][+][-]
  1.   {$IFDEF Win32}
  2.   IterateRegistry(KEY_WRITE);
  3.   {$ENDIF}
  4.   {$IFDEF Win64}
  5.   IterateRegistry(KEY_WOW64_64KEY);
  6.   IterateRegistry(KEY_WOW64_32KEY);
  7.   {$ENDIF}
Woops. I said this was correct but it isn't.
{$IFDEF WIN32} is not is you RUN on Win64bit but if you use Lazarus 32bit. And even if you use Lazarus 32bit you can still use the KEY_WOW64_64KEY to find the 64bit programs.

I checked out your code and was surprised to find 64bit entries while I compiled with Lazarus 32bit. But then I saw the code
Code: Pascal  [Select][+][-]
  1.   LoadEntries(KEY_WOW64_32KEY, HKEY_LOCAL_MACHINE);
  2.   LoadEntries(KEY_WOW64_64KEY, HKEY_LOCAL_MACHINE);
so you didn't have the IFDEF in there.

So the IFDEF is not needed for compiling between 32/64 bit. They always work in Windows 64bit.
if they work on Windows 32bit I don't know yet. If the key does nothing you might end up with duplicate entries. So you might have to do this:
Code: Pascal  [Select][+][-]
  1. if OnWindows64bit then // <-- is there such a function already ?
  2. begin
  3.   LoadEntries(KEY_WOW64_32KEY, HKEY_LOCAL_MACHINE);
  4.   LoadEntries(KEY_WOW64_64KEY, HKEY_LOCAL_MACHINE);
  5. end
  6. else
  7. begin
  8.   LoadEntries(0, HKEY_LOCAL_MACHINE);
  9. end;

But I need help making a proper execute command, currenly it will only do a cmd run of the command that is stored in the registry, but it seems that requires another method of execution or parsing the string, since there are very different commands to just load the data and run.
Example?
Edit: O, you mean that you now have this:
Code: Pascal  [Select][+][-]
  1.     proc := TProcessUTF8.Create(Self);
  2.     proc.Executable := 'cmd.exe /C "' + UninstallData + '"';
and you want to call the regular uninstall without cmd.exe of course.
But doesn't TProcess have a CommandLine-property where you can pass a complete command with parameters and it will automatically separate them ???
So shouldn't this be enhough?
Code: Pascal  [Select][+][-]
  1. proc.CommandLine := UninstallData;



Extra note...:
If you compile under 32bit you can show all programs (including the 64bit programs). But I'm not sure you can uninstall those 64bit programs. An uninstallstring might be "C:\Program Files\Greenshot\unins000.exe" but I'm not sure how a 32bit program would execute a uninstall program in C:\Program Files\ because that's virtualized to C:\Program Files (x86). So if that's the case you might want to show the 64bit programs in grey and/or if they click to uninstall a 64bit program advise them to download the 64bit version of the lainzuninstall.
« Last Edit: September 23, 2016, 09:45:41 am by rvk »

lainz

  • Hero Member
  • *****
  • Posts: 4741
  • Web, Desktop & Android developer
    • https://lainz.github.io/
Re: Getting the list of installed programs
« Reply #17 on: September 23, 2016, 06:06:09 pm »
Hi rvk, the CommandLine of TProcess is deprecated and does nothing. However adding the quotes
Code: Pascal  [Select][+][-]
  1. 'cmd.exe /C "' + UninstallData + '"';
worked in most cases, a few only doesn't works like AVG setup and others that I need to list.

Yes I noticed that the ifdef was not working so I removed it from the application. I will add your code to check if 64 bit os. Edit: Ok, reading again, I need to find that code :)

Also there are applications registered in HKCU not only in HKLM, I've added that line.

There are applications that are MSI installers so these don't have the data pointing to the executable to uninstall, but they have a GUID that must be passed like this:
Code: Pascal  [Select][+][-]
  1. 'msiexec.exe /X' + GUID;
This is in one more recent commit.

However I can't say if all apps that have a GUID that don't have a "unintall string" are MSI installers. Of course the MSI uninstall window will appear since I send a valid GUID but that don't means that they will be uninstalled or not, I actually need to uninstall that applications with the app to see if works as expected.

The problem of uninstalling a 64 bit app with a 32 bit application should work because I run cmd and that is always 64 bits that run the process of uninstall.

rvk

  • Hero Member
  • *****
  • Posts: 6953
Re: Getting the list of installed programs
« Reply #18 on: September 23, 2016, 07:33:00 pm »
Yes I noticed that the ifdef was not working so I removed it from the application. I will add your code to check if 64 bit os. Edit: Ok, reading again, I need to find that code :)
Using IsWow64Process on the GetCurrentProcess.

But there is a wiki for that :D
http://wiki.freepascal.org/Detect_Windows_x32-x64_example

A shame commandline is deprecated. For the cmd.exe... you might want to create the process minimized or even as hidden window so you don't see the black-box before/during uninstall. It is even possible to call cmd.exe with start and start the uninstall-string and directly exiting the cmd process.
Something like
cmd.exe /c start /min commandstring

lainz

  • Hero Member
  • *****
  • Posts: 4741
  • Web, Desktop & Android developer
    • https://lainz.github.io/
Re: Getting the list of installed programs
« Reply #19 on: September 23, 2016, 09:48:59 pm »
I will try that wiki article thanks.

 

TinyPortal © 2005-2018