Eagle
03-07-2006, 11:59 PM
A while back I cooked up some code to assist with some of the various
detection aspects for Product Installers
I have modified things a bit to make for a more generic code template, if you like:
(also added option to run the installed Application via dialog message for those that want it)
Could some of you run some tests on this code, report bugs, weaknesses etc
--For Global Functions:
function IsInstallerRunning()
local ncnt = 0;
local tImageInst = System.EnumerateProcesses();
if tImageInst then
Table.Sort(tImageInst, nil);
for procid, image_path in tImageInst do
if (String.CompareNoCase(image_path, strInstallerPath) == 0) then
ncnt = ncnt + 1;
if (ncnt > 1) then
return true; --reasonable verification another instance of this Installer is running
end
end
end
end
return false;
end
function IsProductRunning()
local tImages = System.EnumerateProcesses();
if tImages then
for procid, binimage_path in tImages do
if (String.Find(binimage_path, strAppFolderPath, 1, false) ~= -1) then
local tAppVerinfo = File.GetVersionInfo(binimage_path);
if tAppVerinfo then
if (tAppVerinfo.FileVersion >= strAppMinVer) and (tAppVerinfo.ProductName == strAppVerProdName) then
return true; --reasonable verification target product is already running
end
end
end
end
end
return false;
end
function IsProductInstalled()
strAppFolderPath = Registry.GetValue(HKEY_LOCAL_MACHINE, strAppMainkey, "InstallPath", true);
if (strAppFolderPath ~= "") then
local tAppVerinfo = File.GetVersionInfo(strAppFolderPath.."\\"..strAppBinName);
if tAppVerinfo then
--attempt file version specs verification
if (tAppVerinfo.FileVersion >= strAppMinVer) and (tAppVerinfo.ProductName == strAppProdName) then
return true; --reasonable verification target product is installed
end
end
end
return false;
end
--For On Startup Event:
Application.Sleep(100);
---- Set your target Application lua variables ----
strProductDislpayName = SessionVar.Expand("%ProductName%");
strAppBinName = "MainApp.exe";
--now set file version specification target variables
strAppMinVer = "4.0.0.0"; --internal 'fileversion' spec to verify
strAppVerProdName = "TheProductName"; --internal 'productname' spec to verify
strInstallerPath = _SourceFilename; --full path to running Installer.exe
--now set registry key-s to target and value-s(these were or will be created during a full install routine)
--(note: for example purposes the valuename is set as 'InstallPath' in related global function)
strAppMainkey = "Software\\My Application";
---- First lets check if the Installer is already running ----
if IsInstallerRunning() then
Application.Exit(0); --nothing to do, previous instance of installer at work, so exit now
else
--- Now Call the Target Application Detection Routines (functions) ---
if IsProductInstalled() then
-- the product appears to be installed, so call function to check if MainApp.exe is already running
if IsProductRunning() then
Application.Exit(0); --nothing to do exit now
else
-- apparently MainApp.exe is not running so offer to start it up for the user
local RunApp = Dialog.Message(" - "..strProductDislpayName.." Information -", "Do you wish to run "..strProductDislpayName.." now", MB_YESNO, MB_ICONQUESTION, MB_DEFBUTTON1);
if (RunApp == 6) then
File.Run(strAppFolderPath.."\\"..strAppBinName, "", "", SW_SHOWNORMAL, false); --run the MainApp.exe
local nerror = Application.GetLastError();
if (nerror == 0) then
Application.Exit(0); --could set a different return code for a log file reference(indicating already installed)
else
Dialog.Message("Error: "..strProductDislpayName.." Failed to Start", _tblErrorMessages[error], MB_OK, MB_ICONINFORMATION, MB_DEFBUTTON1);
Application.Exit(0); --could set a different return code for log file reference(indicate already installed but could not be started)
end
else
Application.Exit(0); --user chose not to run the MainApp.exe, so exit now
end
end
end
end
just modify the string variables in the on startup code to test.
(you need to have the target registry key and valuename for proper functionality)
for sure expanded functionality such as CRC and MD5 checks, encrypted paths, additional path checks etc. can be added...
once we get things nice and solid..will post the final code in the Examples Section
detection aspects for Product Installers
I have modified things a bit to make for a more generic code template, if you like:
(also added option to run the installed Application via dialog message for those that want it)
Could some of you run some tests on this code, report bugs, weaknesses etc
--For Global Functions:
function IsInstallerRunning()
local ncnt = 0;
local tImageInst = System.EnumerateProcesses();
if tImageInst then
Table.Sort(tImageInst, nil);
for procid, image_path in tImageInst do
if (String.CompareNoCase(image_path, strInstallerPath) == 0) then
ncnt = ncnt + 1;
if (ncnt > 1) then
return true; --reasonable verification another instance of this Installer is running
end
end
end
end
return false;
end
function IsProductRunning()
local tImages = System.EnumerateProcesses();
if tImages then
for procid, binimage_path in tImages do
if (String.Find(binimage_path, strAppFolderPath, 1, false) ~= -1) then
local tAppVerinfo = File.GetVersionInfo(binimage_path);
if tAppVerinfo then
if (tAppVerinfo.FileVersion >= strAppMinVer) and (tAppVerinfo.ProductName == strAppVerProdName) then
return true; --reasonable verification target product is already running
end
end
end
end
end
return false;
end
function IsProductInstalled()
strAppFolderPath = Registry.GetValue(HKEY_LOCAL_MACHINE, strAppMainkey, "InstallPath", true);
if (strAppFolderPath ~= "") then
local tAppVerinfo = File.GetVersionInfo(strAppFolderPath.."\\"..strAppBinName);
if tAppVerinfo then
--attempt file version specs verification
if (tAppVerinfo.FileVersion >= strAppMinVer) and (tAppVerinfo.ProductName == strAppProdName) then
return true; --reasonable verification target product is installed
end
end
end
return false;
end
--For On Startup Event:
Application.Sleep(100);
---- Set your target Application lua variables ----
strProductDislpayName = SessionVar.Expand("%ProductName%");
strAppBinName = "MainApp.exe";
--now set file version specification target variables
strAppMinVer = "4.0.0.0"; --internal 'fileversion' spec to verify
strAppVerProdName = "TheProductName"; --internal 'productname' spec to verify
strInstallerPath = _SourceFilename; --full path to running Installer.exe
--now set registry key-s to target and value-s(these were or will be created during a full install routine)
--(note: for example purposes the valuename is set as 'InstallPath' in related global function)
strAppMainkey = "Software\\My Application";
---- First lets check if the Installer is already running ----
if IsInstallerRunning() then
Application.Exit(0); --nothing to do, previous instance of installer at work, so exit now
else
--- Now Call the Target Application Detection Routines (functions) ---
if IsProductInstalled() then
-- the product appears to be installed, so call function to check if MainApp.exe is already running
if IsProductRunning() then
Application.Exit(0); --nothing to do exit now
else
-- apparently MainApp.exe is not running so offer to start it up for the user
local RunApp = Dialog.Message(" - "..strProductDislpayName.." Information -", "Do you wish to run "..strProductDislpayName.." now", MB_YESNO, MB_ICONQUESTION, MB_DEFBUTTON1);
if (RunApp == 6) then
File.Run(strAppFolderPath.."\\"..strAppBinName, "", "", SW_SHOWNORMAL, false); --run the MainApp.exe
local nerror = Application.GetLastError();
if (nerror == 0) then
Application.Exit(0); --could set a different return code for a log file reference(indicating already installed)
else
Dialog.Message("Error: "..strProductDislpayName.." Failed to Start", _tblErrorMessages[error], MB_OK, MB_ICONINFORMATION, MB_DEFBUTTON1);
Application.Exit(0); --could set a different return code for log file reference(indicate already installed but could not be started)
end
else
Application.Exit(0); --user chose not to run the MainApp.exe, so exit now
end
end
end
end
just modify the string variables in the on startup code to test.
(you need to have the target registry key and valuename for proper functionality)
for sure expanded functionality such as CRC and MD5 checks, encrypted paths, additional path checks etc. can be added...
once we get things nice and solid..will post the final code in the Examples Section