如何使用 InstallScript 更新 XML 文件中的属性

发布于 2024-09-30 21:43:00 字数 2674 浏览 1 评论 0原文

问题:

我正在努力弄清楚如何使用 InstallScript 更新 XML 文件中的某些属性。我想使用正确的 XML 解析函数,但我找不到任何表明此版本的 InstallScript 具有此功能的信息。我该怎么做?我应该尝试结合使用 FileInsertLine 和 FileGrep 吗?我缺少图书馆吗?

背景:

软件版本是什么?
我在 Windows Server 2003 R2 上使用 InstallShield 11。

为什么我不只使用现有的“XML 文件更改”功能?
因为我正在进行升级并遇到 这个错误。它会影响 XML 文件更改功能,因为它与组件相关(嗯,这是我的猜测)。我花了太长时间尝试官方解决方法,但无法让它发挥作用。我最终发现使用 InstallScript + 单行批处理文件复制文件更容易、更可靠。感觉有点老套,但它确实有效。

现在,我正在尝试找出几年后最简单、最容易弄清楚的方法来复制 InstallScript 中“XML 文件更改”功能的效果。

如果您需要任何更多信息,请告诉我,我很乐意提供。

编辑:毕竟

,我最终采用了 InstallScript 方式来完成它 - 它往往是此安装程序项目中其他所有内容的实现方式,并且它看起来(并且事实证明)做起来很快。我从该线程中 TheTraveler 显示的代码开始,修改它以满足我的需要。

这是代码:

prototype UpdateWebConfigAttributes();  
prototype ReplaceValueOf(OBJECT, STRING, STRING);   

function UpdateWebConfigAttributes()
    OBJECT oDoc, oNode;
    NUMBER i;                  
    STRING sWebConfigFilePath;   
    BOOL successfulLoad;
begin   

    sWebConfigFilePath = "Path\\To\\Web.config";  

    if Is(FILE_EXISTS, sWebConfigFilePath) = FALSE then
        MessageBox("Could not find Web.config file.", 0);
    endif;

    // get values from public properties
    set oDoc = CreateObject("Msxml2.DOMDocument.4.0");  
    if !IsObject(oDoc) then
        MessageBox("Could not create XML Document", 0);
        return -1;     
    endif;     

    oDoc.async = FALSE;  
    oDoc.setProperty("SelectionLanguage", "XPath");

    successfulLoad = oDoc.load(sWebConfigFilePath);
    if !successfulLoad then
        MessageBox("Could not load Web.config as an xml file", SEVERE);                         
        return -1;
    endif;

    ReplaceValueOf(oDoc, "//add[@key=\"ConnectionDriver\"]", CONNECT_DRIVER);
    ReplaceValueOf(oDoc, "//add[@key=\"ConnectionType\"]", CONNECT_TYPE);
    ReplaceValueOf(oDoc, "//add[@key=\"ConnectionString\"]", CONNECT_STRING_WEBCONFIG);
    ReplaceValueOf(oDoc, "//add[@key=\"ShowConnection\"]", "False");

    oDoc.save(sWebConfigFilePath);
    set oDoc = NOTHING;
end;   


function ReplaceValueOf(oDoc, xPath, valueToPutIn)
    OBJECT oNode;
begin
    set oNode = oDoc.selectNodes(xPath)(0);
    try
        oNode.attributes.getNamedItem("value").value = valueToPutIn;
    catch 
        MessageBox("Could not set '" + xPath + "' with '" + valueToPutIn + "'", SEVERE);
    endcatch;  
end;    

Question:

I am struggling trying to figure out how to update some attributes in an XML file using InstallScript. I would like to use proper XML parsing functions, but I can't find anything that suggests this version of InstallScript is capable of it. How can I do this? Should I just attempt falling back on a combination of FileInsertLine and FileGrep? Is there a library I'm missing?

Background:

What software versions?
I am using InstallShield 11 on Windows Server 2003 R2.

Why am I not just using the existing 'XML File Changes' feature?
Because I am doing an upgrade and running into this bug. It affects the XML File Change feature because it is tied to a Component (well, that's my guess). I spent too long trying the official workaround, but couldn't coax it to work. I eventually found out it was much easier and more reliable to copy the files over using InstallScript + a single line batch file. It feels a bit hacky, but it is something that actually works.

Now I am trying to figure out the easiest and simplest-to-figure-out-years-later way to replicate the effects of the 'XML File Changes' feature in InstallScript.

Please let me know if you need any more information, I will be glad to provide it.

EDIT:

I ended up going with the InstallScript way to do it after all - it has tended to be the way that everything else in this installer project was implemented, and it looked (and turned out to be) pretty quick to do. I started out with the code shown by TheTraveler in that thread and modified it to suit my needs.

Here is the code:

prototype UpdateWebConfigAttributes();  
prototype ReplaceValueOf(OBJECT, STRING, STRING);   

function UpdateWebConfigAttributes()
    OBJECT oDoc, oNode;
    NUMBER i;                  
    STRING sWebConfigFilePath;   
    BOOL successfulLoad;
begin   

    sWebConfigFilePath = "Path\\To\\Web.config";  

    if Is(FILE_EXISTS, sWebConfigFilePath) = FALSE then
        MessageBox("Could not find Web.config file.", 0);
    endif;

    // get values from public properties
    set oDoc = CreateObject("Msxml2.DOMDocument.4.0");  
    if !IsObject(oDoc) then
        MessageBox("Could not create XML Document", 0);
        return -1;     
    endif;     

    oDoc.async = FALSE;  
    oDoc.setProperty("SelectionLanguage", "XPath");

    successfulLoad = oDoc.load(sWebConfigFilePath);
    if !successfulLoad then
        MessageBox("Could not load Web.config as an xml file", SEVERE);                         
        return -1;
    endif;

    ReplaceValueOf(oDoc, "//add[@key=\"ConnectionDriver\"]", CONNECT_DRIVER);
    ReplaceValueOf(oDoc, "//add[@key=\"ConnectionType\"]", CONNECT_TYPE);
    ReplaceValueOf(oDoc, "//add[@key=\"ConnectionString\"]", CONNECT_STRING_WEBCONFIG);
    ReplaceValueOf(oDoc, "//add[@key=\"ShowConnection\"]", "False");

    oDoc.save(sWebConfigFilePath);
    set oDoc = NOTHING;
end;   


function ReplaceValueOf(oDoc, xPath, valueToPutIn)
    OBJECT oNode;
begin
    set oNode = oDoc.selectNodes(xPath)(0);
    try
        oNode.attributes.getNamedItem("value").value = valueToPutIn;
    catch 
        MessageBox("Could not set '" + xPath + "' with '" + valueToPutIn + "'", SEVERE);
    endcatch;  
end;    

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

忆离笙 2024-10-07 21:43:00

我记得当时 XML 变更非常有问题。您使用什么类型的项目?如果它是 MSI 类型,那么我将在 WiX 中创建一个合并模块并使用它的 XML 更改模式。然后,您可以将该合并模块添加到您的 InstallShield 项目中。

如果您确实想在 InstallScript 中执行此操作,那么您将必须使用 CoCreateObject() 来调用 XML DOM。

XML Installscript 有一个讨论和示例,

但是,再次强调,我不会这样做。我要么升级到较新版本的 InstallShield,要么利用 WiX 中的 Util 扩展来保持其声明性。我不喜欢编写这些类型的自定义操作,因为它通常不会有好的结果。

实用架构

I recall the XML Changes being pretty buggy back in those days. What project type are you using? If it's an MSI type then I would create a merge module in WiX and use it's XML changes pattern. You can then add that merge module to your InstallShield project.

If you really do want to do it in InstallScript then you are going to have to use CoCreateObject() to call into an XML DOM.

There is a discussino and example over at XML Installscript

But again, I wouldn't do it this way. I'd either upgrade to a newer version of InstallShield or I'd leverage the Util extension in WiX to keep it declarative. I don't like writing these types of custom actions as it usually doesn't end well.

Util Schema

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文