So, cutting a long story short the section of my code that I am currently unable to figure out is designed to report the current IP settings of a given NIC, so I want it to essentially spit out the IP, Subnet and default Gateway that it is currently set to. I have a solution working but it only seems to play nice when the NIC is set to DHCP which is not good for my application.
Here is my current code:
Public Sub NetGet()
MainForm.NetLabelIP.Text = "IPv4 Address: "
MainForm.NetLabelIP.Text = "subnet Mask: "
MainForm.NetLabelIP.Text = "Default Gateway: "
MainForm.NetLabelCN.Text = "Computer Name: " + System.Net.Dns.GetHostName()
For Each ip In System.Net.Dns.GetHostEntry(System.Net.Dns.GetHostName()).AddressList
If ip.AddressFamily = Net.Sockets.AddressFamily.InterNetwork Then
'IPv4 Adress
MainForm.NetLabelIP.Text = "IPv4 Address: " + ip.ToString()
For Each adapter As Net.NetworkInformation.NetworkInterface In Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces()
If adapter.Name = MainForm.interfaceSelector.SelectedItem Then
For Each unicastIPAddressInformation As Net.NetworkInformation.UnicastIPAddressInformation In adapter.GetIPProperties().UnicastAddresses
If unicastIPAddressInformation.Address.AddressFamily = Net.Sockets.AddressFamily.InterNetwork Then
If ip.Equals(unicastIPAddressInformation.Address) Then
'Subnet Mask
MainForm.NetLabelSM.Text = "Subnet Mask: " + unicastIPAddressInformation.IPv4Mask.ToString()
Dim adapterProperties As Net.NetworkInformation.IPInterfaceProperties = adapter.GetIPProperties()
For Each gateway As Net.NetworkInformation.GatewayIPAddressInformation In adapterProperties.GatewayAddresses
'Default Gateway
MainForm.NetLabelDG.Text = "Default Gateway: " + gateway.Address.ToString()
Next
If unicastIPAddressInformation.PrefixOrigin = 3 Then
DHCP = True
MainForm.NetLabelDHCP.Text = "DHCP Enabled: TRUE"
Else
DHCP = False
MainForm.NetLabelDHCP.Text = "DHCP Enabled: FALSE"
End If
''DNS1
'if adapterproperties.dnsaddresses.count > 0 then
' label5.text = adapterproperties.dnsaddresses(0).tostring()
'end if
''DNS2
'if adapterproperties.dnsaddresses.count > 1 then
' label6.text = adapterproperties.dnsaddresses(1).tostring()
'end if
End If
End If
Next
End If
Next
End If
Next
End Sub
I'm assuming it's going to be something abhorrently daft in hindsight, however I feel it best to share my request with the community so that anyone else looking for a similar solution can find their answers here.
Thanks in advance, guys.
This NetInterfacesInfo class implements two static (shared) methods the return informations on the Network Interfaces of a Machine:
NetInterfacesInfo.GetNetworkInterfaces()
This method returns all the Network Interfaces that support IPV4 except the Loopback interface.
The informations are returned in a List(Of NetWorkInterfacesInfo), which exposes these properties:
ConnectionName: The name assigned to the connection (Local Area Network (LAN))
Description: The firendly name of the Interface
IPV4Addresses: A simplified list of each Ip Address as string, the associated NetMask and Default Gateway.
IpAddresses: A list ot the IP Addresses associated with the Network Interface.
DHCPSservers: A list of the DHCP Servers associated with the Network Interface.
DnsServers: A list of the DNS Servers associated with the Network Interface.
Gateways: A list of Gateways addresses associated with the Network Interface.
IsDHCPEnabled: Specifies whether the IP Address is provided by a DHCP server or is a Static Address.
MacAddress: The MAC address of the NIC
Status: The Interface is functional (Up) or not (Down)
InterfaceType: The type of the Interface. This value can be one of the many possible types of Interfaces: Wireless80211, Tunnel, FastEthernetFx etc.
The IPV4Addresses property return a simplified list of the IP Addresses associated with the Network Interface. These informations are contained in a IpV4AddressInfo class, which provides these properties:
IpAddress: String representation of the IP Address.
NetMask: String representation of the NetMask of the Ip Address.
DefaultGateway: String representation of the Default Gateway address.
IsDnsEligible: Specifies that the IP Address can appear in a DNS (is routable)
Sample usage:
Dim allNicsInfo = NetInterfacesInfo.GetNetworkInterfaces()
For Each nic As NetInterfacesInfo.NetWorkInterfacesInfo In allNicsInfo
Console.WriteLine($"Description: {nic.Description} Type: {nic.InterfaceType}")
Next
Dim Wireless = allNicsInfo.Where(Function(nic) nic.InterfaceType = NetworkInterfaceType.Wireless80211)
NetInterfacesInfo.IpV4AddressSimpleList
The simplified list of IP Addresses associated with a Network Interface can also be retrieved using this static (shared) method, providing the Name (actually, the Description property) of a Network Interface.
This method returns a List(Of IpV4AddressInfo), a simplified, string only version, of each IP Address (of the specified Network Interface), its NetMask and the associated Default Gateway.
Sample usage:
Dim nicInfo = NetInterfacesInfo.IpV4AddressSimpleList("Some NIC Name")
For Each ipV4Addr As NetInterfacesInfo.IpV4AddressInfo In nicInfo
Console.WriteLine(ipV4Addr.IpAddress)
Console.WriteLine(ipV4Addr.NetMask)
Console.WriteLine(ipV4Addr.DefaultGateway)
Next
Attach the main class to a ComboBox:
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim allNicsInfo = NetInterfacesInfo.GetNetworkInterfaces()
ComboBox1.DisplayMember = "ConnectionName"
ComboBox1.DataSource = allNicsInfo
End Sub
Private Sub ComboBox1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ComboBox1.SelectedIndexChanged
Dim cbo = DirectCast(sender, ComboBox)
If cbo.SelectedIndex = -1 Then Return
Dim nicInfo = DirectCast(cbo.SelectedItem, NetInterfacesInfo.NetWorkInterfacesInfo)
TextBox1.Text = String.Join(Environment.NewLine, nicInfo.IPV4Addresses.
Select(Function(nic) $"IP Address: {nic.IpAddress} NetMask: {nic.NetMask}"))
TextBox2.Text = nicInfo.IPV4Addresses.First().DefaultGateway
End Sub
Imports System.Linq
Imports System.Net
Imports System.Net.NetworkInformation
Imports System.Net.Sockets
Public Class NetInterfacesInfo
Public Shared Function GetNetworkInterfaces() As List(Of NetWorkInterfacesInfo)
Dim ifInfo As New List(Of NetWorkInterfacesInfo)()
ifInfo.AddRange(GetNetworInterfaces().
Where(Function(nic) nic.NetworkInterfaceType <> NetworkInterfaceType.Loopback AndAlso
nic.Supports(NetworkInterfaceComponent.IPv4)).
Select(Function(nic) New NetWorkInterfacesInfo() With {
.Description = nic.Description,
.ConnectionName = nic.Name,
.IsDHCPEnabled = nic.GetIPProperties().GetIPv4Properties().IsDhcpEnabled,
.DHCPSservers = nic.GetIPProperties().DhcpServerAddresses.ToList(),
.DnsServers = nic.GetIPProperties().DnsAddresses.ToList(),
.Gateways = nic.GetIPProperties().GatewayAddresses.Select(Function(ipa) ipa.Address).ToList(),
.InterfaceType = nic.NetworkInterfaceType,
.IpAddresses = nic.GetIPProperties().UnicastAddresses.Select(Function(ipa) ipa.Address).ToList(),
.MacAddress = nic.GetPhysicalAddress().GetAddressBytes().
Select(Function(b) b.ToString("X")).Aggregate(Function(s1, s2) s2 + ":" + s1),
.Status = nic.OperationalStatus,
.IPV4Addresses = GetIpV4AddressInfo(nic)
}))
Return ifInfo
End Function
Public Shared Function IpV4AddressSimpleList(nicName As String) As List(Of IpV4AddressInfo)
Dim nic = GetNetworInterfaceByName(nicName)
If nic Is Nothing Then Return Nothing
Return nic.GetIPProperties().UnicastAddresses.
Where(Function(ipa) ipa.Address.AddressFamily = AddressFamily.InterNetwork).
Select(Function(ipa) New IpV4AddressInfo() With {
.IpAddress = ipa.Address?.ToString(),
.NetMask = ipa.IPv4Mask?.ToString(),
.IsDnsEligible = ipa.IsDnsEligible,
.DefaultGateway = nic.GetIPProperties().GatewayAddresses.FirstOrDefault()?.Address?.ToString()
}).ToList()
End Function
Private Shared Function GetIpV4AddressInfo(nic As NetworkInterface) As List(Of IpV4AddressInfo)
Return nic.GetIPProperties().UnicastAddresses.
Where(Function(ipa) ipa.Address.AddressFamily = AddressFamily.InterNetwork).
Select(Function(ipa) New IpV4AddressInfo() With {
.IpAddress = ipa.Address?.ToString(),
.NetMask = ipa.IPv4Mask?.ToString(),
.IsDnsEligible = ipa.IsDnsEligible,
.DefaultGateway = nic.GetIPProperties().GatewayAddresses.FirstOrDefault()?.Address?.ToString()
}).ToList()
End Function
Private Shared Function GetNetworInterfaces() As NetworkInterface()
Return NetworkInterface.GetAllNetworkInterfaces()
End Function
Private Shared Function GetNetworInterfaceByName(nicName As String) As NetworkInterface
Return NetworkInterface.GetAllNetworkInterfaces().FirstOrDefault(Function(nic) nic.Name = nicName)
End Function
Public Class NetWorkInterfacesInfo
Public Property ConnectionName As String
Public Property Description As String
Public Property IPV4Addresses As List(Of IpV4AddressInfo)
Public Property IpAddresses As List(Of IPAddress)
Public Property DHCPSservers As List(Of IPAddress)
Public Property DnsServers As List(Of IPAddress)
Public Property Gateways As List(Of IPAddress)
Public Property IsDHCPEnabled As Boolean
Public Property MacAddress As String
Public Property Status As OperationalStatus
Public Property InterfaceType As NetworkInterfaceType
End Class
Public Class IpV4AddressInfo
Public Property IpAddress As String
Public Property NetMask As String
Public Property DefaultGateway As String
Public Property IsDnsEligible As Boolean
End Class
End Class
Related
My VS2015 VB app is reading the MAC address of the users computer. This has worked well except some users are using laptops with docking stations that assign their own MAC address. The code I am using returns the first one it finds, can a specific one be searched for?
Dim mc As New ManagementClass(New ManagementPath("Win32_Processor"), New ObjectGetOptions(New ManagementNamedValueCollection()))
Dim moc As ManagementObjectCollection = mc.GetInstances()
mc.Path = New ManagementPath("Win32_NetworkAdapterConfiguration")
moc = mc.GetInstances()
Dim sMac As String = String.Empty
For Each mo As ManagementObject In moc
If (mo.GetPropertyValue("IPEnabled") = True) Then
If (sMac = String.Empty) Then
sMac = mo.GetPropertyValue("MacAddress").ToString()
End If
End If
Next
This method is using System.Net.NetworkInformation.NetworkInterface instead of directly querying the WMI interface.
It returns informations on all the current Network Interfaces, except the Loopback interface, where the Operational Status is UP. This usually filters the Teredo and ISATAP interfaces and, of course, all the Network Interfaces that are not currently active.
The NetworkInterfaceType could also be used to filter other specific interface type, the NetworkInterfaceType.Wireless80211 for example.
I'm proposing this variant because it's simpler to modify/expand when required.
Each instance of the NetInterfaceMac class povides:
The Interface human-friendly description
The IPV4 addresses of the Interface
The MAC address if string format ("BF:D1:E8:8C:2B:A4")
The MAC address bytes
Public Class NetInterfaceMac
Public Property InterfaceDescription() As String
Public Property IPAddress() As IPAddress
Public Property MacAddress() As String
Public Property MacAddressBytes() As Byte()
End Class
Public Shared Function GetNetworkMACAddresses() As List(Of NetInterfaceMac)
Dim Macs As New List(Of NetInterfaceMac)()
Dim NetInterfaces As NetworkInterface() = NetworkInterface.GetAllNetworkInterfaces()
Macs.AddRange(NetInterfaces.Where(
Function(ni) ni.NetworkInterfaceType <> NetworkInterfaceType.Loopback AndAlso
ni.OperationalStatus = OperationalStatus.Up).
Select(Function(ni) New NetInterfaceMac() With {
.IPAddress = ni.GetIPProperties().UnicastAddresses?.
Where(Function(ip) ip.IsDnsEligible = True)?.Select(Function(ip) ip.Address).ToArray(),
.InterfaceDescription = ni.Description,
.MacAddress = ni.GetPhysicalAddress().GetAddressBytes().
Select(Function(b) b.ToString("X")).Aggregate(Function(s1, s2) s2 + ":" + s1),
.MacAddressBytes = ni.GetPhysicalAddress().GetAddressBytes()
}))
Return Macs
End Function
Sample call:
Dim Macs As List(Of NetInterfaceMac) = GetNetworkMACAddresses()
I'm pretty new with vb.net so I'm not completely familiar with how public functions are called from one form to another. When hovering over "myIniFile" and "initGPIB" in the class, frmReadTemp, I get the error message - not declared. It may be inaccessible due to its protection level. However, that function and sub is Public in another class.
Public Class frmReadTemp
Private Sub cmdRun_Click(sender As Object, e As EventArgs) Handles cmdRun.Click
Dim err_code As eCode = eCode.ERR_NONEr
myInifile()
err_code = initGPIB()
End Sub
End Class
Public Class PowerSupply_setup
#Region "Variable Declarations"
Dim myIniFile As IniFile
Public instrInfo As New ArrayList
Public myiniObj As iniObj
WithEvents myPS As IPowerSupply
WithEvents myTestSystem As New testSystemObj(4)
#End Region
Public Sub loadIniFile()
Dim tenable As String
'Power Supply
myiniObj.ps_addr.PrimaryAddress = myIniFile.GetInteger("GPIB_INSTRUMENTS", "POWERSUPPLY_ADDR", 6)
myiniObj.ps_addr.ComInterface = 1
myiniObj.ps_type = myIniFile.GetString("GPIB_INSTRUMENTS", "POWERSUPPLY_TYPE", "HP6632").ToUpper
tenable = myIniFile.GetString("GPIB_INSTRUMENTS", "POWERSUPPLY_AVAILABLE", "NO")
myiniObj.ps_available = IIf(tenable.ToUpper.Trim.StartsWith("NO"), False, True)
'myiniObj.ps_available = IIf((myIniFile.GetString("GPIB_INSTRUMENTS", "POWERSUPPLY_AVAILABLE", 0)) = "0", False, True)
myiniObj.ps_port = myIniFile.GetInteger("GPIB_INSTRUMENTS", "POWERSUPPLY_PORT", 1)
myiniObj.ps_ov_offset = Val(myIniFile.GetInteger("GPIB_INSTRUMENTS", "POWERSUPPLY_OVERVOLTAGE_OFFSET", "3.0"))
myiniObj.ps_current_limit = Val(myIniFile.GetInteger("GPIB_INSTRUMENTS", "POWERSUPPLY_CURRENT_LIMIT", "3.0"))
End Sub
Public Function initGPIB() As swiErr.eCode
Dim err_code As eCode = eCode.ERR_NONE
If (instrInfo.Count = 0) Then
'init Power Supply
If (err_code = eCode.ERR_NONE And myiniObj.ps_available) Then
Dim iInfo2(1) As String
If (myiniObj.ps_type.ToUpper.Contains("HP6632")) Then
myPS = New HP6632(myiniObj.ps_addr)
err_code = myPS.ErrCode
ElseIf (myiniObj.ps_type.ToUpper.Contains("E3631")) Then
myPS = New E3631A(myiniObj.ps_addr)
err_code = myPS.ErrCode
ElseIf (myiniObj.ps_type.ToUpper.Contains("E66311")) Then
myPS = New E66311B(myiniObj.ps_addr)
err_code = myPS.ErrCode
ElseIf (myiniObj.ps_type.ToUpper.Contains("E66319")) Then
myPS = New E66311B(myiniObj.ps_addr)
err_code = myPS.ErrCode
ElseIf (myiniObj.ps_type.ToUpper.Contains("SCPI")) Then
myPS = New SCPI_PS(myiniObj.ps_addr)
err_code = myPS.ErrCode
Else
myPS = Nothing
err_code = eCode.ERR_INST_PS_NOT_SUPPORTED
End If
If (err_code = eCode.ERR_NONE) Then
iInfo2(0) = myPS.instrumentName
iInfo2(1) = myPS.gpibAddress.PrimaryAddress
myPS.selectPort = Me.myiniObj.ps_port
instrInfo.Add(iInfo2)
myPS.OverVoltageOffset = myiniObj.ps_ov_offset
myPS.setPwrOff()
End If
If (err_code = eCode.ERR_INST_GPIB_SEARCH) Then err_code = eCode.ERR_INST_MISSING_PWRSUPPLY
Else
'create object but set availability to false
myPS = New E3631A()
End If
Me.myTestSystem.instrument.PS = myPS
End If
Return err_code
End Function
End Class
The variable myIniFile and the method initGPIB are indeed public, so they are accessible from outside of the PowerSupply_setup class. However, since they are members of that class, they must be referenced via an object of that class. For instance:
Dim mySetup As New PowerSupply_setup()
err_code = mySetup.initGPIB()
Since they are instance members (not Shared), you must create an instance (an object) of the class and then you can access them via that object. If you create multiple objects of the class, then you will have multiple copies of the members.
If you only ever need one copy of the members, and you don't want to have to create an object just to use them, you can alternatively decare them as Shared members of the class:
Public Class PowerSupply_setup
Public Shared Sub loadIniFile()
' ...
End Sub
' ...
End Class
Then you can access them directly via the class name:
err_code = PowerSupply_setup.initGPIB()
Personally, I would recommend against doing so, unless really necessary, because it leads to global state which can be dangerous. If you really do want to go down that road, though, and you don't even want to have to use the class name to access those members, you could also put them in a Module rather than in a class.
Couple different things going on here:
Dim is private, not public, so you'll need to declare the var Public or make a Public Property to access it.
Any property/method not declared Shared must be called from an instance member. In other words, you actually have to create a Powersupply_Setup object and call Init_GPIB() from that copy, unless you change the declaration of Init_GIPB().
What is the fastest/most efficient way to count how many Computer objects in the collection have a MAC address (I.e. Computer.MACAddress <> "")
<Serializable>
Public Class Computer
Public Property Name As String
Public Property FQDN As String
Public Property Path As String
Public Property GUID As String
Public Property MACAddress As String
Public Property IPAddress As Net.IPAddress
End Class
<Serializable>
Public Class ComputerCollection
Inherits Collection(Of Computer)
End Class
At the moment I'm using LINQ:
Dim macCount = From comp In computers Where comp.MACAddress <> "" Select comp
ssMACDisc.Text = macCount.Count.ToString + " MAC Addresses Discovered"
Thanks in advance
LINQ also uses loops. But you should prefer the most readable way normally.
Dim nonEmptyMacs = From comp In computers
Where Not String.IsNullOrEmpty(comp.MACAddress)
Dim countNonEmptyMacs = nonEmptyMacs.Count()
If you need something more efficient you could use a Lookup(Of Tkey, TElement) to count all the null/empty macs. You can initialize a lookup only via ToLookup. If the collection doesn't change often you can persist it in a field that you can access later. Perhaps you also recreate it from the method that adds new computers. You need a custom IEqualityComparer(Of Computer) which treats null and empty macs equal:
Public Class ComputerMacComparer
Implements IEqualityComparer(Of Computer)
Public Function Equals1(x As Computer, y As Computer) As Boolean Implements System.Collections.Generic.IEqualityComparer(Of Computer).Equals
If x Is Nothing OrElse y Is Nothing Then
Return False
End If
If String.IsNullOrEmpty(x.MACAddress) AndAlso String.IsNullOrEmpty(y.MACAddress) Then Return True
Return x.MACAddress = y.MACAddress
End Function
Public Function GetHashCode1(obj As Computer) As Integer Implements System.Collections.Generic.IEqualityComparer(Of Computer).GetHashCode
If String.IsNullOrEmpty(obj.MACAddress) Then Return 0
Return obj.MACAddress.GetHashCode()
End Function
End Class
The good thing: you can use this class for many other LINQ methods like GroupBy or Intesect.
I've used this sample data:
Dim computers As New ComputerCollection
computers.Add(New Computer With {.MACAddress = ""})
computers.Add(New Computer With {.MACAddress = nothing})
computers.Add(New Computer With {.MACAddress = "1"})
computers.Add(New Computer With {.MACAddress = "2"})
computers.Add(New Computer With {.MACAddress = "3"})
computers.Add(New Computer With {.MACAddress = Nothing})
As you can see, there are three computers that have either a null- or empty-mac.
You need one examplary "Null"-Computer that you can use later:
Dim nullComp = New Computer With {.MACAddress = Nothing}
Here is the only code that is necessary to create the lookup and to count all computers:
Dim macLookup = computers.ToLookup(Function(comp) comp, New ComputerMacComparer())
Dim countNull = macLookup(nullComp).Count() ' 3
This should be more efficient since a lookup is similar to a Dictionary. It returns an empty sequence if the key is not contained.
I have a program that allows users to setup a client/server to control/run commands from a remote location. Now i'm trying to implement server plugins, and I'm doing that by loading every .vb file in a folder contained inside the current running directory. Everything is great, and the code from the external files compiles just fine... Only problem is, Its returning nothing when I try to compile the script and use one of the methods inside it.
Here's some code for you to check out. My error is in the 2nd. Any idea on how to fix this?
The Interaction Interface:
Public Interface LinkingInterface
Property name As String
Property statetag As String
Sub selected(ByVal Sock As Integer)
Sub deselected(ByVal Sock As Integer)
Sub load()
Function generateOutput(ByVal input As String, ByVal Sock As Integer) As String
End Interface
Detection/Loading of the "Modes" (add-ins):
For Each file In My.Computer.FileSystem.GetFiles("modes\")
Dim thisMode As LinkingInterface = LoadMode(My.Computer.FileSystem.ReadAllText(file))
thisMode.load() '<---------------------------My error is here, saying its a null ref.
modes_InterfaceCollection.Add(thisMode) 'Public modes_InterfaceCollection As New Microsoft.VisualBasic.Collection()
modes_nameIndex.Add(thisMode.name) 'Public modes_nameIndex As New Specialized.StringCollection()
Next
'LoadMode' Function
Public Function LoadMode(ByVal code As String) As LinkingInterface
Using provider As New VBCodeProvider()
Dim parameters As New CompilerParameters()
parameters.GenerateInMemory = True
parameters.ReferencedAssemblies.Add(Reflection.Assembly.GetExecutingAssembly().Location)
parameters.MainClass = "Remote_Command_Line.MainModule"
Dim interfaceNamespace As String = GetType(LinkingInterface).Namespace
Dim codeBuilder As New Text.StringBuilder
Dim namespaces() As String = New String() {"Microsoft.VisualBasic", "System", "System.Console", "System.Collections", "System.Collections.Generic", _
"System.Data", "System.Diagnostics", "Remote_Command_Line.MainModule"}
Dim codeString As New StringBuilder
For Each namespacestring As String In namespaces
codeString.AppendLine("Imports " & namespacestring)
Next
codeString.AppendLine(code)
Dim results As CompilerResults = provider.CompileAssemblyFromSource(parameters, codeString.ToString)
'I commented out this just for debugging purposes
'If results.Errors.HasErrors Then
'For Each scriptError As CompilerError In results.Errors
'WriteLine(scriptError.ToString)
'Next
'Else
Return CType(results.CompiledAssembly.CreateInstance(results.CompiledAssembly.GetType.Name), LinkingInterface)
'End If
End Using
End Function
The Testing file 'test.vb':
Public Class test_mode
'Designed for RCL mode 1.0b
'Matthew 2013
'used for managing the local filesystem.
'####################################
#Region "Properties"
'all of these properties listed are required --------------------
Implements LinkingInterface
Property name As String Implements LinkingInterface.name 'the name the client refers to you in the 'modeswitch' command
Property statetag As String Implements LinkingInterface.statetag 'short tag displayed on the client when active before the input signal '>'
'----------------------------------------------------------------
Public curDirDatabank As New Specialized.StringCollection()
#End Region
'####################################
'####################################
#Region "Subs"
'Its required to have, but not required to do anything. This load sub is here for any modes that may require an initialization
Private Sub load() Implements LinkingInterface.load 'REQUIRED
name = "file" : statetag = "file"
MsgBox("Testing: It's loaded")
End Sub
Private Sub selected(ByVal Sock As Integer) Implements LinkingInterface.selected
MsgBox("Testing: '" & Sock & "' selected the File mode")
End Sub
Private Sub deselected(ByVal Sock As Integer) Implements LinkingInterface.deselected
MsgBox("Testing: '" & Sock & "' deselected the File mode")
End Sub
Private Function generateOutput(ByVal input As String, ByVal Sock As Integer) As String Implements LinkingInterface.generateOutput 'REQUIRED
Return ("Testing: '" & Sock & "' said '" & input & "'")
End Function
#End Region
'####################################
End Class
the following line is wrong.
Return CType(results.CompiledAssembly.CreateInstance(results.CompiledAssembly.GetType.Name), LinkingInterface)
You need to search through the loaded classes for one implementing your interface (it being VB you automatically get classes generated for the My namespace objects such as My.Computer)
Try this instead
For Each t As Type In results.CompiledAssembly.GetTypes()
If t.GetInterface(GetType(LinkingInterface).Name) IsNot Nothing Then
Return CType(results.CompiledAssembly.CreateInstance(t.Name), LinkingInterface)
End If
Next
Return Nothing
Public Class Geocode
Public Structure GeocodeResult
Public Latitude As String
Public Longitude As String
Public Result As String
End Structure
Public Shared Function GetGeocode(ByVal Address As String) As GeocodeResult
Dim strLat As String = ""
Dim strLon As String = ""
Dim strResult As String = ""
Dim oXmlDoc As Object
GetGeocode.Latitude = ""
GetGeocode.Longitude = ""
GetGeocode.Result = ""
Try
Dim baseURL As String = "https://maps.google.com/maps/api/geocode/xml?sensor=false&address=" & Address
baseURL = Replace(baseURL, " ", "+")
oXmlDoc = CreateObject("Microsoft.XMLDOM")
With oXmlDoc
.Async = False
If .Load(baseURL) And Not .selectSingleNode("GeocodeResponse/status") Is Nothing Then
GetGeocode.Result = .selectSingleNode("GeocodeResponse/status").Text
If Not .selectSingleNode("GeocodeResponse/result") Is Nothing Then
GetGeocode.Latitude = .selectSingleNode("//location/lat").Text
GetGeocode.Longitude = .selectSingleNode("//location/lng").Text
Return GetGeocode
End If
End If
End With
oXmlDoc = Nothing
Return GetGeocode
Exit Function
Catch ex As Exception
Throw (ex)
End Try
Return GetGeocode
End Function
End Class
Ok so this works fine in production, qa, and localhost until we moved it to an Azure VM. From the VM we can go use a browser to get to the https://maps.google.com/maps/api/geocode/xml?sensor=false&address= URL. but when another page calls the getgeocode function the results are always blank meaning the rest api call failed in some way.
I don't think its the domain key restrictions because a) im not using a key in this call and b) i set my google api key to any domain to test it.
EDIT: I have tried using another service with the same result. It works in dev and on local machines but not on the Azure VMs. What I do not understand is how the REST apis are accessible via the browser, but return nothing when called from code.
Any ideas?
Explicitly creating a web client and loading that into the xml document has fixed this issue for me.
Imports Microsoft.VisualBasic
Imports System.Xml
Imports System.Linq
Imports System.Xml.Linq
Imports System.Net
Imports System.IO
Public Class Geocode
Public Structure GeocodeResult
Public Latitude As String
Public Longitude As String
Public Result As String
End Structure
Public Shared Function GetGeocode(ByVal Address As String) As GeocodeResult
Dim oXmlDoc As Object
GetGeocode.Latitude = ""
GetGeocode.Longitude = ""
GetGeocode.Result = ""
Try
Dim baseURL As String = "https://maps.google.com/maps/api/geocode/xml?sensor=false&address=" & Address
baseURL = Replace(baseURL, " ", "+")
Using WC As New WebClient()
oXmlDoc = CreateObject("Microsoft.XMLDOM")
With oXmlDoc
.Async = False
If .Load(WC.DownloadData(baseURL)) And Not .selectSingleNode("GeocodeResponse/status") Is Nothing Then
GetGeocode.Result = .selectSingleNode("GeocodeResponse/status").Text
If Not .selectSingleNode("GeocodeResponse/result") Is Nothing Then
GetGeocode.Latitude = .selectSingleNode("//location/lat").Text
GetGeocode.Longitude = .selectSingleNode("//location/lng").Text
Return GetGeocode
End If
End If
End With
oXmlDoc = Nothing
End Using
Return GetGeocode
Exit Function
Catch ex As Exception
Throw (ex)
End Try
Return GetGeocode
End Function
End Class