简体   繁体   English

当Apache通过Task Planner启动时,在Windows 7上通过COM从PHP 5调用Excel失败

[英]Calling Excel from PHP 5 through COM fails on Windows 7 when Apache started through Task Planner

Hey folks, this question can't be too complicated. 大家好,这个问题不能太复杂。 Please provide a solution to at least figure out the ultimate root cause of the problem. 请提供解决方案,以至少找出问题的根本原因。

I currently write an application, which controls Excel through COM : The app creates a COM-based Excel instance, opens some XLS files and reads their contents. 我目前正在编写一个通过COM控制Excel的应用程序:该应用程序创建一个基于COM的Excel实例,打开一些XLS文件并读取其内容。

Scenario I 方案一

On Windows 7, I start Apache and mySQL using xmapp-control with system administrator rights . 在Windows 7上,我使用具有系统管理员权限的xmapp-control启动Apache和mySQL。 All works as expected. 所有工作均按预期进行。 The PHP-based controller script interacts with Excel as expected. 基于PHP的控制器脚本按预期与Excel交互。

Scenario II 方案二

A problem appears, if I start Apache and mySQL as 'background jobs'. 如果我将Apache和mySQL作为“后台作业”启动,则会出现问题。 Here is how: 方法如下:

  • I created two jobs using Windows 7 Task Planner . 我使用Windows 7 Task Planner创建了两个作业。 One runs apache_start.bat, the other runs mysql_start.bat. 一个运行apache_start.bat,另一个运行mysql_start.bat。
  • Both tasks run as SYSTEM with elevated privileges when Windows 7 boots. Windows 7引导时,两个任务均以具有提升的特权的SYSTEM身份运行。

Apache and mySQL work as expected. Apache和mySQL可以正常工作。 Specifically, Apache serves HTTP request from clients and PHP is able to talk to mySQL. 具体来说,Apache提供来自客户端的HTTP请求,而PHP能够与mySQL通信。

When I call the PHP controller, which calls and interacts with Excel using COM, I do receive an error. 当我调用PHP控制器(使用COM调用Excel并与之交互)时,确实收到错误。

The error message comes from Excel [not COM itself] and reads like this: 错误消息来自Excel [不是COM本身],其内容如下:

  • Excel can't read the specified Excel-file Excel无法读取指定的Excel文件
  • Excel failed to save the file due to an ill-name worksheet 由于工作表名称不正确,Excel无法保存文件

Interestingly, the first during the first run of the PHP-based controller script, it takes a few seconds to render the error message. 有趣的是,在第一次运行基于PHP的控制器脚本期间,它需要几秒钟的时间来呈现错误消息。 Each subsequent run immediately renders the error message. 每次后续运行都会立即显示错误消息。

Windows system logs didn't show a single problem report entry. Windows系统日志未显示单个问题报告条目。

Note, that the PHP program and the Apache instance didn't change - except the way Apache was started. 请注意, PHP程序和Apache实例没有改变 -除了启动Apache的方式。

At least the PHP controller script is perfectly able to read the file-system , since it provides the pathes to the XLS-file through scandir() of a certain directory. 至少PHP控制器脚本完全能够读取文件系统 ,因为它通过某个目录的scandir()提供了XLS文件的路径。

Concurrency issues can't be the cause of the problem. 并发问题不能成为问题的原因。 A single instance of the specific PHP controller interacts with Excel. 特定PHP控制器的单个实例与Excel交互。

Question

Could someone provide details, why this happens? 有人可以提供详细信息吗,为什么会这样? Or provide ways to isolate the ultimate cause of the problem (eg by means of a PowerShell 2 script)? 还是提供隔离问题最终原因的方法(例如,通过PowerShell 2脚本)?

UPDATE-1 :: 2011-11-29 UPDATE-1 :: 2011-11-29

As proposed, I switched the Task Planner job from SYSTEM to a conventional user . 按照建议,我将Task Planner的工作从SYSTEM切换到了常规用户 Works. 作品。 Apache and MySQL get started and process request. Apache和MySQL入门并处理请求。

Unfortunately, the situation regarding Excel did't change a bit. 不幸的是,关于Excel的情况并没有改变。 Still, I see the error. 不过,我仍然看到错误。

As assumed earlier, the EXCEL COM server starts. 如前所述,EXCEL COM服务器启动。 I'm able to change various settings (eg suppress dialogs) without a problem through the COM-instance. 我可以通过COM实例无问题地更改各种设置(例如,取消对话框)。

The problem happens while calling this: 调用此问题时发生:

$excelComObject->Workbooks->Open( 'PathToXLSFile' );

UPDATE-2 :: 2011-11-30 UPDATE-2 :: 2011-11-30

Added the accounts USER, GUEST and EVERYONE with the READABLE right to the access control list of the XLS file . 将具有READABLE权限的USER,GUEST和EVERYONE帐户添加到XLS文件的访问控制列表中。 No change. 没变。

Modified the app in such a way, that the PHP part creates a copy of the XLS file as a temporary file and moves the contents of the original file into this. 修改应用程序的方式是,PHP部分将XLS文件的副本创建为临时文件 ,并将原始文件的内容移入其中。 Just to ensure, that the problem isn't forced by odd file / path names. 只是为了确保问题不是由奇数文件/路径名引起的。

Still, the problem persists. 但是,问题仍然存在。

UPDATE-2 :: 2011-12-05 UPDATE-2 :: 2011-12-05

I'm going to send the EXCEL COM-Server methods in such a way, that Excel creates a blank file and saves it to /tmp. 我将以这种方式发送EXCEL COM-Server方法,即Excel创建一个空白文件并将其保存到/ tmp。 Let's see, if Excel even isn't able to read this file. 让我们看看,如果Excel甚至无法读取此文件。

Go into the task planner and let everything run as a local user. 进入任务计划器,让所有内容都以本地用户身份运行。 This will probably require that you enter a password so create one if you don't have one already. 这可能需要您输入密码,如果还没有,请创建一个。

Excel is a user-level application that shouldn't run as SYSTEM. Excel是一个用户级应用程序,不应作为SYSTEM运行。 I'm sure there are ways around it, but you should simply let everything run at the correct level. 我敢肯定有解决方法,但是您应该让所有事情都在正确的水平上运行。

Having Apache run on the user level isn't a problem. 让Apache在用户级别上运行不是问题。

Try creating the following directories: 尝试创建以下目录:

C:\Windows\SysWOW64\Config\Systemprofile\Desktop

C:\Windows\System32\Config\Systemprofile\Desktop

it worked for me :-) 它对我有用:-)

http://social.msdn.microsoft.com/Forums/en-US/innovateonoffice/thread/b81a3c4e-62db-488b-af06-44421818ef91 http://social.msdn.microsoft.com/Forums/zh-CN/innovateonoffice/thread/b81a3c4e-62db-488b-af06-44421818ef91

In the past (read: pre Vista) services had an option called "Allow Service to interact with desktop" which allowed services to spawn windows etc. Starting Vista, this is no longer allowed. 过去(请参阅:Vista之前的版本)服务具有一个称为“允许服务与桌面进行交互”的选项,该选项允许服务生成Windows等。从Vista开始,不再允许这样做。

I suspect Excel is failing because it can't function under this restriction. 我怀疑Excel失败了,因为它无法在此限制下运行。 Thus, any attempt to run it as a service in your Win7 installation will fail. 因此,任何在Win7安装中将其作为服务运行的尝试都将失败。

You can Windows XP and allow desktop interaction for your Apache process, which I don't really recommend for obvious reasons. 您可以使用Windows XP并允许您的Apache进程进行桌面交互,出于明显的原因,我不建议这样做。

Another approach I would take is to create a PHP script that runs as a regular process and listens on a socket in an infinite loop. 我要采取的另一种方法是创建一个PHP脚本,该脚本作为常规进程运行并在无限循环中侦听套接字。 Your PHP script that runs under Apache would communicate with the secondary script through the local socket and have the secondary script spawn Excel. 您在Apache下运行的PHP脚本将通过本地套接字与辅助脚本通信,并使辅助脚本生成Excel。

This may sound complicated but in fact it's not a lot of code and it fixes a problem you will soon have anyway: You should only have one instance of Excel running or you may run into problems. 这听起来可能很复杂,但实际上它并不需要很多代码,而且可以解决您很快就会遇到的问题:您应该只运行一个Excel实例,否则可能会遇到问题。 The secondary script could queue requests, handing off one by one to Excel then taking the next in the queue. 辅助脚本可以将请求排队,将一个接一个地交给Excel,然后将下一个交给队列。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM