Как преобразовать этот код InstallScipt в C#?

Я преобразовываю свои настраиваемые действия InstallScript в управляемые настраиваемые действия, используя пространство имен DTF (Microsoft Deployment Foundation). Есть фрагмент кода InstallScript, который мне не удается преобразовать в C#, где мне нужно выполнить некоторые манипуляции с XML-файлом. Исходный код InstallScript приведен ниже. Мой код ниже - это то, как я его преобразовал до сих пор. Есть ли лучший способ его преобразования, чтобы я мог воспользоваться точечной нотацией (Intellisense) вместо поздней привязки объекта XML-документа.

    set oDoc = CoCreateObject("Microsoft.XMLDOM");
    if (IsObject(oDoc)) then
        oDoc.async = FALSE;
        oDoc.validateOnParse = FALSE;
        oDoc.resolveExternals = FALSE;
        oDoc.preserveWhiteSpace = VARIANT_TRUE;

        oDoc.load(szCryptomaticConfigFile);

        szXPath = CRYPTOMATIC_SETTINGS_PATH;
        set oSettingsNode = oDoc.selectSingleNode(szXPath);

        szValue = CRYPTOMATIC_SETTINGS_VALUE;
        oSettingsNode.nodeTypedValue = szValue;

        oDoc.Save(szCryptomaticConfigFile);
   endif;

Моя конверсия

        dynamic oXMLDOMDoc = Activator.CreateInstance(Type.GetTypeFromProgID("Microsoft.XMLDOM"));
        if (oXMLDOMDoc != null)
        {
            oXMLDOMDoc.async = false;
            oXMLDOMDoc.validateOnParse = false;
            oXMLDOMDoc.preserveWhiteSpace = VARIANT_TRUE;
            oXMLDOMDoc.load(szCryptomaticConfigFile);

            string szXPath = CRYPTOMATIC_SETTINGS_PATH;
            dynamic oSettingsNode = oXMLDOMDoc.selectSingleNode(szXPath);

            string szXValue = CRYPTOMATIC_SETTINGS_VALUE;
            oSettingsNode.nodeTypedValue = szXValue;

            oXMLDOMDoc.Save(szCryptomaticConfigFile);
            return ActionResult.Success;
        }
        else
        {
            return ActionResult.Failure;
        }

person GhostHunterJim    schedule 24.02.2015    source источник
comment
Вы можете (де)сериализовать XML в объекты .NET и из них, используя XmlSerializer. Иногда вам нужно применить атрибуты к вашим классам, чтобы получить именно тот XML, который вам нужен, но это довольно эффективно.   -  person James Thorpe    schedule 24.02.2015
comment
Я сомневаюсь, что это будет то же самое при моем преобразовании из InstallScript (настраиваемые действия InstallShield) в .NET (C#). Но спасибо за предложение.   -  person GhostHunterJim    schedule 24.02.2015
comment
На самом деле это не так - использование XmlDocument в соответствии с ответами здесь гораздо уместнее.   -  person James Thorpe    schedule 24.02.2015


Ответы (2)


Да, это просто открытие XmlDocument, найти конкретный узел и обновить его значение перед повторным сохранением файла.

Код примерно такой (непроверенный, набирается по памяти)

var xml = new XmlDocument();
xml.Load(szCryptomaticConfigFile);
var node = xml.SelectSingleNode(szXPath);
node.Value = CRYPTOMATIC_SETTINGS_VALUE
xml.Save(szCryptomaticConfigFile);
person Jamiec    schedule 24.02.2015
comment
Спасибо за помощь. У меня возникли проблемы с поиском тех же свойств, которые использовались в коде InstallScript, таких как Async. ValidateOnParse и т. д. Я попытался добавить ссылку на Microsoft.MSXML и добавил использование MSXML, что позволило мне получить доступ к свойству Async, однако других там не было. - person GhostHunterJim; 24.02.2015
comment
@Jamiec А-ха! Думаю, я нашел это. :) Мне нужно использовать объект класса DOMDocument в Microsoft.MSXML. Спасибо. Ваши предложения заставили меня задуматься. - person GhostHunterJim; 24.02.2015
comment
@MichaelEdenfield Я только что попытался использовать объект XMLDocument, но свойств, которые я ищу, там нет. - person GhostHunterJim; 24.02.2015
comment
@MichaelEdenfield Теперь у меня все работает. Спасибо! :) - person GhostHunterJim; 24.02.2015

System.Xml.XmlDocument обеспечивает то же поведение, что и объекты Microsoft.XMLDOM COM, как описано в этом MSDN статья.

В этом случае ваш код будет выглядеть примерно так:

var xml = new XmlDocument();
xml.PreserveWhiteSpace = true;
xml.Load(szCryptomaticConfigFile);

string szXPath = CRYPTOMATIC_SETTINGS_PATH;
var settingsNode = xml.selectSingleNode(szXPath);

string szXValue = CRYPTOMATIC_SETTINGS_VALUE;
settingsNode.InnerText = szXValue;

xml.Save(zzCryptomaticConfigFile);

Следует отметить, что многие параметры загрузки/сохранения исчезли. Они больше не устанавливаются на верхнем уровне XmlDocument. Скорее, это настройки XmlTextReader, которые используются для сохранения и загрузки документа. По умолчанию метод Load() является синхронным и проверяющим. Обычно это то, что вы хотите.

Однако, если ваш XML содержит ссылки на DTD, размещенные за пределами сайта, разрешение этих ссылок на DTD занимает много времени. Обычно поэтому validateOnParse отключается. Если вам нужно это сделать, вам нужно использовать перегруженный метод Load с вашим собственным ридером. Вы можете отключить бит, который разрешает ссылки DTD следующим образом:

var settings = new XmlReaderSettings();
settings.XmlResolver = null;
settings.ProhibitDtd = false;

var reader = XmlTextReader.Create(szCryptomaticConfigFile, settings);
xml.Load(reader)
person Michael Edenfield    schedule 24.02.2015
comment
Спасибо! Я тоже попробую. - person GhostHunterJim; 24.02.2015