How can I tell (programmatically) when an Installshield installer is running silently? - installshield

I have a history of Installscript MSI installers (that have been replaced by Basic MSI installers), and when I uninstall them I need to know if the uninstall is being run silently or not. I run some custom code that checks for the existence of .iss files (necessary for silent uninstalls) and if they're not there I pop up a message saying that the files aren't where they're expected to be. The problem is that when the program is uninstalled from the Control Panel (not silently) this code runs and displays the message. So I need a system variable that will tell me it's running in silent mode so when it's not I can suppress the message.
I can't find anything that tells me this. Does anyone know of a way I can tell programmatically?

Assuming you want to detect a silent install from within the install, the answer depends on the project type:
InstallScript projects can check whether they're running silently by comparing the MODE system variable to SILENTMODE
Basic MSIs can compare the UILevel property to 2
InstallScript MSIs can check whichever is more relevant for the context (using MsiGetProperty to retrieve UILevel, if necessary, but watch out in deferred custom actions; they'll need to pass it through CustomActionData).
For completeness, but unlikely to be relevant for your question, Suites can reference the ISSilentInstall property.

Related

How do deal with Installshield installations that extract an MSI with pywinauto?

I am trying to automate an installation that starts out with an InstallShield setup.exe. That kicks off the installation of a MS Visual C++ redistributable. That leads to an error about Adobe Flash not being up to date. I have asked about how to deal with that here:
Error during automated software install using pywinauto
Once I click OK for the Adobe dialog(have to use pyautogui.click() for this for now) I see that there is an .msi being extracted. I have followed the install and it puts it into a new Temp folder under my Users\AppData directory.
How do you get pywinauto to find this new application? I have tried using
adobe = Application().connect(title_re="MyInstaller",class_name="#32770", visible_only=True)
And then try to print_control_identifiers() but get this error:
AttributeError: Neither GUI element (wrapper) nor wrapper method 'print_control_identifiers' were found (typo?)
I have checked Spy++ and Inspect and AutoIT to find the class which I can. I can't use the procid as it will always change.
Any thoughts on how to attach to the .msi process so I can then connect() to it?
Edit:
Is there a way to regex pywinauto to point to a path if I know where MyProgram.msi is? It seems to be in C:\Users\me\AppData\Local\Temp{xxx}\MyProgram.msi as I found several copies there. Thanks!
Add timeout=10 or whatever you need to connect() params. Current default timeout is zero, but it should be timings.Timings.window_find_timeout which is 5 sec by default.
Auto detection of spawned child process is planned for next major release (as well as default timeout fix).
For running an unpacked .msi file you need msiexec standard Windows command in method .start(). Play with it in cmd.exe manually first starting from msiexec /?.
Here is how I deal with the fact that InstallShield exe extracts to an .msi in (into my DownloadedInstallations folder). Yes, timeout is important, but also identifying the new msi window that opens is too. (Also, I found that wait_for_idle had to be FALSE but don't remember why. YMMV :) ).
exe = pywinauto.Application(backend="uia").start(exepath, wait_for_idle=False)
Now it's going to unzip the .exe into .msi installer and that could take a while, and since the .exe window might be named the same as the .msi window must be careful not to attach to the exe window too early and must wait for the .msi window to open!! So, add an appropriate timeout in seconds. The dialog window may not exist yet here, so it's CRITICAL to use class_name of MsiDialogCloseClass especially if the title of the exe and msi are the same. This will identify the .msi window specifically, whenever it arrives.
title = "Enter Title of your App - InstallShield Wizard"
msi = pywinauto.Application(backend="uia").connect(title=title,
class_name="MsiDialogCloseClass",timeout=120)
And for the final touch, in a line I always forget, must use the title again to get the dialog window (for reasons I don't yet understand)
dlg = msi[title]
EXTREMELY HELPFUL way to view all control identifiers at this point is:
print(dlg.print_control_identifiers())
This is what hours of trial and error yielded. To continue on, now you can click buttons, like this:
dlg.Next.wait("ready",timeout=2)
dlg.Next.click()
And to click on radio buttons, this works (there may be other ways that do, but I could never find how to get a handle on the buttons by name)
dlg['I &accept the terms in the License Agreement'].wait('enabled').click()
Then moving on
dlg.Next.click()
dlg.Install.wait("enabled",timeout=5)
dlg.Install.click()

Change Inno Setup messages from Pascal code

I need to change ConfirmUninstall, UninstalledMost (just in case), and UninstalledAll specifically from script to set a condition. Something like this:
if FileExists(ExpandConstant('{app}\Slash.exe')) then
SetupMessage(msgConfirmUninstall) := FmtMessage(SetupMessage(msgConfirmUninstall), ['Dagon Slasher'])
else if FileExists(ExpandConstant('{app}\Frank.exe')) then
SetupMessage(msgConfirmUninstall) := FmtMessage(SetupMessage(msgConfirmUninstall), ['Dagon Frankenstein'])
else
SetupMessage(msgConfirmUninstall) := FmtMessage(SetupMessage(msgConfirmUninstall), ['Dagon Video Tools']);
But this doesn't work. These messages are used in MsgBoxes, so I can't think of any other way. Running in silent mode is not really suitable for me, since setup will run uninstall if the programs (or one of them) has already been installed, so I don't want the user to accidentally uninstall the program by running the setup.
You cannot change these easily, see:
Replace or customize modal uninstallation windows in Inno Setup
Regarding the silent uninstall solution: I do not understand your problem with "setup will run uninstall if the programs (or one of them) has already been installed".
I assume you run the uninstaller only after the user confirms (s)he wants to install the new version, so you actually want to run the uninstaller silently, right?
And anyway, there's nothing that prevents you from running the uninstaller non-silently from your installer, even if the entry in "Add/Remove programs" refers to "silent" installation.
You can use generic messages that covers all setup types:
[Messages]
ConfirmUninstall=Are you sure you want to completely remove this game?
As your uninstall messages depend on a type of the installed application, you can modify the installer to:
Create custom "type" page (like a menu) as the very first one.
Once the user selects the "type", restart the installer with a custom switch (e.g. /APPTYPE=slasher) and exit.
Once the installer is (re-)run with the /APPTYPE, you know from the beginning, what component/type you are installing and hence you can set the AppName accordingly (using a scripted constant).
Of course, you skip the custom "type" page.
This is actually not difficult to implement. The only drawback is that the setup window is "recreated" after the user selects the "type".
I've sketched this solution already in my answer to Inno Setup Change AppName based on component(s) selected.

Inno setup a simple update

Is it possible to use same Inno Setup installer for installing new or updating/upgrading application. For example If the application is already installed the installer will check current version against newly availible. If it is true then I would like the installation procedure to be silent, meaning showing only the progress of update and not all availible installation features (e.g. folder location e.t.c). Thanks.
=======
The solution to the problem was :
Passing the parameters /SILENT/SUPPRESSMSGBOXES
taken from
http://www.jrsoftware.org/ishelp/index.php?topic=setupcmdline
For the standard screens, simply add the following to your [Setup] section:
[Setup]
DisableDirPage=auto
DisableProgramGroupPage=auto
This will automatically hide the directory and group selection pages on subsequent installs (using the previously selected values, by default, unless you've used other settings that disable that behaviour).
Components and Tasks will still display, but that's usually a good thing as it allows the user to add additional components or re-perform certain tasks. (Note that you can use the checkedonce flag on [Tasks] entries to only tick them by default during the initial install, but allow the user to re-tick them manually if required.)
It's possible to skip even more pages through use of [Code], but this is rarely necessary.
Another option is that if the installer is being run from your application itself (eg. as part of a "Check for new versions" task) you can use the /SILENT command line parameter to hide the normal interactive UI.

Silent Installer with custom selection

Currently my installer is need user to choose which type of setting they want to use when install. Lets say got setting A,B and C.
If want to make this in silent installer. Is there any method can use?
I'm using install shield.
You can set PUBLIC PROPERTIES inside the MSI file from the msiexec.exe command line like this:
msiexec /i test.msi /qn TESTPROPERTY=1
These properties are the ones you have hooked up to values input in the GUI. They are now set by the command line (or defaults are used from the Property table) and the entire GUI section of the MSI gets skipped on install.
Here is a sample showing how INSTALLDIR is hooked up to the GUI (Wise for Windows Installer shown, same concept in Installshield and other MSI tools):
To play around with complex command lines for msiexec.exe I always recommend this nifty tool from Altiris: http://www2.wise.com/filelib/WICLB.exe - broken link, resurrected from Wayback Machine, seeing as the tool was freeware I assume that is legal - (see a screenshot of it here: installation using msi.exec open help options every time). Please run the download by virustotal.com for safety.

Pinned shortcut in MFU (Most Frequency Used) Start menu after NSIS setup

A NSIS created deployment setup, installs two executable. After setup, one of them appears in the MFU (Most Frequency Used) list of the start menu. But I don't that.
Is it possible to remove this link or prevent it during install? I have found this document from Microsoft but is very difficult to code this (my knowable is .NET/C#). Or maybe is it possible with NSIS? All tips are welcome.
You could use WriteRegStr to write the NoStartPage value but it is usually not something you should set explicitly except if this .exe is some kind of generic host program for plugin modules.
Is it possible that you just tested the program on this particular machine so many times that the program ended up on the MFU list?
There is no official API to add things to the MFU list and NSIS does not do anything to try to get the program listed there...

Resources