【问题标题】:How can I convert this InstallScipt code to C#?如何将此 InstallScipt 代码转换为 C#?
【发布时间】:2015-02-24 11:41:55
【问题描述】:

我正在使用 DTF(Microsoft 部署基础)命名空间将我的 InstallScript 自定义操作转换为托管自定义操作。有一段 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;
        }

【问题讨论】:

  • 您可以使用 XmlSerializer 将 XML 序列化到 .NET 对象和从 .NET 对象序列化。有时您需要将属性应用到您的类以准确获取您所追求的 XML,但它非常有效。
  • 我怀疑这与我从 InstallScript(InstallShield 自定义操作)到 .NET (C#) 的转换相同。不过谢谢你的建议。
  • 确实不会 - 根据答案使用XmlDocument 在这里更合适

标签: c# installscript installscript-msi


【解决方案1】:

是的,这只是打开XmlDocument,查找特定节点并更新其值,然后再次保存文件。

代码类似于(未经测试,从内存中输入)

var xml = new XmlDocument();
xml.Load(szCryptomaticConfigFile);
var node = xml.SelectSingleNode(szXPath);
node.Value = CRYPTOMATIC_SETTINGS_VALUE
xml.Save(szCryptomaticConfigFile);

【讨论】:

  • 感谢您的帮助。我很难找到在 InstallScript 代码中使用的相同属性,例如 Async。 ValidateOnParse 等。我确实尝试添加对 Microsoft.MSXML 的引用并添加了一个 Using MSXML,它允许我访问 Async 属性,但其他属性不存在。
  • @Jamiec 啊哈!我想我找到了。 :) 我需要在 Microsoft.MSXML 中使用 DOMDocument 类对象。谢谢你。你的建议让我思考。
  • @MichaelEdenfield 我只是尝试使用 XMLDocument 对象,但我正在寻找的属性不存在。
  • @MichaelEdenfield 我现在开始工作了。谢谢! :)
【解决方案2】:

.NET Framework 的System.Xml.XmlDocument 对象为您提供与Microsoft.XMLDOM COM 对象相同的行为,如this MSDN article 中所述。

在这种情况下,您的代码将如下所示:

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)

【讨论】:

  • 谢谢!我也试试看。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-05-26
  • 1970-01-01
  • 2019-09-29
  • 2011-12-08
  • 2021-12-24
  • 2014-03-24
  • 1970-01-01
相关资源
最近更新 更多