Results 1 to 13 of 13

Thread: MSXML parser returns "" string when program is not ran as administrator

  1. #1

    Thread Starter
    Member AndreiMhz's Avatar
    Join Date
    Dec 2010
    Location
    Romania
    Posts
    62

    Question MSXML parser returns "" string when program is not ran as administrator

    Hello, everybody.

    Haven't posted here in a while.
    I wrote an app that read XML files and shows them in a listview - nothing fancy.
    The user can edit the on screen table, then, using MSXML, the listview is repacked and
    the new XML is saved.

    The trouble arises in some corporate environments, where ActiveDirectory is employed.

    For some reason (limited/restricted accounts), MSXML works when reading the file,
    but not when returning the XML string required to write out the file.

    File is not saved with the .save() function directly because i use the .xml property to get the string,
    then convert it to unicode UTF8 and then save it. Files are required to be UTF8.

    Conversion to Unicode works well, this is not the point of failure.
    I know this because as i set up a "debug" version with MsgBox() before the UnicodeFileSave() procedure.
    No errors, i just a "" string before the file save, instead of the XML.

    When running as admin, though, i get the xml string from the .xml property of the MSXML object.

    This might be a Windows BUG, for all i know - i was wondering if there is a way around this....

    Thanks !
    Last edited by AndreiMhz; Oct 7th, 2022 at 03:19 AM.
    If this post solved your problem, please mark your thread as [SOLVED] and rate the post. It's a good way to show appreciation.

  2. #2
    PowerPoster wqweto's Avatar
    Join Date
    May 2011
    Location
    Sofia, Bulgaria
    Posts
    6,167

    Re: MSXML parser returns "" string when program is not ran as administrator

    Quote Originally Posted by AndreiMhz View Post
    This might be a Windows BUG, for all i know - i was wondering if there is a way around this....
    Bug in Windows is extremely unlikely. You can get around this by debugging your code first incl. removing On Error Resume Next and placing better error handling with logging etc.

    You need a stable repro so you have to find/simulate environment where this is failing if custom/AD security is involved.

    Another option for what is happening is simply bad input: e.g. try placing < or > in nodes by editing the listview and see what happens on save.

    Note that XML nodes cannot contain any of the symbols in Chr(0) to Chr(31) excluding vbTab and vbCrLf under any circumstances i.e. CDATA or not.

    cheers,
    </wqw>

  3. #3

    Thread Starter
    Member AndreiMhz's Avatar
    Join Date
    Dec 2010
    Location
    Romania
    Posts
    62

    Re: MSXML parser returns "" string when program is not ran as administrator

    Quote Originally Posted by wqweto View Post
    You can get around this by debugging your code first incl. removing On Error Resume Next and placing better error handling with logging etc.
    There is no "On Error Resume Next" in the procedure.

    Quote Originally Posted by wqweto View Post
    You need a stable repro so you have to find/simulate environment where this is failing if custom/AD security is involved.
    I have it, it's easily reproductible. I cannot run the source code, on the machine, vb6 ide does not run on limited user accounts. My best option is to have a Msgbox() flash the contents of the string - in my case, the string contains the XML file itself.

    Quote Originally Posted by wqweto View Post
    Another option for what is happening is simply bad input: e.g. try placing < or > in nodes by editing the listview and see what happens on save.
    Note that XML nodes cannot contain any of the symbols in Chr(0) to Chr(31) excluding vbTab and vbCrLf under any circumstances i.e. CDATA or not.
    You didn't get me here - the problem occurs when MSXML generates the XML file... not when it reads it. I actually get no error message, just a blank string instead of the XML string.
    None of the elements in the ListView can have CHR(0) and even CHR(31) - because their source is either another XML file (already parsed), either a text that is entered via a standard textbox. When the item is double clicked in the listview, a text box shows up allowing the user to edit the value.
    If this post solved your problem, please mark your thread as [SOLVED] and rate the post. It's a good way to show appreciation.

  4. #4
    PowerPoster wqweto's Avatar
    Join Date
    May 2011
    Location
    Sofia, Bulgaria
    Posts
    6,167

    Re: MSXML parser returns "" string when program is not ran as administrator

    > the problem occurs when MSXML generates the XML file

    How does MSXML generate the file? You already said .xml property is empty before UnicodeFileSave.

    How do you populate the DOM? There call MsgBox on each AppendElement (or similar) if you don't have time to instrument logging.

    At least this is what I would do, I'm not official MS support, have nothing to do with Windows OS development too. It's just my experience that *rarely* there are system components bugs of such proportions.

    I mean ".xml property is not working" has never happened. It's usually a more mundane reason why the whole export is choking and the first (and second) thing to check is your own code.

    cheers,
    </wqw>

  5. #5

    Thread Starter
    Member AndreiMhz's Avatar
    Join Date
    Dec 2010
    Location
    Romania
    Posts
    62

    Re: MSXML parser returns "" string when program is not ran as administrator

    Hello.

    How does MSXML generate thefile?
    Well - i declare some nodes...

    Code:
        Dim wDoc As MSXML2.DOMDocument
        Dim wDocNode As IXMLDOMNode
        Dim wDocNode2 As IXMLDOMNode
        Dim wDocNodeList As IXMLDOMNodeList
    The ListView shows a spreadsheet like table, with a specific structure (rows & columns).
    I open a 1 row XML stored in the application folder... this XML already had this specific structure,
    so i don't need to recreate it. Then, i just multiply the first row of this blank XML.

    Code:
            wDoc.loadXML (sBlankXML)
    
                For u = 2 To oLV.ListItems.Count
                         Set wDocNode = Nothing
                         Set wDocNode = wDoc.selectSingleNode("//table/row")
                         Set wDocNodeRoot = wDocNode.parentNode                       
                         Set wDocNodeClone = wDocNode.cloneNode(True)                
                         'increment id
                         wDocNodeClone.Attributes.Item(0).nodeTypedValue = "2"
                         'add to tree
                         wDocNodeRoot.appendChild wDocNodeClone                       
                Next u
    Now we have a XML with a structure having the same no. of rows and columns as the listview.
    After this, i parse the listview and dump each column / row into its place in the xml.

    Code:
            Set wDocNodeList = wDoc.selectNodes("//table/row")
            i = 1
            For Each wDocNode In wDocNodeList
                wDocNode.Attributes.Item(0).nodeTypedValue = oLV.ListItems.Item(i).Text
                K = 0
                For Each wDocNode2 In wDocNode.childNodes
                    wDocNode2.nodeTypedValue = oLV.ListItems.Item(i).SubItem(K).Text
                    K = K + 1
                Next
                i = i + 1
            Next
    In the end i save the XML in UTF-8 format by using the .xml property.
    The wDoc.xml returns a string containing the XML file. My problem is that the wDoc.xml returns a "" string if the EXE is not ran as administrator. Without failing, without any error messages.

    Code:
    bRestult = writeUTF8File(sFilename, wDoc.xml)
    If this post solved your problem, please mark your thread as [SOLVED] and rate the post. It's a good way to show appreciation.

  6. #6
    PowerPoster dilettante's Avatar
    Join Date
    Feb 2006
    Posts
    24,487

    Re: MSXML parser returns "" string when program is not ran as administrator

    save Method

    Character encoding is based on the encoding attribute in the XML declaration, such as <?xml version="1.0" encoding="windows-1252"?>. When no encoding attribute is specified, the default setting is UTF-8.
    So a lot of pointless gymnastics going on here.

    Using a ListView as a grid is another trap for young players. A flexgrid or datagrid are almost always better choices.


    I can't think of any reason why an elevated process might make a difference here. My guess is that file virtualization is at work here and the actual file isn't written where you think it is. What directory are you trying to target?

  7. #7

    Thread Starter
    Member AndreiMhz's Avatar
    Join Date
    Dec 2010
    Location
    Romania
    Posts
    62

    Re: MSXML parser returns "" string when program is not ran as administrator

    OK, we'll skip the talk about the listview as a grid. It's a matter of personal preference.
    Let's not get off track

    Instead, i shall tell you how i got to the conclusion that the .xml is that the string is empty.
    Here's the actual code... this fails before writing the file.

    Code:
        If wDoc.xml = "" Then
            MsgBox "Could not get the data to save XML.", vbCritical, appName
            Exit Function
        End If
    
    bRestult = writeUTF8File(sFilename, wDoc.xml)
    The file itself, is saved in the app folder.

    I also tried not saving the file, and instead sending the string as an HTTP request to a local server - same result.

    O also would like to address this :

    Code:
    wDoc.loadXML (sBlankXML)
    The BlankXML is, actually, a copy of the original XML loaded into the app. It's stored as a string, in memory.
    So, it's only read from the harddisk once. The fact that the listview gets populated with the data is proof that it's read.

    And, to answer another question: the file gets saved, but as a blank file. Saving does not fail. Usually it's the user's desktop.
    The original XML, it's also read from various locations.
    Last edited by AndreiMhz; Oct 10th, 2022 at 01:15 AM.
    If this post solved your problem, please mark your thread as [SOLVED] and rate the post. It's a good way to show appreciation.

  8. #8
    PowerPoster dilettante's Avatar
    Join Date
    Feb 2006
    Posts
    24,487

    Re: MSXML parser returns "" string when program is not ran as administrator

    Quote Originally Posted by AndreiMhz View Post
    The file itself, is saved in the app folder.
    Do you mean within the protected filesystem under Program Files? Where standard users normally would not have write access?

    If your program has a proper manifest this would raise an error 70 "Permission denied." However if it lacks a manifest with a <trustInfo/> section Windows will chuckle, treat it as legacy code, and apply file virtualization appcompat.

    Most likely your file is being written to the the duplicated path below:

    C:\Users\{user}\AppData\Local\VirtualStore\Program Files.

    Such a program would also fail under WinXP and Win2K without elevated privileges. People used to hand out Power User group membership like candy to let vocational coders ignore the fact they were no longer running on Win9x. This was a major security hole so that group was eliminated beginning back when Vista came out.


    Anyway, look under that path and see whether your file is getting written there.
    Last edited by dilettante; Oct 10th, 2022 at 02:24 AM.

  9. #9
    PowerPoster
    Join Date
    Jun 2013
    Posts
    7,454

    Re: MSXML parser returns "" string when program is not ran as administrator

    I see 3 cases where things could go wrong (after the load-phase was sccessful).
    - the Async-Property of the XML-instance should be "Off"
    - invalid Node-XML-content was added (making the "root-xml-node" behave this way)
    .. (there's and error property on the XML-instance to check for "well-formedness" before trying to write it out, IIRC)
    - yeah, and last but not least the already mentione File-Virtualization which might kick in

    Olaf

  10. #10
    PowerPoster wqweto's Avatar
    Join Date
    May 2011
    Location
    Sofia, Bulgaria
    Posts
    6,167

    Re: MSXML parser returns "" string when program is not ran as administrator

    Quote Originally Posted by AndreiMhz View Post
    Hello.

    How does MSXML generate thefile?
    Well - i declare some nodes...

    Code:
        Dim wDoc As MSXML2.DOMDocument
        Dim wDocNode As IXMLDOMNode
        Dim wDocNode2 As IXMLDOMNode
        Dim wDocNodeList As IXMLDOMNodeList
    The ListView shows a spreadsheet like table, with a specific structure (rows & columns).
    I open a 1 row XML stored in the application folder... this XML already had this specific structure,
    so i don't need to recreate it. Then, i just multiply the first row of this blank XML.

    Code:
            wDoc.loadXML (sBlankXML)
    
                For u = 2 To oLV.ListItems.Count
                         Set wDocNode = Nothing
                         Set wDocNode = wDoc.selectSingleNode("//table/row")
                         Set wDocNodeRoot = wDocNode.parentNode                       
                         Set wDocNodeClone = wDocNode.cloneNode(True)                
                         'increment id
                         wDocNodeClone.Attributes.Item(0).nodeTypedValue = "2"
                         'add to tree
                         wDocNodeRoot.appendChild wDocNodeClone                       
                Next u
    Now we have a XML with a structure having the same no. of rows and columns as the listview.
    After this, i parse the listview and dump each column / row into its place in the xml.

    Code:
            Set wDocNodeList = wDoc.selectNodes("//table/row")
            i = 1
            For Each wDocNode In wDocNodeList
                wDocNode.Attributes.Item(0).nodeTypedValue = oLV.ListItems.Item(i).Text
                K = 0
                For Each wDocNode2 In wDocNode.childNodes
                    wDocNode2.nodeTypedValue = oLV.ListItems.Item(i).SubItem(K).Text
                    K = K + 1
                Next
                i = i + 1
            Next
    In the end i save the XML in UTF-8 format by using the .xml property.
    The wDoc.xml returns a string containing the XML file. My problem is that the wDoc.xml returns a "" string if the EXE is not ran as administrator. Without failing, without any error messages.

    Code:
    bRestult = writeUTF8File(sFilename, wDoc.xml)
    You can instrument logging (or use MsgBox instead) like this

    Code:
            wDoc.loadXML (sBlankXML)
    
                For u = 2 To oLV.ListItems.Count
                         Set wDocNode = Nothing
                         Set wDocNode = wDoc.selectSingleNode("//table/row")
                         Set wDocNodeRoot = wDocNode.parentNode                       
                         Set wDocNodeClone = wDocNode.cloneNode(True)                
                         'increment id
                         wDocNodeClone.Attributes.Item(0).nodeTypedValue = "2"
                         'add to tree
                         wDocNodeRoot.appendChild wDocNodeClone                       
                         If wDoc.xml = "" Then
                            MsgBox "Failed on clone, u=" & u, vbExclamation
                            Exit Sub
                         End If
                Next u
    . . . and here

    Code:
            Set wDocNodeList = wDoc.selectNodes("//table/row")
            i = 1
            For Each wDocNode In wDocNodeList
                wDocNode.Attributes.Item(0).nodeTypedValue = oLV.ListItems.Item(i).Text
                K = 0
                For Each wDocNode2 In wDocNode.childNodes
                    wDocNode2.nodeTypedValue = oLV.ListItems.Item(i).SubItem(K).Text
                    K = K + 1
                Next
                If wDoc.xml = "" Then
                    MsgBox "Failed at set, i=" & i, vbExclamation
                    Exit Sub
                End If
                i = i + 1
            Next
    After days of spent scouring internet forums for issues with MSXML component probably some basic debugging and logging instrumentation might have been better to begin with.

    cheers,
    </wqw>

  11. #11

    Thread Starter
    Member AndreiMhz's Avatar
    Join Date
    Dec 2010
    Location
    Romania
    Posts
    62

    Re: MSXML parser returns "" string when program is not ran as administrator

    Good idea. Will do this. Still, does not explain why it works with administrator rights...
    If this post solved your problem, please mark your thread as [SOLVED] and rate the post. It's a good way to show appreciation.

  12. #12
    PowerPoster wqweto's Avatar
    Join Date
    May 2011
    Location
    Sofia, Bulgaria
    Posts
    6,167

    Re: MSXML parser returns "" string when program is not ran as administrator

    Quote Originally Posted by AndreiMhz View Post
    Good idea. Will do this. Still, does not explain why it works with administrator rights...
    Could it be that the initial contents is different in both cases? So the listview gets populated with different texts.

    Or could be that wDoc.loadXML (sBlankXML) does not load anything (i.e. sBlankXML is an empty string) so wDoc.selectNodes("//table/row") returns empty collection so For Each wDocNode In wDocNodeList does not loop even once.

    This way in bRestult = writeUTF8File(sFilename, wDoc.xml) you get the initial sBlankXML in xml property which is a blank/empty string.

    cheers,
    </wqw>

  13. #13
    PowerPoster dilettante's Avatar
    Join Date
    Feb 2006
    Posts
    24,487

    Re: MSXML parser returns "" string when program is not ran as administrator

    Yeah, I cobbled up a test case:

    Code:
    Option Explicit
    
    Private Const INVALID_FILE_ATTRIBUTES As Long = -1
    
    Private Declare Function GetFileAttributes Lib "kernel32" Alias "GetFileAttributesW" ( _
        ByVal lpFileName As Long) As Long
    
    Private Const S_OK As Long = 0
    Private Const VARIANT_ALPHABOOL As Long = &H2&
    
    Public Enum LCIDs
        'Add more as you need them here:
        LOCALE_INVARIANT = &H7F&
        LOCALE_USER_DEFAULT = &H400&
        LOCALE_SYSTEM_DEFAULT = &H800&
    End Enum
    
    Private Declare Function VariantChangeTypeEx Lib "oleaut32" ( _
        ByRef vargDest As Variant, _
        ByRef varSrc As Variant, _
        ByVal desiredlcid As Long, _
        ByVal wFlags As Integer, _
        ByVal vt As VbVarType) As Long
    
    Private Function ToStr(ByVal Value As Variant) As String
        Dim Converted As Variant
    
        If VariantChangeTypeEx(Converted, _
                               Value, _
                               LOCALE_INVARIANT, _
                               VARIANT_ALPHABOOL, _
                               vbString) <> S_OK Then
            Err.Raise 5 'Invalid procedure call or argument.
        Else
            ToStr = LCase$(Converted)
        End If
    End Function
    
    Private Sub Main()
        Const ssfDESKTOP = 0
        Dim FileName As String
        Dim Doc As MSXML2.DOMDocument
        Dim I As Long
    
        Randomize
        FileName = CreateObject("Shell.Application").NameSpace(ssfDESKTOP).Self.Path _
                 & "\" _
                 & App.EXEName _
                 & ".xml"
        Set Doc = New MSXML2.DOMDocument
        With Doc
            .preserveWhiteSpace = True
            If GetFileAttributes(StrPtr(FileName)) = INVALID_FILE_ATTRIBUTES Then
                With .appendChild(.createNode(NODE_ELEMENT, "Doc", vbNullString))
                    For I = 1 To 5
                        .insertBefore Doc.createTextNode(vbNewLine & Space$(4)), Nothing
                        With .appendChild(Doc.createNode(NODE_ELEMENT, "Row", vbNullString))
                            .Attributes.setNamedItem(Doc.createNode(NODE_ATTRIBUTE, _
                                                                    "Appended", _
                                                                    vbNullString)).nodeValue = _
                                ToStr(False)
                            .insertBefore Doc.createTextNode(vbNewLine & Space$(8)), Nothing
                            With .appendChild(Doc.createNode(NODE_ELEMENT, "Col0", vbNullString))
                                .Text = ChrW$(&H2206&) _
                                      & WeekdayName(Int(Rnd() * 7) + 1) _
                                      & ChrW$(&H2211&)
                            End With
                            .insertBefore Doc.createTextNode(vbNewLine & Space$(8)), Nothing
                            With .appendChild(Doc.createNode(NODE_ELEMENT, "Col1", vbNullString))
                                .Text = ToStr(Round(Rnd() - 0.5, 3))
                            End With
                            .insertBefore Doc.createTextNode(vbNewLine & Space$(4)), Nothing
                        End With
                    Next
                    .insertBefore Doc.createTextNode(vbNewLine), Nothing
                End With
                .save FileName
            Else
                .Load FileName
                With .documentElement
                    .insertBefore Doc.createTextNode(Space$(4)), Nothing
                    With .appendChild(Doc.createNode(NODE_ELEMENT, "Row", vbNullString))
                        .Attributes.setNamedItem(Doc.createNode(NODE_ATTRIBUTE, _
                                                                "Appended", _
                                                                vbNullString)).nodeValue = _
                            ToStr(True)
                        .insertBefore Doc.createTextNode(vbNewLine & Space$(8)), Nothing
                        With .appendChild(Doc.createNode(NODE_ELEMENT, "Col0", vbNullString))
                            .Text = ChrW$(&H2206&) _
                                  & MonthName(Int(Rnd() * 12) + 1) _
                                  & ChrW$(&H2211&)
                        End With
                        .insertBefore Doc.createTextNode(vbNewLine & Space$(8)), Nothing
                        With .appendChild(Doc.createNode(NODE_ELEMENT, "Col1", vbNullString))
                            .Text = ToStr(Round(Rnd() - 0.5, 3))
                        End With
                        .insertBefore Doc.createTextNode(vbNewLine & Space$(4)), Nothing
                    End With
                    .insertBefore Doc.createTextNode(vbNewLine), Nothing
                End With
                .save FileName
            End If
        End With
        MsgBox "Done: File on desktop"
    End Sub
    "First run" creates the XML file on the user's Desktop. Subsequent runs append another Row.

    No issues, whether run elevated or not. UTF-8 output file, just as documented.

    Code:
    <Doc>
        <Row Appended="false">
            <Col0>∆Tuesday∑</Col0>
            <Col1>-0.275</Col1>
        </Row>
        <Row Appended="false">
            <Col0>∆Wednesday∑</Col0>
            <Col1>0.108</Col1>
        </Row>
        <Row Appended="false">
            <Col0>∆Monday∑</Col0>
            <Col1>-0.015</Col1>
        </Row>
        <Row Appended="false">
            <Col0>∆Thursday∑</Col0>
            <Col1>0.244</Col1>
        </Row>
        <Row Appended="false">
            <Col0>∆Wednesday∑</Col0>
            <Col1>0.402</Col1>
        </Row>
        <Row Appended="true">
            <Col0>∆May∑</Col0>
            <Col1>-0.352</Col1>
        </Row>
        <Row Appended="true">
            <Col0>∆July∑</Col0>
            <Col1>-0.062</Col1>
        </Row>
    </Doc>
    VariantChangeTypeEx() calls are used to help generate proper non-localized values, as required of properly-formed XML documents.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width