2015-02-24 49 views
0

我使用DTF(Microsoft部署基础)命名空间将我的InstallScript自定义操作转换为托管自定义操作。有一段InstallScript代码,我在转换到C#时遇到了麻烦,因为我需要执行一些XML文件操作。原始的InstallScript代码如下。我的代码下面是我迄今为止如何转换它。有没有更好的方法来转换它,以便我可以利用点符号(Intellisense)而不是使XML文档对象迟到。如何将此InstallScipt代码转换为C#?

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; 
     } 
+0

您可以使用'XmlSerializer'将XML序列化为和来自.NET对象的序列化。您有时需要将属性应用于您的类,才能获得完整的XML,但这非常有效。 – 2015-02-24 11:47:23

+0

我怀疑这与将我从InstallScript(InstallShield自定义操作)转换为.NET(C#)的过程相同。但是,谢谢你的建议。 – GhostHunterJim 2015-02-24 11:55:22

+0

事实上它不会 - 根据答案使用“XmlDocument”在这里更合适 – 2015-02-24 11:58:38

回答

1

是的,这简直是打开一个XmlDocument,找到一个特定节点,并再次保存文件之前更新其价值。

的代码是沿着线(未经测试,从存储器键入)

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

感谢您的帮助。我无法找到InstallScript代码中使用的相同属性,例如Async。 ValidateOnParse等。我曾尝试添加对Microsoft.MSXML的引用,并添加了使用MSXML,它允许我访问Async属性,但其他人不在那里。 – GhostHunterJim 2015-02-24 11:53:54

+0

@Jamiec啊哈!我想我找到了它。 :)我需要使用Microsoft.MSXML中的DOMDocument类对象。谢谢。你的建议让我思考。 – GhostHunterJim 2015-02-24 12:00:15

+0

@MichaelEdenfield我只是试图使用XMLDocument对象,我正在寻找的属性不存在。 – GhostHunterJim 2015-02-24 12:17:22

0

.NET框架的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) 
+0

谢谢!我也会试一试。 – GhostHunterJim 2015-02-24 12:02:27