Can get process ID from exception? - vb.net

Attempting to deploy updates to a .dll using WebClient.DownloadFile. If the dll is loaded/locked by the program it cannot be overwritten, so i'm trying to use a Try... Catch statement (on the following exception) to curate the Process ID and .Dispose() of it.
System.Net.WebException: 'An exception occurred during a WebClient request.'
Inner Exception
IOException: The process cannot access the file 'xyz' because it is being used by another process.
This may or may not be the best methodology... below is my code. Any pointers much appreciated!
Try
Using WC As New WebClient
WC.DownloadFile("https://urlgoeshere.com/library.dll", strLiveDLL)
End Using
Catch ex1 As System.Net.WebException
Using P As Process = ex1.WhatGoesHere 'can get the process ID here??
If MsgBox("Cannot update because dll file is locked by " & P.ProcessName & vbCr &
"Press OK to dispose of this process and continue with update.",
MsgBoxStyle.OkCancel & MsgBoxStyle.Question,
"Update Interrupted") = MsgBoxResult.Ok Then
P.Dispose()
'continue with update
Else
MsgBox("Update Aborted.")
End If
End Using
Catch ex2 As IOException
'
Catch ex3 As Exception
'
End Try

If anyone else is interested, I never figured out how to get the process ID from the exception (I don't think it's possible) but I discovered that it may not be necessary...
What I'm doing instead is just renaming the DLL if it's locked (everything seems to still run as expected even after rename). After it's renamed, the updated DLL can be downloaded to the standard location for the live DLL.

Related

Why does this compile with "Is" but not with "IsNot"?

I'm hacking some old VB code, and I want a function to return early if an exception is caught, but if it's a System.UnauthorizedAccessException the function should continue. Just so I don't get XY'ed, I know this is a strange requirement, but I'm rewriting the code in C#, and I just need to see the result of this. I know there's probably a better way to do it. Here is the original code:
Try
doSomeStuffWithFiles(files)
Catch ex As Exception
MsgBox("Far Field: error in reading / writing to far field file." & Chr(13) & ex.Message)
Exit Sub
End Try
So I added a couple lines:
Catch ex As Exception
MsgBox("Far Field: error in reading / writing to far field file." & Chr(13) & ex.Message)
If TypeOf ex IsNot System.UnauthorizedAccessException Then
Exit Sub
End If
End Try
Now, I'm not an expert in VB, but as far as I can tell this is perfectly valid VB. It also exactly matches the sample code for TypeOf on MSDN. However, this code fails to compile. I get this error:
Error 21 'Is' expected. C:\FilePath 3114 26 Project
Error 22 'UnauthorizedAccessException' is a type in 'System' and cannot be used as an expression. C:\FilePath 3114 32 Project
If I change that line to
Catch ex As Exception
MsgBox("Far Field: error in reading / writing to far field file." & Chr(13) & ex.Message)
If TypeOf ex Is System.UnauthorizedAccessException Then
Exit Sub
End If
End Try
Then everything compiles and runs fine. (Sans the logic being backwards)
I am using visual studio 2013, and targeting .net framework 2.0.
So what's the reason that IsNot is not valid?
It would work as you have it in Visual Studio 2015, but if you look at the VS2013 version of the docs, you'll see only TypeOf ... Is listed, so you'd need to use Not TypeOf ... Is.
Target .NET Framework version doesn't make a difference. If you're using VS2015, TypeOf ... IsNot will compile.
IsNot didn't exist in pre 2.0 .Net VB.Net
If Not TypeOf ex Is
This syntax came from vb6

Invalid Class ManagementException when working with ManagementEventWatcher

I'm currently talking to another computer to see what events they have occurring. I have setup a Wql Event query like so below:
Console.WriteLine("Polling...")
Try
Dim query As New WqlEventQuery("SELECT * FROM Lnl_AccessEvent")
Dim accessEventWatcher = New ManagementEventWatcher("SELECT * FROM Lnl_AccessEvent")
accessEventWatcher.Start()
accessEventWatcher.WaitForNextEvent()
Console.WriteLine("AccessEvent Occured.")
Catch ex As Exception
Console.WriteLine(ex.Message + " " + ex.StackTrace)
End Try
On the ".Start()" line, I get an exception stating "Invalid class" and "ManagementException". I know the connection is working since before this instance I'm able to connect and get the basic info from the remote computer's WMI, like IP address. The only solutions I have found is that has to do with my target build being only x86, but now it's at AnyCPU and still has this issue.
What is causing this error?

Testing if I have full read/write access to a file in VB .NET 4.5 before processing it

I'm writing a windows service which runs as the local system account. I'm trying to make sure if I have full read/write access to a file beginning to process it any further. Here is my code:
Dim FullPath As String
FullPath = "C:\directory\file.txt"
Dim ps As Security.PermissionSet
ps = New Security.PermissionSet(Security.Permissions.PermissionState.Unrestricted)
ps.AddPermission(New Security.Permissions.FileIOPermission(Security.Permissions.FileIOPermissionAccess.AllAccess, FullPath))
ps.AddPermission(New Security.Permissions.FileIOPermission(Security.Permissions.FileIOPermissionAccess.AllAccess, IO.Path.GetDirectoryName(FullPath)))
Try
ps.Demand()
Catch ex As Security.SecurityException
System.Diagnostics.EventLog.WriteEntry("ShopLink", "File " + FullPath + " will not be parsed. " + ex.Message)
Exit Sub
Catch ex As Exception
System.Diagnostics.EventLog.WriteEntry("ShopLink", "File " + FullPath + " will not be parsed. " + ex.Message)
Exit Sub
End Try
Then I set the full access permissions for the file to "Deny" for the user account my service is running as. After executing, the code above doesn't throw any exceptions and allows file processing to begin. When the service later tries to change and/or delete the file, I get an "Access Denied" exception.
Any suggestions?
For this purpose i use thise small function:
Private Function HasAccess(ByVal ltFullPath As String)
Try
Using inputstreamreader As New StreamReader(ltFullPath)
inputstreamreader.Close()
End Using
Using inputStream As FileStream = File.Open(ltFullPath, FileMode.Open, FileAccess.ReadWrite, FileShare.None)
inputStream.Close()
Return True
End Using
Catch ex As Exception
Return False
End Try
End Function
In your case then:
If HasAccess(FullPath) ...
I have solved the problem by using My.Computer.FileSystem.DeleteFile to delete the file instead of Kill. My.Computer.FileSystem.DeleteFile was executed without problems after successfully demanding full read/write access to the file in the way described above, while Kill consistently threw an "Access denied" exception.
Using "Kill"... I know this is a very old thread but I'll add this in case anyone stumbles on it like I did. I was working on some old VB6 legacy code. One of my clients users was getting a runtime exception during a file open after a kill. The code was "Killing" the file and then rebuilding it from scratch with binary data held in memory. It tuns out that the "Kill" function triggered the user's anti-virus software which locked the file long enough to cause the next "Open" statement to fail. I discovered this using an error logging utility (the name escapes me at the moment). The line in the error log file on the failed "Open" statement was that the file's status was "Delete pending" due to the user's anti-virus software.

Finding specific Exceptions using Visual Studio

I'm using VS 2010 Express for VB.net and wondering if there is an easy way to discover exceptions that I might encounter by using the IDE?
For example if I have the following:
If Me.saveQueryDialog.ShowDialog() = Windows.Forms.DialogResult.OK Then
Try
sqlTextBox.SaveFile(saveQueryDialog.FileName)
Catch ex As Exception
MessageBox.Show(String.Format("Save was unsuccessful encountered: {0}", ex.Message))
End Try
End If
Can I use the IDE to somehow find that the usual exception I'll encounter in this circumstance is ...ex As IO.IOException
Or in the following:
If Me.openQueryDialog.ShowDialog = Windows.Forms.DialogResult.OK Then
Try
sqlTextBox.LoadFile(openQueryDialog.FileName)
Catch ex As Exception
MessageBox.Show(String.Format("Open was unsuccessful encountered: {0}", ex.Message))
End Try
End If
..the most common exception I'll encounter is ...ex As IO.FileLoadException
Or do I need to just try to remember these specific exceptions?
You can check the MSDN Documentation for each method that you are using to see any possible exception they can throw.
This, for example, are the possible exceptions for .SaveFile() method.

ftp connection and upload what happens to connection if there is exception

Below is code for how you can upload a file using ftp. My question is what happens if there is an exception in the try, will the ftp connection automatically close in the catch? Is it better to use a "using"?
thank you
Try
'connect to ftp server
Dim ftp As New FTPConnection
ftp.ServerAddress = "ftp.example.com"
ftp.UserName = "example_user"
ftp.Password = "example_pass"
ftp.Connect()
ftp.TransferType = FTPTransferType.BINARY
'upload a file
ftp.UploadFile("s:\test.txt", "test.txt")
'close the connection
ftp.Close()
Catch ex As Exception
MessageBox.Show(ex.Message.ToString())
End Try
When an exception happens (whatever it is) the control flow skips everything until it arrives to a Catch instruction.
So in this case if you have an exception in the UploadFile you will not close the connection.
If the FTPConnection class is IDisposable then your best option is to use the using keyword. Otherwise use the finally statament after the Catch as Grant said.
No, it won't close if an exception occurs before ftp.Close() has finished executing. You should use a Finally block to make sure that ftp is always closed, even if an exception occurs. This means you should define ftp at a higher scope level than within the try block, so that it is accessible within the finally block. You could technically call Close from within the catch block but that A) won't cover both/all circumstances and B) might not work anyway if code in the catch throws yet another exception.
Dim ftp As New FTPConnection
Try
Catch ex As Exception
MessageBox.Show(ex.Message.ToString())
Finally
ftp.Close()
End Try