Passing parameters to exe from ini file - c#

I'm writing a program to launch a project.
Please tell me how to transfer parameters from such an ini file to exe?
[Data]
User = "Test"
UID = 1234
[Path]
Dir = E:\Test
Exe = test.exe
So I try to assign them
process.StartInfo.FileName = BasePath + "\\Loader.exe";
process.StartInfo.Arguments = Resources.Start;
process.StartInfo.WorkingDirectory = BasePath;
Please tell me how to implement this?
The ini file must be transferred, it does not accept a simple line. Or I am doing something wrong.

If I understand you well, this code should work
(replace "Loader.exe" and "inifile.ini" with proper names of your files):
ProcessStartInfo psi = new ProcessStartInfo(BasePath + "\\Loader.exe");
psi.Arguments = BasePath + "\\inifile.ini";
psi.WorkingDirectory = BasePath;
try
{
Process p = Process.Start(psi);
}
catch (Exception ex)
{
MessageBox.Show("Error:\n" + ex.InnerException, "Run Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}

Related

Fail to execute a specific cmd batch file in C#

I'm using Process to execute a batch file which will generate certificate file.
The code works great when I execute other file (which contains openssl command). But when I execute a file which contains keytool command, it executed, but no file was generated.
I've:
Set UseShellExecute true.
Set WaitForExit(-1) and find the return was true, so it did executed.
I clicked that batch file manually, and the file generates right away, so the command was fine :(
BTW I'm using .Net Core MVC.
I can't find any error code anywhere, so I'm at my wits' end now.
Does anyone has a clue? Any help would be very appriciated!
success code(openssl):
I generate a p12 file (a certificate format) in that folder first, and it works fine.
private string Gen_P12(string domain, string pwd)
{
//generate folder
string folder = #"D:\Temp\";
if (!Directory.Exists(folder))
Directory.CreateDirectory(folder);
//generate bat(p12)
string bat = "openssl.exe pkcs12 -export -inkey " + domain + ".key -in " + domain + ".cer -out " + domain + ".p12 -password pass:" + pwd +"\r\n";
//download in folder
var path = Path.Combine(folder, domain + "_P12.bat");
using (FileStream fs = System.IO.File.Create(path))
{
byte[] content = new UTF8Encoding(true).GetBytes(bat);
fs.Write(content, 0, content.Length);
}
Thread.Sleep(500);
//execute
ProcessStartInfo myBat = new ProcessStartInfo();
string name = domain + "_P12.bat";
myBat.FileName = name;
myBat.WorkingDirectory = folder;
myBat.UseShellExecute = true;
//Process.Start(myBat);
Process p = Process.Start(myBat);
p.WaitForExit(-1);
return folder;
}
fail code(keytool):
Trying to use that P12 file and keytool command to generate a keystore (also a certificate format) but fail.
private string Gen_KS(string domain, string folder, string CA_domain, byte[] cer, string pwd)
{
//generate bat
string bat = "keytool -importkeystore -srckeystore " + domain + ".p12 -srcstoretype PKCS12 -srcstorepass " + pwd + " -destkeystore " + domain + ".keystore -storepass " + pwd + "\r\n";
var path = Path.Combine(folder, domain + "_KS.bat");
using (FileStream fs = System.IO.File.Create(path))
{
byte[] content = new UTF8Encoding(true).GetBytes(bat);
fs.Write(content, 0, content.Length);
}
Thread.Sleep(700);
//execute
ProcessStartInfo myBat = new ProcessStartInfo();
myBat.WorkingDirectory = folder;
string name = domain + "_KS.bat";
myBat.FileName = name;
myBat.UseShellExecute = true;
Process p = Process.Start(myBat);
var a = p.WaitForExit(-1);
string route = folder + domain + ".keystore";
return route;
}
Thanks!
Thanks to #user9938, I solved the problem!
1. Brief conclusion:
I need to process the bat as administrator.
(And I still don't get why only do the keytool command needs administrator rights)
2. Find the errors: (How to apply StanderError when UseShellExecute=true)
In fact we don't have to set it true to execute commands.
Try this (replace execute section):
Process process = new Process();
try
{
process.StartInfo.UseShellExecute = false;
process.StartInfo.CreateNoWindow = true;
process.StartInfo.RedirectStandardInput = true;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardError = true;
process.StartInfo.FileName = "cmd.exe";
process.Start();
process.StandardInput.WriteLine(bat); //command string, not the bat file
process.StandardInput.AutoFlush = true;
process.StandardInput.WriteLine("exit");
StreamReader reader = process.StandardError;
string curLine = reader.ReadLine();
reader.Close();
process.WaitForExit();
process.Close();
}catch (Exception e){}
Check the value of curLine through Breakpoints, the error message was: "'keytool' is not recognized as an internal or external command, operable program or batch file".
3. How to solve it:
Just set the Verb attribute as "runas".
//execute
ProcessStartInfo myBat = new ProcessStartInfo();
myBat.WorkingDirectory = folder;
string name = domain + "_KS.bat";
myBat.Verb = "runas";
myBat.FileName = name;
myBat.UseShellExecute = true;
Process p = Process.Start(myBat);
var a = p.WaitForExit(-1);
Done! Thank you user9938<3

How can I take ownership of a file in c# using takeown or icacls?

I know there are other posts on the matter but none have presented me with a working solution.
I'm trying to take ownership of files under C:\Windows\Media so I can replace them with my own. Currently I've been trying to do that by running either takeown or icacls in CMD, but neither seem to work. The takeown method actually returns success from CMD but I still get access denied when trying to delete the file. With the icacls method I get "the handle is invalid" and still get access denied.
The program is running as administator fyi.
And also in the icacls method changing Environment.Username to "Administrators" doesn't change anything.
Any help is appreciated!
Here is the code for the takeown method:
string[] soundFiles;
soundFiles = Directory.GetFiles(#"C:/Windows/Media", "*.wav");
//string cmdargs = #"/c takeown /F C:\Windows\Media";
string shortcmdargs = #"/c takeown /F ";
//Process.Start("CMD.exe", cmdargs);
string output = "null";
foreach(string file in soundFiles)
{
try
{
Process p = new Process();
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.FileName = "cmd.exe";
p.StartInfo.Arguments = shortcmdargs + #"C:\Windows\Media\" + Path.GetFileName(file);
p.Start();
output = p.StandardOutput.ReadToEnd();
System.IO.File.Delete(file);
System.IO.File.Copy("neco.wav", file);
}
catch(Exception exce)
{
MessageBox.Show("Output: " + output + "\neException: " + exce);
}
}
And here is what I get when running it:
Here is the code for the icacls method:
string[] soundFiles;
soundFiles = Directory.GetFiles(#"C:/Windows/Media", "*.wav");
string cmdargs = #"/c takeown /F C:\Windows\Media";
string shortcmdargs = #"/c takeown /F ";
Process.Start("CMD.exe", cmdargs);
string output = "null";
foreach(string file in soundFiles)
{
try
{
Process p = new Process();
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.FileName = "cmd.exe";
p.StartInfo.Arguments = #"/c icacls " + #"C:\Windows\Media\" + Path.GetFileName(file) + " /grant " + Environment.UserName + ":(OI)(CI)F /T";
p.Start();
output = p.StandardOutput.ReadToEnd();
System.IO.File.Delete(file);
System.IO.File.Copy("neco.wav", file);
}
catch(Exception exce)
{
MessageBox.Show("Output: " + output + "\neException: " + exce);
}
}
And here is what I get with it:

Converting XSD into .cs class

I know this may seem to be a duplicated question but I highly doubt it.
I am currently making a Windows Form application where the user can select an XSD file using the OpenFileDialog
Once the XSD is uploaded/selected I want it to create a .cs file from it using the default developer XSD tool.
But for some reason, it just opens the selected XSD file in notepad(?)
I've tried to comment the code to give it some sense.
//Filter only .xsd files
ofd.Filter = "XSD|*.xsd";
if (ofd.ShowDialog() == DialogResult.OK)
{
//Read file name
string File = ofd.FileName;
string z = ofd.InitialDirectory;
//Start making commands for in the CMD
//Change directory to the folder where the Dev Command prompt is located
string changeDirectory = #"cd C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\Tools\";
//Open the Dev CMD
string bat = "VsDevCmd";
//Change folder to our test folder
string cd = #"cd C:\Users\Pierre\Desktop\testxsd";
//execute xsd /c *selected file* /c is used to create the .cs file.
string command = #"xsd /c " + File;
//Combine the commands into 1 line.
string x = cd + "&" + command;
string xyz = changeDirectory + "&" + bat + "&" + x;
//print the outcome -> When I copy paste this into CMD the .cs file is generated
Console.WriteLine(xyz);
ProcessStartInfo oInfo = new ProcessStartInfo(Environment.ExpandEnvironmentVariables(#"C:\WINDOWS\system32\cmd.exe"), xyz);
oInfo.UseShellExecute = false;
oInfo.ErrorDialog = false;
oInfo.CreateNoWindow = true;
oInfo.RedirectStandardOutput = true;
try
{
Process p = System.Diagnostics.Process.Start(oInfo);
System.IO.StreamReader oReader2 = p.StandardOutput;
string sRes = oReader2.ReadToEnd();
oReader2.Close();
// sRes now contains the output from xsd.exe
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
So, as you can see in the comments, when I copy paste the console.writeline(xyz) into CMD it got properly executed and the .cs file is generated as it should.
However, when I just launch this code it opens the selected xsd in notepad.
Literally no idea what could be wrong
You are kind of taking the very long panoramic route when there is actually a very quick one... As #PatrickHofman stated in the comments use xsd directly...
To do this, open the Visual Studio command prompt, and write where xsd to find exact path of xsd executable.
Then start a process using xsd from the path you found and the various options ie. /c and filename.
using System.Diagnostics;
...
FileInfo fi = new FileInfo(ofd.FileName);
Process process = new Process();
process.StartInfo.FileName = xsdPath;
process.StartInfo.Arguments = "/c " + fi.FullName;
process.StartInfo.WorkingDirectory = fi.DirectoryName;
process.Start();
//wait for exit if needed...
process.WaitForExit();
If for some reason this is not working, capture the output from the command by doing this before process.Start():
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;
process.OutputDataReceived +=
(sender, args) => Console.WriteLine("received output: {0}", args.Data);
process.BeginOutputReadLine();
I think you should use the XmlSchemaClassGenerator package for this (Nuget). That way you wont have to do all the process juggling yourself.
Example from GitHub readme:
var generator = new Generator
{
OutputFolder = outputFolder,
Log = s => Console.Out.WriteLine(s),
GenerateNullables = true,
NamespaceProvider = new Dictionary<NamespaceKey, string>
{
{ new NamespaceKey("http://wadl.dev.java.net/2009/02"), "Wadl" }
}
.ToNamespaceProvider(new GeneratorConfiguration { NamespacePrefix = "Wadl" }.NamespaceProvider.GenerateNamespace)
};
generator.Generate(files);

Open a PDF file from C#.NET using Impersonate

I have a folder on the server containing pdf files(Windows Server 2008 R2 Enterprise). I have to open the folder with the authorized user account and display the pdf file in the browser. The user has full control permissions on the folder and is a member of the Administrator group.
Bellow code works from my local as it opens the pdf file from the folder located in the server in Adobe Reader. But on the server the process does not start(Adobe Reader does not open) and no exception occurs. Most of the forums say that turning off UAC will help, but I don't want to do it, because of security reasons.
How can I deal that issue? Please help.
try
{
WindowsIdentity wi = new WindowsIdentity(#"user_name#DOMAIN");
WindowsImpersonationContext ctx = null;
try
{
ctx = wi.Impersonate();
// Thread is now impersonating you can call the backend operations here...
Process p = new Process();
p.StartInfo = new ProcessStartInfo()
{
CreateNoWindow = true,
Verb = "open",
FileName = ConfigurationManager.AppSettings["mobil"] + "\\" + prmSicilNo + "_" + prmPeriod.ToString("yyyyMM") + ".pdf",
};
p.Start();
}
catch (Exception ex)
{
msj = ex.Message;
}
finally
{
ctx.Undo();
}
return msj;
}
catch (Exception ex)
{
return msj + "Error: " + ex.Message;
}
Try to execute your .exe with Run as Adminstrator on the server.If it works properly then add the below code:
p.StartInfo.Verb = "runas";
#Chintan Udeshi Thank you for you quick answer. I can run the AcroRd32.exe by Run as Administrator but when I tried with runas I got the error which says; "No application is associated with the specified file for this operation".
I also tried to place absolute Acrobat Reader Path, but it still didn't work. Any idea?
p.StartInfo = new ProcessStartInfo(#"C:\Program Files (x86)\Adobe\Reader 10.0\Reader\AcroRd32.exe")
{
CreateNoWindow = true,
Verb = "runas",
FileName = ConfigurationManager.AppSettings["mobil"] + "\\" + prmSicilNo + "_" + prmPeriod.ToString("yyyyMM") + ".pdf", // "c:\\pdf\\",
};

How to create a RAM Disk with imdisk and C#?

I'm trying to create a RAM Directory via imdisk in C#. Since the cmd command is something like: imdisk -a -s 512M -m X: -p "/fs:ntfs /q /y"
I looked up how to process cmd commands with C# and found several hints regarding ProcessStartInfo(). This class works almost the way I intend it to, but since imdisk needs administrator priviliges I'm kinda stuck. Even though the code block is executed without exceptions, I don't see any new devices within the Windows Explorer.
try
{
string initializeDisk = "imdisk -a ";
string imdiskSize = "-s 1024M ";
string mountPoint = "-m "+ MountPoint + " ";
string formatHdd = "-p '/fs:ntfs /q /y' ";
SecureString password = new SecureString();
password.AppendChar('0');
password.AppendChar('8');
password.AppendChar('1');
password.AppendChar('5');
ProcessStartInfo procStartInfo = new ProcessStartInfo();
procStartInfo.UseShellExecute = false;
procStartInfo.CreateNoWindow = true;
procStartInfo.RedirectStandardError = true;
procStartInfo.FileName = "cmd";
procStartInfo.Verb = "runas";
procStartInfo.UserName = "Admin";
procStartInfo.Password = password;
procStartInfo.Arguments = initializeDisk + imdiskSize + mountPoint + formatHdd;
Process.Start(procStartInfo);
catch (Exception objException)
{
Console.WriteLine(objException);
}
I hope someone can give me a little hint, right now I'm out of ideas.
Well I solved my problem in a different way. Somehow it seems that imdisk didn't format the new RamDisk the way it should and therefor no disk were created. As soon as I deleted the formatting option the disk is created and needs to be formatted. Therefore I started another process and used the cmd command "format Drive:"
For anyone who is interested, my solution is as follows:
class RamDisk
{
public const string MountPoint = "X:";
public void createRamDisk()
{
try
{
string initializeDisk = "imdisk -a ";
string imdiskSize = "-s 1024M ";
string mountPoint = "-m "+ MountPoint + " ";
ProcessStartInfo procStartInfo = new ProcessStartInfo();
procStartInfo.UseShellExecute = false;
procStartInfo.CreateNoWindow = true;
procStartInfo.FileName = "cmd";
procStartInfo.Arguments = "/C " + initializeDisk + imdiskSize + mountPoint;
Process.Start(procStartInfo);
formatRAMDisk();
}
catch (Exception objException)
{
Console.WriteLine("There was an Error, while trying to create a ramdisk! Do you have imdisk installed?");
Console.WriteLine(objException);
}
}
/**
* since the format option with imdisk doesn't seem to work
* use the fomat X: command via cmd
*
* as I would say in german:
* "Von hinten durch die Brust ins Auge"
* **/
private void formatRAMDisk(){
string cmdFormatHDD = "format " + MountPoint + "/Q /FS:NTFS";
SecureString password = new SecureString();
password.AppendChar('0');
password.AppendChar('8');
password.AppendChar('1');
password.AppendChar('5');
ProcessStartInfo formatRAMDiskProcess = new ProcessStartInfo();
formatRAMDiskProcess.UseShellExecute = false;
formatRAMDiskProcess.CreateNoWindow = true;
formatRAMDiskProcess.RedirectStandardInput = true;
formatRAMDiskProcess.FileName = "cmd";
formatRAMDiskProcess.Verb = "runas";
formatRAMDiskProcess.UserName = "Administrator";
formatRAMDiskProcess.Password = password;
formatRAMDiskProcess.Arguments = "/C " + cmdFormatHDD;
Process process = Process.Start(formatRAMDiskProcess);
sendCMDInput(process);
}
private void sendCMDInput(Process process)
{
StreamWriter inputWriter = process.StandardInput;
inputWriter.WriteLine("J");
inputWriter.Flush();
inputWriter.WriteLine("RAMDisk for valueable data");
inputWriter.Flush();
}
public string getMountPoint()
{
return MountPoint;
}
}
Doesn't cmd.exe need to have the /C command line option passed through to run a command passed through as an argument? May well be that cmd.exe is just ignoring what you're passing through in procStartInfo.Arguments because you haven't prepended "/C " onto the front of the Arguments.

Categories