I'm a little late to the party, however this is how I would do it.
First of all, there is no need to search from A-Z
as thats what DriveInfo is for.
Secondly, why would you want to add every program to your control panel program, like why would you want the Mobile Plan Application in there?
Forgive me if I have misunderstood your question, however it kinda sounds like you want to search through each file in the programs folder and add their exes to your application?? like dynamically add items?
However with that being said, here is how I achieved what you are asking for in a console application, copy the functions and methods where needed
Imports System.IO
Imports System.Text
Module Module1
'' List Of The Programs We Will Want
'' Key Is The Program Folder Name,
'' Value Is The Programs Name
Private Property Programs As Dictionary(Of String, String)
'' Get Program Files Path
Private ReadOnly Program_Files As String = Environment.ExpandEnvironmentVariables("%ProgramW6432%")
'' Create A String Builder
Private Property ConstructedPath As StringBuilder
Sub Main()
'' Create The String Builder Object Above
ConstructedPath = New StringBuilder()
'' Programs We Wish To Use
'' Why would you want to use them all
'' eg Calculator doesnt really belong in
'' the control panel
Programs = New Dictionary(Of String, String) From {
{"CCleaner", "CCleaner64"}
}
'' Get All Fixed Disk Drives
'' No Need To Search From A-Z
Dim diskDrives As IEnumerable(Of DriveInfo) = DriveInfo.GetDrives().Where(Function(d) d.DriveType = DriveType.Fixed)
'' Loop through each drive And attempt to
'' run the application
For Each drive As DriveInfo In diskDrives
For Each program As KeyValuePair(Of String, String) In Programs
'' path to the executable
ConstructedPath.AppendFormat(String.Format($"{drive.Name}{Program_Files.Split("\"c).Last()}\{program.Key}\{program.Value}.exe"))
'' If the program exits, than lets attempt to
'' execute it
If ProgramExist(ConstructedPath.ToString()) Then
'' boolean for if needed to check status later on
Dim executed As Boolean = ExecuteProgram(ConstructedPath.ToString())
End If
'' Clear String Builder For The Next Loop
ConstructedPath.Clear()
Next
Next
Console.ReadKey()
End Sub
''' <summary>
''' If the Given Path Is Valid,
''' We Will Attempt To Execute It.
''' Executes The Given Path
''' </summary>
''' <param name="path"></param>
''' <returns></returns>
Private Function ExecuteProgram(ByVal path As String) As Boolean
Dim isRunning As Boolean = False
Try
Process.Start(path)
Catch ex As Exception
'' Something Happened
Console.WriteLine(ex.StackTrace)
Finally
For Each p As Process In Process.GetProcesses()
If p.ProcessName.Contains(path.Split("\"c).Last()) Then
isRunning = True
End If
Next
End Try
Return isRunning
End Function
''' <summary>
''' Validate The Given Path
''' </summary>
''' <param name="path"></param>
''' <returns></returns>
Private Function ProgramExist(ByVal path As String) As Boolean
Return System.IO.File.Exists(path)
End Function
End Module
I added a function that will check if the path is valid, if not the process will not execute and if it is valid, well it will.
I used a dictionary to hold the values, key
is used for the programs folder name and value
is used for the programs name, yes if you have multiple programs you want to execute in the same folder,
you will need to write another function or even use a List String as the value
instead.
As for creating a button dynamically, check out this post