Pulling Hardware Serial Number via Visual Basic? - vb.net

I am writing an application in Visual Basic that pulls basic information about the computer and outputs the data onto a form. Currently, I am trying to pull the serial number for the machine I would be using. For example, pulling a serial number of a laptop from the BIOS. I have looked around the internet and haven't really found how to do this in Visual Basic without using WMI or C. Is there a way to do this in Visual Basic?
Below is what I have currently in the form, so you can get an idea of what I am trying to do:
TextBoxComputerName.Text = Environment.MachineName
TextBoxOSVersion.Text = System.Environment.OSVersion.ToString
TextBoxOSFullName.Text = My.Computer.Info.OSFullName
TextBoxCurrentUser.Text = System.Environment.UserName
TextBox64Bit.Text = System.Environment.Is64BitOperatingSystem
TextBoxSystemDirectory.Text = System.Environment.SystemDirectory
TextBoxDomain.Text = System.Environment.UserDomainName
' CHECK SERIAL NUMBER HERE.
Thank you all so much!

This will work for you just great! First add reference to System.Management and then make sure to import it at the top of your class as well. I did this on a form load event, but you can put it anywhere...
Imports System.Management
Dim q As New SelectQuery("Win32_bios")
Dim search As New ManagementObjectSearcher(q)
Dim info As New ManagementObject
For Each info In search.Get
MessageBox.Show("Serial Number: " & info("serialnumber").ToString & vbNewLine & vbNewLine & "Bios Version: " & info("version").ToString)
Next
You can declare a string first if you would like and then set it to: info("serialnumber").ToString and the set that to you txtSerial.Text = your declared string
Here is what I get...

This is VBScript but should be pastable into VB6.
You do know this field is blank on many computers?
strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colItems = objWMIService.ExecQuery("Select * From Win32_BIOS")
For Each objItem in colItems
msgbox objItem.SerialNumber
Next
From a command prompt (but I don't think home editions get the console program wmic)
wmic bios get /format:list
or
wmic bios get serialnumber /format:list

Try to use Treek's Licecnsing Library. It has class for generating hardware serial.
http://msdn.treekslicensinglibrary.com/html/f2bfa10c-d5d9-25ac-39c2-46e2393c0fbe.htm

Here is a class that will return:
*) Computer Name
*) Assembly Name
*) Login User Name
*) Serial No
Imports System.Management
'''
''' Provides the Methods and Properties to retrieve and make available to the
''' Application the:
''' *) Computer Name
''' *) Assembly Name
''' *) Login User Name
''' *) PC Serial Number
'''
'''
Public Class clsGetComputerInformation
Private ReadOnly mstrClsTitle As String = "clsGetComputerInformation"
Public ReadOnly Property pstrComputerName() As String
Get
Return Environment.MachineName
End Get
End Property
Public ReadOnly Property pstrUserName() As String
Get
Return System.Security.Principal.WindowsIdentity.GetCurrent.Name
End Get
End Property
Public ReadOnly Property pstrAssemblyName() As String
Get
Return My.Application.Info.AssemblyName
End Get
End Property
Public Function pstrSystemSerialNumber() As String
Dim query As New SelectQuery("Win32_bios")
Dim search As New ManagementObjectSearcher(query)
Dim info As ManagementObject
Dim lstrSerialNo As String = ""
For Each info In search.Get()
lstrSerialNo = info("SerialNumber").ToString()
Next
Return lstrSerialNo
End Function
End Class

I found a way to get to this a bit backwards in VBA, using the FileSystemObject. You will need to set a reference to the Windows Scripting Runtime.
Option Explicit
Public Sub GetHDSerial()
Dim objFSO As FileSystemObject
Dim objFolder As Folder
Dim strComputer As String
strComputer = "myComputer"
Set objFSO = New FileSystemObject
Set objFolder = objFSO.GetFolder("\\" & strComputer & "\c$")
Debug.Print Hex(objFolder.Drive.SerialNumber)
Set objFSO = Nothing
Set objFolder = Nothing
End Sub
This does not account for multiple physical drives, which wasn't a problem in my environment.

Related

Extracting `dll` files from the Resources after they been added using CodeDOM in VB.Net

I'v seen a lot of answers here on stackoverflow, but none of them help me with exactly what i need and almost all of them in C# when i need VB, so i hope someone will help me with my problem, which is this :
I have compiled a exe file in vb.net using CodeDOM, and i added two dll file to its resources and that worked just fine and you can even notice that the size of the exe has increase after adding the resources, but when i run the exe file like that My.Resources.Touchless, it gives me an error saying that
"Resources" is not a member of "My".
And what i need is to read these dll files from the compiled exe file and then extract them using File.WriteAllBytes()..., if i didn't try to extract the files from the resources and instead of that i copied them manually to the executable path, the application will work perfectly, so the problem is just with trying to call the dll files from the resources.
Here is some code :
Public Shared Function Compile(ByVal Output As String, ByVal Source As String, ByVal Icon As String, ByVal resources As String) As Boolean
Dim Parameters As New CompilerParameters()
Dim cResults As CompilerResults = Nothing
Dim Compiler As CodeDomProvider = CodeDomProvider.CreateProvider("VB")
Parameters.GenerateExecutable = True
Parameters.TreatWarningsAsErrors = False
Parameters.OutputAssembly = Output
Parameters.MainClass = "MyNamespace.MainWindow"
Parameters.EmbeddedResources.Add(Path.GetTempPath & "TouchlessLib.dll")
Parameters.EmbeddedResources.Add(Path.GetTempPath & "WebCamLib.dll")
Parameters.ReferencedAssemblies.AddRange(New String() {"System.dll", "System.Drawing.dll", "System.Windows.Forms.dll", "System.Management.dll", Path.GetTempPath & "TouchlessLib.dll"})
Parameters.CompilerOptions = "/platform:x86 /target:winexe"
If Not String.IsNullOrEmpty(Icon) Then
File.Copy(Icon, "icon.ico")
Parameters.CompilerOptions += " /win32icon:" & "icon.ico"
End If
cResults = Compiler.CompileAssemblyFromSource(Parameters, Source)
If cResults.Errors.Count > 0 Then
For Each compile_error As CompilerError In cResults.Errors
Dim [error] As CompilerError = compile_error
Console.Beep()
MsgBox("Error: " & [error].ErrorText & vbCr & vbLf & [error].Line)
Next
Return False
End If
If Not (String.IsNullOrEmpty(Icon)) Then
File.Delete("icon.ico")
End If
Return True
End Function
When i call them from the compiled exe file like this :
File.WriteAllBytes(Application.StartupPath & "\TouchlessLib.dll", My.Resources.TouchlessLib)
File.WriteAllBytes(Application.StartupPath & "\WebCamLib.dll", My.Resources.WebCamLib)
... i get the following error message :
"Resources" is not a member of "My".
Try adding this class:
Imports System.Dynamic
Imports System.Reflection
Public Class DynamicResources
Inherits DynamicObject
Public Overrides Function TryGetMember(binder As GetMemberBinder, ByRef result As Object) As Boolean
Dim asm As Assembly = Assembly.GetExecutingAssembly()
Dim resouceNames As String() = asm.GetManifestResourceNames
For Each s As String In resouceNames
Dim name As String = IO.Path.GetFileNameWithoutExtension(s)
Dim Manager As New Resources.ResourceManager(name, asm)
Try
Dim resource = Manager.GetObject(binder.Name)
If Not resource Is Nothing Then
result = resource
Return True
End If
Catch ex As Exception
End Try
Next
Return False
End Function
End Class
You can use it like this:
Dim root as string=Application.StartupPath
File.WriteAllBytes(Path.Combine(root, "TouchlessLib.dll"), DynamicResources.TouchlessLib)
File.WriteAllBytes(Path.Combine(root, "WebCamLib.dll"), DynamicResources.WebCamLib)
The My namespace and any associated functionality is created via auto-generated code. Since your code is now the code generator and not the IDE, you will not have those niceties unless your code provides it.
To extract an embedded resource, you need to include code similar to the following in the source code you are compiling with CodeDOM.
Dim asm As Assembly = Assembly.GetExecutingAssembly()
Dim resouceNames As String() = asm.GetManifestResourceNames
For Each s As String In resouceNames
Dim fi As New FileInfo(s)
Using strm As Stream = asm.GetManifestResourceStream(s)
Using fs As Stream = fi.Create()
strm.CopyTo(fs)
End Using
End Using
Next
Make sure that you also include:
Imports System.Reflection
Imports System.IO
This code retrieves the executing Assembly obtains an array of embedded resource names. It then calls GetManifestResourceStream method to get the named resource as a stream. This stream is copied to a file stream.
Modify the example to suite your needs.
Note that I have not included any error checking/handling in this example. Anything dealing with IO should have some error handling.
Edit:
Based on the comment below, it appears that only a copy/paste type answer will do for the OP.
Dim asm As Assembly = Assembly.GetExecutingAssembly()
Dim resourceName As String
Dim fi As FileInfo
resourceName = "TouchlessLib.dll"
fi = New FileInfo(Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, resourceName))
Using strm As Stream = asm.GetManifestResourceStream(resourceName)
Using fs As Stream = fi.Create()
strm.CopyTo(fs)
End Using
End Using

Read Registry Keys from within VBA using Windows Shell

I have been searching around on the internet and am having problems finding a solution to this issue.
Basically I am trying to execute a registry query with administrator privileges using Shell.Application from within VBA to read the value of TypeGuessRows (and eventually modify it to 0 aswell so that excel data can be correctly queried using ADOdb). I have come up with the following sub routine:
Sub Read_Registry_Value()
'Declare variables
Dim reg_key_location As String
Dim reg_key_name As String
Dim wsh As Object
'Define registry key path and name
reg_key_location = "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office\15.0\ClickToRun\REGISTRY\MACHINE\Software\Wow6432Node\Microsoft\Office\15.0\Access Connectivity Engine\Engines\Excel"
reg_key_name = "TypeGuessRows"
'Create instance of windows shell
Set wsh = VBA.CreateObject("Shell.Application")
'Execute registry query with administrative privileges
wsh.ShellExecute "cmd", _
"/K REG QUERY " & Chr(34) & reg_key_location & Chr(34) & " /v " & reg_key_name, _
"", _
"runas", _
1
End Sub
All that is returned from this routine is:
ERROR:
The system was unable to find the specified registry key or value.
However the registry key most definitely exists. Refer to screenshot below. Additionally the command prompt should also be running with admin rights according to my code above.
Registry Key Screenshot:
Furthermore executing the command...
REG QUERY "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office\15.0\ClickToRun\REGISTRY\MACHINE\Software\Wow6432Node\Microsoft\Office\15.0\Access Connectivity Engine\Engines\Excel" /v TypeGuessRows
Directly in command prompt works without any Administrator Rights.
REG EDIT Manually in CMD:
So I'm lost on how to get this function working correctly and any help on this issue would be much appreciated!
**** UPDATE ****
Ok so i've implemented the code suggested by Dinotom in the first answer. See extract of code below.
Sub Read_Registry()
Dim entryArray() As Variant
Dim valueArray() As Variant
Dim reg_key_location As String
Dim x As Integer
reg_key_location = "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office\15.0\ClickToRun\REGISTRY\MACHINE\Software\Wow6432Node\Microsoft\Office\15.0\Access Connectivity Engine\Engines\Excel"
Call EnumerateRegEntries(reg_key_location, entryArray, valueArray)
For x = 0 To UBound(entryArray)
'Do something here
Next x
End Sub
Public Sub EnumerateRegEntries(keyPath As String, arrEntryNames As Variant, arrValueTypes As Variant)
Dim registryObject As Object
Dim rootDirectory As String
rootDirectory = "."
Set registryObject = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & _
rootDirectory & "\root\default:StdRegProv")
registryObject.EnumValues HKEY_LOCAL_MACHINE, keyPath, arrEntryNames, arrValueTypes
End Sub
However the following error is returned on the For x = 0 ... line...
ERROR:
Run-time error '9' Subscript out of range.
It doesn't look like the arrays are being populated with the registry data as suggested below. Any more ideas?
Do you have to use Shell?
This will enumerate your registry entries, manipulate as you need.
Set up empty arrays to pass as the parameters, and the keypath is the local file path to your registry to enumerate. the sub will fill the arrays.
Dim entryArray() As Variant, valueArray() As Variant
Call EnumerateRegEntries("pathtokey",entryArray, valueArray)
The sub below will run and entryArray and valueArray will be populated.
Then you can iterate over the arrays
For x = 0 to UBound(yourarrayhere)
'Do something here
Next x
Enumerate method:
Public Sub EnumerateRegEntries(keyPath As String, arrEntryNames As Variant, arrValueTypes As Variant)
Dim registryObject As Object
Dim rootDirectory As String
rootDirectory = "."
Set registryObject = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & _
rootDirectory & "\root\default:StdRegProv")
registryObject.EnumValues HKEY_LOCAL_MACHINE, keyPath, arrEntryNames, arrValueTypes
End Sub
if you are unable to alter or use this sub, then look here
Chip Pearsons registry page
or, if you have some requirement to use Shell, then look here for how to run as Admin
run shell as admin
The path is wrong.
Set the path like this:
reg_key_location = "SOFTWARE\Microsoft\Office\15.0\ClickToRun\REGISTRY\MACHINE\Software\Wow6432Node\Microsoft\Office\15.0\Access Connectivity Engine\Engines\Excel"
The HKEY_LOCAL_MACHINE is placed when calling the object:
registryObject.EnumValues HKEY_LOCAL_MACHINE, keyPath, arrEntryNames, arrValueTypes
EDIT: Also remind that if you are running windows 64 bits and office 32 bits, the stdregprov only reads inside Wow6432Node.

My.User.CurrentPrincipal not working in Class Library

I am trying to get the current username in a Windows environment that uses Windows Authentication. The code exists in a class library that is built and referenced within a separate Visual Studio application:
Function GetUserName() As String
If TypeOf My.User.CurrentPrincipal Is
Security.Principal.WindowsPrincipal Then
' The application is using Windows authentication.
' The name format is DOMAIN\USERNAME.
Dim parts() As String = Split(My.User.Name, "\")
Dim username As String = parts(1)
Return username
Else
' The application is using custom authentication.
Return My.User.Name
End If
End Function
I get an error when it's located in the class library. My.User.CurrentPrincipal comes back with {System.Security.Principal.GenericPrincipal} and My.User.Name is blank. When I put the exact same code into a brand new windows forms application it works - My.User.CurrentPrincipal comes back with {System.Security.Principal.WindowsPrincipal} and My.User.Name is the user's login name.
Microsoft documentation suggests that the My.User object will work in class libraries. Does anyone know why I'm getting different values when it's put into a class library and added as a .dll reference to a parent application?
The parent application is a class library that is an add-in for Microsoft PowerPoint. The code in the parent application that calls the above code (called UsageDataCollection.dll) is:
Public Class rbnOvaPowerPoint
Private DataCollector As UsageDataCollection.DataCollector
Private Sub butShare_Click(sender As Object, e As RibbonControlEventArgs) Handles butShare.Click
OtherTasks.CreateMailItem()
End Sub
End Class
And then in a separate module:
Module OtherTasks
Private DataCollector As New UsageDataCollection.DataCollector
Sub CreateMailItem()
Dim OutlookApp As Outlook._Application = CreateObject("Outlook.Application")
Dim mail As Outlook.MailItem = Nothing
Dim mailRecipients As Outlook.Recipients = Nothing
Dim mailRecipient As Outlook.Recipient = Nothing
DataCollector.UsageStatistics("CreateMailItem")
Try
mail = OutlookApp.CreateItem(Outlook.OlItemType.olMailItem)
mail.Subject = "OvaPowerPoint"
mail.Body = "Check out OvaPowerPoint, a custom-built Arup add-in for PowerPoint!" & Strings.Chr(13) & Strings.Chr(13) & "About the Add-In:" & Strings.Chr(13) & "http://wiki.oasys.intranet.arup.com/X-Wiki/index.php/OvaPowerPoint" & Strings.Chr(13) & Strings.Chr(13) & "Installation File:" & Strings.Chr(13) & "\\n-ynas12\Software\Custom%20Applications\Plug-Ins\Microsoft%20PowerPoint\OvaPowerPoint\setup.exe"
mail.Display(True)
Catch ex As Exception
System.Windows.Forms.MessageBox.Show(ex.Message,
"An exception is occured in the code of add-in.")
Finally
If Not IsNothing(mailRecipient) Then System.Runtime.InteropServices.Marshal.ReleaseComObject(mailRecipient)
If Not IsNothing(mailRecipients) Then System.Runtime.InteropServices.Marshal.ReleaseComObject(mailRecipients)
If Not IsNothing(mail) Then System.Runtime.InteropServices.Marshal.ReleaseComObject(mail)
End Try
End Sub
End Module
And the UsageStatistics subroutine in UsageDataCollection.dll looks like:
Imports System.IO
Imports System.Text
Public Class DataCollector
Public Sub UsageStatistics(myAction As String)
Dim myAssemblyName As String = System.Reflection.Assembly.GetCallingAssembly.GetName.Name
Dim myFilePath As String = "\\n-ywpress01\uploads\UsageData\" & myAssemblyName & ".csv"
Using LogFile As New StreamWriter(myFilePath, True)
LogFile.WriteLine("[" & DateTime.Now.ToUniversalTime.ToString("yyyy/MM/dd HH':'mm':'ss") & "]" & Chr(44) & GetUserName() & Chr(44) & GetUserLocation() & Chr(44) & myAction)
LogFile.Close()
End Using
End Sub
End Class
Thanks
Zak
In the MS docs, it says
For Windows applications, only projects built on the Windows Application template initialize the My.User object by default. In all other Windows project types, you must initialize the My.User object by calling the My.User.InitializeWithWindowsUser Method explicitly or by assigning a value to CurrentPrincipal.
The fix in your code is:
Function GetUserName() As String
My.User.InitializeWithWindowsUser() 'pulls the network credentials into .NET
If TypeOf My.User.CurrentPrincipal Is
Security.Principal.WindowsPrincipal Then
' The application is using Windows authentication.
' The name format is DOMAIN\USERNAME.
Dim parts() As String = Split(My.User.Name, "\")
Dim username As String = parts(1)
Return username
Else
' The application is using custom authentication.
Return My.User.Name
End If
End Function

Get hardware manufacturer and system model number in VB.net?

I'm trying to get the hardware manufacturer (e.g. "Dell") and the model number (e.g. "Latitude E6320") using vb.net but I'm having no luck.
I've tried
Dim opSearch As New ManagementObjectSearcher("SELECT * FROM Win32_OperatingSystem")
Dim opInfo As ManagementObject
For Each opInfo In opSearch.Get()
Return opInfo("manufacturer").ToString()
Next
Though this returns "Microsoft Corporation" not "Dell".
You are polling the wrong WMI class/hive. Of course Microsoft is the OS manufacturer; what you need is Win32_ComputerSystem:
Imports System.Management
cs = New ManagementObjectSearcher("SELECT * FROM Win32_ComputerSystem")
For Each objMgmt In cs.Get
_Manufacturer = objMgmt("manufacturer").ToString()
_Model = objMgmt("model").ToString()
_SystemType = objMgmt("systemtype").ToString
_totalMem = objMgmt("totalphysicalmemory").ToString()
Next
Manufacturer will be something like "Dell, Inc", Model comes out spot on with mine, but has been known to sometimes include internal sub model identifiers. System type comes back as "x64-based PC" on mine.
MS has a WMI query builder somewhere to help fnd and use the right query, though it generates very wordy code.
Give this a try in a console application. Just remember to add the System.Management reference to your project. You need to access the Win32_ComputerSystem not the Win32_OperatingSystem.
Sub Main()
Dim objCS As Management.ManagementObjectSearcher
Dim manufacturerName As String
'objOS = New Management.ManagementObjectSearcher("SELECT * FROM Win32_OperatingSystem")
objCS = New Management.ManagementObjectSearcher("SELECT * FROM Win32_ComputerSystem")
For Each objMgmt In objCS.Get
manufacturerName = objMgmt("manufacturer").ToString()
Next
Debug.WriteLine("Manufacturer: " & manufacturerName)
End Sub
Hope it helps.

Extracting Filename and Path from a running process

I'm writing a screen capture application for a client. The capture part is fine, but he wants to get the name and path of the file that the capture is of.
Using system.diagnostics.process I am able to get the process that the capture is of, and can get the full path of the EXE, but not the file that is open.
ie. Notepad is open with 'TextFile1.txt' as its document. I can get from the process the MainWindowTitle which would be 'TextFile1.txt - Notepad' but what I need is more like 'c:\users....\TextFile1.txt'
Is there a way of getting more information from the process?
I'm sure there is a way, but I can't figure it out
Any help greatly appreciated.
You can use ManagementObjectSearcher to get the command line arguments for a process, and in this notepad example, you can parse out the file name. Here's a simple console app example that writes out the full path and file name of all open files in notepad..
Imports System
Imports System.ComponentModel
Imports System.Management
Module Module1
Sub Main()
Dim cl() As String
For Each p As Process In Process.GetProcessesByName("notepad")
Try
Using searcher As New ManagementObjectSearcher("SELECT CommandLine FROM Win32_Process WHERE ProcessId = " & p.Id)
For Each mgmtObj As ManagementObject In searcher.Get()
cl = mgmtObj.Item("CommandLine").ToString().Split("""")
Console.WriteLine(cl(cl.Length - 1))
Next
End Using
Catch ex As Win32Exception
'handle error
End Try
Next
System.Threading.Thread.Sleep(1000000)
End Sub
End Module
I had to add a reference to this specific dll:
C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\System.Managment.dll
i think it is the simplest way
For Each prog As Process In Process.GetProcesses
If prog.ProcessName = "notepad" Then
ListBox1.Items.Add(prog.ProcessName)
End If
Next
I know this post is old, but since I've searched for this two days ago, I'm sure others would be interested. My code below will get you the file paths from Notepad, Wordpad, Excel, Microsoft Word, PowerPoint, Publisher, Inkscape, and any other text or graphic editor's process, as long as the filename and extension is in the title bar of the opened window.
Instead of searching, it obtains the file's target path from Windows' hidden Recent Items directory, which logs recently opened and saved files as shortcuts. I discovered this hidden directory in Windows 7. You're gonna have to check if Windows 10 or 11 has this:
C:\Users\ "username" \AppData\Roaming\Microsoft\Windows\Recent
I slapped this code together under Framework 4, running as 64bit. The COM dlls that must be referenced in order for the code to work are Microsoft Word 14.0 Object Library, Microsoft Excel 14.0 Object Library, Microsoft PowerPoint 14.0 Object Library, and Microsoft Shell Controls And Automation.
For testing, the code below needs a textbox, a listbox, a button, and 3 labels (Label1, FilenameLabel, Filepath).
Once you have this working, after submitting a process name, you will have to click the filename item in the ListBox to start the function to retrieve it's directory path.
Option Strict On
Option Explicit On
Imports System.Runtime.InteropServices
Imports Microsoft.Office.Interop.Excel
Imports Microsoft.Office.Interop.Word
Imports Microsoft.Office.Interop.PowerPoint
Imports Shell32
Public Class Form1
'function gets names of all opened Excel workbooks, adding them to the ListBox
Public Shared Function ExcelProcess(ByVal strings As String) As String
Dim Excel As Microsoft.Office.Interop.Excel.Application = CType(Marshal.GetActiveObject("Excel.Application"), Microsoft.Office.Interop.Excel.Application)
For Each Workbook As Microsoft.Office.Interop.Excel.Workbook In Excel.Workbooks
Form1.ListBox1.Items.Add(Workbook.Name.ToString() & " - " & Form1.TextBox1.Text)
Next
Return strings
End Function
'function gets names of all opened Word documents, adding them to the ListBox
Public Shared Function WordProcess(ByVal strings As String) As String
Dim Word As Microsoft.Office.Interop.Word.Application = CType(Marshal.GetActiveObject("Word.Application"), Microsoft.Office.Interop.Word.Application)
For Each Document As Microsoft.Office.Interop.Word.Document In Word.Documents
Form1.ListBox1.Items.Add(Document.Name.ToString() & " - " & Form1.TextBox1.Text)
Next
Return strings
End Function
'function gets names of all opened PowerPoint presentations, adding them to the ListBox
Public Shared Function PowerPointProcess(ByVal strings As String) As String
Dim PowerPoint As Microsoft.Office.Interop.PowerPoint.Application = CType(Marshal.GetActiveObject("PowerPoint.Application"), Microsoft.Office.Interop.PowerPoint.Application)
For Each Presentation As Microsoft.Office.Interop.PowerPoint.Presentation In PowerPoint.Presentations
Form1.ListBox1.Items.Add(Presentation.Name.ToString() & " - " & Form1.TextBox1.Text)
Next
Return strings
End Function
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
'clears listbox to prepare for new process items
ListBox1.Items.Clear()
'gets process title from TextBox1
Dim ProcessName As String = TextBox1.Text
'prepare string's case format for
ProcessName = ProcessName.ToLower
'corrects Office process names
If ProcessName = "microsoft excel" Then
ProcessName = "excel"
Else
If ProcessName = "word" Or ProcessName = "microsoft word" Then
ProcessName = "winword"
Else
If ProcessName = "powerpoint" Or ProcessName = "microsoft powerpoint" Then
ProcessName = "powerpnt"
Else
End If
End If
End If
'get processes by name (finds only one instance of Excel or Microsoft Word)
Dim proclist() As Process = Process.GetProcessesByName(ProcessName)
'adds window titles of all processes to a ListBox
For Each prs As Process In proclist
If ProcessName = "excel" Then
'calls function to add all Excel process instances' workbook names to the ListBox
ExcelProcess(ProcessName)
Else
If ProcessName = "winword" Then
'calls function to add all Word process instances' document names to the ListBox
WordProcess(ProcessName)
Else
If ProcessName = "powerpnt" Then
'calls function to add all Word process instances' document names to the ListBox
PowerPointProcess(ProcessName)
Else
'adds all Notepad or Wordpad process instances' filenames
ListBox1.Items.Add(prs.MainWindowTitle)
End If
End If
End If
Next
End Sub
Private Sub ListBox1_MouseClick(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles ListBox1.MouseClick
Try
'add ListBox item (full window title) to string
Dim ListBoxSelection As String = String.Join(Environment.NewLine, ListBox1.SelectedItems.Cast(Of String).ToArray)
'get full process title after "-" from ListBoxSelection
Dim GetProcessTitle As String = ListBoxSelection.Split("-"c).Last()
'create string to remove from ListBoxSelection
Dim Remove As String = " - " & GetProcessTitle
'Extract filename from ListBoxSelection string, minus process full name
Dim Filename As String = ListBoxSelection.Substring(0, ListBoxSelection.Length - Remove.Length + 1)
'display filename
FilenameLabel.Text = "Filename: " & Filename
'for every file opened and saved via savefiledialogs and openfiledialogs in editing software
'Microsoft Windows always creates and modifies shortcuts of them in Recent Items directory:
'C:\Users\ "Username" \AppData\Roaming\Microsoft\Windows\Recent
'so the below function gets the target path from files's shortcuts Windows created
FilePathLabel.Text = "File Path: " & GetLnkTarget("C:\Users\" & Environment.UserName & "\AppData\Roaming\Microsoft\Windows\Recent\" & Filename & ".lnk")
Catch ex As Exception
'no file path to show if nothing was saved yet
FilePathLabel.Text = "File Path: Not saved yet."
End Try
End Sub
'gets file's shortcut's target path
Public Shared Function GetLnkTarget(ByVal lnkPath As String) As String
Dim shl = New Shell32.Shell()
lnkPath = System.IO.Path.GetFullPath(lnkPath)
Dim dir = shl.NameSpace(System.IO.Path.GetDirectoryName(lnkPath))
Dim itm = dir.Items().Item(System.IO.Path.GetFileName(lnkPath))
Dim lnk = DirectCast(itm.GetLink, Shell32.ShellLinkObject)
Return lnk.Target.Path
End Function
End Class