【问题标题】:How to run excel vba code from a Windows Service如何从 Windows 服务运行 excel vba 代码
【发布时间】:2013-02-09 20:25:01
【问题描述】:

我想从我的 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 窗体?

【问题讨论】:

    标签: c# windows excel windows-services vba


    【解决方案1】:

    你试图做的是not supported:

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

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

    【讨论】:

    • 好的,如果我调用一个我已经编写的 Windows 窗体,它会自动调用宏而无需任何用户交互,那该怎么办?还是这个问题仍然存在,因为在 excel 中仍然会意识到它是由 SYSTEM 帐户而不是用户帐户调用的?
    • 您需要在交互式桌面上运行该进程。这排除了服务。如果它是在登录用户的桌面上运行的桌面应用程序,那么你就可以了。
    • 好的。基本上,我要做的是在将 xml 文件添加到文件系统观察程序正在监视的目录中时从 xml 文件中读取值,然后存储这些值并将它们传递给我用于盈透证券的交易 API。目前我正在使用 excel API,但还有其他可用的 API:C++、Active X、Java 和 POSIX。我对编程和 Windows 服务真的很陌生,你认为哪种 API 最适合我的 C# Windows 服务?
    • 我完全不知道。我不知道这些其他 API 是什么。我刚刚回答了你提出的问题。
    • 好吧好吧,只是想我会试着再挑选你的大脑。再次感谢您的回复,非常感谢。
    【解决方案2】:

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

    【讨论】:

    • FWIW,这不能回答所提出的问题。您问“我想从我的 Windows 服务运行一个 excel 宏”并提出作为答案,在 Windows 服务之外运行 excel 宏。
    【解决方案3】:

    在未启用“桌面交互”的情况下,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 其他没有在第一次与 Excel 交互的情况下服务的错误询问用户凭据并冻结在内存中。您可以在注册表或界面中禁用它(请参阅 Excel 帮助)。其他关于启动进程的信息是there

    【讨论】:

      猜你喜欢
      • 2014-05-16
      • 1970-01-01
      • 1970-01-01
      • 2023-01-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多