当我尝试使用 ShellExecuteEx() 执行 pg_dump.exe 时,它返回退出代码 1(失败),我想我可能对我犯的一个简单错误视而不见。
这是在命令提示符下工作的命令行:
"C:\Program Files\PostgreSQL\9.6\bin\pg_dump.exe" --host=localhost --port=5432 --username=journaluser Journal > "C:\Google Drive\Journal\Journal20170907203244973.backup"
使用正确的内容创建备份文件。
以下是 SHELLEXECUTEINFO 结构的内容:
SHELLEXECUTEINFO see = { 0 };
see.cbSize = sizeof(SHELLEXECUTEINFO);
see.fMask = SEE_MASK_NOCLOSEPROCESS;
see.hwnd = NULL;
see.lpVerb = L"open";
see.lpFile = L"C:\\Program Files\\PostgreSQL\\9.6\\bin\\pg_dump.exe";
see.lpParameters = L" --host=localhost --port=5432 --username=journaluser Journal > \"\"\"C:\\Google Drive\\Journal\\Journal20170907203244973.backup\"\"\"";
see.lpDirectory = NULL;
see.nShow = SW_SHOWNORMAL;
see.hInstApp = NULL;
lpParameters 中的额外引号是因为微软在https://msdn.microsoft.com/en-us/library/windows/desktop/bb759784(v=vs.85).aspx说:“要在lpParameters,将每个标记括在一对引号中,如下例所示..."
ShellExecuteEx() 调用成功,但退出代码为 1,并且未创建 .backup 文件。
我尝试了各种形式的带引号和不带引号的调用,也尝试了 CreateProcess(),但结果是一样的——退出代码 1 并且没有备份文件。
我也尝试过使用 Cmd.exe 作为程序,使用“/K (etc)”作为参数,但这不起作用。
我错过了一些简单的事情吗?
谢谢。
9/8 编辑:我忘了提到 SetEnvironmentVariable() 用于在调用 ShellExecuteEx() 之前设置 PGPASSWORD。在测试过程中,我使用 GetEnvironmentVariable() 来确保该值存在。
编辑 2:我会尝试 Artemy 的建议。同时,我根据https://www.postgresql.org/docs/current/static/libpq-pgpass.html创建了一个密码文件,但没有任何区别。(为了清楚起见,我在 lpParameters 上添加了缺失的“L”。)
编辑 3:正如 Artemy 所建议的,我编写了一个程序来代替 pg_dump 调用。它只是将 pg_dump 通常接收到的命令行参数写入文件并退出。以下是结果(毫不奇怪;备份文件名不同,因为它是根据日期和时间动态创建的):
0: C:\dev\Applications\ParamTest\x64\Release\ParamTest.exe
1: --host=localhost
2: --port=5432
3: --username=journaluser
4: Journal
5: >
6: C:\Google Drive\Journal\Journal20170908093402258.backup
7: Environment password is 'qr71psgk'
如果将结果传递给 pg_dump,那么结果 0 行(程序名称)可能是导致 pg_dump 失败的原因。我会追查到的。
编辑 4:我通过创建一个接受参数并调用 pg_dump 的批处理文件解决了这个问题。那行得通,但我仍然想知道另一种方法出了什么问题。