Listbox is adding too many entries - visual-studio-2013

What I want is for this program to do is to show Microsoft Outlook 2010 in "installed" listbox if it's installed and "notinstalled" if it's not installed. "listbox1" has a list of all installed applications in it on form load.
The issue is that while it does work for the "installed" portion, it lists the application many times in the "notinstalled" box. I only want it to show up once.
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim regkey, subkey As Microsoft.Win32.RegistryKey
Dim value As String
Dim regpath As String = "Software\Microsoft\Windows\CurrentVersion\Uninstall"
regkey = My.Computer.Registry.LocalMachine.OpenSubKey(regpath)
Dim subkeys() As String = regkey.GetSubKeyNames
Dim includes As Boolean
For Each subk As String In subkeys
subkey = regkey.OpenSubKey(subk)
value = subkey.GetValue("DisplayName", "")
If value <> "" Then
includes = True
If value.IndexOf("Hotfix") <> -1 Then includes = False
If value.IndexOf("Security Update") <> -1 Then includes = False
If value.IndexOf("Update for") <> -1 Then includes = False
If includes = True Then ListBox1.Items.Add(value)
End If
Next
Dim count As Integer = (ListBox1.Items.Count - 1)
Dim words As String
Dim softName As String
softName = "Microsoft Outlook 2010"
For a = 0 To count
words = ListBox1.Items.Item(a)
If InStr(words.ToLower, softName.ToLower) Then
Installed.Items.Add(words)
Else
NotInstalled.Items.Add(softName)
End If
Next

I think you should try something like. (I'm a c# guy, so I hope my syntax is right.)
Dim isOutlookInstalled = False
softName = "Microsoft Outlook 2010"
For a = 0 To count
words = ListBox1.Items.Item(a)
If InStr(words.ToLower, softName.ToLower) Then
Installed.Items.Add(words)
End If
Next
If isOutlookInstalled <> True
NotInstalled.Items.Add(softName)
End If

The repeating string is due to a simple error due to the call to NotInstalled.Items.Add(softName) for each item inspected. You probably want to add it only at the end of the loop.
However you could simplify your code with a bit of Linq
Dim result = words.Where(Function(x) x.ToLower().IndexOf("microsoft outlook 2010") >= 0)
if result IsNot Nothing then
Installed.Items.AddRange(result.ToArray)
else
NotInstalled.Items.Add(softName)
end if
But you should consider some problems in your code. If Outlook is installed as part of Office there is not an entry for it in the uninstall section. Then there is the problem of the automatic redirection to different section of the registry if you are running on a 64bit system. And what if your Outlook is a 32bit version installed on a 64bit system and your app run in AnyCPU mode? It is not a trivial task to account for all these possibility. Just to warn you

Related

AutoCAD Architecture Vision Tools in AutoCAD

I have both AutoCAD and AutoCAD Architecture installed on my system. AutoCAD Architecture has a tab called Vision Tools with a nifty command called Display By Layer to set the display order of objects in accordance with the layers of the drawing. Is there anyway to add this tab or use this command in AutoCAD?
Not sure if you're looking for a built-in feature or APIs for it.
For a built in feature, check the DRAWORDER command. For an API/programming approach, check the respective DrawOrderTable method. See below:
Update: please also check this 3rd party tool: DoByLayer.
[CommandMethod("SendToBottom")]
public void commandDrawOrderChange()
{
Document activeDoc
= Application.DocumentManager.MdiActiveDocument;
Database db = activeDoc.Database;
Editor ed = activeDoc.Editor;
PromptEntityOptions peo
= new PromptEntityOptions("Select an entity : ");
PromptEntityResult per = ed.GetEntity(peo);
if (per.Status != PromptStatus.OK)
{
return;
}
ObjectId oid = per.ObjectId;
SortedList<long, ObjectId> drawOrder
= new SortedList<long, ObjectId>();
using (Transaction tr = db.TransactionManager.StartTransaction())
{
BlockTable bt = tr.GetObject(
db.BlockTableId,
OpenMode.ForRead
) as BlockTable;
BlockTableRecord btrModelSpace =
tr.GetObject(
bt[BlockTableRecord.ModelSpace],
OpenMode.ForRead
) as BlockTableRecord;
DrawOrderTable dot =
tr.GetObject(
btrModelSpace.DrawOrderTableId,
OpenMode.ForWrite
) as DrawOrderTable;
ObjectIdCollection objToMove = new ObjectIdCollection();
objToMove.Add(oid);
dot.MoveToBottom(objToMove);
tr.Commit();
}
ed.WriteMessage("Done");
}
With some help from VBA it might look by this. Note i did not add fancy listbox code. I just show the worker and how to list layers. The trivial Code to add things to a listbox on a form and how to sort / rearrange listbox items can be found on any excel / VBA forum on the web . Or you just uses a predefined string like in the example. To get VBA to work download and install the acc. VBA Enabler from autocad. It is free.
'select all items on a layer by a filter
Sub selectALayer(sset As AcadSelectionSet, layername As String)
Dim filterType As Variant
Dim filterData As Variant
Dim p1(0 To 2) As Double
Dim p2(0 To 2) As Double
Dim grpCode(0) As Integer
grpCode(0) = 8
filterType = grpCode
Dim grpValue(0) As Variant
grpValue(0) = layername
filterData = grpValue
sset.Select acSelectionSetAll, p1, p2, filterType, filterData
Debug.Print "layer", layername, "Entities: " & str(sset.COUNT)
End Sub
'bring items on top
Sub OrderToTop(layername As String)
' This example creates a SortentsTable object and
' changes the draw order of selected object(s) to top.
Dim oSset As AcadSelectionSet
Dim oEnt
Dim i As Integer
Dim setName As String
setName = "$Order$"
'Make sure selection set does not exist
For i = 0 To ThisDrawing.SelectionSets.COUNT - 1
If ThisDrawing.SelectionSets.ITEM(i).NAME = setName Then
ThisDrawing.SelectionSets.ITEM(i).DELETE
Exit For
End If
Next i
setName = "tmp_" & time()
Set oSset = ThisDrawing.SelectionSets.Add(setName)
Call selectALayer(oSset, layername)
If oSset.COUNT > 0 Then
ReDim arrObj(0 To oSset.COUNT - 1) As ACADOBJECT
'Process each object
i = 0
For Each oEnt In oSset
Set arrObj(i) = oEnt
i = i + 1
Next
End If
'kills also left over selectionset by programming mistakes....
For Each selectionset In ThisDrawing.SelectionSets
selectionset.delete_by_layer_space
Next
On Error GoTo Err_Control
'Get an extension dictionary and, if necessary, add a SortentsTable object
Dim eDictionary As Object
Set eDictionary = ThisDrawing.modelspace.GetExtensionDictionary
' Prevent failed GetObject calls from throwing an exception
On Error Resume Next
Dim sentityObj As Object
Set sentityObj = eDictionary.GetObject("ACAD_SORTENTS")
On Error GoTo 0
If sentityObj Is Nothing Then
' No SortentsTable object, so add one
Set sentityObj = eDictionary.AddObject("ACAD_SORTENTS", "AcDbSortentsTable")
End If
'Move selected object(s) to the top
sentityObj.MoveToTop arrObj
applicaTION.UPDATE
Exit Sub
Err_Control:
If ERR.NUMBER > 0 Then MsgBox ERR.DESCRIPTION
End Sub
Sub bringtofrontbylist()
Dim lnames As String
'predefined layer names
layer_names = "foundation bridge road"
Dim h() As String
h = split(layernames)
For i = 0 To UBound(h)
Call OrderToTop(h(i))
Next
End Sub
'in case you want a fancy form here is how to get list / all layers
Sub list_layers()
Dim LAYER As AcadLayer
For Each LAYER In ThisDrawing.LAYERS
Debug.Print LAYER.NAME
Next
End Sub
to make it run put the cursor inside the VBA IDE inside the code of list_layers andpress F5 or choose it from the VBA Macro list.

Macro in outlook to mark emails as read

I want to use a macro in outlook 2013. This macro is supposed to mark any emails arriving a specific folder ('work' folder) as read. I'm not familiar with vb. Any help/guidance is much appreciated!
No sure, I have heard this one before of wanting emails automatically read. You have two options:
a) Use Ctrl-A (select all mail in folder), Ctrl-Q (mark selection as read)
b) Use New Email Event something like:
Private Sub Application_NewMailEx(ByVal EntryIDCollection As String)
vID = Split(EntryIDCollection, ",")
Dim i as Long, objMail as Outlook.MailItem
For i = 0 To UBound(vID)
Set objMail = Application.Session.GetItemFromID(vID(i))
objMail.Unread = False
Next i
End Sub
Private Sub Application_NewMailEx(ByVal EntryIDCollection As String)
' version to select folder
Dim i As Long, objMail As Outlook.MailItem, mpfInbox As Outlook.Folder
Set mpfInbox = Application.GetNamespace("MAPI").Folders("YOURACCOUNT").Folders("[Gmail]").Folders("Sent Mail")
For i = 1 To mpfInbox.Items.Count
If mpfInbox.Items(i).Class = olMail Then
Set objMail = mpfInbox.Items.Item(i)
objMail.UnRead = False
End If
Next i
End Sub
You can set up a rule which can trigger your macro.
I'd not suggest working with the NewMailEx event because it is not fired in some case and may introduce issues. See Outlook NewMail event unleashed: the challenge (NewMail, NewMailEx, ItemAdd) for more information.

Specific Registry Key can't be found with VBScript

For a Test automation I have to check if certain Keys are generated in the registry.
By far I have this script:
'Registry Path
Const HKCR = &H80000000 'HKEY_CLASSES_ROOT (0)
Const HKLM = &H80000002 'HKEY_LOCAL_MACHINE (1)
Dim oReg: Set oReg = GetObject("winmgmts:!root/default:StdRegProv")
'Dim Arrays
Dim RegRootArray(1)
Dim RegMachineArray(6)
Dim CurrentArray()
'HKEY_CLASSES_ROOT Array
RegRootArray(0) = "AlmBtPgLib.ALMPlugIn.1\CLSID"
RegRootArray(1) = "AlmBtPgLib.ALMPlugIn\CurVer"
'HKEY_LOCAL_MACHINE Array
RegMachineArray(0) = "SOFTWARE\Macrovision\FlexNet Publisher"
RegMachineArray(1) = "SOFTWARE\Company\SWS\PlugIns\AlmBtPgLib.ALMPlugIn"
RegMachineArray(2) = "SYSTEM\ControlSet001\services\FlexNet Licensing Service"
RegMachineArray(3) = "SYSTEM\CurrentControlSet\services\FlexNet Licensing Service"
RegMachineArray(4) = "SOFTWARE\Company\LMS"
RegMachineArray(5) = "SYSTEM\CurrentControlSet\services\aksfridge"
RegMachineArray(6) = "SYSTEM\CurrentControlSet\services\hasplms"
'Loop through both Arrays and check Registry
For i = 0 To 1
If i=0 Then
ReDim CurrentArray(UBound(RegRootArray)) 'Copy Values from RegRootArray to CurrentArray
For arrI1 = LBound(RegRootArray) To UBound(RegRootArray)
CurrentArray(arrI1) = RegRootArray(arrI1)
Next
Key = HKCR
Else
ReDim CurrentArray(UBound(RegMachineArray)) 'Copy Values from RegMachineArray to CurrentArray
For arrI2 = LBound(RegMachineArray) To UBound(RegMachineArray)
CurrentArray(arrI2) = RegMachineArray(arrI2)
Next
Key = HKLM
End If
'Check Keys in Registry
For Each Path In CurrentArray
If oReg.EnumKey(Key, Path, arrSubKeys) = 0 Then
MsgBox(Path & " exist") 'for development
Else
MsgBox(Path & " don't exist") 'for development
End If
Next
Next
For some reason
"SOFTWARE\Company\SWS\PlugIns\AlmBtPgLib.ALMPlugIn"
is shown as non existing.
I checked if PlugIns or SWS "exists".
None of them do. Company does exist.
I checked the registry and the path manually. Both seem to be okay.
When I create a new Key I can't find it neither.
I restarted the system, no change.
The return value of EnumKey is 2. Simply 2.
I searched the web but couldn't find a solution.
Thanks for your help.
I can't check anything util tomorrow because i leave work for the day.
Update:
When i run the script extern, say as checkReg.vbs it works.
Could it be that UFT somehow has not the right permission? Although both, the .vbs script and UFT run under the same User.
Cheers
sam
In scripting or Visual Basic, the method EnumKey returns an integer value that is 0 (zero) if successful. If the function fails, the return value is a nonzero error code according to Microsoft.
http://msdn.microsoft.com/en-us/library/aa390387%28v=vs.85%29.aspx
Should not you use something like this instead:
Set objReg = Server.CreateObject("WScript.Shell")
RegValue = objReg.RegRead(yourregistryentrypath)

How to get Volume Serial Number using Visual Basic 2010?

I'm trying to get Volume Serial Number using Visual Basic 2010,
Is there a whole code example that shows me how to do this?
Thanks
I guess the simplest answer to my question was given by:
Hans Passant:
From his link,
I just copied and pasted this function and it works for Microsoft Visual basic 2010 express, Without any modifications
Public Function GetDriveSerialNumber() As String
Dim DriveSerial As Long
Dim fso As Object, Drv As Object
'Create a FileSystemObject object
fso = CreateObject("Scripting.FileSystemObject")
Drv = fso.GetDrive(fso.GetDriveName(AppDomain.CurrentDomain.BaseDirectory))
With Drv
If .IsReady Then
DriveSerial = .SerialNumber
Else '"Drive Not Ready!"
DriveSerial = -1
End If
End With
'Clean up
Drv = Nothing
fso = Nothing
GetDriveSerialNumber = Hex(DriveSerial)
End Function
I would like to thank everyone for their help,
And i apologize for repeating the question,
I did do a google search and a stackflow search,
But my search was"
"get hard drive serial number in visual basic 2010"
So this website did not show up,
Thanks again
This thread here http://social.msdn.microsoft.com/Forums/vstudio/en-US/43281cfa-51c8-4c35-bc31-929c67abd943/getting-drive-volume-serial-number-in-vb-2010 has the following bit of code that you could use/adapt.
I made a piece of code for you to show all drive information.
The Volume serial number is included you can get that by simple
putting some more if's in the code
Imports System.Management
Public Class Form1
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim drivetype() As String = {"Unknown", "NoRootDirectory", _
"RemoveableDisk", "LocalDisk", "NetworkDrive", "CompactDisk", "RamDisk"}
Dim allDrives() As String = Environment.GetLogicalDrives()
For Each drive In allDrives
Dim win32Drive As String = _
"Win32_LogicalDisk='" & drive.Substring(0, 2) & "'"
Dim Disk As System.Management.ManagementObject _
= New System.Management.ManagementObject(win32Drive)
Me.ListBox1.Items.Add(drive.ToString & drivetype(CInt((Disk("DriveType").ToString))))
For Each diskProperty In Disk.Properties
If Not diskProperty.Value Is Nothing Then
Me.ListBox1.Items.Add("---" & diskProperty.Name & "=" & diskProperty.Value.ToString)
End If
Next
Next
End Sub
End Class

Visual Studio. How to copy record from database to word .doc and print it

In Visual studio 2010>New Project>Visual Basic>Windows>Windows forms Application, i have made a form (form1.vb) and a database (Local Database>"Database1.sdf") and a Table with 3 Columns ("Name","City","Age").
I like to copy this 3 fields and paste to document "test1.doc" (open this with Ms Office or Open Office Writer). I have bookmarks ("PasteName", PasteCity", "PasteAge") in specified places in test1.doc .
How to make a button to open the document "test1.doc" and copy - paste this 3 items from table to doc and preview before print it? (not for save - only print preview and close without save after printing)
I have find this code for MS Office but didn't work in Visual Studio. I like something similar. (this code is for a doc Form Fields - I have Bookmarks in my doc).
Private Sub cmdPrint_Click()
Dim appWord As Word.Application
Dim doc As Word.Document
Set appWord = GetObject(, "Word.Application")
Set appWord = New Word.Application
Set doc = appWord.Documents.Open("C:\WordForms\CustomerSlip.doc", , True)
With doc
.FormFields("fldCustomerID").Result = Me!CustomerID
.FormFields("fldCompanyName").Result = Me!CompanyName
.FormFields("fldContactName").Result = Me!ContactName
.Visible = True
.Activate
End With
Set doc = Nothing
Set appWord = Nothing
End Sub
Thanks programers people
This works for me. (button action)
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
'Print customer slip for current customer.
Dim appWord As Word.Application
Dim doc As Word.Document
'Avoid error 429, when Word isn't open.
On Error Resume Next
Err.Clear()
'Set appWord object variable to running instance of Word.
appWord = GetObject(, "Word.Application")
If Err.Number <> 0 Then
'If Word isn't open, create a new instance of Word.
appWord = New Word.Application
End If
doc = appWord.Documents.Open("D:\Test.docx", , True)
doc.Visible()
doc.Activate()
With doc.Bookmarks
.Item("Name").Range.Text = Me.NameID.Text
.Item("City").Range.Text = Me.CityID.Text
End With
Dim dlg As Word.Dialog
dlg = appWord.Dialogs.Item(Word.WdWordDialog.wdDialogFilePrint)
dlg.Display()
'doc.Printout
doc = Nothing
appWord = Nothing
Exit Sub
errHandler:
MsgBox(Err.Number & ": " & Err.Description)
End Sub

Resources