Visar inlägg med etikett exit code. Visa alla inlägg
Visar inlägg med etikett exit code. Visa alla inlägg

torsdag 28 december 2017

Installation failed because reasons

Sometimes installations fail. Often, the reason for failure is logical and easily found in a log file, sometimes you just get an 1603 with no indication whatsoever what went wrong.

And sometimes the install fails by design. A retarded design.

Solid Works 2016 installs Microsoft SQL Server 2008, Microsoft SQL Server 2012 and Microsoft SQL Server 2014.

I think most people see a probable cause for disaster right there. But surprisingly it usually works.

Unless your organisation has done the rare but sensible and rational thing and set a password policy:


As it happens, Microsoft SQL Server adheres to the group policy dictating the password policy for the domain.

There are workarounds found when googleing, but they either require disabling the password policy or modifying the way the database is created. Neither of these methods might be possible for an unattended install from a third party vendor.

Mostly because I don't feel like talking to the vendor, nor to my collegues managing the domain.

So here is how you install an SQL instance without supervision, without modifying the install and without modifying the domain:


; Removing password-requirements with secedit:

RunWait('secedit.exe /export /cfg "' & @TempDir & '\sectmporg.cfg" /quiet',"",@SW_HIDE)

FileCopy(@TempDir & '\sectmporg.cfg', @TempDir & '\sectmpcpy.cfg',1)
IniWrite(@TempDir & '\sectmpcpy.cfg',"System Access","MinimumPasswordLength","0")
IniWrite(@TempDir & '\sectmpcpy.cfg',"System Access","PasswordComplexity","0")

RunWait('secedit.exe /configure /db secedit.sdb /cfg "' & @TempDir & '\sectmpcpy.cfg" /quiet',"",@SW_HIDE)
RunWait("gpupdate.exe","",@SW_HIDE)

; **********************
;
; THE INSTALL GOES HERE!
;
; **********************

; Restoring password-requirements:

RunWait('secedit.exe /configure /db secedit.sdb /cfg "' & @TempDir & '\sectmporg.cfg" /quiet',"",@SW_HIDE)
RunWait("gpupdate.exe","",@SW_HIDE)


Code is AutoIt, but I'm sure you figure it out in any language.

onsdag 4 oktober 2017

Success fail

A successful installation should return an exit code of 0, but that is not always the case. These cases need to be handled properly, or I'll get a very red pie-chart in System Center.

The most common exception is 3010, a successfull install that needs a reboot, but there are others. Some more or less retarded.

Just now I needed to deploy an msi that returned 1638 if it was already installed. 1638 is documented as ERROR_PRODUCT_VERSION, "Another version of this product is already installed". This is stupid on many levels. First, if the same version is installed an msi should just install again. If an older version is installed, a proper msi should perform a major upgrade. The exit code might be useful if a newer program exists on the computer, but barely. I would say that installations which return 1638 should be documented as ERROR_MSI_SUCKS. The solution is to always uninstall before installing. This leads to the next problem.

Uninstalling an msi might return 1605, ERROR_UNKNOWN_PRODUCT, "This action is only valid for products that are currently installed." Yes, thank you. Already not there then. Success.

Sometimes you might need to deploy a patch for Windows, usually named kb-something with an msu extension, with your application. Unfortunately a shitload of your computers in your enterprise will report failure 2359302, 0x240006 in hex. This means WU_S_ALREADY_INSTALLED, "The update to be installed is already installed on the system". This is even dumber than 1638. If it is already installed, it is a success!

Related is the msu exit value of 2149842967, 0x80240017 in hex, "The update is not applicable to your computer". You'll get this result if you try to deploy a patch for Windows 7, and you happen to have a few Windows 10 among them, as an example. Not unlikely for many reasons, one of which is the update is included in a larger install where the application needs it on older Windows, but you don't feel like making two different packages for each OS or some other workaround. While the error might be interesting for some reasons, as a deployer I don't care. I filter it to success and I'm just as happy.

Deploying drivers with DPInst is an entire chapter of itself. The return value you get consist of three hexadecimal parts merged with OR like this:

0xYY0000 contains the number of drivers that failed to install.
0x00YY00 contains the number of drivers copied to the driver store.
0x0000YY contains the number of drivers successfully installed.

A return code of 66051 thus means 1 driver failed, two drivers copied to the driver store and 3 drivers installed, because it's 0x010203 in hex.

The simplest way to get a useful value is to do an AND FF0000. If it's zero, it's a success, otherwise you'll get the number of fails times 65536.

But so far the exit codes have at least been valid and have their reasons. Some badly written installers give all kinds of weird return values. Adobe was notorious for a while, returning 255 for a success.

But of all the moronic exit codes to indicate success there is one particularly stupid from msiexec;

1707 - Installation operation completed successfully.

onsdag 13 september 2017

Your Install Sucks

So, you have developed this awesome program, and you want to spread it to the world! You need to create a package to install the program. What should this installation do? I'll tell you!

Things your installation should do:


Install the program.


That's it! That is all! You know what your install should NOT do? Anything else! This includes but is not limited to:

Starting the program. When your install is finished, DO NOT start or allow the option to start the program you just installed! The user launches the program when he wants, and he does it in his own context, NOT the context in which the program was installed!

Actually, don't start ANY process after the install. Deploying a computer with, for instance, Microsoft System Center means installing dozens or hundreds of programs in a row. If your app needs running processes, launch them at startup or logon.

Don't suddenly restart the computer! This should go without saying, but apparently NOOOO. Respect REBOOT=ReallySuppress or other flags. If your app is not quite installed after your installer but needs a restart, exit with 3010.

About that, exit with proper exit codes! 0 (zero) means success. 255 does NOT mean success! Where did you get that idea? I'm talking to you, Adobe! Again: 0 means success! DON'T return zero if the installation failed! If you do, I'll hunt you down!

Don't install other programs! Definitely not malware, but ALSO not prerequirements for your app! If your program requires vc_redist 2027 or dotnet 19, put them in a prereq-folder. If you MUST, have a setup-wrapper that installs them. They are ALREADY outdated when you ship your product and MY environment already have them. Newer and better versions, actually. DON'T force them on me. Merge-modules are ok, of course.

If you have a wrapper, DON'T require it. "This install must be started from setup.exe" is not a valid argument! I don't want to figure out your stupid parameters to run the setup standalone.

Don't require internet during installation. Don't require a network at all. If you are stupid enough to have some stupid license activation requirement, manage that with a manager, NOT the installer. Do you know how ANNOYING it is to have a computer fail during sequencing because some paper pusher didn't add more licenses to some stupid pool of licenses?

Have a working unattended option. A way to silently install your program. And be sure it is SILENT. How hard can it be to NOT display a dialog box? Jeez...

To be continued...