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

本文关键字:转储 数据库 脚本 批处理 windows 服务 运行 | 更新日期: 2023-09-27 18:20:35

我有一个.cmd文件,内容为:

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

该脚本从CMD运行良好,没有任何错误。temp.snapshot.sql文件是使用内容创建的。

我试着在c#中从windows服务运行这个脚本,如下所示:

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

它挂在WaitForExit方法上。如果我为timeout添加一个参数,它就会超时,结果也是一样的。生成了temp.snapshot.sql,但它的大小为0字节。这意味着脚本文件已经运行。temp.snapshot.sql文件也被锁定,无法删除。LockHunter表示已被pg_dump.exe和cmd.exe锁定。

我做错了什么?

感谢

解决方案

您不能将密码作为参数传递给postgres。Postgres是从pgpass.conf获得的。所以在我的情况下,cmd只是挂起等待密码。

因此,您找到了该文件(如果存在),请对其进行备份。用您所需的新密码覆盖它。

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;
}

过程完成后,复制回备份文件

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

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

基本上有两个选项。正如您所指出的,首选选项是使用pgpass.conf。第二个选项是使用PGPASSWORD环境变量传入密码。libpq连接接口接受这两种方法。出于安全原因,通常首选pgpass.conf方法,但在某些情况下,环境变量是完成任务的最佳方式。