Executing a batch file from Windows Forms application - c#

I have written a small batch file that copies an exe from solution to the system32 folder.
copy "blah.exe" "%systemroot%/System32"
The batch file works fine and copies the exe if ran from the desktop by double clikcing (placed exe on the desktop as well)
However, I tried doing that from Windows Application by:
Process.Start("sample.bat");
(EXE file and batfile -> Properties -> Output to Copy Always)
The cmd window does come up, but the .exe file is not there in the destination directory. What am I missing here?

in your batch file change path to that particular folder where you have blah.exe, change to the particular drive and then to particular folderlets say your source folder is C:\test then type cd\test in the batch file, it should be something like:
C:
cd\test
copy "blah.exe" "%systemroot%/System32"
or use copy with complete path e.g
copy "C:\test\blah.exe" "%systemroot%/System32"
EDIT:
To copy using CMD try:
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 copy /b blah.exe %systemroot%/System32";
process.StartInfo = startInfo;
process.Start();
Edit 2: Or for batch file
System.Diagnostics.Process.Start("cmd", "/c sample.bat");

Related

Process.Start() results in Access Denied exception despite Full Control for Everyone group

My project output contains an executable called key_gen.exe that I'm trying to run. The executable is not built by the project, but copied in after the fact. With the code below I receive an Access Denied exception.
string key_gen_dir = Environment.CurrentDirectory.Substring(0, Environment.CurrentDirectory.LastIndexOf("\\")) + #"\Scripts\key_gen\";
Process process = new Process();
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.FileName = key_gen_dir + "key_gen.exe";
startInfo.Arguments = String.Format(". {0}", password);
process.StartInfo = startInfo;
process.Start();
The FileName value is correct and works when tested in Command Prompt. I do not want to run the program as an administrator. I have tried enabling UseShellExecute, but I receive a PlatformNotSupportedException. The key_gen_dir and all subfiles and folders have FullControl permissions for the Everyone group. If it's relevant, my project is targetted for .NET Standard 2.0.
I was able to resolve the access denied error by editing the file properties in Windows and adding the ALL APPLICATION PACKAGES group to the file permissions with Read & Execute allowed.

Backup IIS settings with Windows Process

I can backup the settings of IIS with the following commands
//sites
C:\Windows\system32\inetsrv\appcmd.exe list site /config /xml > C:\Temp\iis_config_sites.xml
//apppools
C:\Windows\system32\inetsrv\appcmd.exe list apppool /config /xml > C:\Temp\iis_config_apppool.xml
When I run these commands from the Command Prompt it works fine. The XML files are created. But I wanted to automate this process by executing this command from C# code with System.Diagnostics.Process. For that I use the following code
using (Process process = new Process())
{
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
startInfo.FileName = #"C:\Windows\system32\inetsrv\appcmd.exe";
startInfo.Arguments = #"list site /config /xml > C:\Temp\iis_config_sites.xml";
process.StartInfo = startInfo;
process.Start();
process.WaitForExit();
}
But when I run this code nothing happens. The XML file is not created. But there are no errors and no warnings also. The program that executes this command runs under the Administrator account with Windows Server 2019 and IIS 10. I also tried adding WorkingDirectory, but that did not help either.
I use Process to generate a zipped folders with WinRar and that also works fine.
So if anyone knows what could be the problem that would be great.
The problem is that you are using '>' in the parameters, which is a CMD command to instruct it to write the output of command (appcmd.exe in this case) to specified file path (C:\Temp\iis_config_sites.xml). Which of course doesn't work as the parameter of appcmd.exe.
You have two options:
To use it the following way, which is equivalent of executing the command in CMD:
startInfo.FileName = #"C:\Windows\system32\cmd.exe";
startInfo.Arguments = "/c \"C:\\Windows\\system32\\inetsrv\\appcmd.exe\" list site /config /xml > C:\\Temp\\iis_config_sites.xml";
Note that the /c is a command line option of cmd.exe to execute the rest of parameters as a "command", just as if you entered it into command line window. The rest is just the same command which you typed in the cmd normally.
Use another option provided by appcmd.exe for backing up IIS that avoids the need to redirect output to file. The command is appcmd.exe add backup %backupname%. This command adds a backup of the IIS config and later you can restore it by restore backup $backupname%.

How to reference an exe file stored in visual studio project resource when running cmd.exe using process.start()

I am developing a C# windows form application project. The form contains a button and after the button click event cmd.exe is started using Process.Start() method. The StartInfo.Arguments() contains path to an exe file stored in the project resources folder (I have created a new folder called Resources and another subfolder called SW1. The exe file is inside SW1 folder)
Right now, the exe file is stored in a different location in local computer and I use the full path to refernce the exe file in StartInfo.Argument(). However, when i publish the C# application, I want the exe file will be bundled as a resource. How can I reference the exe file in this case?
private async void button1_Click(object sender, EventArgs e)
{
await RunCMDAsync();
}
private async static Task RunCMDAsync()
{
try
{
using (Process myProcess = new Process())
{
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.FileName = "cmd.exe";
startInfo.Arguments = #"/C cd <path to the exe file on my local computer here> & <name of exe --additional arguments>";
startInfo.UseShellExecute = false;
startInfo.RedirectStandardInput = true;
myProcess.StartInfo = startInfo;
myProcess.Start();
myProcess.WaitForExit();
}
}
catch(Exception ex)
{
Console.WriteLine(ex.Message);
}
}
In the above code, Whenever the cmd.exe process is started, I want to pass two arguments using StartInfo.Arguments()
startInfo.Arguments = #"/C cd <path to the exe file on my local computer here> & <name of exe --additional arguments>";
The first argument is to cd into the folder which contains the exe file
(/C cd <path to the exe file on my local computer here>)
The second argument runs the exe file with some parameters (<name of exe --additional arguments>)
How can I reference the exe file in Resources > SW1 folder after I publish this as a standalone application? Do I need to extract the exe file to a location on the target computer during installing the C# application and use the same code as above or is there a way to directly reference resources folder?
If what you need is to find the directory where your program is running (I'm not sure I understood your problem) then use System.AppDomain.CurrentDomain.BaseDirectory.
string exePath = System.AppDomain.CurrentDomain.BaseDirectory +
"Resources\\SW1\\" + exefilenameWithExtension;

Run a command line process from unity

I am trying to run an external .exe file with argument from unity, this what I have been doing:
ProcessStartInfo startInfo = new ProcessStartInfo("AAA.exe");
startInfo.WindowStyle = ProcessWindowStyle.Normal;
startInfo.Arguments = "MyArgument";
Process.Start(startInfo);
But an error keeps telling me that unity couldn't find the executable file.
How can I add a path or make unity find the executable file?
Advance Thanks.
It appears you may be giving an incorrect Path to your .exe
Try something like this:
string fullPath = Path.Combine(Environment.CurrentDirectory, "/YourSubDirectory/yourprogram.exe");
ProcessStartInfo startInfo = new ProcessStartInfo(fullPath);
startInfo.WindowStyle = ProcessWindowStyle.Normal;
startInfo.Arguments = "MyArgument";
Process.Start(startInfo);
Application Paths in Unity - Dependent on where your .exe is based, this may be of use.
Well, you may need to use a path relative to your unity build.exe's folder in order to make it work
You should either specify the full path or a relative path of the executable.
Check this post for some examples.

C# calling batch file failed to copy dll files to System32 folder

I have created a batch file that copies some dll files into System32 folder.
I ran this batch from my program written in C# code:
string path = #"ABC\install.bat";
ProcessStartInfo procStartInfo = new ProcessStartInfo()
{
UseShellExecute = true,
CreateNoWindow = false,
FileName = "\"" + path + "\"",
//Arguments = "\"" + path + "\""
Verb = "runas"
};
using (Process proc = new Process())
{
proc.StartInfo = procStartInfo;
proc.Start();
}
Everything has worked fine. I got the popup message to confirm the change from Windows 7. The console also proved that the file had been copied:
C:\Program Files\XXX>copy commpro.dll C:\Windows\system32\
1 file(s) copied.
But when I look in System32 folder I couldn't find my dlls there.
It's so strange!
Does anybody occur this issue?
Edit: My question is different with this question: How to write files in C:\Windows\System32 with full permissions
Here I got the popup that allow me to grant permission to write to System32 folder. And the output of "copy" command didn't show "Access Denied" but "Copied".
The problem is why it doesn't contain my dlls while it said "copied" ?
If your app is a 32-bit application, then the file will end up in the %windir%\SysWOW64 folder. See this page on Msdn for more details.
Your 32-bit application should be able to see this file.
I should point out that copying dlls to your system folder is usually a bad idea and should be avoided if at all possible.

Categories