locked
Windows Service Running Word via DCOM RRS feed

  • Question

  • Hi everyone,

    I developed a Windows service which uses MS Word to generate documents. I call Word using DCOM / OLE. Up to now it worked pretty well.

    I tested the service on Windows Vista (Beta2, RC1, RC2) and it doesn't work anymore. Opening a Document in Word crashes with varying error messages. Office 2003 sais somthing like "Not enough memory".  Office 2007 sais something like "type mismatch".

    I guess it might have to do something with the Session 0 isolation in Windows Vista. As services in Vista now have an own session. But I guess Word has problems with it's screen. In older Windows versions, Word worked "in the dark".

    When I run the service as console everything works fine.

    Anyone an idea what to do? How to find out what the problem is? How to make it work again.

    Thanks,

    Christian

    Wednesday, November 15, 2006 4:08 PM

Answers

  • Hi Christian Hund and Mridu,

    Session 0 is no longer a user session in Windows Vista, therefore applications will not run in the context of Session 0. You can however print the document from the users session without displaying a UI to the user by using the Microsoft Office Object Library. I have included some sample code below to get basic printing on a word document, some modification may be needed for your needs. To reference the library, right click the references folder and select Add Reference. Select the COM tab and scroll down to Microsoft Office x.xx Object Library (replacing x.xx with the version of office you are supporting) and select the OK button.

    using Microsoft.Office.Interop.Word;

    ApplicationClass wordApp = new ApplicationClass();

    object file = @"C:\<PathToFile>\Test.doc";

    object nullobj = System.Reflection.Missing.Value;

    //Load Document Into Memory

    Document doc = wordApp.Documents.Open(ref file, ref nullobj, ref nullobj, ref nullobj, ref nullobj, ref nullobj, ref nullobj, ref nullobj, ref nullobj, ref nullobj, ref nullobj, ref nullobj, ref nullobj, ref nullobj, ref nullobj, ref nullobj);

    //Print The Document

    doc.PrintOut(ref nullobj, ref nullobj, ref nullobj, ref nullobj, ref nullobj, ref nullobj, ref nullobj, ref nullobj, ref nullobj, ref nullobj, ref nullobj, ref nullobj, ref nullobj, ref nullobj, ref nullobj, ref nullobj, ref nullobj, ref nullobj);

     

    The documentation for the Document Object can be found here: http://msdn2.microsoft.com/en-us/library/microsoft.office.interop.word(VS.80).aspx

    Thursday, November 16, 2006 8:58 PM
  • See KB 257757 – in particular this statement:

    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, DCOM, and NT Services), because Office may exhibit unstable behavior and/or deadlock when run in this environment.

    It may have worked for you in the past because of services running on an interactive desktop, but that's ancient history now.

    Monday, November 20, 2006 2:29 AM
  • Hi Aaron,

    I respect all the statements of that note. I know that it is not easy to work with Word "in the dark" we had a lot of issues in the past years, but we could solve or workaround all of them. We implemented all the recommended features which could make the server stop. I am working on this for over 5 years.

    But now the problem is that Word doesn't even open a document anymore.

    Microsoft doesn't state that it is not possible to work with Word in an automated manner. With Windows Vista it does not work.

    Actually I found a workaround by setting a desktop for the service using some Windows API calls. I get a lot of messages in the eventlog from WinLogon and the Session0 compatibility service. But it seemed to work in the first smoke test. I hope it still works in the final.

    The calls were:
    OpenWindowStation
    SetProcessWindowStation
    OpenDesktop
    SetThreadDesktop

    But I would still be interested if Microsoft could confirm that this is an issue. I guess it is rather an issue in Word than in Windows Vista. Or let's say a compatibility probelm of Word with Windows Vista.

    Regards,

    Christian

    Monday, November 20, 2006 9:31 AM

All replies

  • Hello Christian Hund,

    The Application Compatibility Cookbook has a section on session 0 Isolation here http://msdn.microsoft.com/windowsvista/letter/default.aspx?pull=/library/en-us/dnlong/html/AppComp.asp#appcomp_topic10. Here is what they recomend for communicating with a client application on the desktop:

    • If the application's service uses a UI, a built-in mitigation in Windows Vista allows the user to interact with the Session 0 UI in a special desktop. This will make available the UI specific to the application, instead of the entire Session 0 desktop.
    • If the application creates globally named objects, then use the Windows XP compatibility mode to ensure that the application will continue to work with the Session 0 services.

    Compatibility test:

    • Test and verify the application on Windows XP in a Terminal Server mode or a Fast User Switching (FUS) mode. If the application works properly on Windows XP in these scenarios, then it is very likely to work under Windows Vista.
    • Verify that the application functions properly after applying the Windows XP compatibility mode, which contains mitigation for some of the Session 0 issues.
    • Test the driver in Windows Vista to ensure that it runs properly. If that is not possible, test the driver in Windows XP with FUS enabled and multiple users logged on. If the driver works correctly for second and subsequent logged-on users, it is not likely to be affected by the Session 0 changes in Windows Vista. The only issues that this test does not detect are those related to the absence of the video driver in Session 0 in Windows Vista.

    Leverage Windows Vista capability solution:

    • Use client or server mechanisms such as remote procedure call (RPC) or named pipes to communicate between services and applications.
    • Use the WTSSendMessage function to create a simple message box on the user's desktop. This allows the service to give the user a notification and request a simple response.
    • For more complex UI, use the CreateProcessAsUser function to create a process in the user's session.
    • Explicitly choose either the Local\ or Global\ namespace for any named objects, such as events or mapped memory, that the service makes available.

    So it seems like one way to go would be to utilize CreateProcessAsUser (MSDN: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/createprocessasuser.asp) And also the command line interface for Word is here: http://support.microsoft.com/kb/210565/ 

     

    Thanks!

    Matthew Braun

     

    Wednesday, November 15, 2006 6:03 PM
  • Hi Christian,

    I had exactly the same problem as you. Used Office DCOM/Ole from Win32 service to print. It was working fine before Win Vista. In fact it was working fine in Vista Beta1. But it fails in Vista (post Beta1) with the error code "0x800a13e" which means "Not enough memory".

    I didnt get any reply from anyone in the forum when I mentioned about this problem, so I posted a query regarding ShellExecute, thinking that it might be the same issue with ShellExecute (link http://forums.microsoft.com/MSDN/showpost.aspx?postid=926704&siteid=1).

    Please let me know if you get a workaround for this problem. Does it work with Office Word command line options?

    Thanks and regards,

    Mridu

     

    Thursday, November 16, 2006 5:29 AM
  • Hi Matthew, Hi Mridu,

    actually I and Mridu don't need to interact with the users desktop, we just want Word to do open and print a file (OK I want it also to run a Macro). But in Vista it doesn't even open the document, when run in a service environment.

    Concerning the tests:
    I know my service runs on Win XP and Win2003 in FUS and TS mode, because I don't need user interaction.
    The only option would be to turn on Compatibility Mode. I will try that.

    How do I do this for a service? Is it possible to set that mode somehow automatically?

    Would it be an option to programmatically create a desktop in my service? Would Word then use that desktop?

    What about pritner drivers and display drivers? Are they available in Session 0. I guess Word needs them.

    You said you have contact to the Office team.

    Your help would really be appriciated.

    Thanks,

    Christian

    Thursday, November 16, 2006 8:15 AM
  • Hi Christian Hund and Mridu,

    Session 0 is no longer a user session in Windows Vista, therefore applications will not run in the context of Session 0. You can however print the document from the users session without displaying a UI to the user by using the Microsoft Office Object Library. I have included some sample code below to get basic printing on a word document, some modification may be needed for your needs. To reference the library, right click the references folder and select Add Reference. Select the COM tab and scroll down to Microsoft Office x.xx Object Library (replacing x.xx with the version of office you are supporting) and select the OK button.

    using Microsoft.Office.Interop.Word;

    ApplicationClass wordApp = new ApplicationClass();

    object file = @"C:\<PathToFile>\Test.doc";

    object nullobj = System.Reflection.Missing.Value;

    //Load Document Into Memory

    Document doc = wordApp.Documents.Open(ref file, ref nullobj, ref nullobj, ref nullobj, ref nullobj, ref nullobj, ref nullobj, ref nullobj, ref nullobj, ref nullobj, ref nullobj, ref nullobj, ref nullobj, ref nullobj, ref nullobj, ref nullobj);

    //Print The Document

    doc.PrintOut(ref nullobj, ref nullobj, ref nullobj, ref nullobj, ref nullobj, ref nullobj, ref nullobj, ref nullobj, ref nullobj, ref nullobj, ref nullobj, ref nullobj, ref nullobj, ref nullobj, ref nullobj, ref nullobj, ref nullobj, ref nullobj);

     

    The documentation for the Document Object can be found here: http://msdn2.microsoft.com/en-us/library/microsoft.office.interop.word(VS.80).aspx

    Thursday, November 16, 2006 8:58 PM
  • See KB 257757 – in particular this statement:

    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, DCOM, and NT Services), because Office may exhibit unstable behavior and/or deadlock when run in this environment.

    It may have worked for you in the past because of services running on an interactive desktop, but that's ancient history now.

    Monday, November 20, 2006 2:29 AM
  • Hi Aaron,

    The main reason that we are printing Word from Win32 service is because we do not want to show any "Print Progress" Dialog on the desktop. So the service need not be interactive in our case. In cases when the document is password potected etc.. we timeout after some X minutes.

    Moreover if applications cannot run in Session0 in Vista, how come Notepad works fine? I have tried ShellExecute with Notepad (print verb) and this is OK. But MS Word fails.

    Thanks and regards,

    Mridu

    Monday, November 20, 2006 7:04 AM
  • Hi Aaron,

    I respect all the statements of that note. I know that it is not easy to work with Word "in the dark" we had a lot of issues in the past years, but we could solve or workaround all of them. We implemented all the recommended features which could make the server stop. I am working on this for over 5 years.

    But now the problem is that Word doesn't even open a document anymore.

    Microsoft doesn't state that it is not possible to work with Word in an automated manner. With Windows Vista it does not work.

    Actually I found a workaround by setting a desktop for the service using some Windows API calls. I get a lot of messages in the eventlog from WinLogon and the Session0 compatibility service. But it seemed to work in the first smoke test. I hope it still works in the final.

    The calls were:
    OpenWindowStation
    SetProcessWindowStation
    OpenDesktop
    SetThreadDesktop

    But I would still be interested if Microsoft could confirm that this is an issue. I guess it is rather an issue in Word than in Windows Vista. Or let's say a compatibility probelm of Word with Windows Vista.

    Regards,

    Christian

    Monday, November 20, 2006 9:31 AM
  • Mridu and Christian:

    The Office desktop applications were designed for interactive use on a standard desktop.  They probably all have expectations that there is a desktop process (like explorer.exe) servicing DDE requests and so forth.  Notepad is a much simpler applet and so is more likely to work in a more spare environment such as in a Vista session 0 environment.

    Christian:  you said, "Microsoft doesn't state that it is not possible to work with Word in an automated manner."  Word can be automated, but the KB article makes it quite clear (IMO) that its automation is designed for interactive desktops, not server/service-side automation.  Using the APIs you mentioned might work, but if it does it entirely defeats the purpose of session 0 isolation - you will now have interactive apps running as LocalSystem, exploitable by any process on the interactive desktop.  I would strongly discourage doing that.

    If you've ever gotten the service to work in the past, it has probably been due to the fact that your background service has been sharing the same session as the interactive user's desktop.  I suspect that Vista is not the first time it's been broken -- you may already have issues with it working completely correctly with XP and Fast User Switching, and with Server 2000 or 2003's remote desktops.  (For FUS:  log on, then FUS to another session, then log out of the first session.  Now the second user is in Session 1, and there is no interactive Session 0 desktop.)

    Mridu:  have you looked at the "Background" parameter (the first parameter) of the .PrintOut method?  Does it prevent a progress/cancel dialog from appearing?

     

    Monday, November 20, 2006 4:45 PM
  • Aaron,

    in my humble opinion the KB article http://support.microsoft.com/default.aspx/kb/257757 gives hints how to automate Word from a service. Sure it is not recommended, because a lot of thinks can happen, I am aware of that, and as already mentioned in the last few years we had several issues with Word troubeling us. But up to now it worked.

    Again in my opinion I don't think I defeat the Session 0 isolation. If it were that easy every hacker could do that and it would be useless.

    I don't put my application to session 1 or anything, I just give it a desktop. I guess I won't be able to display Word running in Session 0 to Session 1 where I am logged on. That feature would be great for debugging purpose, but I couldn't find how to change the session of a process, I guess that doesn't work. if there is a possibility I would be very interested in it for debugging. Please let me know when I am wrong and put Word to the other session. In my tests, Word didn't pop up I just got the same messages from that "Session 0 Isolation Compatibility Service Thing".

    Thanks for warning that there might be exploits, but as I run a service on a server with no users logged on and no interactive processes, and no Internet connection and so on... I consider it quite save, as my service is the only one to use Word on that server.

    Next I don't run my service as Local System, as Word doesn't run using the LocalSystem account as mentioned in the KB article above. Simple reason is printers are user specific and I don't know how to configure printers for LocalSystem. Also in my environment there are no interactive users. The service is running solely on a server printing files, so there is no additional danger to my service or that server, not more or less than before. Also the sessions keep isolated.

    Actually my service is running with no user logged on at all, what is a requirement for my application as it is a server application and runs on a server in the data center, no one will watch the desktop of that server and no one wants to have a user logged on. So I guess no user logged in equals the test you suppose. Also we tested on Server 2003 no user logged in but a Terminal Client. It works fine, only I can't debug my application then, because my service can't break out of Session 0 or I can't switch from Session 1 to Session 0.

    Mridu: Concerning the Background parameter. Setting the Background parameter just tells word to open another thread for printing, so the user can go on working on the document. But using it will be deadly for automation, as then printing is asynchroneous and you don't know when word finished and you'll get error messages when trying to close Word, when it is still printing. I would advice to disable all background operations (save, open print...) because of that. I alrady had issues with that.

    Maybe you also want to try it by setting the Window Station  to "winsta0" and the desktop to "default".

    Best regards,

    Christian

    Monday, November 20, 2006 6:13 PM
  • You wrote:  "Sure it is not recommended..."
    It is also not supported -- dependence on undocumented/unsupported/unsupportable behaviors always incurs the risk of any hotfix or service pack breaking your system.

    You wrote:  "Again in my opinion I don't think I defeat the Session 0 isolation. If it were that easy every hacker could do that and it would be useless."
    You are defeating session 0 isolation by taking a service and moving it to an interactive session, making it exploitable by processes in that session.  The isolation feature still protects against hackers who exploit desktop apps or get the interactive user to run a malicious app, since the app runs with the privileges of the logged-on user and cannot subvert services in session 0.  (If a hacker manages to install and start a service on your system, then session 0 isolation doesn't buy you anything.  UAC and session 0 isolation is intended to mitigate the risk of malware gaining those privileges.)

    You wrote:  "I don't run my service as Local System".
    What account does your service run under?

    I'm confused by the conflicting statements that you're logged on in session 1 (3rd paragraph) and that no user is logged on (6th paragraph).  In the latter, you describe a data center server scenario.  Is Vista going to be running unattended in a data center as a server?  Or is that just your development platform?

    Monday, November 20, 2006 8:44 PM
  • Yes it is not supported as there are too many risks and things to consider when doing it. Anyway there are a lot of people doing it, because there is no other way (besides migrating to another Office suite). Word is the defacto standard for office documents, so there needs to be a way to automatically print them or convert them e.g. to PDF what is the next scenario where services need to automat Word. Most PDF converter services run that way by automatically printing a document, even Adobe works that way in their latest product LiveCycle PDF Generator. Well Ok it is another story but the same issue. I am curious how they solve this issue. Another scenario would be how do you convert Word DOC files automatically in the background to the new Word XML Document format?

    In my opinion I don't take the service and move it to an interactive session. My service still runs in session 0 afaik, but I will check. I don't know how to break out of a session, do you?

    My service is intended to run with a normal user account, as described in the mentioned KB article. As mentioned I need a user with a user profile because of Word settings and printer settings. The only thing it needs is logon as a service and the DCOM privileges to run Word. So it can harm the system as would a interactive user. Also my service is a server product, so there will be seldomly an interactive user being able to inject malicious code. Also we are using RTF doucments so there is no harm of malicious macros. Next threat would be corrupt RTF documents, well I can't do anything against that, at least there is the hope that there will only be clean documents in our system as there will be no foreign sources.

    Concerning your last question, we tested our service on Windows 2003 Server with no interactive user logged on, but with terminal server users logged on and it works. Another test is no users logged in at all so no user sessions should exist, and it works.

    Vista probably is not going to run in a data center scenario, but I guess Vista Server alias "Longhorn" will. So I guess what is running on Vista will also run on Longhorn as in Windows XP and Windows Server 2003. Probably the Vista scenario will never be in production use, but maybe customers will us it for testing purpose, you never know what customers will do ;)

    Thanks a lot for your ideas and considerations.

    Tuesday, November 21, 2006 9:14 AM
  • Hi Christian,

    Thanks for your suggestion. I tried using the APIs OpenWindowStation, SetProcessWindowStation, OpenDesktop and SetThreadDesktop to set the Windows Station of the Service to "winsta0" and the desktop to "default".

    But the printing still fails with a COM error 0x800a11fd.  This time it is not the Open function but the PrintOut function which is failing. Any idea why this might be happening?

    I have tried this on Vista RC2 and Office 2007. I have not yet tried on Office 2003 or earlier versions. In Windows XP the Win32 Service displays the Print Progess Dialog, so looks like setting the station and desktop is successful.

    Thanks and regards,

    Mridu

    Wednesday, November 22, 2006 8:44 AM
  • Hi Mridu,

    up to know I didn't have time to do the printing tests with my service. But I'll do today.

    Maybe this is again due to the seesion 0 isolation, I believe I read something that there might be problems with pritner drivers in Session 0, but I am not sure if it is the case in our scenario.

    Do you use a user account for your service with a profile and a printer installed? I guess so ...

    Let's see if we can solve or better workaround this issue some how ...

    Best regards,

    Christian

    Wednesday, November 22, 2006 8:59 AM
  • Hi Mridu,

    Ok I did a lot of testing today and everything worked again as before. Including Printing etc.

    Well I call teh PrintOUt from a Macro. maybe you could try to use a Macro to print perhapse that makes the difference.

    Did you check that your service is running using a user accoutn other than Localsystem?

    The above mentioned KB article gives a lot of hints what to take care of. I think it is very helpful.

    Best regards,

    Christian

     

    Wednesday, November 22, 2006 7:31 PM
  • Hi Christian,

    Thanks for the mail. My service is running in LocalSystem and not under user account. I think that's the reason why print is failing in my scenario.

    As my service is part of a client application, I cannot have it as a user account, because there is no way for me to get the user password while silent installation of the service.

    Any workaround in this regard will be of great help.

    Thanks and regards,

    Mridu

    Thursday, November 23, 2006 10:59 AM
  • Hi Mridu,

    I don't think there is a workaround besides using a user account with a profile. Did that work in earlier Windows Versions with no user account?

    The only thing you can do is to set up a user account during installation, or use a domain user account, which you set during installation. Using a domain user account would also allow to configure the user centrally.

    Next thing would be to set up a printing server as we have it and print everything centrally, where setup is easier.

    Last idea / question is why do you use a service when you trigger printing from a client application anyway, so you could also start printing in the client context and maybe set Word to not show up, so the printing is not visible to the user. If that is the main aim.

    But I think this discussion should get an own thread.

    Regards,

    Christian

    Thursday, November 23, 2006 2:54 PM
  • Hi Christian,

     

    my intention is to carry out

     

         ShellExecute( NULL, "print", "AnyDoc.doc", NULL, NULL, 0 );

     

    under Windows Vista. As mentioned before within this thread, Session 0 isolation in Windows Vista blocks opening AnyDoc.doc in MS Word, while - as Mridu has already pointed out - Notepad works fine with ShellExecute, so I tried your workaround using

     

        OpenWindowStation

        SetProcessWindowStation

        OpenDesktop

        SetThreadDesktop

     

    like this:

     

        hWinStaUser = OpenWindowStation("WinSta0", FALSE, MAXIMUM_ALLOWED);

        SetProcessWindowStation( hWinStaUser );

        hDeskUser = OpenDesktop("Default", 0, FALSE, MAXIMUM_ALLOWED);

        SetThreadDesktop( hDeskUser );

        ShellExecute( NULL, "print", "AnyDoc.doc", NULL, NULL, 0 );

     

    but it didn't change anything, because I was just assigning to the very combination of Window Station and Desktop to which my process would have been assigned anyway by default. At least that is how I tend to interpret this result - my knowledge and understanding of Window Stations and Desktops is rather poor.

     

    So I tried to assign to a combination of Window Station and Desktop other than WinSta0 / Default, like this:

     

        hWinStaUser = CreateWindowStation( "LupoWinStation",  0, MAXIMUM_ALLOWED, NULL );
          SetProcessWindowStation( hWinStaUser );

        hDeskUser = CreateDesktop( "LupoDesktop", NULL, NULL, 0, MAXIMUM_ALLOWED, NULL );

        SetThreadDesktop( hDeskUser );

        if ( ShellExecute( NULL, "print", "AnyDoc.doc", NULL, NULL, 0 ) <= (HINSTANCE)32 )
          {
             dwLastError = GetLastError();
             printf( "ShellExecute error: %d", dwLastError );
          }

     

    MS Word opens, but without any document, and ShellExecute and GetLastError both return ERROR_FILE_NOT_FOUND, which means AnyDoc.doc from the viewpoint of the new Window Station / Desktop is out of sight... 

     

    Any idea how to solve this? Did I call the right API functions, but with wrong parameters ? Or is ShellExecute finally really dead under Windows Vista ? 

     Thanks a lot in advance,

    Lupo

     

    Thursday, May 24, 2007 7:43 PM
  •  

    Hi Lupo,

     

    basically I used Open....

    and I set the Inheritance Flag to true. I guess this is the main difference, as only by that the Desktop Handle can be passed to Word as Child process.

     

    Code Snippet

    hWinStaUser = OpenWindowStation("WinSta0", TRUE, MAXIMUM_ALLOWED);

    SetProcessWindowStation( hWinStaUser );

    hDeskUser = OpenDesktop("Default", 0, TRUE, MAXIMUM_ALLOWED);

    SetThreadDesktop( hDeskUser );

     

     

    Just give it a try.

     

    Of course you need to start your Service with a user assigned, otherwise Word settings and pritners are missing.

     

    Hope it helps.

    Christian

     

    Friday, May 25, 2007 1:03 PM
  • Try Aspose.Words for .NET to avoid automation in this case.

     

     

     

    Saturday, December 6, 2008 3:46 AM
  • we faced similar kind of issues and found some workarounds ...

    1. Issue in opening word document (from DCOM component, in windows 2008 64 bit machines)
    create folder called "Desktop" under "C:\Windows\SysWOW64\config\systemprofile" or "C:\Windows\System32\config\systemprofile" as mentioned in http://social.msdn.microsoft.com/Forums/en/innovateonoffice/thread/b81a3c4e-62db-488b-af06-44421818ef91

     2. Issue in printing
    configure word to run as "Interactive user"

    Steps to configure word to run as “Interactive User”
    1. open registry editor (regedit)
    2. Search for winword.exe, copy the AppId/Guid for word from “HKEY_CLASSES_ROOT\AppID\WINWORD.EXE”
    3. Open Compent Services (dcomcnfg), Go to Computers->MyComputer->DCOM Cnfg
    4. Select the application with the guid copied from registry.
    5. Right click on it, select properties, select Identity tab, select “Interactive User”, click on “Apply” button.

     

     

    • Proposed as answer by solversa Wednesday, November 24, 2010 2:07 AM
    Monday, October 18, 2010 12:38 PM