Thursday, September 1, 2011

Patching Civil 3D 2011 - Part 2

Since I already blogged about common MSIexec error codes, I should have added some discussion about this to my previous blog post on patching Civil 3D 2011, but alas: I didn't.

If you run the same .MSP patch files (updates 1, and 2) on the same installation target, you will get an immediate return code of 0 on each patch, but a cumulative result of 1642.  At first, this may sound like a good thing.  However, since it waits to return the 1642, rather than immediately after running update 1, that doesn't provide a reliable "early out" to abort a repeated installation.

My current script looks like this...

@echo off
rem ****************************************************************
rem  Filename..: setup.cmd
rem  Author....:  skatterbrainz, who else?
rem  Date......: 09/01/2011
rem  Purpose...: install updates 1 and 2 for AutoCAD Civil 3D 2011
rem ****************************************************************
cls
setlocal
set APPNAME=AutoCAD_Civil3D_2011_Update2
set LOG=%TMP%\%APPNAME%_install.log
::
title Civil 3D 2011 Update 2
echo log file: %LOG%
echo %DATE% %TIME% installing... %APPNAME%... >%LOG%
echo %DATE% %TIME% source....... %~dps0 >>%LOG%
echo %DATE% %TIME% target....... %COMPUTERNAME% >>%LOG%
echo %DATE% %TIME% windir....... %WINDIR% >>%LOG%
echo %DATE% %TIME% progfiles.... %PROGRAMFILES% >>%LOG%
echo %DATE% %TIME% temp......... %TMP% >>%LOG%
echo ----------------------------------------------- >>%LOG%
echo %DATE% %TIME% info: searching for civil 3d 2011 installation... >>%LOG%
if exist "%programfiles%\Autodesk\AutoCAD Civil 3D 2011\acad.exe" (
echo %DATE% %TIME% info: installing update 1... >>%LOG%
msiexec /p "%~dp0c3d2011_win32_update1.msp" /quiet /norestart
echo %DATE% %TIME% info: exit code is %errorlevel% >>%LOG%
msiexec /p "%~dp0c3d2011_win32_update2.msp" /quiet /norestart
echo %DATE% %TIME% info: exit code is %errorlevel% >>%LOG%
) else (
echo %DATE% %TIME% info: civil 3d 2011 installation not found. >>%LOG%
)
::
echo ----------------------------------------------- >>%LOG%
echo %DATE% %TIME% completed / exit code: %errorlevel% >>%LOG%
endlocal
exit %errorlevel%


My client log output looks like this...


Thu 09/01/2011  9:06:53.03 installing... AutoCAD_Civil3D_2011_Update2... 
Thu 09/01/2011  9:06:53.03 source....... \\Server01\packages$\APPLIC~1\Autodesk\CIVIL3~2\ 
Thu 09/01/2011  9:06:53.07 target....... Computer1234 
Thu 09/01/2011  9:06:53.07 windir....... C:\WINDOWS 
Thu 09/01/2011  9:06:53.07 progfiles.... C:\Program Files 
Thu 09/01/2011  9:06:53.07 temp......... C:\DOCUME~1\dstein\LOCALS~1\Temp 
----------------------------------------------- 
Thu 09/01/2011  9:06:53.07 info: searching for civil 3d 2011 installation... 
Thu 09/01/2011  9:06:53.07 info: installing update 1... 
Thu 09/01/2011  9:06:53.08 info: exit code is 0 
Thu 09/01/2011  9:06:53.10 info: exit code is 0 
----------------------------------------------- 
Thu 09/01/2011  9:08:36.04 completed / exit code: 1642 


Notice the two "0" exit codes and the final "1642"?  Scratching your head yet?

Why does any of this matter?

I'm glad you didn't ask.  Well, even though Autodesk provides the means to modify an existing Deployment to slipstream updates into the installation package, this doesn't help with existing field installations.  You could use the Communication Center patch list approach, but some customer environments to not allow for the use of vendor-specific patch mechanisms (it circumvents centralized, single-product management policies like Configuration Manager, etc.).  So that typically means you have to develop a distinct update package to deploy to your existing clients.  In those situations, it's often desirable to build in some sort of detection mechanism so that each time the package is run against a given client it will check if it was already installed and gently abort without throwing a "real" error back to the monitoring systems.  If update 1 returned 1642 then I could trap that in my script/package and return a forced 0 instead.  That way it won't automatically re-run it if the previous result was "failed".

The fallback is to add more code to check for specific files and registry keys, which is less-than-ideal in my opinion, but what can you do?

No comments: