1

我想从我的 Windows 服务运行一些 excel vba 代码。该服务正在使用 fileSystemWatcher 来监视要添加的 xml 文件的目录。添加文件后,xml 文件的内容将反序列化为对象属性。在这个阶段,我想打开一个 excel 文件并将这些值传递到某些单元格并从该工作簿运行 vba 代码。我可以在 Windows 窗体应用程序中完美运行它,但我无法从我的 Windows 服务应用程序中运行它。我将调试器附加到应用程序以尝试查看发生了什么,但没有抛出任何错误并且所有步骤都成功完成。我知道 Windows 服务不支持打开 MS Office 文件,因为与 UI 交互及其拥有的用户权限存在问题。但我正在寻找一种能够让这个 vba 代码从服务运行的方法。我使用的是 Windows 7 Home Premium 32 位,并且我的服务帐户设置为 LocalSystem。这是我正在使用的代码:

    private void FSWatcherTest_Created(object sender, System.IO.FileSystemEventArgs e)
    {
            Trade t;
            XmlSerializer serializer;
            XmlReader reader;
            XmlWriter writer;

            string filePath = @"C:\Inbox\TradeInfo.xml";


            serializer = new XmlSerializer(typeof(Trade));
            reader = XmlReader.Create(filePath);
            t = (Trade)serializer.Deserialize(reader);
            reader.Close();



            string path=@"C:\Windows\System32\config\systemprofile\Desktop\TwsDde.xls";

            oXL = new Microsoft.Office.Interop.Excel.Application();

            oXL.Visible = true;

            oXL.DisplayAlerts = false;

            mWorkBook = oXL.Workbooks.Open(path,2, false, 5, "", "", true,Microsoft.Office.Interop.Excel.XlPlatform.xlWindows, "", true, false, 0, true,false, false);

            //Get all the sheets in the workbook

            mWorkSheets = mWorkBook.Worksheets;

            //Get the allready exists sheet

            mWSheet1=(Microsoft.Office.Interop.Excel.Worksheet)mWorkSheets.get_Item("Basic Orders");

            // Microsoft.Office.Interop.Excel.Range range= mWSheet1.UsedRange;

            mWSheet1.Cells[12, 1] = "GE";
            mWSheet1.Cells[12, 2] = "STK";
            mWSheet1.Cells[12, 7] = "SMART";
            mWSheet1.Cells[12, 9] = "USD";
            mWSheet1.Cells[12, 12] = "Buy";
            mWSheet1.Cells[12, 13] = "100";
            mWSheet1.Cells[12, 14] = "MKT";

            Excel.Range range;
            Excel.Range row;

            range = mWSheet1.get_Range("A12", "O12");
            range.EntireRow.Select();

            oXL.Run("TwsDde.xls!Sheet2.placeOrder");
        }

任何帮助将不胜感激。或者做同样事情的替代方法,即运行包含此代码的 Windows 窗体?

4

3 回答 3

5

不支持您尝试执行的操作:

Microsoft 目前不推荐也不支持任何无人值守、非交互式客户端应用程序或组件(包括 ASP、ASP.NET、DCOM 和 NT 服务)的 Microsoft Office 应用程序自动化,因为 Office 可能表现出不稳定的行为和/或在此环境中运行 Office 时出现死锁。

如果该过程在交互式桌面中运行,您可以自动化 Excel。不支持从非交互式桌面(例如从会话)自动执行 Excel 的尝试并且失败。

于 2013-02-24T19:25:06.860 回答
1

嗨,我设法让这个工作以某种方式进行。我基本上按照本教程和代码从服务启动交互式进程以允许服务以 SYSTEM 用户身份运行,但采用第一个登录用户的会话 ID 并赋予用户管理权限以运行交互式进程,例如 GUI 应用程序. 为了打开 excel 并通过 Windows 服务运行宏,我首先在 Windows 窗体应用程序中编写了所有代码来执行此操作,并首先测试它在那里工作。然后我更改了可执行文件,它运行良好。我希望这可以帮助其他有同样问题的人。

于 2013-02-27T15:41:10.837 回答
0

在没有启用“桌面交互”的情况下,Excel 在用户服务下运行良好。
首先,创建 Excel COM 的标准方法在服务下不起作用。您需要从您的程序中启动 Excel.exe 进程 - 使用 ShellExecuteEx(推荐方式)或 CreateProcess(不推荐)来执行此操作。
第二阶段:使用 GetActiveObject 附加到 Excel COM 应用程序对象。现在您可以正确访问所有 Excel COM 接口。
此外,在多个操作系统中,Excel 可能会在 LocalSystem 帐户下无法正常工作 - 要更正此问题,请手动创建 2 个文件夹:C:\Windows\system32\config\systemprofile\desktop
C:\Windows\SysWow64\config\systemprofile\desktop 在没有 desctop 的情况下第一次与 Excel 交互的服务下的其他错误询问用户凭据并冻结在内存中。您可以在注册表或界面中禁用它(请参阅 Excel 帮助)。那里有关于启动进程的其他信息。

于 2013-04-26T13:14:33.200 回答