I have a list of a thousand items, Each of these items must be checked by the CMD.exe, With the help of the following code, I can check an item by CMD
var p = new Process
{
StartInfo =
{
UseShellExecute = false,
RedirectStandardOutput = true,
CreateNoWindow = true,
FileName = "cmd",
Arguments = $"list {Id}"
}};
p.Start();
var _Data = await p.StandardOutput.ReadToEndAsync();
But the question is, I want all of these items to be checked quickly by CMD, I'm currently doing this as follows
foreeach(var item in list)
{
var p = new Process
{
StartInfo =
{
UseShellExecute = false,
RedirectStandardOutput = true,
CreateNoWindow = true,
FileName = "cmd",
Arguments = $"list {item}"
}};
p.Start();
var _Data = await p.StandardOutput.ReadToEndAsync();
}
But it takes a long time to do this
You can redirect standard input and use a StreamWriter to write to it:
Process p = new Process();
ProcessStartInfo info = new ProcessStartInfo();
info.FileName = "cmd.exe";
info.RedirectStandardInput = true;
info.UseShellExecute = false;
p.StartInfo = info;
p.Start();
using (StreamWriter sw = p.StandardInput)
{
if (sw.BaseStream.CanWrite)
{
sw.WriteLine("mysql -u root -p");
sw.WriteLine("mypassword");
sw.WriteLine("use mydb;");
}
}
Related
There are two endpoints, I am thinking to add one endpoint to start the process and another is to do process communication(stdin/stdin). Is it possible? Or should I use some other ways to do this like websocket?
I am trying to start a process as below.
Process process = new Process();
ProcessStartInfo procStartInfo = new ProcessStartInfo("/bin/sh");
procStartInfo.RedirectStandardError = true;
procStartInfo.RedirectStandardOutput = true;
procStartInfo.RedirectStandardInput = true;
procStartInfo.UseShellExecute = false;
procStartInfo.Arguments = "-c " + Constants.CMDName + args;
process.StartInfo = procStartInfo;
Console.WriteLine("Start res: " + process.Start());
Process is getting started but when I am trying to do stdin/out like below I am getting an error saying StandardIn not redirected.
Process[] processes = Process.GetProcessesByName(Constants.VSDebugProcessName);
if (processes.Length == 0)
{
throw new Exception("Process is not running");
}
Console.WriteLine(JsonSerializer.Serialize(processes[0].StartInfo));
var process = processes[0];
StreamWriter sw = process.StandardInput;
await sw.WriteLineAsync(JsonSerializer.Serialize(payload));
Should I combine these two endpoints or is there any other workaround for this issue?
You can set EnableRaisingEvents = true in the ProcessStartInfo, and add a handler on the process’s OutputDataReceived message to collect the output. The following snippet illustrates the procedure. It also handles error output (stderr).
var process = new Process
{
StartInfo = new ProcessStartInfo
{
FileName = fileName,
Arguments = arguments,
RedirectStandardOutput = true,
RedirectStandardError = true,
UseShellExecute = false,
},
EnableRaisingEvents = true,
};
var output = new StringBuilder();
var error = new StringBuilder();
process.OutputDataReceived += (_, args) =>
{
output.AppendLine(args.Data);
};
process.ErrorDataReceived += (_, args) =>
{
error.AppendLine(args.Data);
};
process.Start();
process.BeginOutputReadLine();
process.BeginErrorReadLine();
process.WaitForExit();
ResultsText.Value = output.ToString();
I'm creating Process to run pg_dump.exe in C#
var processStartInfo = new ProcessStartInfo
{
Arguments = #"-U postgres -W -f D:\postgres\test123_dump.sql postgres",
CreateNoWindow = true,
FileName = #"C:\PostgreSQL\bin\pg_dump.exe",
UseShellExecute = false,
WindowStyle = ProcessWindowStyle.Hidden,
RedirectStandardInput = true
};
Process process = new Process() { StartInfo = processStartInfo, EnableRaisingEvents = true };
process.Start();
using( StreamWriter sw = process.StandardInput)
{
sw.WriteLine("123"); // test password
};
It will run pg_dump.exe, it will show prompt to pass the password, but StreamWriter seems to not work for some reason.
You could use this string to put your authentication info directly in argument list
var processStartInfo = new ProcessStartInfo
{
Arguments = #"--dbname=postgresql://user_name:pass_word#Localhost:5432/bd_name_to_save -F c -b -f output_bd_name",
CreateNoWindow = true,
FileName = #"C:\PostgreSQL\bin\pg_dump.exe",
UseShellExecute = false,
WindowStyle = ProcessWindowStyle.Hidden,
RedirectStandardInput = true
};
Process process = new Process() { StartInfo = processStartInfo, EnableRaisingEvents = true };
process.Start();
I want to run mc.exe using by PowerShell as I write below.
How can I do that? I tried to add in Filename but it doesn't work.
var mcExe = #"C:\Users\developer\Desktop\Example\mc.exe ";
var proc = new System.Diagnostics.Process();
proc.StartInfo.FileName = mcExe;
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.Verb = "runas";
proc.StartInfo.Arguments = String.Format("{0}{1}{2}", "./mc alias set myCloud http://localhost:9000", "admin", "123456");
proc.Start();
Did you try set proc.StartInfo.UseShellExecute = true; ?
Because this property responsible for using powershell
Starting Powershell directly might work for you, e.g. :
using System.Diagnostics;
ProcessStartInfo startInfo = new ProcessStartInfo
{
FileName = #"powershell.exe",
Arguments = #"& 'C:\Users\developer\Desktop\Example\mc.exe' #('./mc alias set myCloud http://localhost:9000', 'admin', '123456')",
RedirectStandardOutput = true,
RedirectStandardError = true,
UseShellExecute = false,
CreateNoWindow = true,
Verb = "runas",
};
Process process = new Process();
process.StartInfo = startInfo;
process.Start();
string output = process.StandardOutput.ReadToEnd();
string errors = process.StandardError.ReadToEnd();
This is my code and I'm using it in a while loop.
The cmd command changes every time. It means if I write "cd .." and in the next round of while loop if I write "dir" that's not gonna give me the previous folder items or in simpler language previous cmd closed and another one opens.
while (i < 99) {
System.Diagnostics.Process process = new
System.Diagnostics.Process();
process.StartInfo.WindowStyle =
System.Diagnostics.ProcessWindowStyle.Hidden;
process.StartInfo.FileName = "cmd.exe";
process.StartInfo.Arguments = #"/C " + lastMsg; //this line is a cmd command
process.StartInfo.UseShellExecute = false;
process.StartInfo.CreateNoWindow = true;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardInput = true;
process.Start();
string q = "";
while (!process.HasExited)
{
q += process.StandardOutput.ReadToEnd();
}
}
If you want to send all commands to the same instance of cmd, you must create this instance outside your loop, redirect the standard input, and send the commands through the standard input:
var cmdStartInfo = new ProcessStartInfo
{
FileName = "cmd",
RedirectStandardInput = true,
WindowStyle = ProcessWindowStyle.Hidden,
UseShellExecute = false,
CreateNoWindow = true,
RedirectStandardOutput = true
};
var cmdProcess = Process.Start(cmdStartInfo);
while (i < 99)
{
cmdProcess.StandardInput.WriteLine(lastMsg);
}
I have to share a folder to a user and unshare it programmatically using c#.
I am able to share a folder using InvokeMethod of Win32_Share class.
int IsShared = 0;
ManagementClass mc = new ManagementClass("Win32_Share");
object[] methodargs = { folderPath, shareName, "0" };
object result = mc.InvokeMethod("Create", methodargs);
if ((uint)result != 0)
{
IsShared = 1;
return IsShared;
}
else
return IsShared;
But how to do it for a particular user?
Also please let me know how to unshare it? Win32_Share class has delete() method.But I am unable to unshare using it.
Maybe not the best approach, but I ended up calling a command line silently and it worked for me:
To share:
var folderName = "your_shared_folder_name";
var targetDir = "your_folders_target_path";
var process = new Process();
process.StartInfo = new ProcessStartInfo()
{
UseShellExecute = false,
RedirectStandardError = true,
RedirectStandardInput = true,
RedirectStandardOutput = true,
CreateNoWindow = true,
ErrorDialog = false,
WindowStyle = ProcessWindowStyle.Hidden,
FileName = "cmd.exe",
Arguments = $"/C net share {folderName}=\"{targetDir}\" /Grant:Everyone,READ"
};
process.Start();
process.WaitForExit();
Notice the /Grant:Everyone,READ. This is what I wanted, but you might wanna fiddle with this part a little bit.
To delete:
var folderName = "your_shared_folder_name";
var process = new Process();
process.StartInfo = new ProcessStartInfo()
{
UseShellExecute = false,
RedirectStandardError = true,
RedirectStandardInput = true,
RedirectStandardOutput = true,
CreateNoWindow = true,
ErrorDialog = false,
WindowStyle = ProcessWindowStyle.Hidden,
FileName = "cmd.exe",
Arguments = $"/C net share \"{folderName}\" /delete"
};
process.Start();
process.WaitForExit();
Check the following
private void shareDir(string p)
{
string shareName = "testshare";
string shareDesc = "This is a test share kekelar2000";
string path = p;
SHARE_INFO_502 info = new SHARE_INFO_502();
info.shi502_netname = shareName;
info.shi502_type = SHARE_TYPE.STYPE_DISKTREE;
info.shi502_remark = shareDesc;
info.shi502_permissions = 0; // ignored for user-level security
info.shi502_max_uses = 1;
info.shi502_current_uses = 1;
info.shi502_path = path;
info.shi502_passwd = null; // ignored for user-level security
info.shi502_reserved = 0;
info.shi502_security_descriptor = IntPtr.Zero;
uint error = 0;
uint result = NetShareAdd(Dns.GetHostName(), 502, ref info, out error);
}