I was wondering whether it is possible to unzip files in c sharp without using open source dll's in .net 4.0 or lower?
I have some VBA code (below) that uses the "Shell" command. Is that also possible from c sharp?
Sub UnzipMe(path)
Dim strDOSCMD As String
Dim filename As String
Dim i As Integer
filename = path + "\test.txt"
strDOSCMD = "unzip -n " + path + "\zipfile.zip -d " + path
'SEND TO DOS
retval = Shell(strDOSCMD, vbHide)
End Sub
This works fine and is very simple but I would like to do it all in c sharp and not mix and match. Surely that should be doable or there should be an equally simple solution?
You can start a process in C# using Process.Start.
Your code can look like (not tested..):
public void UnzipMe(string path){
System.Diagnostics.Process process = new System.Diagnostics.Process();
System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
startInfo.FileName = "cmd.exe";
startInfo.Arguments = "/C unzip -n " + path + "\zipfile.zip -d " + path;
process.StartInfo = startInfo;
process.Start();
//do some extra stuff here
}
For zip stuff consider to use a third party library like sharpziplib I use it with success in many projects.
Take a look to these samples: https://github.com/icsharpcode/SharpZipLib/wiki/Zip-Samples
Related
I have to rename multiple files on my server. For this I make a c# project in visual studio. (side info: this project has to do other stuff too)
Now I try to call a batch file from that project. This batch file has to rename a file using the old and the new filename.
Here is the code from the batch file:
#echo off
set FILENAME_OLD="%~1"
set FILENAME_NEW="%~nx2"
ren %FILENAME_OLD% %FILENAME_NEW%
set error=%errorlevel%
echo %error%
This is the code in my c# project:
process.StartInfo.FileName = location;
process.StartInfo.Arguments = string.Format("\"{0}\" \"{1}\"", oldfilename, newfilename);
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;
process.Start();
result = process.StandardOutput.ReadLine();
As result I always get 1. Which means that "ren" didn't work. What am i doing wrong here?
The filenames are all in a structure like this in my c# project: #"C:\test\test\test.bat"
EDIT:
I came somewhat closer to a solution. The problem was that I cant pass the double quotes as an argument. I need those double quotes as some of my filenames contain spaces.
How can I pass those filenames correctly to that batchfile?
I managed to fix the problem with on a in my opinion 'dirty' way:
//I changed newfilename so it's only the filename with extention and not the full path anymore.
string text = "\"" + oldfilename+ "\"" + " " + "\"" + newfilename;
System.IO.File.WriteAllText(#"c:\test\test.txt", text);
process.StartInfo.FileName = location;
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;
process.Start();
result = process.StandardOutput.ReadLine();
As you can see I wrote the arguments to a txt file so the quotes will be escaped.
The batchfile now is as simple as this:
set /p arguments=<c:\test\test.txt
ren %arguments%
echo %errorlevel%
I'm currently working with reg.exe and I'm creating a process with reg.exe as the Process.FileName.
When I try to execute reg.exe like following
REG EXPORT HKLM\\SOFTWARE\\Intel\\IntelAMTUNS D:\\Backups\\Test.reg
everthing works fine.
But as soon as I try to execute it like this
REG EXPORT HKLM\\SOFTWARE\\Intel\\IntelAMTUNS D:\\Backups\\Backup folder 1\\Test.reg
nothing happens - and I know why! The target path isn't put in quotes. As soon as I do that everything works fine again.
My problem now is that I'm handling all my file and folder paths as instances of DirectoryInfo. When I pass the path with quotes as a string, e.g. like that
DirectoryInfo targetFolder = new DirectoryInfo("\"D:\\Backups\\Backup folder 1\\Test.reg\"")
I instantly receive an exception telling me that the given path's format is not supported.
Is there any way to put the path in quotes and still work with DirecotryInfo?
I really need to put my path in quotes - otherwise the command won't work.
Here's some example code:
DirectoryInfo backupPath = new DirectoryInfo("D:\\Backups\\Backup folder 1\\Test.reg");
Process process = new Process();
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.FileName = "reg.exe";
startInfo.CreateNoWindow = true;
startInfo.Arguments = "REG EXPORT HKLM\\SOFTWARE\\Intel\\IntelAMTUNS " + backupPath.FullName;
process.StartInfo = startInfo;
process.Start();
process.WaitForExit();
When I run this code, nothing happens - nor errors or exceptions. The .reg file itself isn't created either.
When I try to run it like this
DirectoryInfo backupPath = new DirectoryInfo("\"D:\\Backups\\Backup folder 1\\Test.reg\"");
Process process = new Process();
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.FileName = "reg.exe";
startInfo.CreateNoWindow = true;
startInfo.Arguments = "REG EXPORT HKLM\\SOFTWARE\\Intel\\IntelAMTUNS " + backupPath.FullName;
process.StartInfo = startInfo;
process.Start();
process.WaitForExit();
I'm getting a System.NotSupportedException telling me "The given path's format is not supported." But I actually need to put the path in quotes - otherwise the command itself won't work...
You are adding quotes in the wrong place: constructor of DirectoryInfo will strip them anyway to normalize the path, so you can skip adding them:
var backupPath = new DirectoryInfo("D:\\Backups\\Backup folder 1\\Test.reg");
You can force quotes around the path when you add backupPath.FullName to the arguments, like this:
startInfo.Arguments = "REG EXPORT HKLM\SOFTWARE\Intel\IntelAMTUNS \"" + backupPath.FullName + "\"";
I've looked through the internet on how winrar's command line parameters work, and this is what I have so far
void LOCK(string fld, string pw)
{
Process p = new Process();
p.StartInfo.FileName = #"C:\Program Files\WinRAR\WinRAR.exe";
p.StartInfo.Arguments = "rar a -p" + pw + " PL_LOCKED_ARCHIVE.rar " + fld;
p.Start();
}
void UNLOCK(string fld, string pw)
{
Process p = new Process();
p.StartInfo.FileName = #"C:\Program Files\WinRAR\WinRAR.exe";
p.StartInfo.Arguments = "unrar x -p" + pw + " PL_LOCKED_ARCHIVE.rar";
p.Start();
}
However it doesn't seem to create any archive anywhere, with a test folder being C:\PicsAndStuff
The StartInfo you define results in running WinRAR.exe with command line:
C:\Program Files\WinRAR\WinRAR.exe unrar x -p pw PL_LOCKED_ARCHIVE.rar
That is of course wrong as you do not want to run WinRAR.exe with first argument being a reference to console version Rar.exe or UnRAR.exe. The result is most likely an error message because of invalid command rar respectively unrar as the first argument must be a or x for WinRAR.exe.
So first of all you need to correct StartInfo:
void LOCK(string fld, string pw)
{
Process p = new Process();
p.StartInfo.FileName = #"C:\Program Files\WinRAR\Rar.exe";
p.StartInfo.Arguments = "a -p" + pw + " PL_LOCKED_ARCHIVE.rar " + fld;
p.Start();
}
void UNLOCK(string fld, string pw)
{
Process p = new Process();
p.StartInfo.FileName = #"C:\Program Files\WinRAR\UnRAR.exe";
p.StartInfo.Arguments = "x -p" + pw + " PL_LOCKED_ARCHIVE.rar";
p.Start();
}
Further all commands and switches of console version Rar.exe are briefly explained when simply running Rar.exe without any parameter in a command prompt window. Also UnRAR.exe outputs a brief help if executed without any parameter.
Last but not least there is a complete manual for Rar.exe which of course can also extract files and folders from a RAR archive which makes additional usage of UnRAR.exe useless. The manual is text file Rar.txt in program files folder of WinRAR which you should read from top to bottom. I suggest to build the command line while reading it and test the command line first from within a command prompt window.
Note 1:
Rar.exe is shareware. Only UnRAR.exe is freeware.
Note 2:
GUI version WinRAR.exe supports more than console version Rar.exe and therefore the list of switches differ slightly. Complete documentation for WinRAR.exe can be found in help of WinRAR opened with Help - Help Topics or pressing key F1. Open in help on tab Contents the item Command line mode and read. WinRAR.exe is also shareware.
You need to encrypt both file data and headers.
According to Documentation (Command line mode > Switches > "-hp[pwd] - encrypt both file data and headers"):
This switch is similar to -p[p], but switch -p encrypts only file data
and leaves other information like file names visible. This switch
encrypts all sensitive archive areas including file data, file names,
sizes, attributes, comments and other blocks, so it provides a higher
security level.
This is how you can access to it using command line:
Syntax: rar a -hp[MyPassword] -r [filepath] [folderpath]
"C:\Program Files\WinRAR\WinRAR.exe" a -hp12345678 -r d:\zipProject d:\Project
C# Code:
void LOCK(string fld, string pw)
{
Process p = new Process();
p.StartInfo.FileName = #"C:\Program Files\WinRAR\WinRAR.exe";
p.StartInfo.Arguments = "rar a -hp" + pw + " PL_LOCKED_ARCHIVE.rar " + fld;
p.Start();
}
so I have a small chunk of code that detects files in a folder and systematically zips them after they become a certain age. I'm now working on a piece of code to unzip files of a certain date-range at user request for use in the software.
My issue is that the command-line string to zip files works great, but the unzip does not... below is the excerpt of code showing how I unzip, please let me know what I should do differently to ensure unzipping. thanks!
private void UnZipFile()
{
if (myRecord == null)
{
if (File.Exists(zipInfo.FullName))
{
Process LogUnzipper = new Process();
//32-bit system
if (File.Exists("c:\\Program Files\\WinZip\\WZZIP.exe"))
{
//WZZIP.exe being the WinZip executable
LogUnzipper.StartInfo.FileName = "c:\\Program Files\\WinZip\\WZZIP.exe";
}
//64-bit system
else if (File.Exists("c:\\Program Files (x86)\\WinZip\\WZZIP.exe"))
{
//WZZIP.exe being the WinZip executable
LogUnzipper.StartInfo.FileName = "c:\\Program Files (x86)\\WinZip\\WZZIP.exe";
}
//here is where I think I'm screwing up something..
string action = "-e " + "\"" + zipInfo.FullName + "\"" + " \"" + zipInfo.DirectoryName + "\"";
//happen in background
LogUnzipper.StartInfo.CreateNoWindow = true;
LogUnzipper.StartInfo.UseShellExecute = false;
LogUnzipper.StartInfo.Arguments = action;
LogUnzipper.Start();
while (!LogUnzipper.HasExited)
{
LogUnzipper.WaitForExit(500);// 1/2 sec
}
//adding break point at this line yields no unzipped Log file :(
}
...
my thoughts are that I'm somehow calling the cmd wrong in string action? even though if I test it in a windows command prompt that's correct formatting.
***it should be noted that ZipInfo.FullName is something along the ex: "C:\Users\16208\Software\Beta\logs\6_2013\Log_10AM_to_11AM.zip" as far as formmat, so I am giving an accurate path to the zipped Item.
You can use some free and open-source .Net library for zipping and unzipping (as SLaks suggested). For example DotNetZip.
using (ZipFile decompress = ZipFile.Read(ZipFilePath))
{
foreach (ZipEntry e in decompress)
{
e.Extract(TargetPath, ExtractExistingFileAction.OverwriteSilently);
}
}
As for your code, waiting half a second may not be enough for unzipping to complete. Also you can try running your unzip command in a command line and check the output.
If you have WinZip installed try this:
System.Diagnostics.ProcessStartInfo procStartInfo = new System.Diagnostics.ProcessStartInfo("cmd", #"/c start winzip32 -e " + fileName + #" C:\SomeDirectory");
rocStartInfo.UseShellExecute = false;
System.Diagnostics.Process proc = new System.Diagnostics.Process();
proc.StartInfo = procStartInfo;
proc.Start();
proc.WaitForExit();
Where fileName is the full path to your *.rar file.
I need to run a legacy app that is run from a cmd window using the Process class.
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.FileName = "cmd.exe";
startInfo.Arguments = "/C \"C:\\MySys\\My2Com.exe –r " + Parameters.FullPath;
startInfo.CreateNoWindow = true;
startInfo.UseShellExecute = false;
try
{
// Start the process with the info we specified.
// Call WaitForExit and then the using statement will close.
using (Process exeProcess = Process.Start(startInfo))
{
exeProcess.WaitForExit();
}
}
catch (Exception e)
{
string sMsg = "Error copying the files to " + Parameters.FullPath + ".";
HandleErrorMsg(e, sMsg);
return;
}
The process My2Com.exe should run in the background, however, I consistantly get the message that a file, used when run from the cmd line with different flags, is missing. If I run the command as indicated in a cmd window, C:\MySys\My2Com.exe –r FullyQualPath, it works as expected. I have tried several different ways to set up the Process class without success.
Any suggestions would be appreciated.
Thank you.
Try this one -
startInfo.Arguments = "/C \"C:\\MySys\\My2Com.exe –r\" " + Parameters.FullPath;
will this work if you do the following
startInfo.Arguments = #"/C "C:\MySys\My2Com.exe /r" " + Parameters.FullPath +"\"";
keep in mind that if there are spaces in the filepath you need to wrap around """ for example if the filepath were like this #"""C:\Wolf Lair\WorkDeskTemp\"
notice the # and the """
you need to append the ending quotes to the string +"\""; after Parameters.FullPath;
You know why is it not working because
You haven't completed quotes
Try this:-
startInfo.Arguments = "/C \"C:\\MySys\\My2Com.exe\" –r \"" + Parameters.FullPath+"\"";
startInfo.Arguments = #"/C ""C:\MySys\My2Com.exe –r """ + Parameters.FullPath + "\"";
Also, see Sending commands to cmd prompt in C#. I'd recommended using some of the code from my answer there so that you can intercept the standard output and standard error to see what you're getting.