简体   繁体   中英

Running batch script from windows service to dump database

I have a .cmd file with content:

pg_dump -h localhost -p 5432 -U postgres --create --format=plain --encoding=UTF8 --file="D:\temp.snapshot.sql" database_name

That script runs from CMD well without any error. temp.snapshot.sql file is created with content.

I try to run this script from windows service in c# like this:

Process process = new Process();
process.StartInfo = new ProcessStartInfo("D:\script.cmd");
process.StartInfo.UseShellExecute = false;
process.EnableRaisingEvents = true;

process.Start();
process.WaitForExit();

It hangs on WaitForExit method. If I add a parameter for timeout, it timeouts and the result is the same. temp.snapshot.sql is generated, but it is 0 bytes large. So that means the script file have been ran. Also temp.snapshot.sql file gets locked and cannot be deleted. LockHunter says it is locked by pg_dump.exe and cmd.exe.

What I'm doing wrong?

Thanks

Solution

You cannot pass a password as parameters to postgres. Postgres gets it from pgpass.conf. So in my situation cmd just hangs waiting for the password.

So you find the file (if it exists), make a backup of it. Overwrite it with your new required password.

string appdata = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);

string postgresPath = Path.Combine(appdata, "postgresql");
if (!Directory.Exists(postgresPath))
   Directory.CreateDirectory(postgresPath);
string passFile = Path.Combine(postgresPath, "pgpass.conf");
string passFileContent = string.Format("{0}:{1}:*:{2}:{3}", "localhost", "5432", "user", "pass");
bool passwordBackuped = false;
//Backup previous password if exists
if (File.Exists(passFile))
{
   File.Copy(passFile, passFile + "_", true);
   passwordBackuped = true;
}

After process is finished copy back backuped file

if (passwordBackuped)
   File.Copy(passFile + "_", passFile, true);

Basically you have two options. The preferred option, as you noted, is to use the pgpass.conf. The second option is to pass the password in using the PGPASSWORD environment variable. The libpq connection interfaces accept both approaches. Usually the pgpass.conf method is preferred for security reasons, but there are cases where the environment variable is the best way to get things done.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM