I want to extract archive.
But the problem is, when the code runs, it throws the exception below:
System.IO.IOException: 'The file 'filename' already exists.'
Here are the code
File.WriteAllBytes(String_TempDir & "\rzip.zip", My.Resources.Resszip) 'I wrote the file from my application resources
Compression.ZipFile.ExtractToDirectory(String_TempDir & "\rzip.zip", String_TempDir) 'This line throws the exception
File.Delete(String_TempDir & "\rzip.zip")
I saw nothing(no file) before that code executed...
After the code executed, It throws the exception, but, my archived file has been extracted.
I used Try statement to distinguish the exception but it's still throwing that exception...
Try
Compression.ZipFile.ExtractToDirectory(String_TempDir & "\rzip.zip", String_TempDir)
Catch ex As IOException
'That's it.
End Try
The String_TempDir is a string which I assign it with:
'global declaration:
Dim folder As String = Path.Combine(Path.GetTempPath, Path.GetRandomFileName)
'End of global declaration
Public Function GetTempDir() As String
Do While Directory.Exists(folder) Or File.Exists(folder)
folder = Path.Combine(Path.GetTempPath, Path.GetRandomFileName)
Loop
Return folder
End Function
'Form loads
Directory.CreateDirectory(folder)
String_TempDir = folder
Just guessing, but it could be that you are putting the Zip file into the same directory you are extracting to. Try extracting to a subdirectory of your temp directory. e.g.
Compression.ZipFile.ExtractToDirectory(String_TempDir & "\rzip.zip", String_TempDir & "\extracted")
The MSDN article on ExtractToDirectory says the following (emphasis mine):
This method creates the specified directory and all subdirectories.
The destination directory cannot already exist. Exceptions related to
validating the paths in the destinationDirectoryName or
sourceArchiveFileName parameters are thrown before extraction.
Otherwise, if an error occurs during extraction, the archive remains
partially extracted. Each extracted file has the same relative path to
the directory specified by destinationDirectoryName as its source
entry has to the root of the archive.
Have you also checked that the Zip file doesn't contain any duplicate names?
If it was compressed on Linux, it might have both Filename and filename inside it, and that might cause this error. Especially since you say that it doesn't contain any files at first and that it seems that it succeeds in decompressing it.
Somewhat similar question here, but with 7-Zip
Related
I have some code that uses System.IO to find files with a given extension. This works fine with regular folders but fails when the files are in Onedrive's local cache.
My assumption is that the problem is to do with the Onedrive cache folder because if the files are moved out of Onedrive and into a local folder e.g. c:\temp, it all works fine.
Dim Folder As New IO.DirectoryInfo(TextBox_RootFolder.Text)
Filelist = Folder.GetFiles("*.xlsx", IO.SearchOption.AllDirectories)
This is VB, so I believe there should not be any issues with string literals, so I'm stumped.
The path string comes out as something similar to: "C:\Users\user\OneDrive - ThisPlace\MyFolder" so there's nothing particularly weird about the string.
When presented with a folder on Onedrive, my variable 'Folder' is correctly assigned with the full path but an exception is thrown on calling Folder.Getfiles. This results in the error "The tag present in the reparse point buffer is invalid".
BTW, I'm a novice so example code would be really appreciated as a detailed technical explanation is likely to go whoosh over my head.
I'm please to report that I found an easy way to solve the problem.
Firstly I retained the code that uses Folder.Getfiles to provide a list of files as this is fast, elegant and retrieves files in sub-folders.
It still throws an exception when it encounters a cloud sync folder such as Onedrive, DropBox etc., so in the catch I use the Dir() function to loop through the files as this does not have problems with folders of this type.
Here is some pseudo-code to show an example:
Dim sFile As String
sFile = Dir(sPath + "\*.xlsx")
Do While sFile <> ""
[ do stuff here ]
sFile = Dir() '' Get the next file
Loop
I hope this is helpful to someone.
I want to be able to copy resources I've compiled into the program to a location on the local machine where the application is run. Mostly a few DLLs that my program will not use, but others will (think Installer type of application).. But I can't find a way to reference the resources by path in order to do a File.Copy, for instance:
File.Copy(My.Resources.conversion, BinPath & "conversion.dll")
...tells me "Value of type 'Byte()' cannot be converted to 'String'". And I get why, obviously the first parameter needs to be a string path and not the resource itself. Is there a better way to copy resources or how can I obtain a reference path to the resource so I can use File.Copy?
For what it's worth, I've also tried
File.WriteAllBytes(BinPath & "conversion.dll", My.Resources.conversion)
...which "works" to copy it where I want it, but then I get errors when I try to call regsvr32 on the
new dll: "The module ... was loaded but the entry-point DLLRegisterServer was not found."
If there's a better way altogether, I'm open to any idea.
The following steps work for me:
Change the 'Build Action' of the dll in 'Resources' file to 'Embedded Resource'.
Use the following method to save resource file to disk.
Public Sub WriteResourceToFile(ByVal resourceName As String, ByVal fileName As String)
Using resource = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName)
Using file = New FileStream(fileName, FileMode.Create, FileAccess.Write)
resource.CopyTo(file)
End Using
End Using
End Sub
Example of usage:
WriteResourceToFile("yournameSpace.conversion.dll", BinPath & "conversion.dll")
im totally new to vb.net
I figured how to find files using wildcard and it works fine but i need error meassage if file not found.
here's my code.
any help highly appreciated !
For Each hist In Directory.GetFiles("C:\temp", "*.*", SearchOption.TopDirectoryOnly)
If File.Exists(hist) Then
File.Copy(hist, Path.Combine("C:\temp\1", Path.GetFileName(hist)), True)
MessageBox.Show("file exist and copied") <-- this message shows up and files are copied
Else
MessageBox.Show("No files. Folder is empty !") <--this message never shows up when folder is empty . no files at all
End If
Next
It is unlikely you would see that second message. You are grabbing the list of files from the OS directly - so, at least at the time that you retrieve the file name that file exists. If you wanted to simulate a case where the file doesn't exist, place a break point on the IF File.Exists(hist) Then line. While the program is paused there, go find and delete whatever the current file is. Then continue the program.
i got it working.
here's what i added before foreach :
Dim myDir As DirectoryInfo = New DirectoryInfo("c:\temp\")
If (myDir.EnumerateFiles().Any()) Then
foreach ....
else
MessageBox.Show("no files in directory ") <-- my message
thanks for advice!!
I am trying to make a program in Visual Basic that can download files to a directory but unfortunately I keep on getting an error similar to this every time:
'An unhandled exception of type 'System.ArgumentException' occurred in Microsoft.VisualBasic.dll
Additional information: The given file path ends with a directory separator character.'
It also highlights this whenever it gives me the error:
My.Computer.Network.DownloadFile(
"https://copy.com/TUr3BCzMbTf4kWNk/symsrv.yes?download=1",
appdata & "\DownloadedFiles\")
I've tried many google searches but nothing, this code used to work on a previous program I've made with VB.net that downloads a game file and replaces it with the current so that users can access parts of the game they couldn't access before without doing certain tasks. Here is the code that did this:
My.Computer.Network.DownloadFile(
"https://copy.com/4WkvAdu4O7sRb3gd/fn4?download=1",
appdata & "/MMFApplications/fn4")
Is there anything I'm doing wrong that prevents me from making my current project work?
The error message is self-explanatory:
The given file path ends with a directory separator character
You should write a filepath as destination (a file that ends with a file extension), not a directory path neither a filepath that ends with a "\" char.
The My.Computer.Network.DownloadFile function just downloads the data, it does not know the filename.
An example:
My.Computer.Network.DownloadFile(
"https://copy.com/TUr3BCzMbTf4kWNk/symsrv.yes?download=1",
System.IO.Path.Combine(appdata, "\DownloadedFiles\File.ext"))
I am working on a GUI for a simulation program. The simulation program is a single .exe which is driven by an input file (File.inp placed in the same directory).
The Original.inp file functions as a template from which the form reads all the values into an array. Then it changes these values reflecting the changes done by the user in the form. After that it writes all the new values to File.inp.
By pushing the "Run" button the Simulation.exe file is executed.
The folder structure looks like this:
root
|
|---input
| |
| |--Original.inp
|
|---GUI.exe
|---Simulation.exe
|---File.inp
Ideally I would supply only the GUI, the user would select the working directory and then the GUI.exe would create an input folder and extract the Original.inp and Simulation.exe in the appropriate locations. So far I have only managed to include Original.inp and Simulation.exe as "EmbeddedResources" in my VB project and I have let my code create an input folder in the working directory chosen by the user.
Can someone please explain to me how I can extract the .inp and .exe file into the correct directories? I've searched on google, tried File.WriteAllBytes and Filestream.WriteByte but did not get the desired results.
The problem with File.WriteAllBytes was that I could not point to the embedded resource ("Simulation.exe is not a member of Resources" and with Filestream.WriteByte I got a 0 kb file.
The question commenters are correct, this is probably a task best left for a setup program. However, that having been stated, in the interest of answering the question as asked I offer the following approach.
Contrary to your supposition in your question comment, you do need to "read" the embedded resource from the GUI's executable file, since it's an embedded resource and not an external resource. It won't magically extract itselt from the executable file. You need to do the manual read from the assembly and write to your specified locations. To do this, you need to read the resource using .Net Reflection, via the currently executing assembly's GetManifestResourceStream method.
The Simulation.exe file is a binary file so it must be handled as such. I assumed that the Orginal.inp file was a text file since it afforded the opportunity to demonstrate different types of file reads and writes. Any error handling (and there should be plenty) is omitted for brevity.
The code could look something like this:
Imports System.IO
Imports System.Reflection
Module Module1
Sub Main()
'Determine where the GUI executable is located and save for later use
Dim thisAssembly As Assembly = Assembly.GetExecutingAssembly()
Dim appFolder As String = Path.GetDirectoryName(thisAssembly.Location)
Dim fileContents As String = String.Empty
'Read the contents of the template file. It was assumed this is in text format so a
'StreamReader, adept at reading text files, was used to read the entire file into a string
'N.B. The namespace that prefixes the file name in the next line is CRITICAL. An embedded resource
'is placed in the executable with the namespace noted in the project file, so it must be
'dereferenced in the same manner.
Using fileStream As Stream = thisAssembly.GetManifestResourceStream("SOQuestion10613051.Original.inp")
If fileStream IsNot Nothing Then
Using textStreamReader As New StreamReader(fileStream)
fileContents = textStreamReader.ReadToEnd()
textStreamReader.Close()
End Using
fileStream.Close()
End If
End Using
'Create the "input" subfolder if it doesn't already exist
Dim inputFolder As String = Path.Combine(appFolder, "input")
If Not Directory.Exists(inputFolder) Then
Directory.CreateDirectory(inputFolder)
End If
'Write the contents of the resource read above to the input sub-folder
Using writer As New StreamWriter(Path.Combine(inputFolder, "Original.inp"))
writer.Write(fileContents)
writer.Close()
End Using
'Now read the simulation executable. The same namespace issues noted above still apply.
'Since this is a binary file we use a file stream to read into a byte buffer
Dim buffer() As Byte = Nothing
Using fileStream As Stream = thisAssembly.GetManifestResourceStream("SOQuestion10613051.Simulation.exe")
If fileStream IsNot Nothing Then
ReDim buffer(fileStream.Length)
fileStream.Read(buffer, 0, fileStream.Length)
fileStream.Close()
End If
End Using
'Now write the byte buffer with the contents of the executable file to the root folder
If buffer IsNot Nothing Then
Using exeStream As New FileStream(Path.Combine(appFolder, "Simulation.exe"), FileMode.Create, FileAccess.Write, FileShare.None)
exeStream.Write(buffer, 0, buffer.Length)
exeStream.Close()
End Using
End If
End Sub
End Module
You will also have to add logic to determine if the files have been extracted so it doesn't happen every time the GUI is invoked. That's a big reason why an installation program might be the correct answer.