Запуск LibreOffice soffice.exe на Windows из PHP застрял exec () - PullRequest
0 голосов
/ 09 мая 2018

У меня проблемы с преобразованием документов Word в PDF с использованием soffice.exe в LibreOffice 5.4.6 - при работе в Windows Server 2012 R2 через IIS.

После изменения каталога на соответствующий программный каталог LibreOffice на PHP (chdir), я вызываю команду на PHP:

$cmd = "soffice.exe --headless -convert-to pdf -outdir ".sys_get_temp_dir()." ".$workingdoc;
exec($cmd);

Где $ workingdoc - полный путь к файлу .docx Word.

sys_get_temp_dir () в моей системе переводится как C: \ Windows \ Temp

Если я выведу переменную $ cmd в браузер, а затем в интерактивном режиме на сервере скопировать и вставить эти выходные данные в командную строку cmd.exe, PDF будет создан без проблем.

Например, эхом $ cmd, который я копирую и вставляю в приглашение cmd.exe, может быть:

soffice.exe --headless -convert-to pdf -outdir C:\Windows\TEMP C:\Windows\Temp\pdD125.docx

Однако, запуск этой переменной $ cmd из PHP через exec () в том же пользовательском контексте, что и интерактивный запуск cmd.exe, просто зависает. Я вижу soffice.exe в диспетчере задач с использованием оперативной памяти между 10-20 МБ. Кроме того, в моей папке C: \ Windows \ Temp я получаю несколько пустых папок, которые непрерывно создаются каждую секунду, пока soffice.exe продолжает работать, все с именем в формате lu * .tmp

Например, одна из множества создаваемых папок: lu1124fq1pud.tmp

Файл PDF не создается, и единственный способ разрешить сценарию PHP завершить работу и остановить создание папок lu (помимо времени ожидания PHP) - принудительно завершить задачу soffice.exe в задаче менеджер.

Итак, почему команда soffice.exe работает при вызове из cmd.exe, а не через PHP, даже если оба метода запускаются в одном пользовательском контексте?

1 Ответ

0 голосов
/ 15 октября 2018

Оказывается, это известная проблема как , о которой здесь сообщается . Короче говоря, это похоже на проблему с разрешениями пользователя.

Я решил свою проблему, сначала создав временную папку профиля пользователя LibreOffice в системном временном каталоге (не создавайте каталог, разрешите его инициализации soffice.exe):

$tempLibreOfficeProfile = sys_get_temp_dir()."\\LibreOfficeProfile".rand(100000, 999999);

Затем добавьте параметр env в команду soffice.exe:

$cmd = 'soffice "-env:UserInstallation=file:///'.str_replace("\\", "/", $tempLibreOfficeProfile).'" --headless --convert-to pdf -outdir "'.sys_get_temp_dir().'" '.$workingDoc;
exec($cmd);

Обязательно очистите папку временного профиля после завершения, чтобы не засорять временную папку, например:

exec('rmdir /S /Q "'.$tempLibreOfficeProfile.'"');
...