从PHP exec()在Windows上运行LibreOffice soffice.exe卡住了 [英] Running LibreOffice soffice.exe on Windows from PHP exec() stuck

查看:104
本文介绍了从PHP exec()在Windows上运行LibreOffice soffice.exe卡住了的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在使用LibreOffice 5.4.6中的soffice.exe将Word文档转换为PDF时遇到问题-通过IIS在Windows Server 2012 R2上运行.

I am having issues converting Word documents to PDF using soffice.exe in LibreOffice 5.4.6 - running on Windows Server 2012 R2 via IIS.

在将目录更改为PHP(chdir)中的相关LibreOffice程序目录后,我在PHP中调用的命令是:

After changing directory into the relevant LibreOffice program directory in PHP (chdir), the command I am calling in PHP is:

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

$ workingdoc 是.docx Word文件的完整路径.

Where $workingdoc is the full path to the .docx Word file.

sys_get_temp_dir()转换为C:\ Windows \ Temp

sys_get_temp_dir() on my system translates to C:\Windows\Temp

如果我将$ cmd变量回显到浏览器,然后在服务器上交互地将输出粘贴到cmd.exe命令提示符下,则生成PDF不会出现问题.

If I echo out the $cmd variable to a browser, then copy-paste that output into a cmd.exe Command Prompt interactively on the server, a PDF gets produced without issue.

例如,我复制粘贴到cmd.exe提示符下的$ cmd回声可能是:

For example, an echoed out $cmd that I copy-paste into a cmd.exe prompt might be:

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

但是,在与我以挂起方式交互式启动cmd.exe的用户上下文相同的用户上下文中,通过 exec()从PHP运行此$ cmd变量.我可以在任务管理器中看到soffice.exe,RAM使用量徘徊在10-20MB之间.此外,在我的C:\ Windows \ Temp文件夹中,我每秒都连续创建多个空文件夹,而soffice.exe仍在运行,所有文件夹的名称格式为 lu * .tmp

However, running this $cmd variable from PHP via exec() in the same user context as what I interactively initiated the cmd.exe from just hangs. I can see soffice.exe in Task Manager with RAM usage hovering between 10-20MB. Additionally, in my C:\Windows\Temp folder, I get multiple empty folders continuously created every second whilst soffice.exe remains running, all with a name in the format of lu*.tmp

例如,产生的许多文件夹之一是 lu1124fq1pud.tmp

For example, one of the many folders that get produced are lu1124fq1pud.tmp

不会创建PDF,并且允许PHP脚本完成和停止正在创建的 lu 文件夹(除了PHP超时)的唯一方法是强制结束soffice.exe任务.任务管理器.

The PDF does not get created, and the only way to allow the PHP script to finish and stop the lu folders being created (besides PHP timeouts) is to force end the soffice.exe task in Task Manager.

那么,为什么从cmd.exe而不是通过PHP调用soffice.exe命令,即使通过这两种方法在相同的用户上下文中启动它们,也是如此?

So, why does the soffice.exe command work when called from cmd.exe, but not via PHP, even though through both methods they are launched in the same user context?

推荐答案

事实证明,这是一个已知问题,在这里报告.简而言之,这似乎是用户权限问题.

It turns out this is a known issue as reported here. In short, it appears to be a user permissions issue.

我首先在系统的temp目录中创建了一个临时的LibreOffice用户配置文件文件夹来解决我的问题(不要创建该目录,请允许soffice.exe对其进行初始化):

I solved my issue by first creating a temporary LibreOffice user profile folder in the system's temp directory (don't make the directory, allow the soffice.exe to initialise it):

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

然后将 env 参数添加到soffice.exe命令:

Then add an env parameter to the soffice.exe command:

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

确保完成后清理临时配置文件文件夹,以免阻塞您的温度,例如:

Make sure to clean up your temporary profile folder once finished to not clog up your temp, for example:

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

这篇关于从PHP exec()在Windows上运行LibreOffice soffice.exe卡住了的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆