Run-time error '40006'; Wrong protocol or connection state for the requested transaction or request

Hello Experts. My VB app checks if there's an update, and if there is an update available, it uses winsock to download & run the exe. Unfortunately, it generates the following error on some computers while not on others: Run-time error '40006'; Wrong protocol or connection state for the requested transaction or request.

And I cannot figure out for the life of me, why it does this only on some of my computers but not all--they all seem to have the same components, etc. Nonetheless, Of course this should not happen on any computer. Please advise!

Many thanks in advance,
John AccountAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

It means your winsock connection has 'reset' itself, or you are trying to either load data too fast, or too soon.
Oh yes -- basically, to fix this, before you do something:

(a) Make sure your winsock connection is open before trying to read/send data, and if it is closed, reopen a new connection. Something like:
if winsock.state=9 ' error state
  while winsock.state<>0 ' closed state
  wend ' you need a while loop, because it doesn't close "immediately".
end if
' now you reopen it, or do whatever else you need

Also, try downloading SP3 (the winsock control in the newest/latest Microsoft VB). It sometimes fixes some of the stupid winsock errors.
John AccountAuthor Commented:
Thanks, cool12399, but it didn't work.
About SP3--I don't think there's a SP3 out for Windows XP. Is there?
Big Business Goals? Which KPIs Will Help You

The most successful MSPs rely on metrics – known as key performance indicators (KPIs) – for making informed decisions that help their businesses thrive, rather than just survive. This eBook provides an overview of the most important KPIs used by top MSPs.

<<< Run-time error '40006'

From my experience that error means that theres another instance of the program running with that port open.

Typically when you would run the executable on one user and then switch users it would throw out that error.

I would recommend implementing multiple connections or reset the localport to 0

Winsock1.LocalPort = 0
John AccountAuthor Commented:
I'm not having any luck at all at fixing this. I'm stuck big time, egl1044. Would you like to download and take a look at it?
Sure. I have some free time on my hands. Haven't been around lately been working on a large project.
Muhammad KhanManager, ITCommented:
which protocol are u using? TCP or UDP?
Naveen SwamyYash Infinite Solutions Private LimitedCommented:
Muhammad KhanManager, ITCommented:
This error occurs normally when you use TCP and try to connect the winsock when it is already connected or in the listening state.... check the winsock state befure u try to connect
'I dug up an old winsock project of mine

'For connection..

With Winsock1
      If .State <> sckClosed Then .Close
      .RemoteHost = "" 'remote host to connect
      .RemotePort = 1011  'port
   End With

'This goes in the winsock error event...

Private Sub Winsock1_Error(ByVal Number As Integer, Description As String, ByVal Scode As Long, ByVal Source As String, ByVal HelpFile As String, ByVal HelpContext As Long, CancelDisplay As Boolean)
If Number > 0 Then
      If Winsock1.State <> sckClosed Then
   End If
End Sub
John AccountAuthor Commented:
Here ya go--here's the troublesome project, if you want to take a look:
It will work on some computers, but not on all. Really appreciate the help! Thanks.
John AccountAuthor Commented:
UGH. I'm not having any luck here at all. I hate this stupid winsock.

That's not the problem, navstar16--I checked it out, and the difference in internet connection speed isn't a factor--but thanks, anyway.

Looks like I might just have to come up with another way to skin this cat...unless one of you can help me figure out how to do this utilizing the established method, herein. Any other ideas? Thanks.
There is a much easier solution to this problem.

1. Is your updated file located on an FTP server?
John AccountAuthor Commented:
Yes it is, eg1044
No. I have created a wrapper for you to use. I am almost finished, it will use all  WinInet API's except for the news check it will use WinHTTP just to read the news.txt file, you can change it if you want but I will add it to the activex anyway.
John AccountAuthor Commented:
Oh wow...what a guy!  Are you serious???--I sure hope so!!!
'Alright give this a shot. This will download using API letting your application responsive since its all done in a different thread. :)

'Download the Updater ActiveX.exe located below:


'Start up a New Standard.EXE project
'Add a Reference to updater.exe below is how to add the reference.
'Click Project , References , then click BROWSE, now you need to change the "files of type" dropdown menu to "executables" or "all files" locate updater.exe and add it to your reference. (it should display eglThreadFTP) then click OK.
'Add 1 Command Button
'Add 1 Timer

'-------------- Form Code -------------

Option Explicit

Dim MyUpdates As DownloadUpdates
Dim UpdateCheck As String

Private Sub Command1_Click()

'Set up FTP Connection settings
MyUpdates.Server = ""
MyUpdates.Port = 21 'ftp port
MyUpdates.Username = "ftp username"
MyUpdates.Password = "ftp password"

'LocalFile = File on server to download
'SaveAs = Save it to location on hard disk
MyUpdates.LocalFile = "clock.avi" ' <-- root or ie.. /update/clock.avi
MyUpdates.SaveAs = "D:\clockupd.avi" '<-- save to.

'Check the news.txt file for a match...
UpdateCheck = MyUpdates.ReadNewsFile("")
    Caption = UpdateCheck
    'If they match then download the file.
    If UpdateCheck = "version 1.1.2" Then
'Connect and Download if news.txt = "version 1.1.2"
'Initiate timer if need be, lets you know when download is complete.
Timer1.Enabled = True
Timer1.Interval = 1000

'Finally Connect to the ftp settings and Download the file.
    End If

End Sub

Private Sub Form_Load()
Set MyUpdates = New DownloadUpdates
End Sub

Private Sub Timer1_Timer()
'If isDownloadComplete Returns True then downloading is complete.
'Otherwise returns False
If MyUpdates.isDownloadComplete = True Then
    MsgBox "Updates have been downloaded."
    Timer1.Enabled = False
End If

End Sub

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
John AccountAuthor Commented:
Oh wow, this is great. Thanks!--but I got to run out right now to pick up my baby son at day care. Will test it out as soon as I return. Thanks, egl1044. What a guy!
John AccountAuthor Commented: going to include the source code for that wrapper?--
Have you tried it yet?
John AccountAuthor Commented:
Sorry...but I can't, in good conscience, enter these ftp parameters into an exe of which I have no control over. I'm sure you're a man of high integrity, and I know you're highly respected here in the Experts community; but opening that ftp up would compromise my own integrity with others involved therein. I would lose my integrity. I hope you understand.
Alright. I Understand your concern.

'New ActiveX EXE
'Project/Project Properties/Compile TAB/ P-CODE
'Instancing = 3 SingleUse

'----------- DownloadUpdates.cls --------------

Option Explicit

Private intPort%
Private strServer$
Private strUsername$
Private strPassword$
Private strLocalFile$
Private strSaveAs$

Public Sub FTPConnect()
    hInternet = InternetOpen(vbNullString, 1, 0&, 0&, &H4000000)
    hConnect = InternetConnect(hInternet, strServer, intPort, strUsername, strPassword, 1, &H20000000 Or &H8000000, &H0)
End Sub

Public Function FTPDownload() As String
Dim Dummy As Long
    FTPDownload = 0 'Success

    LocFile = strLocalFile
    SavFile = strSaveAs

If LenB(strServer) > 0 And _
    LenB(strUsername) > 0 And _
    LenB(strPassword) > 0 And _
    LenB(intPort) > 0 Then 'valid entry's proceed
        ThreadHandle = CreateThread(0&, 0&, AddressOf AddOfDownload, 0&, ByVal 0&, Dummy)
        EventHandle = CreateEvent(ByVal 0&, False, False, ByVal 0&)
    If IsNull(ThreadHandle) Then
        FTPDownload = "Error: creating thread."
    End If
        FTPDownload = "Error:  You didn't set up all of your FTP settings."
End If

End Function

Public Function ReadNewsFile(NewsURL As String) As String
    Dim HttpReq As Object
    Set HttpReq = CreateObject("WinHttp.WinHttpRequest.5.1")
        HttpReq.Open "GET", NewsURL, False
        ReadNewsFile = HttpReq.ResponseText
    Set HttpReq = Nothing
End Function

Public Property Get Server() As String
    Server = strServer
End Property

Public Property Let Server(ByVal nServer As String)
    strServer = nServer
End Property

Public Property Get UserName() As String
    UserName = strUsername
End Property

Public Property Let UserName(ByVal nUserName As String)
    strUsername = nUserName
End Property

Public Property Get Password() As String
    Password = strPassword
End Property

Public Property Let Password(ByVal nPassword As String)
    strPassword = nPassword
End Property

Public Property Get LocalFile() As String
    LocalFile = strLocalFile
End Property

Public Property Let LocalFile(ByVal nLocalFile As String)
    strLocalFile = nLocalFile
End Property

Public Property Get SaveAs() As String
    SaveAs = strSaveAs
End Property

Public Property Let SaveAs(ByVal nSaveAs As String)
    strSaveAs = nSaveAs
End Property

Public Property Get Port() As Integer
    Port = intPort
End Property

Public Property Let Port(ByVal nPort As Integer)
    intPort = nPort
End Property

Public Property Get isDownloadComplete() As String
    isDownloadComplete = DownloadComplete
End Property

Public Property Let isDownloadComplete(ByVal nDownloadComplete As String)
    DownloadComplete = nDownloadComplete
End Property

'----------------------- FTP.BAS ----------------------------------

Option Explicit

Public Declare Function InternetCloseHandle Lib "wininet" (ByRef hInet As Long) As Long
Public Declare Function InternetConnect Lib "wininet.dll" Alias "InternetConnectA" (ByVal hInternetSession As Long, ByVal sServerName As String, ByVal nServerPort As Integer, ByVal sUserName As String, ByVal sPassword As String, ByVal lService As Long, ByVal lFlags As Long, ByVal lContext As Long) As Long
Public Declare Function InternetOpen Lib "wininet.dll" Alias "InternetOpenA" (ByVal sAgent As String, ByVal lAccessType As Long, ByVal sProxyName As String, ByVal sProxyBypass As String, ByVal lFlags As Long) As Long
Public Declare Function FtpGetFile Lib "wininet.dll" Alias "FtpGetFileA" (ByVal hConnect As Long, ByVal lpszRemoteFile As String, ByVal lpszNewFile As String, ByVal fFailIfExists As Long, ByVal dwFlagsAndAttributes As Long, ByVal dwFlags As Long, ByRef dwContext As Long) As Boolean

Public Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Public Declare Function CreateThread Lib "kernel32" (lpThreadAttributes As Any, ByVal dwStackSize As Long, ByVal lpStartAddress As Long, lpParameter As Any, ByVal dwCreationFlags As Long, lpThreadID As Long) As Long
Public Declare Function WaitForSingleObject Lib "kernel32.dll" (ByVal hHandle As Long, ByVal dwMilliseconds As Long) As Long
Public Declare Function CreateEvent& Lib "kernel32" Alias "CreateEventA" (ByVal lpEventAttributes As Long, ByVal bManualReset As Long, ByVal bInitialState As Long, ByVal lpname As String)
Public Declare Function TerminateThread Lib "kernel32" (ByVal hThread As Long, ByVal dwExitCode As Long) As Long
Public Declare Function GetExitCodeThread Lib "kernel32" (ByVal hThread As Long, lpExitCode As Long) As Long

Public ThreadHandle As Long
Public EventHandle As Long
Public LocFile As String
Public SavFile As String
Public lRes As Long
Public hInternet As Long
Public hConnect As Long
Global DownloadComplete As Boolean

Public Sub AddOfDownload()

Dim lRet As Long
Dim lExit As Long
Dim lExitPointer As Long

DownloadComplete = False

lRes = FtpGetFile(hConnect, LocFile, SavFile, False, 0, &H0, 0)
lRes = InternetCloseHandle(hConnect)
lRes = InternetCloseHandle(hInternet)

DownloadComplete = True

lRet = WaitForSingleObject(EventHandle, 500)

If lRet > 0 Then
        lExit = GetExitCodeThread(ThreadHandle, lExitPointer)
    If lExitPointer > 0 Then
             CloseHandle (EventHandle)
             CloseHandle (ThreadHandle)
        If ThreadHandle > 0 Then TerminateThread ThreadHandle, ByVal 0&
    End If
End If

End Sub
John AccountAuthor Commented:
Thanks for the understanding. I gotta run my son to a doctor's appointment. Will test this out when I get back tonight. Thanks.
John AccountAuthor Commented:
Renders the following error message: Compile Error: User-defined type not defined
John AccountAuthor Commented:
Are there any parameters concerning the downloading of binary files, etc?
I know there's no erros in the code so you must of accidently misplaced the code.

First Start NEW activeX EXE project
'Add 1 module.bas
'Class 1 is created by default

Rename Project1 to: UDownloader
Rename Class1 to: DownloadUpdates
Rename Module1.bas to: FTP
No, it will work for Binary,Text, etc.. doesn't matter
John AccountAuthor Commented:
UGH, silly me. Well, it's working now...except for one small problem: Error message box popups with this message:
UpdateWrapper has encountered a problem and needs to close. We are sorry for the inconvenience. Please tell Microsoft about this problem?
Did you do like I said above, Compile the activeX.exe in P-CODE not Native CODE.
Project/Project Properties/ P-CODE
John AccountAuthor Commented:
Yes I did.
Just a little tip, If you added the Reference to the .exe this is what you need to do to go back and change it.
You need to remove the reference to the activex.exe in your test project, and then click File,Save Project as.. then close that project

Now you will be able to update the activeX.exe or compile it, then you can re-open the test project and re-add the reference.

If you don't follow these steps then you will get an error "file in use or something similiar, also if you don't remove the reference and click save project as, you will get some errors when trying to re-add the newer version later. so the simplest way is to do what I mentioned above.
John AccountAuthor Commented:
Are there other properties that need setting?
It works for me. I am wondering if you tried to change anything around in the code.

Did you set up your test project like I have shown above?
<<<Are there other properties that need setting?

In what regards are you refering to? All of the examples of the properties are in my example above.
John AccountAuthor Commented:
There's something I'm just not seeing here. I think I followed your instructions to a T, but there's obviously something I'm missing. If you want, you can take a look at:  (of course, the FTP parameters have been changed)
It looks fine to me and it works for me, so you compiled the exe and added it to your reference's. Does it download the file?
You can try : camcolada/updates/Camcolada.exe
John AccountAuthor Commented:
Actually, it's working quite well, except that I get that error box prompting if I want to inform Microsoft, when I unload the exe. I'm going to try it on a few other see how it works. Maybe there's something messed up with this computer.
Dont attempt to Set MyUpdates = nothing

Use End, instead of Unload Me
John AccountAuthor Commented:
Wow...that fixed it. End. LOL. I never use End. Well...there's a first time for everything!
Thank you very VERY much, egl1044. This has been a great learning experience for me!!
There are only certain circumstances where you should use End. Since we are creating a thread microsoft recommends that you end all applications with End and not Unload Me
John AccountAuthor Commented:
Thanks for sharing. You're a great guy. I appreciate it very much.
Glad I could help, Hope it works out for you in the long run.
John AccountAuthor Commented:
Hi egl1044. Sorry to bother you, but I'm getting the following error:
Run-time error '429': ActiveX component can't create object

Was wondering if you knew what that was about? I don't need to call regsvr32 or anything like that, do I?
Whats up, John
When does this error happen? More details about when it started happening. Does this happen when you install it on another machine?
I would be willing to bet that that error is from ReadNewsFile() because its the only function in the ActiveX.EXE that exposes latebinding.
Look in the registry under HKEY_CLASSES_ROOT\WinHttp.WinHttpRequest.5.1
On the following registry key  if it says anything other than the 5.1 version then this error will probrably occur because we are attempting to latebind to a newer version but that machine has an old version. Possibly 5.0 While latebinding is more version compatible if the machine is not up to date then you will get this error
John AccountAuthor Commented:
It started happening after including it in setupfactory project and making a setup file. By the way, in this version, I removed all reference to ReadNewsFile and am simply downloading the file directly.
John AccountAuthor Commented:
It works fine on my local machine. It's when I install it on another computer that there is that problem.
Strange. So your saying that you still get that error when you removed ReadNewsFile function from ActiveX.EXE and from the Test APP? MyUpdates.ReadNewsFile "www. etc..."?

In your setup program have you made sure that MyDownloader.exe is in the same location as your main Executable that contains the reference to MyDownloader.exe?
John AccountAuthor Commented:
You mean it has to be in the same folder name & path, etc?  In other words, my working folders are like this:
C:\CamColada\UpdateWrapper  --------- contains the activex exe
C:\CamColada\UpdaterNew       --------- the other stuff

Then it installs to wherever. But are you saying the the activex exe must be installed in the same path as C:\CamColada\UpdateWrapper?

Yes, in my setup app, the activex exe and main exe are in the same location. But they are not before they are compiled into a setup exe.
You need to ship both your standard.exe and activex.exe and install them into the same directory.

C:\CamColafa\Main.exe that contains reference to MyDownloader.exe
John AccountAuthor Commented:
They are. They're both in my setup factory project coming from different directories but installing to the same directory.
Here's a compiled version of the standard.exe and activex.exe. They work here on this computer where they were created, but not on any other:
I don't know what the prblem could be unless you added additional reference's to the project or changed the declerations code.

In Form_Declerations add this:

Dim MyUpd As New eglThreadFTP.DownloadUpdates
Dim MyUpdates As New eglThreadFTP.DownloadUpdates
I forgot to mention to remove Set MyUpdates = New DownloadUpdates in Form_Load
Alright I will fix this error for you give me 15 minutes...This is bugging me!! I will get back to you.

Just so you know, make sure that the Timer is not Enabled at runtime by default a timer is set to True, so change it to False in Timer properties.
John AccountAuthor Commented:
Just so you can see where I'm coming from, here's all the source code:

'I just wasnt thinking clearly sorry for the trouble. You can keep everything the same. However Remove Dim MyUpdates As DownloadUpdates from form declerations section also remote Set MyUpdates = New DownloadUpdates from Form_Load and replace it with the code below.

STEP 1. you need to just add a temp Public Variable to the ActiveX.exe so open it up and add this public variable to DownloadUpdates.cls

Public rDownloadUpdates As String

OK. Now compile the activeX.exe


Open up your Main project and add the reference to your compiled ActiveX.exe

'Add the following code to  Form_Load event

Private Sub Form_Load()

On Error GoTo ErrEXE
         Dim MyObj As New eglThreadFTP.DownloadUpdates
         MyObj.rDownloadUpdates = "test"
         Set MyObj = Nothing
         Exit Sub


    If Err.Number = 429 Then
    'where updater.exe is the filename of you activex.exe
    Shell "updater.exe", vbNormalFocus
    End If
End Sub

Now you need to add this to Command Button:

Dim MyUpdates As New DownloadUpdates
John AccountAuthor Commented:
Getting error: User-defined type not defined
For: Dim MyObj As New eglThreadFTP.DownloadUpdates

What does eglThreadFTP represent?
Oh my bad, eglThreadAPI is just the ActiveX.EXE project name, yours is probrably different
John AccountAuthor Commented:
ahhh...yes. Thanks.  Okay. far so good. Hopefully this turns out well.
John AccountAuthor Commented:
Oh yeah....this is really sweet, egl1044. Thanks. I salute you.
You sure do know your stuff!
Hi, JohnLucio,

You might want to consider changing the current activeX.EXe to this:

John AccountAuthor Commented:
Wow. What a guy! Thanks, egl1044...for a most useful & educational experience.
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Programming Languages-Other

From novice to tech pro — start learning today.