How to execute multiple batch commands inside a C# forms project - c#

So i want to run a bunch of different batch commands that do different things. Currently my software works by running the .bat file that is included with the software, but i want to simply remove the syntax from the .bat file and integrate it inside my software so when i click the button it runs the code directly and not launch the .bat file.
Problem is how do i run multiple batch commands, not only that but also wait for each command to finish running just like batch does?
Overall i wanna execute batch commands like stop services, delete registry files, delete folders and software.
PS : this is a C# Forms application ( so i click one button and it all executes )
Currently i have : with examples
var proc1 = new ProcessStartInfo();
string stopservices =
"net stop \"serviceexample1\"" +
"net stop \"serviceexample2\"";
string deleteregistry =
"REG ADD HKEY_LOCAL_MACHINE\\SYSTEM\\EXAMPLE\\.. / t REG_DWORD / v Start / d 0x00000004 / f" +
"rem REG ADD HKEY_LOCAL_MACHINE\\SYSTEM\\EXAMPLE\\.. /t REG_SZ /v Start /d 5 /f";
string deletesoftware =
"MsiExec.exe /X{EXAMPLESOFTWARE} /quiet" +
"MsiExec.exe /X{EXAMPLESOFTWARE} /quiet";
string removedirectories =
"rmdir /s /q C:\\Program Files\\EXAMPLE" +
"rmdir /s /q C:\\Program Files(x86)\\EXAMPLE";
proc1.UseShellExecute = true;
proc1.WorkingDirectory = #"C:\Windows\System32";
proc1.FileName = #"C:\Windows\System32\cmd.exe";
proc1.Verb = "runas";
proc1.Arguments = "/c " + stopservices + deleteregistry + deletesoftware + removedirectories;
proc1.WindowStyle = ProcessWindowStyle.Normal;
System.Diagnostics.Process processwait = System.Diagnostics.Process.Start(proc1);
while (!processwait.HasExited && processwait.Responding)
{
System.Threading.Thread.Sleep(100);
}
I have tried to look in internet how to run batch code directly from c# and the only way i found how to do it was using a string. But i dont think that will wait for each command to finish to begin the next one because a string is just a line of text so it will take it all at once.
I also wanna make sure that when the code was successfully executed the command prompt will stay untill i close it ( like pause in batch ).
Sorry if this is a simple question, i am a student with less then half a year experience in c#

Related

How do i include batch files inside of my .exe Instead of needing them in the folder the .exe is located in

So been searching or the web but can't seem to find an answer that has helped me. I have been looking for almost a week now.
I created a program in vs, alongside with some batch files. The Batch files run great by themselves and through the debug/release when including them in the folder with the .exe.
My problem is I want to be able to ONLY have the .exe file from my release and it still work.
Is there a way i can build these files inside the .exe? I have tried using c# to write my console commands instead of including seperate batch files. But im pretty new to c# and i get nothing but errors with the commands i want to run/if i run to many lines.
I would much rather have just c# instead of including the batch files but that I can't seem to figure out a solution to either.
Any help would be appreciated.
This is me currently calling batch files which works just fine. Again, if there is a way to just write this in c# instead of calling a batch file I would be happy to learn.
Process process = new Process();
ProcessStartInfo psi = new ProcessStartInfo();
psi.CreateNoWindow = false;
psi.Verb = "runas";
psi.FileName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + #"/" + "undo.bat";
psi.UseShellExecute = true;
process.StartInfo = psi;
_ = process.Start();
process.WaitForExit();
I'm starting CyberSecurity soon and am playing around with some Security stuff on my computer. Below is a sample code from my batch file to enable Security Protocols. If anything how would i write this in c#?
echo ...
echo Enabling Windows Firewall
netsh advfirewall set allprofiles state on
echo Enalbing HyperVisor
bcdedit /set hypervisorlaunchtype auto
echo Enabling UAC
%windir%\System32\reg.exe ADD HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System /v EnableLUA /t REG_DWORD /d 1 /f
echo.
echo.
echo Your Computer will now be restarting for changes to take effect!
timeout 10
shutdown /r /t 001
What you can do is include the batchfiles as embedded resources in your project. Then read them and then execute them.
to include them as embedded resources example...
add them to your project.
right click and go to properties
select embedded resource
then to extract...
Write file from assembly resource stream to disk
you can then write the file to disk and create process on it. or there is a way to execute cmd.exe without writing the file to disk but this is a little complicated so the best way is to just write to disk.
Execute BATCH script in a programs memory
I followed the guide given above and a few others to get my solution to work. Embed the resource that's in your solution, then I used the following code to pretty much create the functions of being able to write it.
private static void Extract(string nameSpace, string outDirectory, string internalFilePath, string resourceName)
{
Assembly assembly = Assembly.GetCallingAssembly();
using (Stream s = assembly.GetManifestResourceStream(nameSpace + "." + (internalFilePath == "" ? "" : internalFilePath + ".") + resourceName))
using (BinaryReader r = new BinaryReader(s))
using (FileStream fs = new FileStream(outDirectory + "//" + resourceName, FileMode.OpenOrCreate))
using (BinaryWriter w = new BinaryWriter(fs))
w.Write(r.ReadBytes((int)s.Length));
}
Here is what I used to save, execute then delete the file.
Extract("nameSpace", "outDirectory", "internalFilePath", "resourceName");
Process process = new Process();
ProcessStartInfo psi = new ProcessStartInfo();
psi.CreateNoWindow = false;
psi.Verb = "runas";
psi.FileName = #"C:/" + "resourceName";
psi.UseShellExecute = true;
process.StartInfo = psi;
_ = process.Start();
process.WaitForExit();
System.Threading.Thread.Sleep(10);
if ((System.IO.File.Exists(psi.FileName)))
{
System.IO.File.Delete(psi.FileName);
}
Keep in mind im new when it comes to this so im sure there is a better way of writing it, but this worked for me!

How to combine multiple gz files into one from Process in C# program when one is missing EOF

I have multiple .gz files in a directory (2 or more), with at least one file missing the end of file marker. Our C# process is unable to read the file with missing end of file, but since they are coming from a third party we do not have control over how they are created.
As such, we've been running the following Linux command manually:
cat file1.gz file2.gz > newFile.gz
In order to automate this, I am looking for a way to leverage the Process functionality in C# to trigger the same command, but this would only be available in Cygwin or some other Linux shell. In my example, I'm using git bash but it could be Powershell or Cygwin or any other available Linux shell that runs on a Windows box.
The following code does not fail, but it does not work as expected. I am wondering if anyone has recommendations about how to do this or any suggestions on a different approach to consider?
Assume that the working directory is set and initialized successfully, so the files exist where the process is run from.
Process bashProcess = new Process();
bashProcess.StartInfo.FileName = #"..\Programs\Git\git-bash.exe";
bashProcess.StartInfo.UseShellExecute = false;
bashProcess.StartInfo.RedirectStandardInput = true;
bashProcess.StartInfo.RedirectStandardOutput = true;
bashProcess.Start();
bashProcess.StandardInput.WriteLine("cat file1.gz file2.gz > newFile.gz");
bashProcess.StandardInput.WriteLine("exit");
bashProcess.StandardInput.Flush();
.
.
.
bashProcess.WaitForExit();
My expectation is that newFile.gz is created
I was able to find a solution to my problem using a DOS command, and spawning a cmd Process from CSharp.
My code now looks like this, avoids having to launch a linux-based shell from Windows, and the copy command in windows does the same thing as cat:
Process proc = new Process();
proc.EnableRaisingEvents = false;
proc.StartInfo.FileName = "cmd";
proc.StartInfo.Arguments = #"/C pushd \\server\folder && copy *.txt.gz /b
combined.gz";
proc.StartInfo.RedirectStandardOutput = true;
proc.StartInfo.RedirectStandardError = true;
proc.StartInfo.UseShellExecute = false;
proc.Start();
proc.WaitForExit();
System.Threading.Thread.Sleep(2000);
string line = proc.StandardOutput.ReadLine();
while (line != null)
{
output.Append(line);
line = proc.StandardOutput.ReadLine();
}

Call to Process works fine with Debug, but it doesn't work in the installed application

I am developing a Windows Form program that has callings to ffmpeg library through the class Process.
It works fine when I run it with the Debug in Visual Studio 2013. But when I install the program and I invoke the operation that call to the ffmpeg Process, it doesn't work. The cmd screen appears an disappears and nothing happens.
I have tried to know what can be happening getting a log file with the output of ffmpeg, in case it was a problem in the ffmpeg libraries. However, after executing it the log is empty, what means that the ffmpeg command has not been executed.
Can someone help me, please?
The code is this:
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.FileName = "cmd.exe";
startInfo.Arguments = "/c " + ffmpegPath + " " + commandArguments;
using (Process processTemp = new Process())
{
processTemp.StartInfo = startInfo;
processTemp.EnableRaisingEvents = true;
processTemp.Start();
processTemp.WaitForExit();
}
I am invoking to cmd.exe (not directly ffmpeg.exe) because in the arguments sometimes there can be a pipe (that is why the command starts with "/c").
Are you sure this isn't a privileges issue when trying to execute the cmd.exe (e.g you need administrator privileges)
try adding
startInfo.Verb = "runas";
Paul
Hmm its not a path issue with spaces in file/directory names is it? For ffmpegPath or one of your command parameters (if a file path). Surround all file paths with ' like below.
Try surrounding any file paths with '
startInfo.Arguments = "/c '" + ffmpegPath + "' " + commandArguments;
Also you could try adding /K to the cmd command call to stop if from closing the command prompt when it finishes. It might tell you the error before it closes the window but you wont see it if it closes so quickly
Good luck :)
Paul

Self-Updating, Download, Extract, and Replace Exe

I'm using Visual Studio 2015, C#, WPF.
I'm trying to give MyProgram.exe the ability to easily update itself.
I have code that downloads the file MyProgram.7z to %UserProfile%\AppData\Local\Temp\.
From the 7z it extracts MyProgram.exe to the currently running MyProgram.exe's directory.
While the 7-Zip extraction is starting, the program closes itself to allow overwriting the exe.
// AppData Temp Directory
string tempDir = System.IO.Path.GetTempPath();
// MyProgram.exe Current Directory
string currentDir = Directory.GetCurrentDirectory().TrimEnd('\\') + #"\";
// ...
//
// Download Code Here
// Saves MyProgram.7z to AppData Temp
//
// ...
// Unzip MyProgram.7z
// Overwrite MyProgram.exe
//
using (Process extract = new Process())
{
extract.StartInfo.UseShellExecute = false;
extract.StartInfo.CreateNoWindow = false;
extract.StartInfo.RedirectStandardOutput = true;
extract.StartInfo.FileName = "7z.exe";
extract.StartInfo.Arguments = "-r -y e " + "\"" + tempDir + "MyProgram.7z" + "\"" + " -o\"" + currentDir + "\"" + " *";
// 7z.exe -r -y e "C:\Users\Matt\AppData\Local\Temp\MyProgram.7z" -o"C:\Program Files\MyProgram\" *
extract.Start();
}
// Exit Program
// 7-Zip will continue to run in the background after MyProgram.exe has exited
//
Environment.Exit(0);
I've tested it and it appears to work.
Is there a better way of doing this? Is there anything that can go wrong with this way? I'like to have it within the program and not in a separate helper program. I also need to use 7z.exe in this case.
Is there a way to instead launch cmd and chain commands into it like timeout 5 && 7z.exe ... and have it relaunch the program after extraction?
You may want to check out Squirrel. It is an open-source library that completely manages both installation and updates of desktop Windows applications.
There is a getting starting guide available on GitHub: https://github.com/Squirrel/Squirrel.Windows/blob/master/docs/getting-started/0-overview.md.
There is also the ClickOnce deployment technology from Microsoft: https://msdn.microsoft.com/en-us/library/142dbbz4(v=vs.90).aspx.
No reason to reinvent the wheel.
Instead of launching 7z process directly you can also:
launch cmd /c process that will wait 5 seconds, then unzip, the relaunch the app
shutdown yourself
cmd /c timeout 5 & [your unzip command] & MyProgram.exe
PS. & is used to execute multiple commands one after another

CommandPrompt command not run after release the build C# application

I am using a command of a Command Prompt in my application. Application able to run and execute that command of a Command Prompt when I run my application using Visual Studio while debugging but when I take my application's executable file(.exe) and save in my pc drive and then run the file it skips the Command Prompt Command. I research for the topic and get this :
CMD command not running in console
but no success.
My code :
Process process = new Process();
process.StartInfo.FileName = #"cmd.exe";
process.StartInfo.WorkingDirectory = sentencesList;
process.StartInfo.Arguments = "/C findstr /V /I \"" + ListOfSomeWords + "\" " + sentencesList+ ">" + filteredList;
process.Start();
process.WaitForExit();
process.Close();
process.Dispose();
Command remove the sentence/line from a text file(sentenceList) which contains a word(ListOfSomeWords) and make a another text file(filteredList) which contains only those line which not contains any of word specify in ListOfSomeWords.
You are not escaping filteredList with quotes. If it contains a space, then it could not be interpreted correctly by cmd.exe .
Also make sure that you are setting WorkingDirectory to an existing directory path(variable name file_path looks suspicious).

Categories

Resources