הערה
הגישה לדף זה מחייבת הרשאה. באפשרותך לנסות להיכנס או לשנות מדריכי כתובות.
הגישה לדף זה מחייבת הרשאה. באפשרותך לנסות לשנות מדריכי כתובות.
Question
Thursday, April 23, 2015 1:31 PM
I have program 2 program in VB.Net that uses Winsock. The program is client and server. I want to make an external config in .ini file in server side for setting localport in Winsock.
The program works when I'm running it, but when I want to listen the localport I get an error.
Here is the function that reads .ini file:
Public Function GetSettingItem(ByVal File As String, ByVal Identifier As String) As String
Dim S As New IO.StreamReader(File) : Dim Result As String = ""
Do While (S.Peek <> -1)
Dim Line As String = S.ReadLine
If Line.ToLower.StartsWith(Identifier.ToLower & ":") Then
Result = Line.Substring(Identifier.Length + 2)
End If
Loop
Return Result
End Function
This it the Winsock Listen Port:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
AxWinsock1.LocalPort = GetSettingItem("D:\MainConfig.ini", "port")
AxWinsock1.Listen()
End Sub
My ini file
[Port Server]
;; Port Server you can set it as you want
Port : 29092
Error
An unhandled exception of type 'System.InvalidCastException' occurred in Microsoft.VisualBasic.dll
Additional information: Conversion from string "" to type 'Integer' is not valid.
Where is the problem? How to listen port in .ini files?
All replies (15)
Saturday, April 25, 2015 3:36 PM ✅Answered
I have to ask, are you creating the ini file yourself? Usually an ini file uses an "=" between the Key name and the number or string value stored after it like this
[Section Name]
KeyName=29092
In your case it would need to look like this in order for the GetPrivateProfileString or GetPrivateProfileInt Api functions to work.
[Port Server]
;; Port Server you can set it as you want
Port=29092
For example, i created an ini file that was exactly the same as you show and it would not find the number no mater how i tried it using ether of the functions until i formatted it like i just showed using the "=". If you are creating the file yourself then you can change the way it is being written to the file and just use the GetPrivateProfileInt Api function like this.
Imports System.Runtime.InteropServices
Public Class Form1
''' <summary>Returns an integer number from the specified Section and Key. If not successful it returns the default number.</summary>
''' <param name="lpAppName">The Section name.</param>
''' <param name="lpKeyName">The Key name.</param>
''' <param name="nDefault">The default number that is returned if it fails.</param>
''' <param name="lpFileName">The full path to the INI file.</param>
<DllImport("kernel32.dll", EntryPoint:="GetPrivateProfileIntW")> _
Public Shared Function GetPrivateProfileIntW(<MarshalAs(UnmanagedType.LPWStr)> ByVal lpAppName As String, <MarshalAs(UnmanagedType.LPWStr)> ByVal lpKeyName As String, ByVal nDefault As Integer, <MarshalAs(UnmanagedType.LPWStr)> ByVal lpFileName As String) As Integer
End Function
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim iniPathName As String = "C:\TestFolder\MainConfig.ini"
If IO.File.Exists(iniPathName) Then
Dim num As Integer = GetPrivateProfileIntW("Port Server", "Port", 0, iniPathName)
If num > 0 Then
MessageBox.Show(num.ToString)
Else
MessageBox.Show("Failed to get number")
End If
End If
End Sub
End Class
If you are not creating the ini file yourself and have no control over the way it is written then you will need to do it using some .Net methods. Make sure you are not finding the word "port" in a section that may be before the [Port Server] section. You may need to set your file reading function up to find "[Port Server]" and then find the very next line that starts with "port" from there.
Public Class Form1
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim iniPathName As String = "C:\TestFolder\MainConfig.ini"
Dim portnum As Integer = GetPortNum(iniPathName, "Port Server", "Port")
If portnum > 0 Then
MessageBox.Show(portnum.ToString)
Else
MessageBox.Show("Failed to get number")
End If
End Sub
Private Function GetPortNum(ByVal FileName As String, ByVal SectionName As String, ByVal KeyName As String) As Integer
Dim sectionfound As Boolean = False
Dim pn As Integer = 0
If IO.File.Exists(FileName) Then
For Each s As String In IO.File.ReadAllLines(FileName)
If sectionfound And s.StartsWith("[") Then Exit For
If s.ToLower = "[" & SectionName.ToLower & "]" Then sectionfound = True
If sectionfound And s.ToLower.StartsWith(KeyName.ToLower) Then
Dim str() As String = s.Split(":"c)
If str.Length > 1 Then
Integer.TryParse(str(1), pn)
Exit For
End If
End If
Next
End If
Return pn
End Function
End Class
If you say it can`t be done then i`ll try it
Thursday, April 23, 2015 1:47 PM | 1 vote
Hi Andre,
do yourself a favor and get rid of the interop winsock component. In .Net, use System.Sockets, System.Net, etc. (TcpListener, TcpClient,...)
Add Option Strict On at the top of the file and fix the errors first. It will make you aware of conversions and how you want to handle them.
Armin
Thursday, April 23, 2015 1:48 PM | 1 vote
Obviously the line does not start with "Port:" because it starts with "Port :".
Armin
Thursday, April 23, 2015 2:04 PM
ini files and WinSock? Someone was speeding in their Delorean today... ;-)
Thursday, April 23, 2015 2:55 PM
The LocalPort property is a Long data type in VB 6.0 (it's a VB 6.0 component) so you would want to convert the string value coming out of the INI file to Integer (.NET). I would just use the CInt function, but you may want to assign the value to String variable first (so you can check whether it's an empty string before converting).
Paul ~~~~ Microsoft MVP (Visual Basic)
Thursday, April 23, 2015 3:37 PM
The LocalPort property is a Long data type in VB 6.0 (it's a VB 6.0 component) so you would want to convert the string value coming out of the INI file to Integer (.NET). I would just use the CInt function, but you may want to assign the value to String variable first (so you can check whether it's an empty string before converting).
Paul ~~~~ Microsoft MVP (Visual Basic)
how i can convert from string to integer?
i don't know about this
Thursday, April 23, 2015 3:38 PM
Hi Andre,
do yourself a favor and get rid of the interop winsock component. In .Net, use System.Sockets, System.Net, etc. (TcpListener, TcpClient,...)
Add Option Strict On at the top of the file and fix the errors first. It will make you aware of conversions and how you want to handle them.
Armin
I don't know about that because I newbie in VB .NET Programing ...
can you help me to fix the error?
Thursday, April 23, 2015 3:48 PM
how i can convert from string to integer?
i don't know about this
Call Integer.Parse.
Armin
Thursday, April 23, 2015 3:56 PM
Or CInt, as I mentioned in my previous post:
Dim PortNum As String = GetSettingItem("D:\MainConfig.ini", "port")
If String.IsNullOrEmpty(PortNum) Then
MsgBox("Port number not found in config file!")
Else
AxWinsock1.LocalPort = CInt(PortNum)
AxWinsock1.Listen()
End If
Paul ~~~~ Microsoft MVP (Visual Basic)
Thursday, April 23, 2015 4:00 PM | 1 vote
I don't know about that because I newbie in VB .NET Programing ...
can you help me to fix the error?
dim setting as string
setting = GetSettingItem("D:\MainConfig.ini", "port")
If setting is nothing then
'Handle the case that the setting is not found
else
dim port as integer
if not integer.tryparse(setting, port) then
Messagebox.show("a meaningful error message")
Return
end if
AxWinsock1.LocalPort = port '
end if
This is still based on your code using the Winsock control. But as already written, newer classes are recommended instead.
I assume that the function GetSettingItem returns Nothing if the settings is not found. However, I do not post the corrected code as you would additionally have to obey the section name of the Ini file ("[Port Server]" in this case) if you want to read it correctly. Consequently, if you want to use an Ini file, there are the API functions (declared obsolete but still usable) to read and write Ini files. However, I'm sure there is also a managed wrapper (a .Net way) to work with them.
Armin
Friday, April 24, 2015 6:37 PM
Try
Public Function GetSettingItem(ByVal File As String, ByVal Identifier As String) As Integer Dim S As New IO.StreamReader(File) : Dim Result As Integer=-1
Do While (S.Peek <> -1)
Dim Line As String = S.ReadLine
If Line.ToLower.StartsWith(Identifier.ToLower & ":") Then Try Result = CInt(Line.Substring(Identifier.Length + 2)) Exit Do Catch End Try End If
Loop
Return Result
End Function
You need a Try in the button also when -1 is returned, even though everyone says upgrade to modern YES ITS TRUE but to exact help your problem here it is ✘
My goal of posting is to make you and I better educated programmers while solving our problems ✘
Saturday, April 25, 2015 7:55 AM
Or CInt, as I mentioned in my previous post:
Dim PortNum As String = GetSettingItem("D:\MainConfig.ini", "port") If String.IsNullOrEmpty(PortNum) Then MsgBox("Port number not found in config file!") Else AxWinsock1.LocalPort = CInt(PortNum) AxWinsock1.Listen() End If
Paul ~~~~ Microsoft MVP (Visual Basic)
if i use your code the port always not found ....
Saturday, April 25, 2015 8:01 AM
Try
Public Function GetSettingItem(ByVal File As String, ByVal Identifier As String) As Integer Dim S As New IO.StreamReader(File) : Dim Result As Integer=-1 Do While (S.Peek <> -1) Dim Line As String = S.ReadLine If Line.ToLower.StartsWith(Identifier.ToLower & ":") Then Try Result = CInt(Line.Substring(Identifier.Length + 2)) Exit Do Catch End Try End If Loop Return Result End Function
You need a Try in the button also when -1 is returned, even though everyone says upgrade to modern YES ITS TRUE but to exact help your problem here it is ✘
My goal of posting is to make you and I better educated programmers while solving our problems ✘
if i use your code i have a new error
An unhandled exception of type 'System.Runtime.InteropServices.COMException' occurred in AxInterop.MSWinsockLib.dll
Additional information: Exception from HRESULT: 0x800A017C (CTL_E_INVALIDPROPERTYVALUE)
Saturday, April 25, 2015 8:37 AM
dim setting as string
setting = GetSettingItem("D:\MainConfig.ini", "port")
If setting is nothing then
'Handle the case that the setting is not found
else
dim port as integer
if not integer.tryparse(setting, port) then
Messagebox.show("a meaningful error message")
Return
end if
AxWinsock1.LocalPort = port '
end ifThis is still based on your code using the Winsock control. But as already written, newer classes are recommended instead.
I assume that the function GetSettingItem returns Nothing if the settings is not found. However, I do not post the corrected code as you would additionally have to obey the section name of the Ini file ("[Port Server]" in this case) if you want to read it correctly. Consequently, if you want to use an Ini file, there are the API functions (declared obsolete but still usable) to read and write Ini files. However, I'm sure there is also a managed wrapper (a .Net way) to work with them.
Armin
sorry i don't understand what you mean ...
my program still error
Saturday, April 25, 2015 11:15 AM
sorry i don't understand what you mean ...
my program still error
I meant you shall use API functions to read Ini files. Windows API functions are functions in Windows Dlls like kernel32.dll, user32.dll, etc. There is a set of functions for reading/writing Ini files. To use these functions (for example, one is named "GetPrivateProfileString"), you need to declare them (see VB's Declare statement). An alternative is a so-called "manged wrapper". It is a class that internally calls these API functions, and it is written in a manged language (like VB.Net or C#) that offers you the same features, but you can use it more easily than directly using the API functions. So it's a kind of intermediate layer between your code and the API functions. I do not have a manged wrapper, but I'm certain you'll find one in the web. Though, as already mentioned, Ini files are considered "obsolete" by Microsoft, however, the functions are still there and working.
If you still have an error, post the current code and which error occurs in which line.
Armin