Executing batch file for postgre dbinit with NSIS

2019-07-23 15:01发布

问题:

Following my previous question I'm now trying to execute a batch file trough NSIS code in order to successfully setup the postgres installation after it is being unzipped. The batch file contains command for initializing the database but it fails because of permission restrictions. I am on a Win7 x64 PC. My user account is the administrator and I start the Setup.exe with Run as adminitrator option. This is the error I get:

C:\Program Files (x86)\Poker Assistant>cd "pgsql\bin" C:\Program Files (x86)\Poker Assistant\pgsql\bin>initdb -U postgres -A password --pwfile "pwd.txt" -E utf8 -D "..\data" The files belonging to this database system will be owned by user "Mandarinite".

This user must also own the server process.

The database cluster will be initialized with locale "Bulgarian_Bulgaria.1251". initdb: could not find suitable text search configuration for locale "Bulgarian_ Bulgaria.1251" The default text search configuration will be set to "simple".

Data page checksums are disabled.

creating directory ../data ... initdb: could not create directory "../data": Permission denied

EDIT: After tinkering little more with the installer I got to the root of the problem. I cannot in any way execute the following command when the installation is in the Program Files folder:

initdb -U postgres -A password --pwfile "pwd.txt" -E utf8 -D "..\data"

I tried from .bat file. I tried from .cmd file. I tried manually from Command Prompt. I tried start as Administrator. All attempts resulted in the Permission denied error

EDIT2: I did not find any way to fix the problem so I made a workaround. Now I distribute the postgres with its data directory already initialized. Then I only need to create the service and start it.

回答1:

I just realised what the issue here is.

If you run postgres as Administrator, it uses a special Windows API call to drop permissions (acquire a restricted token), so that it runs without full Administrator rights for security. See PostgreSQL utilities and restricted tokens on windows.

I suspect that what's happening here is that initdb isn't creating the target data directory and setting its permissions before doing that, so it drops permissions and then doesn't have the permissions to create the data directory.

To work around it, simply md ..\data to create the empty directory and then use icacls.exe to grant appropriate permissions before you try to initdb. Or, even better, store it in a more appropriate place like %PROGRAMDATA%\MyApp\pgdata or whatever; application data should not go in %PROGRAMFILES%.