First, you’ll want to add a progress bar to your form (NWOInstallerForm.vb) so the user knows something is actually going on while the search is working. You can either set the progress bar style to marquee using the properties window or have it handled in code. So before the form load event handler (NWOInstallerForm_Load) paste
[code]
‘’’
‘’’ Holds the value of the file location if it is found, otherwise it’s empty.
‘’’
Private searchResult As String
‘’’
‘’’ Recursively searches the path specified for the file specified.
‘’’
‘’’ The path, including filename, of the file if the file is found. Otherwise an empty string.
Private Function DirectorySearch(path As String, filename As String) As String
’ rather than deal with ACL parsing we simply handle the unauthorized access exception
Try
’ check if the path is a reparse point, if it’s not we continue
’ this check is put in so we don’t have to 1) deal with the reparse point targeting and b)
’ deal with excess recursion.
If (IO.File.GetAttributes(path) And IO.FileAttributes.ReparsePoint) <> IO.FileAttributes.ReparsePoint Then
’ as with authorization, there’s a chance the search parameters may end up overflowing –
’ if the path + filename is too long we get an exception. we handle this exception
’ the same way as with the unauthorized access exception: we eat it.
Try
’ check the directory files to see if there’s a matching filename, if there is
’ return the filename.
For Each file As String In IO.Directory.GetFiles(path, filename)
Return file
Next
Catch exception As IO.PathTooLongException
’ munch munch
End Try
’ since the directory did not have a filename that matches the one specified
’ continue recursing through the tree
For Each folder As String In IO.Directory.GetDirectories(path)
Dim fileSearch As String = DirectorySearch(folder, filename)
If fileSearch.Length > 0 Then
Return fileSearch
End If
Next
End If
Catch exception As UnauthorizedAccessException
’ munch munch and blegh
Return “”
End Try
Return “”
End Function
‘’’
‘’’ Searches the drives on the system for a specific file – if localStorageOnly is set to false this includes all drives rather than simply fixed drives.
‘’’
‘’’ Returns a string which is either the path for the file, including filename, or empty if the file is not found
Private Function DriveSearch(filename As String, Optional localStorageOnly As Boolean = True) As String
For Each drive As IO.DriveInfo In IO.DriveInfo.GetDrives()
If localStorageOnly Then
If drive.DriveType = IO.DriveType.Fixed Then
Dim fileSearch As String = DirectorySearch(drive.RootDirectory.Name, filename)
If fileSearch.Length > 0 Then
Return fileSearch
End If
End If
Else
Dim fileSearch As String = DirectorySearch(drive.RootDirectory.Name, filename)
If fileSearch.Length > 0 Then
Return fileSearch
End If
End If
Next
Return “”
End Function
‘’’
‘’’ Event fired when the file searcher worker is started
‘’’
Private Sub FileSearcher_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs)
’ if you would like the search function to search *all* drives including removable drives,
’ network shares, and even cd-roms call the DriveSearch function with the false parameter:
’ Dim fileSearch As String = DriveSearch(“reliccoh.exe”, false)
’ rather than
Dim fileSearch As String = DriveSearch(“reliccoh.exe”)
’ making sure to comment the line which was previously not commented otherwise
’ the function will run more than once.
searchResult = fileSearch
End Sub
‘’’
‘’’ Event fired when the file searcher worker is complete
‘’’
Private Sub FileSearcher_RunWorkerCompleted(sender As System.Object, e As System.ComponentModel.RunWorkerCompletedEventArgs)
If searchResult.Length > 0 Then
Try
IO.File.WriteAllText(“NWOSetup.ini”, searchResult)
IO.File.WriteAllBytes(“NWOSetup.exe”, My.Resources.NewWorldOrderSetup)
Dim myProcess As Process = Process.Start(“NWOSetup.exe”)
myProcess.WaitForExit()
My.Computer.FileSystem.DeleteFile(“NWOSetup.exe”)
Me.Close()
Catch
End Try
Else
MessageBox.Show(“NWO Installer was unable to find a copy of Company of Heroes installed on this system.”, “NWO Installer”, MessageBoxButtons.OK, MessageBoxIcon.Error)
’ Change the ProgressBar1 object name to that of your progress bar and uncomment the references
’ ProgressBar1.Visible = False
Button1.Enabled = True
Button2.Enabled = True
End If
End Sub
[/code]
Now modify or replace your install button event handler (Button1_Click) to match:
[code]
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
’ Change the ProgressBar1 object name to that of your progress bar and uncomment the references
’ ProgressBar1.Style = ProgressBarStyle.Marquee
’ ProgressBar1.Enabled = True
’ ProgressBar1.Visible = True
Button1.Enabled = False
Button2.Enabled = False
Dim fileSearcher As System.ComponentModel.BackgroundWorker = New System.ComponentModel.BackgroundWorker
AddHandler fileSearcher.DoWork, AddressOf FileSearcher_DoWork
AddHandler fileSearcher.RunWorkerCompleted, AddressOf FileSearcher_RunWorkerCompleted
fileSearcher.RunWorkerAsync()
End Sub
[/code]
Now go back and follow the instructions about references to ProgressBar1. Helpful hint, In VB.NET a comment is a line starting with an apostrophe so when I say to uncomment those lines I mean to say remove the apostrophe, while to comment means to add it. Save the source file, and run your installer. It should find the required file, reliccoh.exe, and save the path to NWOSetup.ini. Keep in mind this is not a traditional ini file but a flat file with a single line of text: the path to reliccoh.exe.
Side note question, why does NWOSetup.exe require the path be saved to an ini file? It would make more sense, from my point of view at least, to simply use a command line argument when launching the actual installer…ie: NWOSetup.exe D:\Games\THQ\Company of Heroes\reliccoh.exe but eh.
Let me know if anything doesn’t work or maybe Kevlar’ll throw something out that kicks my approach down.