QInstall An alternative to Windows uninstaller

This tool allows you to uninstall programs as well as see when they were installed. It lets you search through the apps. It can remove files left over by the program. It can clean clean the uninstall registry key.

To see how to use it just open the exe file.

QInstall query on Pale Moon
program qinstall;

{$apptype console}
{$RESOURCE QINSTALL-32.RES}
uses
  SysUtils,filectrl,
  windows,shellapi,
  Classes;
const KiloBytes=1.0;
MegaBytes=1024*kilobytes;
GigaBytes=1024*megabytes;
ERROR_REGOPENKEY='RegOpenKey: %s';
prompt_yesno='Type yes or no: ';
filesize_fmt='#,##0.000';
reg_installdir='InstallLocation';
error_regdeletekey='RegDeleteKey: %s';
error_regqueryvalueex='RegQueryValueEx: %s';
var uninstallkey:hkey;
appcount:dword;
ftUninstall:filetime;
Command_Switch:String;
stinfo:systemtime;
err:longint;

function FormatLanguage(lpLang:pchar):string;
var langs:tstringlist;
begin
langs:=tstringlist.Create;
langs.CommaText:=stringreplace(lpLang,';',',',[rfReplaceall]);
result:=langs[0];
langs.Free;
end;

function GetLanguageID(lang:word):string;
var hklangs:hkey;
rs:dword;
langsz:array[0..4]of char;
language:array[0..128]of char;
begin
rs:=129;
regopenkey(hkey_classes_root,'MIME\Database\Rfc1766',hklangs);
regqueryvalueex(hklangs,Strpcopy(langsz,inttohex(lang,4)),nil,nil,@language,@rs);
regclosekey(hklangs);result:=formatlanguage(language);
end;

function FormatRegValue(const RegName:string;data:array of byte;
DataType:dword):String;
var x,y:extended;
lpdw:pdword;
lpStr:pchar;
metric:char;
begin
lpdw:=@data[0];
lpstr:=@data[0];
result:=regname+':';
if lowercase(regname)='estimatedsize'then begin x:=lpdw^;metric:='K';y:=x;
if x>=megabytes then begin y:=x/megabytes;metric:='M';end;
if x>=gigabytes then begin y:=x/gigabytes;metric:='G';end;
result:=result+formatfloat(filesize_fmt,y)+#32+Metric+'B';
end else if lowercase(regname)='language'then result:=result+GetLanguageID(lpdw^)
else case datatype of
reg_sz,reg_expand_sz:result:=regname+':'+strpas(lpstr);
reg_dword:result:=regname+':'+inttostr(lpdw^);
end;
end;

procedure listsoftware;
var i,j:integer;
st:systemtime;
hkapp:hkey;
ftinstalled:filetime;
progname,vname:array[0..max_path]of char;
value:array[0..2048]of byte;
vcount,typ,rs,ns:dword;
begin
for i:=0to appcount-1do
begin
regenumkey(uninstallkey,i,progname,max_path);
if(pos(lowercase(paramstr(2)),lowercase(progname))>0)or(paramcount=1)then begin
writeln('AppName:',progname);
regopenkey(uninstallkey,progname,hkapp);
regqueryinfokey(hkapp,nil,nil,nil,nil,nil,nil,@vcount,nil,nil,nil,@ftinstalled);
filetimetosystemtime(ftinstalled,st);
writeln('Program installed: ',datetimetostr(systemtimetodatetime(st)));
for j:=0to vcount-1 do begin ns:=max_path;rs:=2048;regenumvalue(hkapp,j,vname,ns,
nil,@typ,@value,@rs);writeln(formatregvalue(vname,value,typ));end;
regclosekey(hkapp);writeln;
end;
end;
end;

procedure uninstallinfo;
begin
writeln('Last Install/Uninstall: ',datetimetostr(systemtimetodatetime(stinfo)));
writeln('There are ',formatfloat('#,###',appcount),' programs installed');
end;

function execString(commandline:pchar):longint;
var urlexec:shellexecuteinfo;
confirm:string;
label badconfirm,skipconfirm;
begin
result:=0;
if lowercase(paramstr(4))='/yes'then confirm:='yes';
if confirm='yes' then goto skipconfirm;
badconfirm:write(prompt_yesno);
readln(confirm);
if(confirm<>'yes')and(confirm<>'no')then goto badconfirm;
if confirm='no'then exit;
skipconfirm:
result:=winexec(commandline,sw_show);
if result<32 then begin zeromemory(@urlexec,sizeof(urlexec));urlexec.cbSize:=
sizeof(urlexec);urlexec.fMask:=see_mask_nocloseprocess or see_mask_flag_no_ui;
result:=33;urlexec.lpFile:=commandline;urlexec.nShow:=sw_show;
if not shellexecuteex(@urlexec)then begin result:=urlexec.hInstApp;exit;end;
waitforsingleobject(urlexec.hprocess,infinite);closehandle(urlexec.hProcess);
end;
end;

function removetree(const Dir:string):longint;
var comspec,params:array[0..max_path+15]of char;
shellexec:shellexecuteinfo;
begin
getenvironmentvariable('ComSpec',comspec,max_path+15);
zeromemory(@shellexec,sizeof(shellexec));
shellexec.cbsize:=sizeof(shellexec);
shellexec.lpfile:=comspec;
shellexec.lpparameters:=strplcopy(params,'/C RD /S /Q "'+dir+'"',max_path+15);
shellexec.fMask:=see_mask_nocloseprocess or see_mask_no_console or
SEE_MASK_FLAG_NO_UI;
shellexec.nShow:=sw_show;
result:=33;
if not shellexecuteex(@shellexec)then begin result:=shellexec.hInstApp;exit;end;
waitforsingleobject(shellexec.hprocess,infinite);
closehandle(shellexec.hProcess);
end;

procedure RemoveFiles;
var confirm:string;
installdir,progname:array[0..max_path]of char;
rs:dword;
hkapp:hkey;
err:longint;
label badconfirm1,skipwarning;
begin
if paramcount<2 then raise exception.Create('Need more parameters');
err:=regopenkey(uninstallkey,strplcopy(progname,paramstr(2),max_path),hkapp);
if err<>error_success then raise exception.CreateFmt(Error_regopenkey,[
syserrormessage(err)]);
rs:=max_path+1;
err:=regqueryvalueex(hkapp,reg_installdir,nil,nil,@installdir,@rs);
if err<>error_success then raise exception.CreateFmt(ERROR_REGQUERYVALUEEX,[
syserrormessage(err)]);
if uppercase(paramstr(3))='/YES'then confirm:='yes';
if confirm='yes'then goto skipwarning;
writeln('Warning you are about to delete everything in "',installdir,'" continue?');
badconfirm1:
write(prompt_yesno);readln(confirm);confirm:=lowercase(confirm);
skipwarning:
case confirm[1] of
'y':begin removetree(installdir);regclosekey(hkapp);err:=regdeletekey(
uninstallkey,progname);if err<>error_success then writeln(error_regdeletekey,
syserrormessage(err));exit;end;
'n':writeln('Deletion canceled');
end;
regclosekey(hkapp);
end;

procedure cleanregistry;
var szPath,progname:array[0..max_path]of char;
hkapp:hkey;
rs:dword;
i:integer;
err:longint;
begin
for I:=0to appcount-1do begin regenumkey(uninstallkey,i,progname,max_path);
strcopy(szpath,'');rs:=max_path+1;regopenkey(uninstallkey,progname,hkapp);
regqueryvalueex(hkapp,reg_installdir,nil,nil,@szpath,@rs);regclosekey(hkapp);
if(strlen(szPath)>0)and(not directoryexists(szpath))then begin err:=regdeletekey(
uninstallkey,progname);if err<>error_success then writeln('Found:',progname,' - ',
syserrormessage(err));
end;
end;
end;

procedure searchexec;
var hkapp:hkey;
progname,cmdline1,cmdline2,szName:array[0..max_path]of char;
typ,err,rs:dword;
i:integer;
begin
if paramcount<3then raise Exception.Create('Need search_text and method strings');
strpcopy(szName,paramstr(2));
for i:=0to appcount-1do begin regenumkey(uninstallkey,i,progname,max_path);
if pos(lowercase(paramstr(3)),lowercase(progname))>0then begin writeln('Found:',
progname);
err:=regopenkey(uninstallkey,progname,hkapp);
if err<>error_success then raise exception.CreateFmt(error_regopenkey,[
syserrormessage(err)]);
rs:=max_path+1;
err:=regqueryvalueex(hkapp,szname,nil,@typ,@cmdline1,@rs);
if err<>error_success then begin regclosekey(hkapp);raise exception.CreateFmt(
error_regqueryvalueex,[syserrormessage(err)]);end;
case typ of
reg_sz:strcopy(cmdline2,cmdline1);
reg_expand_sz:expandenvironmentstrings(cmdline1,cmdline2,max_path);
else raise
exception.CreateFmt('The value "%s" is not a REG_SZ or REG_EXPAND_SZ value',[
paramstr(2)]);
end;//case end
err:=execstring(cmdline2);
if(err<33)and(err>0)then writeln('ExecError:',syserrormessage(err));
regclosekey(hkapp);
end;
end;
end;

begin
if paramcount=0then begin
writeln('Usage: ',extractfilename(paramstr(0)),' [/LIST "seach_text"] [/EXEC "method" "search_text" [/YES]] [/REM "appname" [/YES]] [/CLEAN] [/INFO]');
writeln('Parameters:');
writeln('/LIST         Lists software that is installed on here. The next parameter is the optional search text.');
writeln('/EXEC         Executes a string found in the app that matches ["search_text"]');
writeln('method string can be QuietUninstallString,UninstallString,URLInfoAbout,HelpLink,URLUpdateInfo, or Readme');
writeln('/CLEAN        Removes any uninstaller registry information left over by an uninstalled program.');
writeln('/INFO         Shows last install/uninstall information');
writeln('/REM          Remove the directory of files left over. This should be used only when the program fails to uninstall. To uninstall a program use /EXEC command switch with "UninstallString" as the method');
writeln('/YES          Automatically use yes option on prompts');
write('Press enter to return...');readln;exitprocess(0);
end;
try
err:=regopenkey(HKEY_LOCAL_MACHINE,
'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall',uninstallkey);
if err<>error_success then raise exception.CreateFmt(error_regopenkey,[
syserrormessage(err)]);
err:=regqueryinfokey(uninstallkey,nil,nil,nil,@appcount,nil,nil,nil,nil,nil,nil,
@ftuninstall);filetimetosystemtime(ftuninstall,stinfo);
if err<>error_success then raise exception.CreateFmt('RegQueryInfoKey: %s',[
syserrormessage(err)]);
command_switch:=uppercase(paramstr(1));
if '/LIST'=command_switch then listsoftware else
if '/INFO'=command_switch then uninstallinfo else
if '/EXEC'=command_switch then searchexec else
if '/REM'=command_switch then removefiles else
if '/CLEAN'=command_switch then cleanregistry else
writeln('Unknown command "',paramstr(1),'"');
except on e:exception do writeln(e.message);end;
regclosekey(uninstallkey);
end.

Published by Justin Roeder

I am an electronics engineer and computer programmer that has autism. I learned by myself

Join the Conversation

40 Comments

  1. I absolutelү love your blog and find thе majority of youг
    post’s to Ьe exactly whаt I’m looking for. Do you offer guest writers tߋ write content fоr y᧐u?
    Ι wоuldn’t mind composing a post օr elaborating oon sߋme ᧐f
    tһe subjects you write wіth reցards tߋ hегe.
    Аgain, awesome blog!

  2. Admiringg the commitment you put ino your blog and in depth information you offer.
    It’s great to come across a blog every once in a while that isn’t the same
    unwanted rehashed material. Great read! I’ve bookmarked your site annd I’m
    adding your RSS feeds to my Google account.

  3. Hey just wanted to give you a quick hewads up. The
    text in your post seem to bee running off the screen in Safari.
    I’m not sure if this is a formatting issue or something to do with internet browser compatibility butt I thought I’d post to let you know.
    The style aand design look great though! Hopee you
    get the issue solved soon. Kudos

  4. Greetings from Ohio! I’m bored att work so I decided to browse your website on my iphone during
    lunch break. I really like the knowledge you provide here and can’t wait to take a look wen I get home.
    I’m shocked at how quick your bpog loaded on my cell phone ..
    I’m not even using WIFI, just 3G .. Anyhow, excellent blog!

  5. Hi! Quick question that’s totally off topic. Do you know how to make your site
    mobile friendly? My site looks weird when browsing from my iphone 4.
    I’m trying to find a theme or plugin that might be able to correct this issue.
    If you have any recommendations, please share. With thanks!

  6. It’s a shame you don’t have a donate button! I’d most certainly donate
    to this superb blog! I guess for now i’ll settle for book-marking
    and adding your RSS feed to my Google account. I look forward
    to brand new updates and will talk about this blog with my Facebook group.
    Talk soon!

  7. I’m really loving the theme/design of your blog. Do you ever run into any web browser compatibility problems?
    A couple of my blog readers hav complained about my blg not working correctly in Explorer but looks great in Firefox.
    Do you have any ideas to help fix thiis problem?

  8. We stumbled over here from a different web page and thought I might as well check things
    out. I like what I see so now i am following you.

    Look forward to looking into your web page for a second time.

  9. I have learn a few excellent stuff here. Certаinly vаlue bookmarking fօr revisiting.

    Ӏ wondеr how a lot effort you set to make suxh а great informative website.

  10. An impressive share! I have just forwarded this onto a coworker who has
    been conducting a little homework on this. And he actually bought me breakfast due to the fact that I
    found it for him… lol. So allow me to reword this….
    Thanks for the meal!! But yeah, thanks for spending the time to talk about this subject here on your web site.

  11. Long time reader, first time commenter — so, thought I’d drop
    a comment.. — and at the same time ask for a favor.

    Your wordpress site is very simplistic – hope you don’t mind me asking what theme you’re using?
    (and don’t mind if I steal it? :P)

    I just launched my small businesses site –also built in wordpress like yours– but
    the theme slows (!) the site down quite a bit.

    In case you have a minute, you can find it by searching for “royal cbd” on Google
    (would appreciate any feedback)

    Keep up the good work– and take care of yourself during the coronavirus scare!

    ~Justin

Leave a comment

Your email address will not be published. Required fields are marked *