简体   繁体   English

从Windows服务运行批处理脚本以转储数据库

[英]Running batch script from windows service to dump database

I have a .cmd file with content: 我有一个带有内容的.cmd文件:

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. 该脚本可以很好地从CMD运行,没有任何错误。 temp.snapshot.sql file is created with content. temp.snapshot.sql文件是使用内容创建的。

I try to run this script from windows service in c# like this: 我尝试从Windows服务在C#中像这样运行此脚本:

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. 它挂在WaitForExit方法上。 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. 生成了temp.snapshot.sql,但它的大小为0个字节。 So that means the script file have been ran. 因此,这意味着脚本文件已运行。 Also temp.snapshot.sql file gets locked and cannot be deleted. temp.snapshot.sql文件也将被锁定,无法删除。 LockHunter says it is locked by pg_dump.exe and cmd.exe. LockHunter表示它已被pg_dump.exe和cmd.exe锁定。

What I'm doing wrong? 我做错了什么?

Thanks 谢谢

Solution

You cannot pass a password as parameters to postgres. 您不能将密码作为参数传递给postgres。 Postgres gets it from pgpass.conf. Postgres从pgpass.conf获取它。 So in my situation cmd just hangs waiting for the password. 因此,在我的情况下,cmd只是挂起等待密码。

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); 字符串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. 如您所指出的,首选选项是使用pgpass.conf。 The second option is to pass the password in using the PGPASSWORD environment variable. 第二个选项是使用PGPASSWORD环境变量传递密码。 The libpq connection interfaces accept both approaches. libpq连接接口接受两种方法。 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. 通常出于安全考虑,首选pgpass.conf方法,但是在某些情况下,环境变量是完成任务的最佳方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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