Running pg_dump from ShellExecuteEx()

508 views Asked by At

When I attempt to execute pg_dump.exe with ShellExecuteEx(), it returns an exit code of 1 (failed), and I think I may be blind to a simple error I have made.

Here is the command line that works at a command prompt:

"C:\Program Files\PostgreSQL\9.6\bin\pg_dump.exe" --host=localhost --port=5432 --username=journaluser Journal > "C:\Google Drive\Journal\Journal20170907203244973.backup"

The backup file gets created with correct contents.

And here are the contents of the SHELLEXECUTEINFO structure:

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;

The extra quotes in the lpParameters are because of Microsoft says at https://msdn.microsoft.com/en-us/library/windows/desktop/bb759784(v=vs.85).aspx : "To include double quotation marks in lpParameters, enclose each mark in a pair of quotation marks, as in the following example..."

The ShellExecuteEx() calls succeeds, but the exit code is 1, and the .backup file does not get created.

I have tried various forms of the call with and without quotes, and I have tried CreateProcess(), but the results are the same -- exit code 1 and no backup file.

I have also tried using Cmd.exe as the program, with " /K (etc)" as the parameters, but that did not work.

Have I missed something simple?

Thanks.

9/8 Edit: And I forgot to mention that SetEnvironmentVariable() is used to set PGPASSWORD before the call to ShellExecuteEx(). During testing, I used GetEnvironmentVariable() to make sure the value was there.

Edit 2: I'll try Artemy's suggestion. In the meantime, I created a password file according to https://www.postgresql.org/docs/current/static/libpq-pgpass.html, but it made no difference. (And for clarity, I added the missing "L" on lpParameters.)

Edit 3: As Artemy suggested, I wrote a program to be called in place of pg_dump. It just writes the command line parameters that pg_dump would ordinarily receive to a file and exits. Here are the results (no surprises; the backup file name is different because it is dynamically created from the date and time):

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'

Perhaps that result 0 line (the program name) is what's causing pg_dump to fail, if that is being passed to pg_dump. I'll track that down.

Edit 4: I worked around the problem by creating a batch file that accepts the parameters and calls pg_dump. That works, but I'd still like to know what went wrong with the other approach.

0

There are 0 answers