错误码
(-2147352567, ‘发生意外。’, (0, ‘Microsoft Excel’, ‘抱歉,无法找到 1.xlsx。是否可能被移动、重命名或删除?’, ‘xlmain11.chm’, 0, -2146827284), None)
手动运行时可以正常执行
操作系统为windows server 2016
简单解决方法
手动建一个"c:\windows\syswow64\config\systemprofile\desktop"文件夹
某支呼叫Excel的轉檔程式(做法如前文所述),直接執行正常,移入Windows 2008排程執行,卻發生錯誤:
Task Scheduler successfully completed task “\Run Excel” , instance “{2b987743-dfa2-4883-b7ee-0f26b1534c64}” , action “X:\Temp\RunExcel.exe” with return code 3762504530.
經過實驗,發現將安全選項改為"Run only when user is logged on"可避開問題,切換到"Run whether user is logged on or not"則會產生錯誤。
使用錯誤碼爬文,在MSDN論壇找到一則密技:
手動建個"c:\windows\syswow64\config\systemprofile\desktop"資料夾,就醬!
很多深受Excel無法在排桯執行所苦的網友證言,此技神奇無比一帖見效! 深入搜查找到另一篇MS RD的心得,歸納問題只發生在Windows 2008以Service方式執行Excel Automation時(在Windwos 2003上不會),推測可能因Excel嘗試在Desktop資料夾寫入暫存檔而引發錯誤!
在問題主機加入desktop資料夾,問題迎刃而解! 但是試著在我的本機模擬同一情境,加desktop卻不管用。調整程式,把Exception寫成Log,再配合事件檢視器,整理得到以下線索:
排程仍出現return code 3762504530錯誤
程式本身發生的Exception為
System.UnauthorizedAccessException: Retrieving the COM class factory for component with CLSID {00024500-0000-0000-C000-000000000046} failed due to the following error: 80070005 Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED)).
at System.Runtime.Remoting.RemotingServices.AllocateUninitializedObject(RuntimeType objectType) …後面省略…
事件檢視器有一則系統錯誤: The machine-default permission settings do not grant Local Activation permission for the COM Server application with CLSID
{00024500-0000-0000-C000-000000000046}
and APPID Unavailable to the user JEFFBOX\jeffrey SID (S-1-5-21-1234…8303-1000) from address LocalHost (Using LRPC). This security permission can be modified using the Component Services administrative tool.
其中JEFFBOX\jeffrey是執行排程的身分。
事件檢視器訊息很清楚地提出是DCOM預設權限(machine-default permission settings)問題,開啟DCOMCNFG,授予jeffrey帳號"Local Activation"權限。
終於在本機上也成功以排程呼叫Excel。
基於好奇,把desktop資料夾刪除,故意引發錯誤,留下Exception訊息當關鍵字供未來參考:
System.Runtime.InteropServices.COMException (0x800A03EC): Exception from HRESULT: 0x800A03EC
at Microsoft.Office.Interop.Excel._Workbook.SaveAs(Object Filename, Object FileFormat, Object Password, Object WriteResPassword, Object ReadOnlyRecommended, Object CreateBackup, XlSaveAsAccessMode AccessMode, Object ConflictResolution, Object AddToMru, Object TextCodepage, Object TextVisualLayout, Object Local)
最後一個疑問,為什麼設成Run only when user is logged on可以過關,推測是如此讓Excel從當下登入者環境中執行(如同gelis在[元件服務]的[安全性]與[權限]驗證模型一文中所提到的"互動式使用者"選項),狀況較單純無切換成其他執行身分(systemprofile)的需求,但需留意權限範圍無法預期(視當時登入的是誰,權限就有多大)以及無入登入時會掛點的副作用。