?
Solved

VB6 Problem with http call: XML error

Posted on 2010-01-07
34
Medium Priority
?
1,657 Views
Last Modified: 2012-05-08
Dear Experts,

My VB6 program makes an http call to validate its license key and this works well in Windows XP.

But in Vista, I am getting the error -2146697211 on the command objHTTP.send. Please see attached code.

What can I do to make this work?

Thanks!
Dim objHTTP As New MSXML2.XMLHTTP
    Dim strEnvelope As String
    Dim strReturn As String
    Dim objReturn As New MSXML2.DOMDocument
    Dim nodeReturned As IXMLDOMNode
    Dim strStatus As String

strEnvelope = "https://www.abc.com..."
objHTTP.Open "get", strEnvelope, False
objHTTP.send
objReturn.Load objHTTP.responseBody
Set nodeReturned = objReturn.selectSingleNode("data")
strStatus = nodeReturned.Text

Open in new window

0
Comment
Question by:ttobin333
  • 18
  • 11
  • 5
34 Comments
 
LVL 14

Expert Comment

by:VBClassicGuy
ID: 26209998
The error number -2146697211 means that the server or proxy server was not found. Make sure the account is enabled, and permissions/rights are in order.
0
 
LVL 14

Expert Comment

by:VBClassicGuy
ID: 26210151
This MIGHT also help, but I doubt it...
http://support.microsoft.com/kb/934387 
0
 
LVL 14

Expert Comment

by:VBClassicGuy
ID: 26210236
Also, this line is suspect...
strEnvelope = "https://www.abc.com..."
Try something like strEnvelope = "https://www.abc.com/index.html" 
0
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 

Author Comment

by:ttobin333
ID: 26210536
Thanks guys, the server addresses and account are fine. The code works perfectly when the program runs within Win XP. It fails when running in Vista as standard user and even when I right click and run as admin.
0
 
LVL 14

Expert Comment

by:VBClassicGuy
ID: 26210700
I read somewhere that Vista doesn't like to switch between unsecure and secure web sites when a certain option is set. You might look into that.
0
 

Author Comment

by:ttobin333
ID: 26211355
I looked into the Vista secure vs unsecure question and that does not seem to be the problem. I can successfully make the html SOAP call and receive a response using Internet Explorer.  
0
 

Author Comment

by:ttobin333
ID: 26211450
I also tried making the call with my program to an unsecure address and it failed with the same error.
0
 
LVL 14

Expert Comment

by:VBClassicGuy
ID: 26211724
The only other thing I read about this is to make sure urlmon.dll is properly registered and has its dependencies, and that .NET 3.5 is installed.
0
 

Author Comment

by:ttobin333
ID: 26211947
.NET 3.5 is necessary for a VB6 app?
0
 

Author Comment

by:ttobin333
ID: 26212168
I also tried adding shdocvw.dll  to references and it didn't work.
0
 

Author Comment

by:ttobin333
ID: 26212347
UPDATE: It works if I LOG IN to Windows Vista as an administrator, but not as a standard user even if I right-click and "run as administrator". What's the difference and how can I get this to work for a standard user?

Thanks!
0
 
LVL 29

Expert Comment

by:nffvrxqgrcfqvvc
ID: 26212973
This works for me on a standard account.

Using the following XML for the test.
[example.xml]

<?xml version='1.0'?>
<License>
<data>ABC12345</data>
</License>
Option Explicit

Public Function XMLTest() As String

Dim http          As MSXML2.XMLHTTP
Dim doc           As MSXML2.DOMDocument
Dim mnode         As MSXML2.IXMLDOMNode

Set http = New MSXML2.XMLHTTP
Set doc = New MSXML2.DOMDocument

http.Open "GET", "http://www.somesite.com/example.xml", False
http.send
doc.loadXML http.responseText
Set mnode = doc.selectSingleNode("//data")
If IsNull(mnode) Then
 Debug.Print "No nodes selected"
Else
 MsgBox mnode.Text
End If
Set http = Nothing
Set doc = Nothing

End Function

Private Sub Command1_Click()
  Call XMLTest
End Sub

Open in new window

0
 

Author Comment

by:ttobin333
ID: 26213029
Thanks egl...would you please show me how this would fit into/replace my code?
0
 
LVL 29

Expert Comment

by:nffvrxqgrcfqvvc
ID: 26213074
You can replace your code with the example. Update the website address is all you should have to do unless your XML is more complicated than what you shown.

I think the root of the problem is objReturn.Load() where it might expect a file location try using .LoadXML() where you can load a direct string.
0
 

Author Comment

by:ttobin333
ID: 26213792
Ok, thanks! I'll be able to test this later today. I will update you.  
0
 

Author Comment

by:ttobin333
ID: 26213866
Ok, thanks! I'll be able to test this later today. I will update you.  
0
 

Author Comment

by:ttobin333
ID: 26231301
egl, it worked on XP but on Vista, gave the same error (-2146697211), on the http.send command.
0
 
LVL 29

Expert Comment

by:nffvrxqgrcfqvvc
ID: 26234578
hmm.. What reference do you have I used the version: Microsoft XML v2.6
0
 

Author Comment

by:ttobin333
ID: 26239195
I was using 3.0 but tried 2.6 after you mentioned it. Same result, unfortunately.

I tried sending the string with Internet Explorer and successfully retrieved the server response.
0
 
LVL 29

Expert Comment

by:nffvrxqgrcfqvvc
ID: 26241477
Is it possible for you to provide the real URL or create a temporary URL that I could try on my system? I don't get this error on my system.
0
 

Author Comment

by:ttobin333
ID: 26243882
egl, are you using Vista?
0
 
LVL 29

Expert Comment

by:nffvrxqgrcfqvvc
ID: 26246636
I tested the code on XP/Windows7 using a standard account. Unless there was some type of hotfix pushed that I don't know about the compatability is identical for Vista/Win7.

Could you change the URL in the code to the test URL that I created and see if it works for you.
http://egl1044.angelfire.com/example.xml
0
 

Author Comment

by:ttobin333
ID: 26248393
Thanks for hanging in there with this frustrating case, egl!

The URL gives the same error. Clearly there is something going on with my Vista machine but it's not an isolated case. I also received the same complaint about this error with my program from another Vista user.

What could possibly be going on here?
0
 
LVL 29

Expert Comment

by:nffvrxqgrcfqvvc
ID: 26250290
I'm going to write an API version of this just to see if you can get the resulting XML from the site on a standard account.
0
 

Author Comment

by:ttobin333
ID: 26250780
Will do...thanks!
0
 
LVL 29

Expert Comment

by:nffvrxqgrcfqvvc
ID: 26273687
I can't replicate your problem. The only problem I had was that when I created a new standard account when I manually run internet explorer I had to select my options from the dialogs that prompted for using interner explorer for the first time on a new account. If I never finished this process I couldn't get any connections after choosing the basic options on the dialogs everything was working fine at that point IE must have completed the settings in the registry. This allowed the application to connect without issues on a standard account.


0
 
LVL 29

Accepted Solution

by:
nffvrxqgrcfqvvc earned 2000 total points
ID: 26273951
I have tried a variety of API this morning HttpOpenRequest() using "GET" works. I also just directly read the XML file into a string using InternetOpenUrl() and that works. I am starting to think that it's not a code issue but an external issue maybe a firewall application that is blocking access to the port because the application is not on the "allowed" list it's possible for this to occur sometimes. I really don't have an answere for you here unless the example below magically works for you. You should be able to get access regardless of the account type so I don't see why it doesn't work for you. I tested what I mentioned above again and this time when I created a new standard account I had no issues even if I didn't complete the IE settings for the first time it could be a possible (Windows Firewall) issue. There is API for adding your application to the (Windows Firewall) trusted list. I never had to do this for using port 80, but you may have to for using port 443(SSL).

The first thing I would try on your machine would be to disable windows firewall or any firewall you may be running and see if you can make the request.
Option Explicit

Private Const INTERNET_OPEN_TYPE_PRECONFIG = 0
Private Const INTERNET_FLAG_NO_CACHE_WRITE = &H4000000
Private Const INTERNET_FLAG_RELOAD = &H80000000
Private Const INTERNET_FLAG_RESYNCHRONIZE = &H800&
Private Const INTERNET_FLAG_SECURE = &H800000
Private Const WININET_API_FLAG_SYNC = &H4&

Private Declare Function InternetOpenW Lib "wininet" (ByVal lpszAgent As Long, ByVal dwAccessType As Long, ByVal lpszProxyName As Long, ByVal lpszProxyBypass As Long, ByVal dwFlags As Long) As Long
Private Declare Function InternetOpenUrlW Lib "wininet" (ByVal hInternet As Long, ByVal lpszUrl As Long, ByVal lpszHeaders As Long, ByVal dwHeadersLength As Long, ByVal dwFlags As Long, ByVal dwContext As Long) As Long
Private Declare Function InternetReadFile Lib "wininet" (ByVal hFile As Long, ByVal lpBuffer As Long, ByVal dwNumberOfBytesToRead As Long, lpdwNumberOfBytesRead As Long) As Long
Private Declare Function InternetCloseHandle Lib "wininet" (ByVal hInternet As Long) As Long
Private Declare Function InternetQueryDataAvailable Lib "wininet" (ByVal hFile As Long, lpdwNumberOfBytesAvailable As Long, ByVal dwFlags As Long, ByVal dwContext As Long) As Long

Public Function GetXML(ByVal szUrl As String, Optional ByVal UseSSL As Boolean = False) As String
  
  Dim Buffer()    As Byte
  Dim hOpen       As Long
  Dim hConn       As Long
  Dim dwBytes     As Long
  Dim dwReadBytes As Long
  Dim szXML       As String
  
  ' Open connection
  hOpen = InternetOpenW(0, 1, 0, 0, WININET_API_FLAG_SYNC)
  
  If UseSSL Then
    ' SECURE connection to URL.
  hConn = InternetOpenUrlW(hOpen, StrPtr(szUrl), 0, 0, _
    INTERNET_FLAG_NO_CACHE_WRITE Or _
    INTERNET_FLAG_RELOAD Or _
    INTERNET_FLAG_RESYNCHRONIZE Or _
    INTERNET_FLAG_SECURE, 0)

  Else
  
  ' connection to URL.
  hConn = InternetOpenUrlW(hOpen, StrPtr(szUrl), 0, 0, _
    INTERNET_FLAG_NO_CACHE_WRITE Or _
    INTERNET_FLAG_RELOAD Or _
    INTERNET_FLAG_RESYNCHRONIZE, 0)
    
  End If
  
  If hConn = 0 Then
    MsgBox "InternetOpenUrl() " & Err.LastDllError
    GetXML = vbNullString
    InternetCloseHandle hOpen
    Exit Function
  End If
  
  
  Do
   
    If InternetQueryDataAvailable(hConn, dwBytes, 0, 0) Then
     
      ' Allocate the amount that is immediatley available.
      ReDim Buffer(dwBytes) As Byte
  
    Else
     
      ' Allocate 1KB chunk if the amount available fails.
      dwBytes = 1024
       
      ReDim Buffer(dwBytes) As Byte
       
    End If
    
    If InternetReadFile(hConn, VarPtr(Buffer(0)), dwBytes, dwReadBytes) Then
       
      ' This can happen if the buffer is larger then the data.
      If dwReadBytes < dwBytes Then
      
        ReDim Preserve Buffer(dwReadBytes) As Byte
        
      End If
      
      szXML = szXML & StrConv(Buffer, vbUnicode)
       
    Else
     
      Exit Do ' _leave
     
    End If

  Loop Until dwReadBytes = 0
  
  GetXML = szXML
  
  ' perform cleanup.
  InternetCloseHandle hConn
  InternetCloseHandle hOpen

  ' free memory
  Erase Buffer
  szXML = vbNullString

End Function

Private Sub Command1_Click()
  ' using Microsoft XML v2.6
  Dim doc           As MSXML2.DOMDocument
  Dim mnode         As MSXML2.IXMLDOMNode
  Dim xml           As String
  
  
  xml = GetXML("http://egl1044.angelfire.com/example.xml")
  'xml = GetXML("https://www.somesite.com/example.xml", True) ' use SSL for https:
  If LenB(xml) <> 0 Then
  Set doc = New MSXML2.DOMDocument
  doc.loadXML xml
  Set mnode = doc.selectSingleNode("//data")
  If IsNull(mnode) Then
   Debug.Print "No nodes selected"
  Else
   MsgBox mnode.Text
  End If
  xml = vbNullString
  Set doc = Nothing
  End If
  
End Sub

Open in new window

0
 

Author Comment

by:ttobin333
ID: 26274084
egl, I got suspicious about external factors also and tried logging in as another standard user -- it worked. Then when I went back to the standard user account that was not working -- and it worked!

Somehow, switching to another user account and then back corrected the connection problem. What could cause this? I didn't change any settings. I wonder what I can do to prevent users from encountering this quirky issue?
0
 

Author Comment

by:ttobin333
ID: 26274099
Even though your original method works, do you think the new one you posted should be used instead? Which one do you think is more robust?
0
 
LVL 29

Expert Comment

by:nffvrxqgrcfqvvc
ID: 26274160
I can't be sure but here was my setup. I had two account types Administrator and Standard Account. I only used the standard account for debug stuff so I probrably never used IE on that account. I am really suspect about the initial settings because it was the first standard account IE might have setup the settings in the registry under they HKEY_CURRENT_USER section. If this was the case then all additional users would inherit these same settings. The first standard user may have never had the settings which IE would need to setup. This is my only suspect cause because I wasn't able to get a connection until I completed the wizard for IE.

The fact that you probrably won't be able to reproduce this problem unless you un-install IE because the per user settings have already been created.

Well you should use the XMLHTTP object to send your requests instead of the API. I wanted to see what the cause of the issue could be and I had to confirm to myself that the API works as intended.

I think sticking with XMLHTTP should be simple enough, the API version is better for downloading files to your hard drive that can be very large > 1MB etc..
0
 
LVL 29

Expert Comment

by:nffvrxqgrcfqvvc
ID: 26274211
Make sure that your data inside the XML is not the real key but an encyption string that your program can convert to a real key. XMLHTTP probrably generates cache copies and anyone can see the key if you use that approach the API gives you more control in the API example you can see that I set specific flags so the file will never be added to the IE cache something to consider.
0
 

Author Comment

by:ttobin333
ID: 26274595
Last question for you: since the string is being sent to the server of a company that handles our registration keys (and I don't control that end of the communication), I can't use encryption. So it seems the API method is going to be preferable for security reasons.

Are there any drawbacks to the API method that I should be aware of?
0
 
LVL 29

Expert Comment

by:nffvrxqgrcfqvvc
ID: 26275275
Well the example I posted is a direct read of the file which is different than using a GET/POST. If all you needed to do was read the XML file and load to parse XML then there shouldn't be any issues besides that strange problem we both encountered.

If you need to use "GET" then should use HttpOpenRequest(). HttpSendRequest() which is probrably what XMLHTTP does under the hood.
0
 

Author Closing Comment

by:ttobin333
ID: 31675092
egl1044, you are a fantastic resource! Thanks for all your help.

Please see my other active question if you have a chance.
0

Featured Post

Vote for the Most Valuable Expert

It’s time to recognize experts that go above and beyond with helpful solutions and engagement on site. Choose from the top experts in the Hall of Fame or on the right rail of your favorite topic page. Look for the blue “Nominate” button on their profile to vote.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction While answering a recent question about filtering a custom class collection, I realized that this could be accomplished with very little code by using the ScriptControl (SC) library.  This article will introduce you to the SC library a…
I was working on a PowerPoint add-in the other day and a client asked me "can you implement a feature which processes a chart when it's pasted into a slide from another deck?". It got me wondering how to hook into built-in ribbon events in Office.
Get people started with the process of using Access VBA to control Outlook using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Microsoft Outlook. Using automation, an Access applic…
Show developers how to use a criteria form to limit the data that appears on an Access report. It is a common requirement that users can specify the criteria for a report at runtime. The easiest way to accomplish this is using a criteria form that a…
Suggested Courses

850 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question