I am trying to zip and encrypt a chosen file from the user. Everything works fine except that I am zipping the whole path, i.e not the file itself. Below is my code, any help on how I can zip and encrypt on the chosen file.
openFileDialog1.ShowDialog();
var fileName = string.Format(openFileDialog1.FileName);
string path = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
using (ZipFile zip = new ZipFile())
{
zip.Password = "test1";
zip.Encryption = EncryptionAlgorithm.WinZipAes256;
zip.AddFile(fileName);
zip.Save(path + "\\test.ZIP");
MessageBox.Show("File Zipped!", "Complete", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
You must set the file name explicitly for the zip-archive:
zip.AddFile(fileName).FileName = System.IO.Path.GetFileName(fileName);
This is how you can zip up a file, and rename it within the archive . Upon extraction, a file will be created with the new name.
using (ZipFile zip1 = new ZipFile())
{
string newName= fileToZip + "-renamed";
zip1.AddFile(fileToZip).FileName = newName;
zip1.Save(archiveName);
}
Reference : C# Examples
Related
I have 1 folder that contains many txt files. I want to zip them but separated.
Example:
In this folder I have A.txt, B.txt, C.txt.
I want to zip all the files but separated so the result will be A.zip, B.zip, C.zip.
string outputPath = "C:\\Users\\Desktop\\VA";
string path = outputPath + "\\VA_" + tglskrg;
foreach (string dirFile in Directory.GetDirectories(path))
{
foreach (string fileName in Directory.GetFiles(dirFile))
{
using (ZipFile zip = new ZipFile())
{
zip.UseUnicodeAsNecessary = true;
zip.AddFile(); //dont know what to put
zip.Save(); //dont know what to put
}
}
}
Any help will be appreciated.
I'm using dotnetzip (Ionic.zip) and C# Visual Studio Express 2010.
You could do that as follows:
foreach (string fileName in Directory.GetFiles(dirFile))
{
var zipFile = Path.Combine(outputPath, Path.ChangeExtension(fileName, ".zip"));
using (ZipFile zip = new ZipFile())
{
zip.AddFile(fileName); // add A.txt to the zip file
zip.Save(zipFile); // save as A.zip
}
}
This takes all the files found in the folder dirFile, and saves them under outputPath, with the same file name but replacing the extension with .zip.
I have automated a test script in selenium and c# whereby I click on an icon and it downloads a pdf file. I do not know the name of this file, so what I need is confirmations its been downloaded, the file name and then it deletes the file?
I have done some research and found some code but it doesn't work. Here is the latest code I have found but all it tells me in "files" is the number of pdf files in my directory.
string fileName = ConfigurationManager.AppSettings["Don't know file name"];
string pathUser = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
string pathDownload = Path.Combine(pathUser, "Downloads");
DirectoryInfo downloadDir = new DirectoryInfo(pathDownload);
FileInfo[] files = downloadDir.GetFiles("*.pdf");
var file = files.Where(x => x.Name.Replace(" ", "") == fileName + ".pdf").FirstOrDefault();
fileName = file.FullName;
In case someone wants to know I have figured it out. So here is the code to confirm file has been downloaded and exists and then its deleted:
string pathUser = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
string pathDownload = Path.Combine(pathUser, "Downloads");
DirectoryInfo downloadDir = new DirectoryInfo(pathDownload);
FileInfo[] files = downloadDir.GetFiles("*.pdf");
var filename = files[0].FullName;
string getFileName = Path.GetFileName(filename);
if (File.Exists(filename))
{
Console.WriteLine("The file has been downloaded successfully");
Console.WriteLine("The filename is: " + getFileName);
}
File.Delete(filename);
Hope it helps someone.
Scenario: upload file than try zip it using DotNetZip with password protection, password is generated with Membership.GeneratePassword() method. Everything is working fine except that sometimes user is not able to unzip files with generated password. Wired thing is that this happens only sometimes let's say 1 out of 15 times.
Generate password:
public static String FilePassword()
{
while (_filePassword.Length < 12)
{
_filePassword += string.Concat(Membership.GeneratePassword(1, 0).Where(char.IsLetterOrDigit));
}
return _filePassword;
}
Save file:
if (FileUploadControl.HasFile)
{
fileName = Path.GetFileName(FileUploadControl.FileName);
FileUploadControl.SaveAs(FileSavePath + fileName);
// Archive uploaded file to zip.
using (ZipFile zip = new ZipFile())
{
// File to be archived.
var file = FileUploadControl.PostedFile;
// Enable encryption of file
zip.Encryption = EncryptionAlgorithm.PkzipWeak;
// Set password.
zip.Password = Settings.FilePassword();
// Set temporary folder path for archive process.
zip.TempFileFolder = tempPath;
// Add file to archive with its path.
zip.AddFile(FileSavePath + file.FileName, "");
File objFile = new File(file.FileName, FileSavePath);
// Save zip file with the name as file ID.
zip.Save(FileSavePath + file.FileName);
}
}
I logged password while creating in method and also while protecting zip file with password, they are always matching, I cannot see what's wrong, why sometimes while unzipping file it shows wrong password.
Why do you use the static global variable _filePassword in FilePassword() instead of one in scope?
This way it could be modified from outside, or possible even still contain the last used value. Also it isn't thread safe without lock.
Settle with a local variable and it should be fine.
public static String FilePassword()
{
string retString = string.Empty;
while (retString.Length < 12)
{
retString += string.Concat(Membership.GeneratePassword(1, 0).Where(char.IsLetterOrDigit));
}
return retString;
}
You can log a return Value too.
Sample for understanding
if (FileUploadControl.HasFile)
{
fileName = Path.GetFileName(FileUploadControl.FileName);
FileUploadControl.SaveAs(FileSavePath + fileName);
string filePassword = Settings.FilePassword(); // Contains the Password
using (ZipFile zip = new ZipFile())
{
var file = FileUploadControl.PostedFile;
zip.Encryption = EncryptionAlgorithm.PkzipWeak;
zip.Password = filePassword; // <-- Set password for ZIP
zip.TempFileFolder = tempPath;
zip.AddFile(FileSavePath + file.FileName, "");
File objFile = new File(file.FileName, FileSavePath);
zip.Save(FileSavePath + file.FileName);
}
// Log this value!
Log(filePassword);
}
I am able to zip files from a specific folder using ZipFile.CreateFromDirectory in the following test code (I only used this code to test how zipping works):
// Where the files are located
string strStartPath = txtTargetFolder.Text;
// Where the zip file will be placed
string strZipPath = #"C:\Users\smelmo\Desktop\testFinish\" + strFileNameRoot + "_" + txtDateRange1.Text.Replace(#"/", "_") + "_" + txtDateRange2.Text.Replace(#"/", "_") + ".zip";
ZipFile.CreateFromDirectory(strStartPath, strZipPath);
However, this zips together ALL of the contents in the folder. I am trying to zip together specific items in the folder using ZipArchive in the following code:
// Where the files are located
string strStartPath = txtTargetFolder.Text;
// Where the zip file will be placed
string strZipPath = #"C:\Users\smelmo\Desktop\testFinish\" + strFileNameRoot + "_" + txtDateRange1.Text.Replace(#"/", "_") + "_" + txtDateRange2.Text.Replace(#"/", "_") + ".zip";
using (ZipArchive archive = ZipFile.OpenRead(strStartPath))
{
foreach (ZipArchiveEntry entry in archive.Entries)
{
if (!(entry.FullName.EndsWith(".TIF", StringComparison.OrdinalIgnoreCase)))
{
entry.ExtractToFile(Path.Combine(strZipPath, entry.FullName));
}
}
}
It is giving the error at ZipFile.OpenRead(strStartPath). Why am I able to access the exact folder in the first block of code but not the second? Or is there an easier way to search through a folder and only zip specific items?
You are utilizing the Zip libraries wrong
Effectively you are trying to open a directory as if it were a zip file, then loop over the contents of that directory (which again is actually a zip file) and then attempting to extract each member into a different zip file
Here is a working example of what you have described you are trying to do:
string strStartPath = #"PATH TO FILES TO PUT IN ZIP FILE";
string strZipPath = #"PATH TO ZIP FILE";
if (File.Exists(strZipPath))
File.Delete(strZipPath);
using (ZipArchive archive = ZipFile.Open(strZipPath, ZipArchiveMode.Create))
{
foreach (FileInfo file in new DirectoryInfo(strStartPath).GetFiles())
{
if (!(file.FullName.EndsWith(".TIF", StringComparison.OrdinalIgnoreCase)))
{
archive.CreateEntryFromFile(Path.Combine(file.Directory.ToString(), file.Name), file.Name);
}
}
}
This will take all the root level contents of a folder and put it in the zip file. You will need to implement your own way of getting subfolders and their contents recursively, but that is beyond the scope of this question.
EDIT: Here is a working example with proper folder recursion to select all files even in subdirectories
public void ZipFolder()
{
string strStartPath = #"PATH TO FILES TO PUT IN ZIP FILE";
string strZipPath = #"PATH TO ZIP FILE";
if (File.Exists(strZipPath))
File.Delete(strZipPath);
using (ZipArchive archive = ZipFile.Open(strZipPath, ZipArchiveMode.Create))
{
foreach (FileInfo file in RecurseDirectory(strStartPath))
{
if (!(file.FullName.EndsWith(".TIF", StringComparison.OrdinalIgnoreCase)))
{
var destination = Path.Combine(file.DirectoryName, file.Name).Substring(strStartPath.Length + 1);
archive.CreateEntryFromFile(Path.Combine(file.Directory.ToString(), file.Name), destination);
}
}
}
}
public IEnumerable<FileInfo> RecurseDirectory(string path, List<FileInfo> currentData = null)
{
if (currentData == null)
currentData = new List<FileInfo>();
var directory = new DirectoryInfo(path);
foreach (var file in directory.GetFiles())
currentData.Add(file);
foreach (var d in directory.GetDirectories())
RecurseDirectory(d.FullName, currentData);
return currentData;
}
I already protect the csv files with zip by using the ionic.zip.dll
see the below code
using (ZipFile zip = new ZipFile())
{
TargetFileName = TargetNamePrefix;
OutPutDirectoryPath = TargetLocation + "\\" + TargetNamePrefix + ".zip";
zip.Password = zipFilePassword;
zip.AddFiles(FilePaths, TargetNamePrefix);
zip.Save(OutPutDirectoryPath)
}
here file paths is string[] variable it consists of files(csv/text) Names.
TargetNamePrefix means inside zipfile folder Name.OutPutDirectoryPath means
output directoty with zipfileName.
then How can i Open the those protected files in write mode why because I want to write Datainto the Protected csv file.
You can just extract them using a similar method:
using(ZipFile zip = ZipFile.Read(OutPutDirectoryPath))
{
zip.Password = zipFilePassword;
try
{
zip.ExtractAll(TargetLocation);
}
catch (BadPasswordException e)
{
// handle error
}
}
Update
Access single file entry into a stream without extracting
string entry_name = TargetNamePrefix + ".csv"; // update this if needed
using (ZipFile zip = ZipFile.Read(OutPutDirectoryPath))
{
// Set password for file
zip.Password = zipFilePassword;
// Extract entry into a memory stream
ZipEntry e = zip[entry_name];
using(MemoryStream m = new MemoryStream())
{
e.Extract(m);
// Update m stream
}
// Remove old entry
zip.RemoveEntry(entry_name);
// Add new entry
zip.AddEntry(entry_name, m);
// Save
zip.Save(OutPutDirectoryPath);
}