I have a very large zip file which contains other zip files inside of it. I want my c# program to be able to recognize that the file is a zip file and if it is a zip file, then to extract it to a folder in the same location as the zip file. My code is here:
private void Unzip(OpenFileDialog tvZipOpen)
{
string zipFile = tvZipOpen.FileName; // file to unzip
int i = zipFile.LastIndexOf(".zip");
string targetDirectory = zipFile.Substring(0, i); // location to extract to
using (ZipArchive zip = ZipFile.OpenRead(zipFile))
{
zip.ExtractToDirectory(targetDirectory);
}
tvZipOpen.InitialDirectory = targetDirectory;
tvZipOpen.ShowDialog();
}
I am using the ZipFile class from .NET 4.5 and i call on this method here:
if (tvOpen.ShowDialog() == DialogResult.OK)
{
while (tvOpen.FileName.ToLower().EndsWith(".zip"))
{
Unzip(tvOpen);
}
return tvOpen.FileNames;
}
The code works fine for extracting the first zip file but when I try to extract the second zip file, I get an InvalidDataException that says local file header is corrupt. However, I don't think it is corrupt because I am able to open and extract the zip files perfectly in windows explorer. I'm not sure if the fact that it is a large zip file with a zip64 extension has anything to do with it but whatever the problem is, how come I don't get the problem when I open and extract in windows explorer and how do I fix this? Any help would be greatly appreciated.
c# does not support the .zip64 extension.
how large is your zip file because if it under 4GiB rename it to .zip and it should work fine if it is larger than that see this
http://dotnetzip.codeplex.com/
To change the file extension
Open windows explorer and press Alt + V
Then go to tools and then folder options and make sure that the hide extensions for known file types box is unchecked and click apply and ok.
then simply rename the file to remove the 64 from the extension so it is just .zip
Then Click yes on the prompt
And then you should be able to open the file in your program
hope this helps
Related
I have a problem.
I have a text file "hello.pdf"
I put the file to the resource of the project and read the file
string filename = #"C:\Users\vivio\Documents\Visual Studio 2015\Projects\STool\STool\Resources\hello.pdf";
System.Diagnostics.Process.Start(filename);
I have a question: If I want packet STool to STool.exe, and then install this packet in the (D:)disk then I think I will not read file hello.pdf because in the code I set pathfile is "C:\Users\vivio\Documents\Visual Studio 2015\Projects\STool\STool\Resources\hello.pdf"
Help me to resolve this problem, thanks all
The following link is same with yours, maybe it would be helpful.
How to read embedded resource text file
Or this one.
How to open a PDF file that is also a project resource?
First, copy the file to your project directory and include it in your project. In the file's properties, set the Copy to Output Directory to Copy Always. Now it will always copy to the build directory when you compile.
It will be saved to Directory.GetCurrentDirectory(), so to reference the file you will always be able to use:
string filename = Directory.GetCurrentDirectory() + "\\Resources\\hello.pdf";
I'm running into a strange problem using ZipFile and ZipArchive with .Net 4.5.
ZipFile.CreateFromDirectory takes all content of a directory, including folders that are empty.
If I try to create the same zip file using Windows explorer by right clicking > Send to > Compressed folder, I get a warning message saying the empty folder was omitted.
I'm loading the resulting zip file into an application that runs on Apache Tomcat. This application throws errors for every single file contained in the zip that I produced with ZipFile.CreateFromDirectory. The zip that I created manually through Windows explorer is read just fine.
I suspect the problem lies in the empty zipped folders, but haven't yet been able to definitively conclude this. If the empty folders are the cause, I'd need a way to use ZipFile.CreateFromDirectory excluding empty folders.
Taken from my comment above:
I have no .NET 4.5, but from the remarks section: "The directory structure from the file system is preserved in the archive. If the directory is empty, an empty archive is created." So this is by design.
So you either have to
fix it in the comsuming app on tomcat or you have to
create a temporary folder which just contains the non-empty folders, if possible
I haven't found a way to exclude empty folders in CreateFromDirectory in the first place.
Alternatively, I can remove empty directories from the created zip file. Though this still causes errors in the Tomcat application.
// compress and copy new zip
ZipFile.CreateFromDirectory(dirtocopy.FullName, NewZipFilePath);
using (ZipArchive za = ZipFile.Open(NewZipFilePath, ZipArchiveMode.Update))
{
// only empty folders end with \
List<ZipArchiveEntry> emptyFolders = (from ZipArchiveEntry zae in za.Entries
where zae.FullName.EndsWith("\\")
select zae).ToList<ZipArchiveEntry>();
emptyFolders.ForEach((ZipArchiveEntry folder) => folder.Delete());
}
I am new here
I have a c# program with WPF that
generates some pdf
saves it in the same directory
then opens the pdf for viewing
-->all that works fine with no error when exe launched directly.
But when the .exe is lauched by an excel macro (shell function) in an excel file in the same directory: excel macro is OK, program starts OK, generates the pdf OK, ... pdf is opened & viewed automatically OK (so makes me think the pdf was saved someghere)... and when all is closed ... not pdf in the directory !
It's probably an obvious general error, but I can't figure it out.
Detailed help appreciated as I am new to that
Fabrice
If Excel is using a different working directory, the file will be placed there and not where you expected. If this is the case, you can use the following method...
public string GetFullSaveName(string pdfName)
{
string myDirectoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
if (myDirectoryName != null)
{
string fullSaveName = Path.Combine(myDirectoryName, pdfName);
return fullSaveName;
}
throw new ApplicationException("Unable to locate assembly path");
}
This method uses Reflection to find out which directory your application is running in. It uses this to build up a fully qualified path so that your pdf file will be written to a predictable place. The path returned is the working directory of the application, and not Excel's.
I'm trying to make my image viewer app work with files that are opened by clicking an image file directly inside a Zip folder (using windows explorer to browse Zip files). The application seems to be run with correct command line, which looks like this:
"C:\myApp.exe" "C:\Users\Admin\AppData\Local\Temp\Temp1_Wallpapers.zip\Wallpaper1.jpg"
The file is being read with the following code:
using (var fs = new FileStream(path, FileMode.Open))
And the exception is thrown at that line:
Exception:Thrown: "Access to the path 'C:\Users\Admin\AppData\Local\Temp\Temp1_Wallpapers.zip\Wallpaper1.jpg' is denied." (System.UnauthorizedAccessException)
A System.UnauthorizedAccessException was thrown: "Access to the path 'C:\Users\Admin\AppData\Local\Temp\Temp1_Wallpapers.zip\Wallpaper1.jpg' is denied."
I figured this may be a problem with how the path is interpreted. There's a .zip in the middle of it, so this could be the problem, but I don't know how to solve that.
Also, simply opening a file at that path directly (not through zipped folder explorer window) results in the same exception.
Windows Explorer gains the ability to treat a .zip archive as a folder through a shell name extension handler. Such handlers extend the capability of the shell. But that's however restricted to shell functions only, it doesn't automagically make the low-level file access functions capable of doing the same. Like FileStream.
You'll need to copy the file out of the .zip archive first, then you can open it with FileStream. Lots of .zip support libraries around, SharpZipLib and DotNetZip are popular. It got finally added to .NET 4.5 with the System.IO.Compression.ZipArchive class. Let's pick that one for the most future-proof example code.
I created an Example.zip archive with a single image and copied it to my temp directory. This code retrieved it and made it the background image of a Winforms form:
using System.IO;
using System.IO.Compression; // Add reference to System.IO.Compression
...
private void button1_Click(object sender, EventArgs e) {
var srcePath = #"c:\users\hpass_000\appdata\local\temp\example.zip";
using (var file = new FileStream(srcePath, FileMode.Open)) {
var zip = new ZipArchive(file, ZipArchiveMode.Read);
var entry = zip.GetEntry("Chrysanthemum.jpg");
var destPath = Path.GetTempFileName();
using (var srce = entry.Open())
using (var dest = new FileStream(destPath, FileMode.Create)) {
srce.CopyTo(dest);
}
using (var img = Image.FromFile(destPath)) {
this.BackgroundImage = new Bitmap(img);
}
File.Delete(destPath);
}
}
I just found out what the problem was. Files extracted from compressed folders into temp folder will have read-only attribute, which my image viewer app apparently can't handle and throws UnauthorizedAccessException. I just need to remove that attribute and everything will be fine. Guess trying to read read-only files is an access violation of sorts.
The issue has nothing to do with the . in the temp file path because periods are legal in file names as well as directory names.
As you expect, opening a Zip folder in the shell and opening a file automatically extracts the contents to a temp folder, which is just a normal folder. The only thing that looks strange here is that it's opening the Administrator temp folder. Are you running the exe as a normal user? If the exe and shell are running under separate users, the exe may not be able to access the temp folder used by the shell.
I need to combine 3 files into 1 zip file and make it available to download for the user. I am able to achieve my requirement except one thing: it zips the files into the subfolders.
For example, my files are located like the following:
C:\TTCG\WebSites\Health\ABC.CSV
C:\TTCG\WebSites\Health\XYZ.CSV
C:\TTCG\WebSites\Health\123.CSV
But in the zip file, it zip the files in the folder by using "TTCG\WebSites\Health\" as the path. Please see the attach file.
I don't want the folders in the path. I just want 3 files in the zip file without folders. How can I achieve that?
My codes to generate the zip file is as below:
ZipFile z = ZipFile.Create(Server.MapPath("~" + #"\Accident.zip"));
//initialize the file so that it can accept updates
z.BeginUpdate();
//add the file to the zip file
z.Add(Server.MapPath("~" + #"\ABC.csv"));
z.Add(Server.MapPath("~" + #"\XYZ.csv"));
z.Add(Server.MapPath("~" + #"\123.csv"));
//commit the update once we are done
z.CommitUpdate();
//close the file
z.Close();
Based on the FAQ, you have to strip the folder path out manually:
How can I create a Zip file without folders?
Remove the path portion of the filename used to create a ZipEntry
before it is added to a ZipOutputStream
ZipEntry entry = new ZipEntry(Path.GetFileName(fullPath));
The FAQ can be found here.
It seems to be a limitation of the library. Hope this helps!
If you have your files in a FileSystemInfo, you can use: z.Add(file.FullName, Path.GetFileName(file.FullName));
This will add your files in the root directory of your zip.
z.Add(pathToFile, pathInZipFile);