ClearAll[parseRevisionFile, parseInfoPlist, findKernel, findAddOnPackages, findJLinkJar]; validateMathematicaInstallation::err = "`` could not validate ``"; abort[f_, arg_] := (Message[validateMathematicaInstallation::err, f, arg]; Abort[]); parseRevisionFile[path_ /; FileExistsQ[path]] := With[{ versionFile = FileNameJoin[{path, ".VersionID"}], creationFile = FileNameJoin[{path, ".CreationID"}] }, Rule @@@ Transpose[{{"Version", "Build"}, Import /@ {versionFile, creationFile}}] /; FileExistsQ[versionFile] && FileExistsQ[creationFile] ]; parseRevisionFile[arg___] := abort["parseRevisionFile", {arg}]; parseInfoPlist[file_ /; FileExistsQ[file]] := Module[{data = Import[file], pos, res}, pos = Position[ StringMatchQ[#, __ ~~ "CFBundleShortVersionString" ~~ __] & /@ data, {True}]; res = StringReplace[ data[[1 + pos[[1, 1]]]], ___ ~~ "" ~~ version__ ~~ "." ~~ revision__ ~~ "" ~~ ___ :> {version, revision}]; {"Version" -> res[[1, 1, 1]], "Build" -> res[[1, 1, 2]]} /; MatchQ[pos, {{_Integer}}] && MatchQ[res, {_StringExpression}] ]; parseInfoPlist[arg___] := abort["parseInfoPlist", {arg}]; findKernel[path_ /; FileExistsQ[path]] := Switch[$OperatingSystem, "Windows", findKernel[path, "MathKernel.exe"], _, findKernel[path, "MathKernel"] ]; findKernel[path_, kernelName_] := With[ {kernel = First@FileNames[kernelName, {path}, Infinity]}, {"Kernel" -> kernel} /; FileExistsQ[kernel] ]; findKernel[ arg___] := (Message[validateMathematicaInstallation::err, "findKernel", {arg}]; Abort[]); findAddOnPackages[addOnsPath_] := With[{initFiles = FileNames["init.m", {addOnsPath}, Infinity]}, {"AddOnPackages" -> (With[{packageName = FileNameSplit[#][[-3]]}, packageName] & /@ initFiles)} /; Length[initFiles] > 0]; findAddOnPackages[arg___] := abort["findAddOnPackages", {arg}]; findJLinkJar[root_ /; FileExistsQ[root]] := With[{jLinkPath = FileNameJoin[{root, "SystemFiles", "Links", "JLink", "JLink.jar"}]}, {"JLink" -> jLinkPath} /; FileExistsQ[jLinkPath]]; findJLinkJar[arg___] := abort["findJLinkJar", {arg}]; validateMathematicaInstallation[path_] := Module[ {root, version, jlink, addOns, kernel}, Switch[$OperatingSystem, "MacOSX", With[{cont = FileNameJoin[{path, "Contents"}]}, If[$VersionNumber < 10, root = path, root = cont ]; version = parseInfoPlist[FileNameJoin[{cont, "Info.plist"}]]; ], _,(* All other OS *) root = path; version = parseRevisionFile[path]; ]; kernel = findKernel[root]; addOns = findAddOnPackages[root]; jlink = findJLinkJar[root]; Flatten[{version, kernel, addOns, jlink}] ]