How to run excel vba code from a Windows Service

假如想象 提交于 2019-11-28 12:54:42

问题


I want to run some excel vba code from my Windows Service. The Service is using a fileSystemWatcher to monitor a directory for an xml file to be added. Once a file is added the content of the xml file is deserialized into object properties. At this stage I want to open an excel file and pass these values in to certain cells and run vba code from that work book. I have this working perfectly from a windows forms application but I cant get it working from my Windows Service application. I attached a debugger to the application to try and see what was happening but there were no errors thrown and all the steps completed successfully. I know a Windows Service does not support opening MS Office files as there is issues with interacting with the UI and the User permissions it has. But I am looking for a work around any way to be able to get this vba code running from a service. I am using Windows 7 Home Premium 32 bit and I have my Account for my service set to LocalSystem.This is the code that I am using:

    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");
        }

Any help would be greatly appreciated. Or alternative ways of doing the same thing i.e running a windows form that contains this code maybe?


回答1:


What you are attempting to do is not supported:

Microsoft does not currently recommend, and does not support, Automation of Microsoft Office applications from any unattended, non-interactive client application or component (including ASP, ASP.NET, DCOM, and NT Services), because Office may exhibit unstable behavior and/or deadlock when Office is run in this environment.

You can automate Excel if the process is run in an interactive desktop. Attempts to automate Excel from a non-interactive desktop (e.g. from a session) are not supported and fail.




回答2:


Hi I managed to get this working in a kind of round about way. I basically followed this tutorial and code on launch an interactive process from a service to allow the service to run as SYSTEM user but to adopt the session ID for the first logged on user and give the user Administrative privileges to run interactive processes such as GUI applications. To open excel and run a macro through a Windows service I first wrote all the code to do this in a Windows Forms application and tested it worked there first. I then changed the executable and it worked perfectly. I hope this helps someone else with the same problem.




回答3:


The Excel is working nice under user service without "desktop interacting" enabled.
First, The standard ways to creating Excel COM not working under service. You need launch Excel.exe process from you program - use ShellExecuteEx(recomended way) or CreateProcess(not recomended) to do it.
Second stage: Attach to Excel COM Application object using GetActiveObject. Now you can correctly access to all Excel COM interfaces.
Also in several operating systems the Excel may be work incorrectly crash under LocalSystem Account - to correct this manually create 2 folders: C:\Windows\system32\config\systemprofile\desktop
C:\Windows\SysWow64\config\systemprofile\desktop Other bug under service without desctop interacting the Excel in first time ask the user credentials and freeze in memory. You can disable it in registry or interface (see Excel help). Other information about launching processes is there.



来源:https://stackoverflow.com/questions/15054332/how-to-run-excel-vba-code-from-a-windows-service

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!