I have a service that runs and saves a file to a remote server. This works within the service but now I need to send a command
Public Declare Function cwbDQ_Create Lib "Cwbdq" (ByVal qName As String, ByVal lName As String, ByVal sName As String, ByVal queueAttr As Integer, ByVal errorHandle As Integer) As Integer
Public Declare Function cwbDQ_SetConvert Lib "Cwbdq" (ByVal dataHandle As Integer, ByVal convert As Integer) As Integer
rc = cwbDQ_Create(queueName, libName, sysName, attrHandle, errHandle)
rc1 = cwbDQ_SetConvert(dataHandle, convert)
This is where is stops processing, the service keeps running it just doesnt do anything with this.
Related
I have been trying to connect remote PC(with known credentials and on the same network) to my PC with vb.net but struck at following Error:
Managed Debugging Assistant 'PInvokeStackImbalance' : 'A call to PInvoke function 'WindowsApp1!WindowsApp1.Form1::WNetAddConnection2' has unbalanced the stack. This is likely because the managed PInvoke signature does not match the unmanaged target signature. Check that the calling convention and parameters of the PInvoke signature match the target unmanaged signature.'
Whereas same code has been executed flawlessly in Vb6.
Code:
Private Declare Function WNetAddConnection2 Lib "mpr.dll" Alias "WNetAddConnection2A" (lpNetResource As NETRESOURCE, ByVal lpPassword As String, ByVal lpUserName As String, ByVal dwFlags As Long) As Long
Private Declare Function WNetCancelConnection2 Lib "mpr.dll" Alias "WNetCancelConnection2A" (ByVal lpName As String, ByVal dwFlags As Long, ByVal fForce As Long) As Long
Private Structure NETRESOURCE
Dim dwType As Long
Dim lpRemoteName As String
End Structure
Private Const RESOURCETYPE_DISK = &H1
Private Sub ConnectToPC()
Dim networkResource As New NETRESOURCE
Dim lon As Long
With networkResource
.dwType = RESOURCETYPE_DISK
.lpRemoteName = "\\192.168.1.1"
End With
lon = WNetAddConnection2(networkResource, "123", "ADMIN", 0)
End Sub
Exception is thrown at lon and code coudn't execute further.
I am new to VB.net language.Any assistance would be very helpful.
From JQSOFT's comment:
In the signature replace (lpNetResource As NETRESOURCE, ...
with
(ByRef lpNetResource As NETRESOURCE, ... because the NETRESOURCE here is a
structure and not a class. Also, replace any Long with Integer
I'm trying to call the following unmanaged dll and it returns an error:
Attempted to read or write protected memory
' this is the declare part
Declare Ansi Function GuestCard Lib "C:\proRFL.Dll" (ByVal fUSB As Byte,
ByVal dlsCoID As Long, ByVal CardNo As Integer, ByVal dai As Integer,
ByVal llock As Integer, ByVal pdoors As Integer, ByVal BTime As String,
ByVal ETime As String, ByVal LockNo As String, ByVal Buffer As String) As Integer
' this is the calling part
Dim st As Integer = GuestCard(flagUSB, CLng(dlsCoID), CInt(CardNo) Mod 16, CInt(dai) Mod 256, llock, pdoors, BTime, ETime, LockNo, bufHexStr)
What have I done wrong?
Found the problem. I should declare the function in a module instead of a class. A simple yet stupid mistake. Thank you all for helping me out. #GSerg You are right about the type. Tank you.
I'm trying to communicate with a usb device that uses the FDTI 232RL. I've installed the drivers and integrated the .dll calls into my VB5 code and it works well. I want to get this to work on VB.net but I get the PInvokeStackImballance error message. In VB5 I have the following code sequence:
Private Declare Function FT_ListDevices Lib "FTD2XX.DLL" (ByVal arg1 As Long, ByVal arg2 As String, ByVal dwFlags As Long) As Long
...
Dim strSerialNumber As String * 256
...
LoggerList.AddItem ("ListDevices by S/N")
If FT_ListDevices(0, strSerialNumber, FT_LIST_BY_INDEX Or FT_OPEN_BY_SERIAL_NUMBER) <> FT_OK Then
...
In VB.NET:
Private Declare Function FT_ListDevices Lib "FTD2XX.DLL" (ByVal arg1 As Long, ByVal arg2 As String, ByVal dwFlags As Long) As Long
...
Dim strSerialNumber As Stringbuilder new = stringbuilder (" ",256)
...
LoggerList.AddItem ("ListDevices by S/N")
If FT_ListDevices(0, strSerialNumber, FT_LIST_BY_INDEX Or FT_OPEN_BY_SERIAL_NUMBER) <> FT_OK Then
...
The error occurs at the if statement. Do I need to import the Dll with import("FTD2XX.dll")? I've also tried Dim strSerialNumber(256) as char and that doesn't work either. Am I working the wrong problem?
In VB5 a long is 32 bits while it is 64 its in VB.Net. Change the parameters in your function from long to int which is 32 bits on VB.Net.
Private Declare Function FT_ListDevices Lib "FTD2XX.DLL" (ByVal arg1 As Integer, _
ByVal arg2 As String, ByVal dwFlags As Integer) As Integer
I'm facing a problem importing a DLL on different environments.
I have to check Windows platform and import the third-party DLL that will be placed in C:\Program Files\ (for 32-bit) or C:Program Files (x86)\ (for 64-bit).
Before the code was written like this:
Declare Function RDRCConnect Lib "c:\program files\TP-DLL\RDRCAP32.DLL" (ByVal lpszServerName As String, ByVal lNetConnType As Integer, ByVal lpszParam1 As String, ByVal lpszParam2 As String, ByVal lpszParam3 As String, ByRef lNetConn As Integer, ByRef lNetErr As Integer) As Integer
Declare Function RDRCDisconnect Lib "c:\program files\TP-DLL\RDRCAP32.DLL" (ByVal lNetConn As Integer, ByRef lNetErr As Integer) As Integer
...and I changed to use attributes:
Private Const CheminDLL As String = "C:\Program Files\TP-DLL\RDRCAP32.DLL"
<System.Runtime.InteropServices.DllImport(CheminDLL)>
Private Shared Function RDRCConnect(ByVal lpszServerName As String, ByVal lNetConnType As Integer, ByVal lpszParam1 As String, ByVal lpszParam2 As String, ByVal lpszParam3 As String, ByRef lNetConn As Integer, ByRef lNetErr As Integer) As Integer
End Function
How can I change the DLL path dinamically in this scenario, once the DLLImport expects a Constant as parameter?
There's no way to pass anything other than a constant into the attribute, since attributes, by definition are evaluated at compile-time, not at runtime. There may be better alternatives, but one option I can give you would be to create separate imports for each version:
<DllImport("C:\Program Files\TP-DLL\RDRCAP32.DLL", EntryPoint := "RDRCConnect")>
Private Shared Function RDRCConnect32(ByVal lpszServerName As String, ByVal lNetConnType As Integer, ByVal lpszParam1 As String, ByVal lpszParam2 As String, ByVal lpszParam3 As String, ByRef lNetConn As Integer, ByRef lNetErr As Integer) As Integer
End Function
<DllImport("C:\Program Files (x86)\TP-DLL\RDRCAP32.DLL", EntryPoint := "RDRCConnect")>
Private Shared Function RDRCConnect64(ByVal lpszServerName As String, ByVal lNetConnType As Integer, ByVal lpszParam1 As String, ByVal lpszParam2 As String, ByVal lpszParam3 As String, ByRef lNetConn As Integer, ByRef lNetErr As Integer) As Integer
End Function
Then you would need to choose which one to call appropriately each time you call the method.
I just stumbled upon this a couple of days ago when I had a similar issue to yours and it put me on the right path. Look for it here.
If the dlls are the same (same name and signatures) but just in different locations then you can p/invoke LoadLibrary explicitly with the full path of the dll as determined at runtime. As long as you do this before you invoke any of the exported APIs then it will use the one already loaded as long as the name of the dll in the import is the same.
I'm trying to find a simple way of checking user stats via FTP, wininet seems to be the best option.
How do I get the output from the command though?
Private Declare Function InternetCloseHandle Lib "wininet.dll" (ByVal HINet As Integer) As Integer
Private Declare Function InternetOpen Lib "wininet.dll" Alias "InternetOpenA" (ByVal sAgent As String, ByVal lAccessType As Integer, ByVal sProxyName As String, ByVal sProxyBypass As String, ByVal lFlags As Integer) As Integer
Private Declare Function InternetConnect Lib "wininet.dll" Alias "InternetConnectA" (ByVal hInternetSession As Integer, ByVal sServerName As String, ByVal nServerPort As Integer, ByVal sUsername As String, ByVal sPassword As String, ByVal lService As Integer, ByVal lFlags As Integer, ByVal lContext As Integer) As Integer
Public Declare Function ftpCommand Lib "wininet.dll" Alias "FtpCommandA" (ByVal hConnect As Integer, ByVal fExpectResponse As Boolean, ByVal dwFlags As Integer, ByVal lpszCommand As String, ByRef dwContext As Integer, ByRef phFtpCommand As Integer) As Boolean
Dim INet, INetConn As Integer
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
INet = InternetOpen("MyFTP", 1, vbNullString, vbNullString, 0)
INetConn = InternetConnect(INet, "192.168.1.6", 21, "user", "pwd", 1, 0, 0)
strCommand = "SITE SHOW SERVER 192.168.1.6.21"
Dim retv As Long
Dim Test = ftpCommand(INetConn, True, 2, strCommand, 0, retv)
Debug.Write(Test)
InternetCloseHandle(INetConn)
InternetCloseHandle(INet)
End Sub
The output I'm expecting is:
Response: 200- Server IP = "192.168.1.6"
Response: 200- Port = "21"
Response: 200- Start time = "10/02/2010 02:46:57 PM"
Response: 200- Download = "0.000 KB"
Response: 200- Upload = "0.000 KB"
Response: 200- Online Users = "0"
Response: 200-======================================
Response: 200 Site command OK
Thanks.
I think you may find use of InternetGetLastResponseInfo which is a link to the c++ definition
(found this by navigating the WinINet function list) but provides a useful hint
it says:
InternetGetLastResponseInfo Function
Retrieves the last error description or server response on the thread calling this function.
Consider this sample implementation
Private Function GetServerResponse() As String
Dim lError As Long
Dim strBuffer As String
Dim lBufferSize As Long
Dim retVal As Long
retVal = InternetGetLastResponseInfo(lError, strBuffer, lBufferSize)
strBuffer = New String("", lBufferSize + 1)
retVal = InternetGetLastResponseInfo(lError, strBuffer, lBufferSize)
GetServerResponse = strBuffer
End Function
Which calls the external function (here for copy paste access)
Declare Function InternetGetLastResponseInfo Lib "wininet" Alias "InternetGetLastResponseInfoA" (ByRef lpdwError As Long, ByVal lpszBuffer As String, ByRef lpdwBufferLength As Long) As Boolean
twice, once to get the buffer length and again to fill the buffer string then returns the filled buffer