@@ -1249,6 +1249,92 @@ class PythonBootstrapperApplication : public CBalBaseBootstrapperApplication {
12491249 return hr;
12501250 }
12511251
1252+ //
1253+ // ParseVariablesFromUnattendXml - reads options from unattend.xml if it
1254+ // exists
1255+ //
1256+ HRESULT ParseVariablesFromUnattendXml () {
1257+ HRESULT hr = S_OK;
1258+ LPWSTR sczUnattendXmlPath = nullptr ;
1259+ IXMLDOMDocument *pixdUnattend = nullptr ;
1260+ IXMLDOMNodeList *pNodes = nullptr ;
1261+ IXMLDOMNode *pNode = nullptr ;
1262+ long cNodes;
1263+ DWORD dwAttr;
1264+ LPWSTR scz = nullptr ;
1265+ BOOL bValue;
1266+ int iValue;
1267+ BOOL tryConvert;
1268+ BSTR bstrValue = nullptr ;
1269+
1270+ hr = BalFormatString (L" [WixBundleOriginalSourceFolder]unattend.xml" , &sczUnattendXmlPath);
1271+ BalExitOnFailure (hr, " Failed to calculate path to unattend.xml" );
1272+
1273+ if (!FileExistsEx (sczUnattendXmlPath, &dwAttr)) {
1274+ BalLog (BOOTSTRAPPER_LOG_LEVEL_VERBOSE, " Did not find %ls" , sczUnattendXmlPath);
1275+ hr = S_FALSE;
1276+ goto LExit;
1277+ }
1278+
1279+ hr = XmlLoadDocumentFromFile (sczUnattendXmlPath, &pixdUnattend);
1280+ BalExitOnFailure1 (hr, " Failed to read %ls" , sczUnattendXmlPath);
1281+
1282+ // get the list of variables users have overridden
1283+ hr = XmlSelectNodes (pixdUnattend, L" /Options/Option" , &pNodes);
1284+ if (S_FALSE == hr) {
1285+ ExitFunction1 (hr = S_OK);
1286+ }
1287+ BalExitOnFailure (hr, " Failed to select option nodes." );
1288+
1289+ hr = pNodes->get_length ((long *)&cNodes);
1290+ BalExitOnFailure (hr, " Failed to get option node count." );
1291+
1292+ BalLog (BOOTSTRAPPER_LOG_LEVEL_STANDARD, " Reading settings from %ls" , sczUnattendXmlPath);
1293+
1294+ for (DWORD i = 0 ; i < cNodes; ++i) {
1295+ hr = XmlNextElement (pNodes, &pNode, nullptr );
1296+ BalExitOnFailure (hr, " Failed to get next node." );
1297+
1298+ // @Name
1299+ hr = XmlGetAttributeEx (pNode, L" Name" , &scz);
1300+ BalExitOnFailure (hr, " Failed to get @Name." );
1301+
1302+ tryConvert = TRUE ;
1303+ hr = XmlGetAttribute (pNode, L" Value" , &bstrValue);
1304+ if (FAILED (hr) || !bstrValue || !*bstrValue) {
1305+ hr = XmlGetText (pNode, &bstrValue);
1306+ tryConvert = FALSE ;
1307+ }
1308+ BalExitOnFailure (hr, " Failed to get @Value." );
1309+
1310+ if (tryConvert &&
1311+ CSTR_EQUAL == ::CompareStringW (LOCALE_INVARIANT, NORM_IGNORECASE, bstrValue, -1 , L" yes" , -1 )) {
1312+ _engine->SetVariableNumeric (scz, 1 );
1313+ } else if (tryConvert &&
1314+ CSTR_EQUAL == ::CompareStringW (LOCALE_INVARIANT, NORM_IGNORECASE, bstrValue, -1 , L" no" , -1 )) {
1315+ _engine->SetVariableNumeric (scz, 0 );
1316+ } else if (tryConvert && ::StrToIntExW (bstrValue, STIF_DEFAULT, &iValue)) {
1317+ _engine->SetVariableNumeric (scz, iValue);
1318+ } else {
1319+ _engine->SetVariableString (scz, bstrValue);
1320+ }
1321+
1322+ ReleaseNullBSTR (bstrValue);
1323+ ReleaseNullStr (scz);
1324+ ReleaseNullObject (pNode);
1325+ }
1326+
1327+ BalLog (BOOTSTRAPPER_LOG_LEVEL_STANDARD, " Finished reading from %ls" , sczUnattendXmlPath);
1328+
1329+ LExit:
1330+ ReleaseObject (pNode);
1331+ ReleaseObject (pNodes);
1332+ ReleaseObject (pixdUnattend);
1333+ ReleaseStr (sczUnattendXmlPath);
1334+
1335+ return hr;
1336+ }
1337+
12521338
12531339 //
12541340 // InitializeData - initializes all the package information.
@@ -1264,6 +1350,9 @@ class PythonBootstrapperApplication : public CBalBaseBootstrapperApplication {
12641350 hr = ParseOverridableVariablesFromXml (pixdManifest);
12651351 BalExitOnFailure (hr, " Failed to read overridable variables." );
12661352
1353+ hr = ParseVariablesFromUnattendXml ();
1354+ ExitOnFailure (hr, " Failed to read unattend.ini file." );
1355+
12671356 hr = ProcessCommandLine (&_language);
12681357 ExitOnFailure (hr, " Unknown commandline parameters." );
12691358
@@ -1323,7 +1412,9 @@ class PythonBootstrapperApplication : public CBalBaseBootstrapperApplication {
13231412
13241413 hr = StrAllocString (psczLanguage, &argv[i][0 ], 0 );
13251414 BalExitOnFailure (hr, " Failed to copy language." );
1326- }
1415+ } else if (CSTR_EQUAL == ::CompareStringW (LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1 ], -1 , L" simple" , -1 )) {
1416+ _engine->SetVariableNumeric (L" SimpleInstall" , 1 );
1417+ }
13271418 } else if (_overridableVariables) {
13281419 int value;
13291420 const wchar_t * pwc = wcschr (argv[i], L' =' );
0 commit comments