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

标签 c# .net postgresql batch-file windows-services

我有一个包含内容的 .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 方法上。如果我为超时添加一个参数,它超时并且结果是一样的。生成了 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);

最佳答案

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

关于c# - 从 Windows 服务运行批处理脚本以转储数据库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17418734/

相关文章:

json - Postgres 以高效方式访问 JSONB 元素

django - 谷歌云运行 : Cant connect to Postgress SQL

c# - 比较存储在字符串中的非常大的数字

c# - 在文档准备好之前隐藏元素?

c# - 将 HTML 呈现为图像

c# - 为我解释 maxstack 指令

c# - 在 .NET 应用程序中嵌入 Android 模拟器

c# - 使用 Rhino Mocks stub 只读属性

c# - 构造函数定义中的 ": base"是什么意思?

sql - PostgreSQL - 我应该如何使用 first_value()?