04/11/2019 85 views

In the process of deploying the latest Adobe Acrobat DC msp I am getting a few hundred failures due to msi not being found. I found that the InstallSource for Adobe Acrobat DC in the registry no longer matches that of ccmcache because ccmcache has been cleared and now will not complete the msp deployment. After researching, I have tried variations of /f and REINSTALL on the original Adobe Acrobat DC application to the few hundred that are failing with no success. The content downloads over and over to ccmcache but never updates the registry to re-associate the InstallSource.

Any advice is greatly appreciated.

0 Comments   [ + ] Show comments


Community Chosen Answer


This kind of thing is simple to trace using ProcMon, a tool I *may* have mentioned once or twice... I'll take pity on you this time, though.

The first thing you need to do is work out what Microsoft calls the "compressed GUID" from the product's ProductCode. Quite how removing the dashes and braces and then performing a frankly bizarre and unnecessary reformulation of the existing GUID qualifies it as "compressed" is beyond me but there you are. At the bottom of this is some QAD code that you can use to feed in either and get the opposite, i.e. feed it a GUID and you get the "compressed" version and vice-versa. It can be prettied-up a great deal but I've never bothered. There are other examples; Google "msi compressed guid".

Next, find the compressed GUID in HKEY_CLASSES_ROOT\\Installer\Products. 

Next, browse to 'HKEY_CLASSES_ROOT\Installer\Products\[compressed_GUID]\SourceList\Net.

Next, a value with the next number in sequence, with the data pointing to the new source folder: I generally use the ProductCode to create a folder in %ProgramData%\PackageCache, as adding folders into %windir%\ccmcache can cause issues. It really doesn't matter where it is, as long as your client machines can reach it. Make sure the last character is a backslash.

Finally, run the repair command line against a bunch of test machines to ensure that the new source is found, then get coffee.

strCode 	= "{7299052b-02a4-4627-81f2-1818da5d550d}"
strMungedCode = "C5583ABE8A39FF94F93C9C0EC41C2740"
'Call MungeGUID(strCode, strMungedCode)
'WScript.Echo strCode & " munged becomes " & strMungedCode
Call UnMungeGUID(strMungedCode, strCode)
WScript.Echo strMungedCode & " unmunged becomes " & strCode

Sub MungeGUID(ByVal strGUID, ByRef strMungedCode)
'// This routine munges the GUID into the munged format 
'// used by various registry entries for Windows Installer
'// For example: {D650B8A9-C547-42D3-A7DF-0FAD0AC6E9ED}
'// becomes
'// 9A8B056D745C3D247AFDF0DAA06C9EDE
Dim arrSortOrder
Dim strNewCode
Dim intIndex
arrSortOrder = Array(9,8,7,6,5,4,3,2,14,13,12,11,19,18,17,16,22,21,24,23,27,26,29,28,31,30,33,32,35,34,37,36)
'// Generate the munged code
For intIndex = 0 To UBound(arrSortOrder)
strNewCode = strNewCode & Mid(strGUID,arrSortOrder(intIndex),1)
strMungedCode = strNewCode
End Sub
Sub UnMungeGUID(ByVal strMungedCode, ByRef strGUID)
'// This routine reconstructs a GUID from the munged format 
'// used by various registry entries for Windows Installer
'// For example: 9A8B056D745C3D247AFDF0DAA06C9EDE
'// becomes
'// {D650B8A9-C547-42D3-A7DF-0FAD0AC6E9ED}
Dim arrSortOrder
Dim intIndex
Dim strPartTemp
Dim strPart1
Dim strPart2
Dim strPart3
Dim strPart4
Dim strPart5
'// Part 1
strPartTemp = Left(strMungedCode, 8)
strPart1 = StrReverse(strPartTemp)
'// Part 2
strPartTemp = Mid(strMungedCode, 9, 4)
strPart2 = StrReverse(strPartTemp)
'// Part 3
strPartTemp = Mid(strMungedCode, 13, 4)
'// Excuse me! May I borrow these variables for a moment?
strPart3 = Left(strPartTemp, 2)
strPart4 = Right(strPartTemp, 2)
strPart3 = StrReverse(strPart4) & StrReverse(strPart3)
'// Now deal with part 4 properly
strPartTemp = Mid(strMungedCode, 17, 2)
strPart4 = Mid(strMungedCode, 19, 2)
strPart4 = StrReverse(strPartTemp) & StrReverse(strPart4)
strPartTemp = Mid(strMungedCode, 21, 12)
arrSortOrder = Array(2,1,4,3,6,5,8,7,10,9,12,11)
'// Generate the product code
For intIndex = 0 To UBound(arrSortOrder)
strPart5 = strPart5 & Mid(strPartTemp,arrSortOrder(intIndex),1)
strGUID = ""
strGUID = strGUID & "{"
strGUID = strGUID & strPart1
strGUID = strGUID & "-"
strGUID = strGUID & strPart2
strGUID = strGUID & "-"
strGUID = strGUID & strPart3
strGUID = strGUID & "-"
strGUID = strGUID & strPart4
strGUID = strGUID & "-"
strGUID = strGUID & strPart5
strGUID = strGUID & "}"
End Sub

Answered 04/12/2019 by: VBScab
Red Belt

All Answers


Adobe installs a copy of the source media files into the "Setup files" sub folder, eg.
C:\Program Files (x86)\Adobe\Acrobat 2015\Setup Files\{AC76BA86-1033-FFFF-7760-0E0F06755100}\

I've deployed a similar script for Reader 11 few year ago - it modifies the registry entry mentioned by VBScab (it fixed the patching issue with missing source MSI).

Script assumptions:
 * 68AB67CA7DA73301B744BA0000000010 is a 'compressed' MSI GUID for Reader 11.0
 * C:\Program Files (x86)\Adobe\Reader 11.0\Setup Files\{AC76BA86-7AD7-1033-7B44-AB0000000001}\ is a local copy made during Reader 11.0 installation.

Option Explicit
On Error Resume Next

Dim objShell : Set objShell = CreateObject("WScript.Shell")
Dim objFSO : Set objFSO = CreateObject("Scripting.FileSystemObject")
Dim strParentFolder : strParentFolder = Replace(WScript.ScriptFullName, WScript.ScriptName, "")
Dim strProgramF86 : strProgramF86 = objShell.ExpandEnvironmentStrings("%ProgramFiles(x86)%")
Dim strRegPath : strRegPath = "HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Installer\Products\68AB67CA7DA73301B744BA0000000010\SourceList\Net"
Dim strTargetPath : strTargetPath = strProgramF86 &"\Adobe\Reader 11.0\Setup Files\{AC76BA86-7AD7-1033-7B44-AB0000000001}\"
Dim strMsiName : strMsiName = "AcroRead.msi"
Dim strRegValue
Dim i

FOR i = 1 TO 5
If Err.Number = 0 Then
'Wscript.Echo strRegPath &"\" &i &" - Exists. Getting reg value..."
strRegValue = objShell.RegRead (strRegPath &"\" &i)
'Wscript.Echo "Registry entry points to: '" & strRegValue &"'."

If objFSO.FileExists (strRegValue &strMsiName) Then
'Wscript.Echo "MSI file exists in target location - SUCCESS."
'Wscript.Echo "MSI file NOT FOUND in target location."
End If
If objFSO.FileExists (strTargetPath &strMsiName) Then
'Wscript.Echo "MSI file exists in '" &strTargetPath &"'. Setting reg value..."
objShell.RegWrite strRegPath &"\" &i, strTargetPath, "REG_EXPAND_SZ"
'Wscript.Echo "MSI file DOES NOT exist in '" &strTargetPath &"'."
'Wscript.Echo "Execution finished with Exit Code 2 - ERROR_FILE_NOT_FOUND, The system cannot find the file specified."
WScript.Quit (2) 'ERROR_FILE_NOT_FOUND - The system cannot find the file specified.
End If
End If
Answered 04/12/2019 by: rad33k
Second Degree Brown Belt