I'm a beginner in programming. I wrote a script to set DNS setting using VB. I was able to set the primary address.
However, I don't know how to set the secondary address because it will require the use of array.
How can this be done?
Dim DNS As String() = {"192.168.1.1", "192.168.1.2"}
Dim objMC As ManagementClass = New ManagementClass("Win32_NetworkAdapterConfiguration")
Dim objMOC As ManagementObjectCollection = objMC.GetInstances()
For Each objMO As ManagementObject In objMOC
If (Not CBool(objMO("IPEnabled"))) Then
Continue For
End If
Try
Dim objSetIP As ManagementBaseObject = Nothing
Dim objNewDNS As ManagementBaseObject = Nothing
objNewDNS = objMO.GetMethodParameters("SetDNSServerSearchOrder")
'Set DNS to DHCP
objNewDNS("DNSServerSearchOrder") = New String() {DNS()}
objSetIP = objMO.InvokeMethod("SetDNSServerSearchOrder", objNewDNS, Nothing)
Console.WriteLine("Updated IPAddress, SubnetMask and Default Gateway!")
Catch ex As Exception
MessageBox.Show("Unable to Set IP : " & ex.Message)
End Try
Next objMO
In VB.Net the Dim keyword is actually short for Dimension and can be used for declaring arrays.
Simply apply brackets to the variable or type and hey presto you have an array.
Dim arrayOfString As String()
Or
Dim arrayOfString() As String
Of course, its a little more complicated than that. You may want to declare your array with a predefined number of elements, say 5, assuming Option Base 0.
Dim arrayOfInt(4) As Int
Or you might want to assign your array with a number of predefined values.
Dim arrayofInt As Int() = {1, 2, 3, 4, 5}
You can also use this syntax,
Dim arrayOfStrings = New String() {"1.2.3.4", "5.6.7.8"}
for instance. Your example,
Dim DNS As String() = {"192.168.1.1", "192.168.1.2"}
seems perfectly valid.
In your example you have the misforstune to be using WMI. I see you want to invoke the "SetDNSServerSearchOrder" method on the "Win32_NetworkAdapterConfiguration" class.
The objNewDNS = objMO.GetMethodParameters("SetDNSServerSearchOrder") sets objNewDNS to a ManagementBaseObject that is a collection of parameters for the "SetDNSServerSearchOrder" method.
The "SetDNSServerSearchOrder" takes one parameter called "DNSServerSearchOrder" as described here which happens to be an array of strings.
So unless I'm mistaken, and assuming the string array DNS is your search order, your code should read:
'Set DNS to DHCP
objNewDNS("DNSServerSearchOrder") = DNS
objMO.InvokeMethod("SetDNSServerSearchOrder", objNewDNS)
note that this code discards the return value of the method call.
EDIT:
From your comments it seems that the object returned by the objMO.InvokeMehtod call is actually a ManagementBaseObject. This wraps the "returnValue" of the invoked method. So somthing like the code below will help you get to the return value, if necessary.
'Set DNS to DHCP
objNewDNS("DNSServerSearchOrder") = DNS
Dim oResult As ManagementBaseObject = _
objMO.InvokeMethod("SetDNSServerSearchOrder", objNewDNS)
Dim result As Integer = CType(oResult["returnValue"], Integer)
So your problems are not related to your ability to declare arrays but rather the tedious interface to WMI. I guess you might need a few more calls for your console output to be entirely valid but I hope this helps you out.
Related
I'm trying to get a Device Unique Identifier in vb.net code. I have tried with
Private Function SystemSerialNumber() As String
Dim value As String = ""
Dim baseBoard As ManagementClass = New ManagementClass("Win32_BaseBoard")
Dim board As ManagementObjectCollection = baseBoard.GetInstances()
If board.Count > 0 Then
value = board(0)("SerialNumber")
If value.Length > 0 Then value = value.Substring(2)
End If
Return value
End Function
Which works on some computers but of the board doesn't have a serial number it returns "Default String" or whatever they put in there. Even tried with Win32_Processor and some have it and others just return "To be filled by O.E.M" lol
Also tried with,
Private Function SystemSerialNumber() As String
Dim value As String
Dim q As New SelectQuery("Win32_bios")
Dim search As New ManagementObjectSearcher(q)
Dim info As New ManagementObject
For Each info In search.Get
value = info("SerialNumber").ToString
Return value
Next
End Function
But its the same some devices have it some don't and just returns default string.
So I'm now trying is:
Private Function SystemSerialNumber() As String
Dim value As String
value = Windows.System.Profile.SystemIdentification.GetSystemIdForPublisher()
End Function
But I'm having trouble referencing to it. I tried Imports Windows.System but it just gives the error it cant be found.
As a side note I'm using this program in tablets with windows10, laptops, and desktops.
UPDATE: I'll be using as suggested by Heinzi. Thanks!
Also changed variable names to be more accurate.
Private Function NetworkAdapterMacAddress() As String
Dim McAddress As String
Dim netadapter As ManagementClass = New ManagementClass("Win32_NetworkAdapterConfiguration")
Dim mo As ManagementObject
Dim adapter As ManagementObjectCollection = netadapter.GetInstances()
For Each mo In adapter
If mo.Item("IPEnabled") = True Then
McAddress = mo.Item("MacAddress").ToString()
Return McAddress
End If
Next
End Function
Well, there is no guaranteed ID that identifies every PC out there uniquely (fortunately, I might add. Privacy is a good thing).
You best bets are probably
the MAC of the network adapter (changes when the network adapter is replaced) or
the Windows Computer SID (changes when Windows is reinstalled).
Oh, and on a philosophical note, you might want to ponder on the Ship of Theseus.
Hi I want to set different propertyvalues of different control objects at runtime. Therefore I want to DirectCast the object by its name and its type.
But I want to set it dynamically. So I want to use the Controltype string as type for the DirectCast.
Here is an example. For sure I know it does not work with this but I already tried several approaches with e.g: DynamicCast or Gettype...
Please tell if you need further information
Dim Controlname As String = inhalt(0, 0, 0)
Dim ControlProperty As String = inhalt(0, 0, 1)
Dim text As String = inhalt(0, 0, 2)
Dim Controltype As String = "System.Windows.Controls.TabItem"
Dim control = DirectCast(FindName(Controlname), controltype)
Dim prop = control.[GetType]().GetProperty(ControlProperty, BindingFlags.[Public] Or BindingFlags.Instance)
prop.SetValue(control, text, Nothing)
I need a list of printers that DO NOT print direct. Getting a list that do print direct seems reasonably easy. But how to do the opposite?
Dim PrintServer As New SysPrint.PrintServer
Dim arrFlags(0) As SysPrint.EnumeratedPrintQueueTypes
arrFlags(0) = System.Printing.EnumeratedPrintQueueTypes.DirectPrinting
Dim QColl As SysPrint.PrintQueueCollection = PrintServer.GetPrintQueues(arrFlags)
PrintServer.GetPrintQueues Method
EnumeratedPrintQueueTypes Enumeration
MSDN says that the EnumeratedPrintQueueTypes has a FlagsAttribute attribute that allows a bitwise combination of its member values. So I should be able to specify NOT direct somehow. How do I do it?
I tried to do this arrFlags(0) = Not System.Printing.EnumeratedPrintQueueTypes.DirectPrinting but that returned no results. Clearly incorrect.
So how do I manipulate the flags attribute to eliminate all printers printing direct?
This is one way to do it but it seems very inelegant:
'get full list
Dim PrintServer As New SysPrint.PrintServer
Dim QColl As SysPrint.PrintQueueCollection = PrintServer.GetPrintQueues()
'get those not printing direct
Dim Qcoll2 As List(Of SysPrint.PrintQueue) = QColl.Where(Function(x) Not (x.IsDirect)).ToList
'select name only
Dim strList As List(Of String) = Qcoll2.Select(Function(x) x.Name).ToList
I have some trouble creating my XmlDocument class. This is what I've tried to do:
Dim myDoc = New XmlDocument()
Dim docType As XmlDocumentType = myDoc.CreateDocumentType("DtdAttribute", Nothing, "DtdFile.dtd", Nothing)
myDoc.XmlResolver = Nothing
myDoc.AppendChild(docType)
Dim xmldecl As XmlDeclaration = myDoc.CreateXmlDeclaration("1.0", Encoding.GetEncoding("ISO-8859-15").BodyName, "yes")
Dim root As XmlElement = myDoc.CreateElement("RootElement")
myDoc.AppendChild(root)
myDoc.InsertBefore(xmldecl, root)
This will result in error: Cannot insert the node in the specified location. Line throwing this error is myDoc.InsertBefore(xmldecl, root)
Just cannot figure out this. Which order should I insert these elements? I've tried different orders but I think I'm just doing something totally wrong and this shouldn't even work in the first place :) But then how to do this?
This works for me:
Dim myDoc As New XmlDocument()
Dim xmldecl As XmlDeclaration = myDoc.CreateXmlDeclaration("1.0", Encoding.GetEncoding("ISO-8859-15").BodyName, "yes")
myDoc.AppendChild(xmldecl)
Dim docType As XmlDocumentType = myDoc.CreateDocumentType("DtdAttribute", Nothing, "DtdFile.dtd", Nothing)
myDoc.XmlResolver = Nothing
myDoc.AppendChild(docType)
Dim root As XmlElement = myDoc.CreateElement("DtdAttribute")
myDoc.AppendChild(root)
Note that the root element name must be the same as the name parameter given to XmlDocument.CreateDocumentType.
You may find, however, that for building an XML document from scratch like this, it's easier to just use the XmlTextWriter:
Using writer As New XmlTextWriter("C:\Test.xml", Encoding.GetEncoding("ISO-8859-15"))
writer.WriteStartDocument()
writer.WriteDocType("DtdAttribute", Nothing, "DtdFile.dtd", Nothing)
writer.WriteStartElement("DtdAttribute")
writer.WriteEndElement()
writer.WriteEndDocument()
End Using
I am trying to run an event which will search through the different files in a given directory. The goal is to have it search for all files that begin with 'SP_', which are .sql files containing Stored Procedures. I would then like to add the full text of these Procedures to an array to be used later. This is causing an error when run, which I believe is because 'FullProcedureArray()', the string array I am trying to load does not have defined boundaries. When I declare it as 'FullProcedureArray(7)', or with some other value, it appears to run fine. But I don't want to have to hard-code a boundary for 'FullProcedureArray'; I would rather let it be defined by whatever the number of files in the folder is.
My question: Is there a way to declare 'FullProcedureArray' without having to give it an absolute value? I may just be missing something painfully obvious, but I haven't worked with this type of array much in the past. Thanks in advance for your help.
Dim AppDataLocation As String = "C:\Files\TestFiles\"
Dim ProcedureArray As String()
Dim ProcedureText As String
Dim FullProcedureArray() As String
Dim sourceDirectoryInfo As New System.IO.DirectoryInfo(AppDataLocation)
Dim fileSystemInfo As System.IO.FileSystemInfo
Dim i As Integer = 0
For Each fileSystemInfo In sourceDirectoryInfo.GetFileSystemInfos
If (fileSystemInfo.Name.Contains("SP_")) Then
ProcedureArray = System.IO.File.ReadAllLines(AppDataLocation & fileSystemInfo.Name)
ProcedureText = Join(ProcedureArray, "")
FullProcedureArray.SetValue(ProcedureText, i)
i = (i + 1)
End If
Next
An array by definition has a fixed upper bound. If you don't want a fixed upper bound, don't use an array. Use, for example, a List(Of String) instead:
Dim AppDataLocation As String = "C:\Files\TestFiles\"
Dim ProcedureList As New List(Of String)
Dim sourceDirectoryInfo As New System.IO.DirectoryInfo(AppDataLocation)
For Each fileSystemInfo As System.IO.FileSystemInfo In sourceDirectoryInfo.GetFileSystemInfos
If (fileSystemInfo.Name.Contains("SP_")) Then
Dim ProcedureText As String = _
System.IO.File.ReadAllText(AppDataLocation & fileSystemInfo.Name)
ProcedureList.Add(ProcedureText)
End If
Next
If, for some reason, you still need the result as an array afterwards, simply convert the list to an array:
Dim myArray() As String = ProcedureList.ToArray()
If you don't want to give a size to your array or want to change at runtime, you can use "Redim Preserve"
http://msdn.microsoft.com/en-us/library/w8k3cys2%28v=vs.71%29.aspx