I have an application, running in .Net Framework 4.7.2 that I need to connect to a postgresql database. The connection works when the database exists, but if it doesn’t, I want to create the database. In order to do that from the application, I planned on using ProcessStartInfo and sending the command:
string strDbCreationCmd = $"createdb -U postgres {dbName}";
I was easily able to create the database using solely the command line, which additionally prompts me for the password for the superuser, which I type into the command line:
I have additionally gotten a working ProcessStartInfo reader that I have used in previous applications for doing something similar (such as starting a docker container, which I unfortunately cannot use for instantiating the database for this specific case). I have modified it slightly to perform some directory navigation and then run the command. This works fine, up until the point where the password prompt appears. First off, it shows up in the launched command prompt, which I was not expecting:
Then, when I try to write the password (“test” is the fill-in here) nothing happens and I time out on the next read. If I type “test” into the command line, it will register and continue, but obviously, I cannot rely on someone entering the superuser password into the command line.
How would I send input to the command line for the Password?
Here is my code for running the command line:
static Tuple<string, string> RunCmdLine(string cmd, string navCmd1 = "", string navCmd2 = ""){
var startInfo = new ProcessStartInfo()
{
WindowStyle = ProcessWindowStyle.Normal,
WorkingDirectory = @"C:",
FileName = "cmd.exe",
UseShellExecute = false,
RedirectStandardInput = true,
RedirectStandardOutput = true,
RedirectStandardError = true
};
var response = new StringBuilder();
var error = new StringBuilder();
Process process = new Process() { StartInfo = startInfo };
AutoResetEvent errorWaitHandle = new AutoResetEvent(false);
process.ErrorDataReceived += (sender, args) =>
{
if (args.Data == null)
{
errorWaitHandle.Set();
}
else
{
error.AppendLine(args.Data);
}
};
process.Start();
/* clear out the boot up text:
Microsoft Windows [Version 10.0.19045.4170]
(c) Microsoft Corporation. All rights reserved.
empty line
*/
process.StandardOutput.ReadLine();
process.StandardOutput.ReadLine();
process.StandardOutput.ReadLine();
// if navigation to a directory is needed
if (!string.IsNullOrEmpty(navCmd1))
{
process.StandardInput.WriteLine(navCmd1);
process.StandardOutput.ReadLine(); // cd
process.StandardOutput.ReadLine(); // space
}
if (!string.IsNullOrEmpty(navCmd2))
{
process.StandardInput.WriteLine(navCmd2);
process.StandardOutput.ReadLine(); // cd "Program FilesPostgreSQL15bin"
process.StandardOutput.ReadLine(); // space
}
// now write the actual command
process.StandardInput.WriteLine(cmd);
response.AppendLine(process.StandardOutput.ReadLine());
errorWaitHandle.WaitOne(1000);
process.StandardInput.WriteLine("test");
// read the input
response.AppendLine(process.StandardOutput.ReadLine());
// get the output we actually want
response.AppendLine(process.StandardOutput.ReadLine());
// get any errors that arrived
process.BeginErrorReadLine();
// give a second for errors to read if any (freezes if none otherwise)
errorWaitHandle.WaitOne(1000);
// close the process
process.Close();
return new Tuple<string, string>(response.ToString(), error.ToString());}