Большое спасибо за предложение Стейна - оно в конечном итоге позволило мне найти решение, хотя это было далеко не просто.Я не уверен, как изложить это объяснение так же, как сделать ваш комментарий правильным ответом.
Я обнаружил, что установил элемент CustomDataAction, который определил путь к appsettings.json в CustomAction,хотя отображается правильно при отправке в session.Log, это НЕ то, что было на самом деле установлено (см. ПРЕДУПРЕЖДЕНИЕ в строке).
[CustomAction]
public static ActionResult SetCustomActionData(Session session)
{
CustomActionData _data = new CustomActionData();
// ..escape single ';'
string _connectionString = session["CONNECTION_STRING"];
_connectionString.Replace(";", ";;");
_data["connectionString"] = _connectionString;
// ..correctly output in install log
session.Log(string.Format("SetCustomActionData() setting _connectionString: {0}", _connectionString));
// Property set to [#appSettings] in Product.wxs
string _filePath = session["PATH_TO_APPSETTINGS_JSON"];
_data["filepath"] = _filePath;
// ..correctly output in install log
session.Log(string.Format("SetCustomActionData() setting _filepath: {0}", _filePath));
// ..set the CustomActionData programmatically
session["UpdateJsonAppSettings"] = _data.ToString();
return ActionResult.Success;
}
Install.log:
[SNIP]
SetCustomActionData() setting _connectionString: 'Data Source=localhost\SQLEXPRESS;;Initial Catalog=...'
SetCustomActionData() setting _filepath: 'C:\inetpub\wwwroot\UServiceApi\appsettings.json'
[CustomAction]
public static ActionResult UpdateJsonAppSettings(Session session)
{
// ..as per Stein's suggestion
MessageBox.Show("Attach run32dll.dll now");
// ..correctly output to log (i.e. 2)
session.Log(string.Format("Session.CustomActionData.Count(): {0}", session.CustomActionData.Count));
// ..correctly output two key/value pairs to log
foreach(string _key in session.CustomActionData.Keys)
session.Log(string.Format("key: {0}, value: {1}", _key, session.CustomActionData[_key]));
string _connectionString = session.CustomActionData["connectionString"];
string _pathToAppSettings = session.CustomActionData["filepath"];
// WARNING: _pathToAppSettings has reverted to the literal "[#appSettings]" - which of course triggers File not found Exception.
ActionResult _retVal = UpdateJsonConnectionString(_connectionString, _pathToAppSettings, out string _result);
// ..log failure
if (_retVal != ActionResult.Success)
session.Log(string.Format("UpdateJsonAppSettings() returned: {0}; _result: {1}; filepath: {2}; connectionString: {3}",
_retVal, _result, _pathToAppSettings, _connectionString));
return _retVal;
}
Install.log:
[SNIP]
key: connectionString, value: Data Source=localhost\SQLEXPRESS;Initial Catalog=...
key: filepath, value: C:\inetpub\wwwroot\UServiceApi\appsettings.json
[SNIP]
UpdateJsonAppSettings() returned: NotExecuted; _result: File not found:C:\inetpub\wwwroot\ServiceApi\appsettings.json...
Я пробовал несколько различных комбинаций реализаций Properties и CustomAction, нов конце концов обнаружилось, что единственный способ правильно установить CustomActionData для содержания «реального» элемента filepath - это установить его в CustomAction типа 51 (я думаю) в Product.wxs.Никакая другая комбинация, которую я пробовал, не сработала.
Фрагмент рабочего кода из Product.wxs:
<Property Id="PATH_TO_APPSETTINGS_JSON" Value="[#appSettings]" />
<CustomAction Id="SetCustomActionData"
Return="check"
Property="UpdateJsonAppSettings"
Value="connectionString=[CONNECTION_STRING_FORMATTED];filepath=[#appSettings]" />// NOTE: cannot use filepath=[PATH_TO_APPSETTINGS_JSON] here
Вывод: возможная ошибка WiX - журнал не говорит правду (выборочно)'Элементы CustomActionData, в то время как скомпилированный код установщика фактически использует разные значения).