Cannot delete just created file - vb.net-2010

My application can create a directory, put a file in it from a ZIP file and then remove the ZIP file.
When I then try to delete that file, I get an Access Denied error even though nothing was done with it.
Here is the code:
File.WriteAllBytes(OpslagLocatieDocumenten + myTicketNummer.ToString + "\documenten.zip", op.Documenten)
Using zp As New ZipFile(OpslagLocatieDocumenten + myTicketNummer.ToString + "\documenten.zip")
zp.FlattenFoldersOnExtract = True
zp.ExtractAll(OpslagLocatieDocumenten + myTicketNummer.ToString, ExtractExistingFileAction.OverwriteSilently)
zp.Dispose()
End Using
Try
For Each itm As String In Directory.GetFiles(OpslagLocatieDocumenten + myTicketNummer.ToString)
Try
File.Delete(itm)
Catch ex As Exception
End Try
Next
Catch ex As Exception
End Try
It looks a bit messy right now, but that is for testing purposes.
In the for-next part, right after writing the file from the ZIP, I try to delete the files.
At the moment there are two files in the directory, one ZIP and one PDF document from the ZIP.
The first file in itm is the PDF, it errors with an ACCESS DENIED.
The second file in itm is the ZIP which gets deleted.
The PDF is 311 kb in size.
Via Windows explorer I can delete it without any problem, even with the application still running.
Why is my file being locked?
What can I do to by-pass or remove this lock?
rg,
Eric

Found the problem.
The file that was added to the ZIP had it's attribute set to READ ONLY.
So when the application writes the file, windows would, as it should, not allow the application to delete it.
Unfortunately, windows does allow to delete the file via windows explorer without a message that the file is read only.

Have you also tried the File.Kill(fileLocation) method?

Related

Problem handling errors with FileSystemWatcher

To start with it has been many years since I have done much programming, probably about 15 years, in fact VB 6 was still being taught then so I'm not up to date on anything and can get lost in what I'm reading but I am trying. I'm using Visual Studio 2019 and trying to create a VB Windows Forms App that uses the FileSystemWatcher. Unfortunately the only solutions to my problem that I could find are in C#. I tried to transfer them to my app but couldn't get them to work. Actually Visual Studio wasn't happy with what I put in and wouldn't run at all, probably due to incorrect syntax.
This part of my little app is supposed to copy a file that another program creates, while the other program is running, and place the copy in another folder. It seemed simple, detect that the file had been changed and then copy the changed file. Well I came across a few problems.
The first problem is that if I create an empty file the code works most times with no problems but occassionally 2 copies of the file are created. I could live with that but.
If I replace the empty file with a larger file, the file that it is meant to copy, then it can make 3 or 4 copies and most times produces a messagebox telling me that it can't access the file because it is in use. The main program is also minimised to display the error message, which I don't want.
Even if my app is the only program running and I replace the watched file manually with the larger file I still get the file in use error, so I am assuming that the event has been triggered twice and one of them is the process that is using the file and causing the error.
If I tell the error message to cancel then my program continues and produces only 1 copy of the file. Which is what I do want.
The second problem is that the file being copied is also accessed by another program for a short period imediately after it has been changed and this also causes an extra few copies of it to be made and sometimes a file in use error message box appears, and again the main program is minimised to display the error message. I originally had other IO.NotifyFilters in place that weren't really necassary and thought that they may have been triggering the errors so I removed them, but it made no difference.
The most common error is that the file is in use but there has also been the odd "Unhandled exception has occured in your application. could not find file.". The only reason that I can think of for this error is that the file may have been renamed to a backup file and a new version created by the main program at the exact time my program tried to access it.
From what I have read the FileSystemWatcher can trigger multiple times and I presume that this is what is causing the duplicate copies from both problems.
I need my app to make only 1 copy without the error messagebox appearing as this program needs to run in the background with no user input. Essentially this part of my app is an external program to backup a file when the file changes because the main program changes this file often but only seems to back up the file every few hours.
The following code is what I have used but nothing that I have tried has caught the error so I removed the error event handler. This code was copied from something else that was similar and in C# then modified for my purpose. I thought that the {} were used for C# not VB but it seems to work and if I take them out it won't.
My code for the FileSystemwatcher is:-
WatchFile = New System.IO.FileSystemWatcher With {
.Path = Path.GetDirectoryName(strArkMapFileNamePath),
.Filter = Path.GetFileName(strArkMapFileNamePath),
.NotifyFilter = IO.NotifyFilters.LastWrite
}
' add the handler to each event
AddHandler WatchFile.Changed, New FileSystemEventHandler(AddressOf OnLastWrite)
'Set this property to true to start watching
WatchFile.EnableRaisingEvents = True
The event handler is:-
Private Sub OnLastWrite(sender As Object, e As FileSystemEventArgs)
'Copy the Save file to a new folder and rename it.
My.Computer.FileSystem.CopyFile(
strArkMapFileNamePath,
strBackupPath & "\" & strArkMapFileName & "_" &
DateTime.Now.ToString("dd.MM.yyyy_hh.mm.ss") & ".ark",
Microsoft.VisualBasic.FileIO.UIOption.OnlyErrorDialogs,
Microsoft.VisualBasic.FileIO.UICancelOption.DoNothing)
End Sub
I added an error event handler after AddHandler WatchFile.Changed, New FileSystemEventHandler(AddressOf OnLastWrite) but that did nothing.
I tried to add an on error statement before the end sub and that did nothing either, I presume because the Microsoft.VisualBasic.FileIO.UIOption.OnlyErrorDialogs, caught the error first.
I got frustrated and tried to add a statement before the Microsoft.VisualBasic.FileIO.UIOption.OnlyErrorDialogs, but it didn't like that and I didn't expect it to work.
So how do I catch the errors before the FileSystemWatcher acts on the error?
I don't know what I am doing wrong so any help would be appreciated.
Also if anybody could offer code for what I need to do can it please be code for a Windows Forms App because I don't seem to have much luck in converting C# or anything else.
Edit
I have replaced the My.Computer.FileSystem.CopyFile with the File.Copy method as suggested and added a few extra bits..
Private Sub OnLastWrite(sender As Object, e As FileSystemEventArgs)
'Verify that source file exists
If File.Exists(strArkMapFileNamePath) Then
'Copy the Save file to a new folder and rename it.
Dim i As Integer
For i = 0 To 3
Try
' Overwrite the destination file if it already exists.
File.Copy(strArkMapFileNamePath, strBackupPath & "\" & strArkMapFileName & "_" & DateTime.Now.ToString("dd.MM.yyyy_hh.mm.ss") & ".ark", True)
i = 3
' Catch exception if the file was already copied.
Catch copyError As IOException
'If copy failed reset counter
i += 1
End Try
Next
End If
End Sub
Although this shouldn't be required because this is done before the FileSystemWatcher is enabled I have added an If statement to check that the files exists before attempting to copy the file.
I'm not entirely happy with the loop but I know under normal conditions that it's not going to be an endless loop.
Is there a way to just catch the specific errors that I would need to deal with or will it be fine the way it is?
I will probably still need to work out how to stop the FileSystemWatcher from sending more than 1 event or somehow make multiple events appear as 1.
The If statement was the last thing that I added and for some reason the program now seems to only make 1 copy and appears to be faster.
The other external program that accesses the file being copied must be slower to react than my program because now it displays a message that it's waiting until my program has finished copying the file.
My program is now performing as it was intended but I believe that it is just a matter of timing rather than the correct code.

How to Copy a file without locking it?

I have a large log file located on a network drive that is being constantly written to. How can I copy it through code without locking it?
Try
Microsoft.VisualBasic.FileSystem.FileCopy("sourcefile", "destinationfile")
Catch ex As Exception
' Handle Error
End Try
The code above, unfortunately does not work well, because while its copying the file, nothing can be written to that file.
Edit 1:
It was suggested to read the content of the file and write it to the output. I would prefer not to do this, because the file is several gigabytes. I reserve this option only as a last resort, only if there is no other way to copy the file without locking it and without readying the content.
how about using FileOpen in shared mode and reading and writing the output file yourself
FileOpen(1, "SourceFile", OpenMode.Input, OpenAccess.Default, OpenShare.Shared)
// open destination file here read and while not at end of sourcefile read it // and write blocks out to destinatioon file.
FileClose(1)
If you can't copy the file to work on it, or don't want to open the file in shared mode and then copy it that way, then another option is to have the system that generates the log file generate a series of smaller log files. Maybe one per unit, or production run, or hour, or day, or some other arbitrary break point.

UnauthorizedAccessException with File.AppendAllText in VB.NET

I have recently started getting System.UnauthorizedAccessException errors when using File.AppendAllText to write to a shared drive on the network. I think there were some changes to the network when this happened. The code in my application hasn't changed.
I have asked our IT dept to grant me full permission to the folder. I can see I have permissions for Modify, Read & Execute, Read, Write under my username if I navigate to the file and look at the Security tab under properties. I am also part of a group with read, write and modify permissions to the folder.
This works without error in the same folder:
File.WriteAllText(myFile, myText)
This generates a System.UnauthorizedAccessException error when it reaches the AppendallText:
If File.Exists(myFile) = False Then
' Create a file to write to.
Dim createText As String = logTime & " " & report_data
File.WriteAllText(myFile, createText)
Else
Dim appendText As String = logTime & " " & report_data
File.AppendAllText(myFile, appendText)
End If
I have tried deleting the file and creating it again, that made no difference.
I tried File.SetAttributes(myFile, FileAttributes.Normal)
The IT dept can't see what the problem is.
I can manually open, change and modify the file. The problem only arises if I am trying to do this programmatically.
Is there a different 'user' which tries to modify files? Could the file be open somehow, or would that generate a different error?
I'm using VB.NET 2012, .net framework 4.5, Windows 8.1
The network changes were the problem. It doesn't seem possible to resolve this as it is. Instead I made a copy of the text data, append my new text to that, delete the file, and save the updated text to a new file.

Can't Delete INI File After Calling GetPrivateProfileString

I am having trouble deleting files after calling the GetPrivateProfileString command. I have the following code:
'Read the INI File
sb = New StringBuilder(500)
Select Case FileType
Case "Scanner File"
res = GetPrivateProfileString("ScannerSetings", "ScannerType", "", sb, sb.Capacity, Filename)
Case "Scale File"
res = GetPrivateProfileString("ScaleSetings", "ScaleType", "", sb, sb.Capacity, Filename)
End Select
'If the result is a value store it, otherwise move it to unprocessed
If res <> 0 Then InputArray.Add(sb.ToString)
File.Delete(Filename)
After reading the details from the INI file, as soon as I try to delete the file, I am getting the following error: The process cannot access the file 'R:\Drop\011_11_Scanner' because it is being used by another process.
I cannot even delete these files manually until I exit my application.
Any help would be appreciated.
Thanks
I cannot even delete these files manually until I exit my application.
This clearly shows that the file that Filename points to is locked. As long as it's locked, you won't be able to delete it.
Check your code for any file handles you have opened (eg for writing purposes) and did not close.
If you don't close a file after you've opened it, the file is not released and remains in locked state… which practically means it can not be deleted until (a) you close that file-handle, or (b) you close your program, since that's what's holding the file-handle after opening.
EDIT
The next thing that comes to mind is that VB.NET may need special user access rights to remove the INI on recent Windows versions. You can quickly cross-check that by simply executing your application with elevated user rights (eg via right-click menu; run as admin). I can't imagine that that's actually the problem — but it's worth a shot. Should it indeed be the problem, check (and modify) the permissions on the folder your application and/or INI resides in.

Deleting a file causes an untrapable error

In my app i have to copy and then delete image files from memory cards, the problem comes when some of the card inadvertantly have the "Lock" switch engaged turning them to read only.
When trying to delete these files i want to log the failure to delete but not show any UI messages until a time of my choosing.
Here is some sample code i am having trouble with.
Sub Main()
Try
System.IO.File.Delete("K:\BYZTCSQ_0050.JPG")
Catch ex As Exception
'Error would be logged here
End Try
End Sub
This works fine when debuging i.e. it tries to delete the file and if not the error is caught and i can proccess it as nessecary, but when i build and run the app i get an error message telling me that the file cannot be deleted.
To test this code you will need a drive that can be physically set to read only (USB memory key, SD card) and try to delete a file on it while debuging and after a build.
Why would the same code run differently and how can i stop the excess error messages?
You can try to create a file on the memory card. For reasons only known to Microsoft (or not), creating a file on a copy-protected drive will raise the error condition in the Try block while deleting a file will not. Incidentally, I got the same odd result -- catching the delete worked fine in debug mode, but not from the .exe.
Imports System.IO
...
Try
fs = File.Create(drive & "\tmp.~tmp")
Catch ex As Exception
copyprotected = true
End Try
if not copyprotected then
file.delete(drive & "\tmp.~tmp")
file.delete(the file you wanted to in the first place)
end if
Instead of wrapping it in a try/catch block, test to see if the file exists before trying to execute the delete:
Dim strFilePath as String = "K:\BYZTCSQ_0050.JPG"
If File.Exists(strFilePath) Then
System.IO.File.Delete(strFilePath)
End If