2013-02-24 151 views
0

我想从Windows服务运行一些excel vba代码。该服务正在使用fileSystemWatcher来监视要添加的xml文件的目录。一旦添加文件,xml文件的内容就被反序列化为对象属性。在这个阶段,我想打开一个excel文件,并将这些值传递给某些单元格,并从该工作簿中运行vba代码。我从Windows窗体应用程序完美地工作,但我无法从我的Windows服务应用程序工作。我将一个调试器附加到应用程序中,试着查看发生了什么,但没有发生错误并且所有步骤都成功完成。我知道Windows服务不支持打开MS Office文件,因为与用户界面和用户权限进行交互时存在问题。但是我正在寻找一种以任何方式获得这个vba代码的服务。我使用Windows 7家庭高级版32位,我有我的客户对我的服务设置为LocalSystem.This是我使用的代码:如何从Windows服务运行excel vba代码

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 [email protected]"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窗体可能?

回答

1

嗨,我设法得到这种工作在一种方式周围。我基本上遵循本教程和launch an interactive process from a service上的代码,以允许服务以SYSTEM用户身份运行,但为第一个登录用户采用会话标识,并授予用户管理权限以运行GUI应用程序等交互过程。通过Windows服务打开Excel并运行宏我首先编写了所有代码,以便在Windows窗体应用程序中执行此操作,并首先对其进行测试。然后我改变了可执行文件,并且完美运行。我希望这能帮助有同样问题的其他人。

+0

FWIW,这并不回答被问到的问题。你问“我想从我的Windows服务中运行一个excel宏”,并且提议作为答案,在Windows服务之外运行excel宏。 – 2013-03-25 21:08:42

3

你所试图做的是not supported

微软目前并不提倡,不支持,从任何无人参与的非交互式客户端应用程序或组件Microsoft Office应用程序(包括ASP自动化, ASP.NET,DCOM和NT服务),因为Office在此环境中运行时可能会出现不稳定的行为和/或死锁。

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

+0

好的如果我调用一个我已经写过的Windows窗体而不用任何用户交互就自动调用宏,那么怎么样?或者,这个问题仍然存在,因为在Excel中仍然会意识到它被一个SYSTEM帐户而不是一个用户帐户调用? – user1948787 2013-02-24 19:49:09

+0

您需要在交互式桌面上运行该进程。这就排除了一项服务。如果它是在登录用户的桌面上运行的桌面应用程序,那么你很好。 – 2013-02-24 19:50:11

+0

好的。基本上我试图做的是当它被添加到文件系统监视器正在监视的目录中时从XML文件中读取值,然后存储这些值并将它们传递给我用于Interactive Brokers的交易API。目前我正在使用excel API,但还有其他API可用,它们是:C++,Active X,Java和POSIX。我对编程和Windows服务非常陌生,你认为哪种API最适合我的C#Windows服务? – user1948787 2013-02-24 19:59:15

0

在没有启用“桌面交互”的情况下,Excel在用户服务下运行良好。
第一个,创建Excel COM的标准方法不能在服务范围内工作。您需要从您的程序启动Excel.exe进程 - 使用ShellExecuteEx(建议的方式)或CreateProcess(不建议)来做到这一点。
阶段:使用GetActiveObject附加到Excel COM应用程序对象。现在您可以正确访问所有Excel COM接口。
此外,在几个操作系统的Excel可能是工作在本地系统账户错误地崩溃 - 纠正这种手动创建2个文件夹: C:\ WINDOWS \ system32 \设置\ systemprofile \桌面
C:\ WINDOWS \ SYSWOW64 \设置\ systemprofile \ desktop 服务中没有第一次与Excel交互的其他问题询问用户凭证并冻结在内存中。您可以在注册表或界面中禁用它(请参阅Excel帮助)。有关启动过程的其他信息是there