1

コンテンツを含む .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);
4

1 に答える 1

0

基本的に、2 つのオプションがあります。ご指摘のとおり、推奨されるオプションは pgpass.conf を使用することです。2 番目のオプションは、PGPASSWORD 環境変数を使用してパスワードを渡すことです。libpq 接続インターフェースは両方のアプローチを受け入れます。通常、セキュリティ上の理由から pgpass.conf メソッドが好まれますが、環境変数が最適な方法である場合もあります。

于 2013-10-28T08:56:32.547 に答える