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

Leave a comment

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