I'm using the Microsoft.Office.Interop.Outlook to do the following:-
Read an Outlook folder called 'Pending'
Get the attachment from all emails under 'Pending' folder
Save the attachment to hard disk folder
Read the attachment from the saved file and upload to our data base
All the above points are working perfectly fine if I run my C# console application manually.
It also works sometimes when I launch the console application from Windows Service. But some times not.
I read somewhere in Stack that Microsoft.Office.Interop.Outlook is not designed for Windows Services.
What is the best method (quick and fast to develop) to all the above task from Windows Service?
What is the best method (quick and fast to develop) to all the above task from Windows Service?
Short answer - you can't.
COM Automation servers such as the ones from Microsoft Office are GUI-based and therefore require a message pump. When you consider that Windows Services typically run prior to a user logging in, it's not possible to launch a process that attempts to show a GUI. It would simply lock-up.
One could argue that you could always wait until the user logs into Windows but then it sort of defeats the purpose of windows services - that user login is not necessary. Plus if Windows were to reboot your app would not run until the user logs in again.
Related
I have written a Windows service that allows me to remotely run and stop applications. These applications are run using CreateProcess, and this works for me because most of them only perform backend processing. Recently, I need to run applications that present GUI to the current log in user. How do I code in C++ to allow my service to locate the currently active desktop and run the GUI on it?
Roger Lipscombe's answer, to use WTSEnumerateSessions to find the right desktop, then CreateProcessAsUser to start the application on that desktop (you pass it the handle of the desktop as part of the STARTUPINFO structure) is correct.
However, I would strongly recommend against doing this. In some environments, such as Terminal Server hosts with many active users, determining which desktop is the 'active' one isn't easy, and may not even be possible.
But most importantly, if an application will suddenly appear on a user's desktop, this may very well occur at a bad time (either because the user simply isn't expecting it, or because you're trying to launch the app when the session isn't quite initialized yet, in the process of shutting down, or whatever).
A more conventional approach would be to put a shortcut to a small client app for your service in the global startup group. This app will then launch along with every user session, and can be used start other apps (if so desired) without any juggling of user credentials, sessions and/or desktops.
Also, this shortcut can be moved/disabled by administrators as desired, which will make deployment of your application much easier, since it doesn't deviate from the standards used by other Windows apps...
The short answer is "You don't", as opening a GUI program running under another user context is a security vulnerability commonly known as a Shatter Attack.
Take a look at this MSDN article: Interactive Services. It gives some options for a service to interact with a user.
In short you have these options:
Display a dialog box in the user's session using the WTSSendMessage function.
Create a separate hidden GUI application and use the CreateProcessAsUser function to run the application within the context of the interactive user. Design the GUI application to communicate with the service through some method of interprocess communication (IPC), for example, named pipes. The service communicates with the GUI application to tell it when to display the GUI. The application communicates the results of the user interaction back to the service so that the service can take the appropriate action. Note that IPC can expose your service interfaces over the network unless you use an appropriate access control list (ACL).
If this service runs on a multiuser system, add the application to the following key so that it is run in each session: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run. If the application uses named pipes for IPC, the server can distinguish between multiple user processes by giving each pipe a unique name based on the session ID.
WTSEnumerateSessions and CreateProcessAsUser.
Several people suggested WTSEnumerateSessions and CreateProcessAsUser. I wonder why no one suggested WTSGetActiveConsoleSessionId, since you said you only want to target one logged in user.
Several people sure are right to suggest CreateProcessAsUser though. If you call plain old CreateProcess the way you said, then the application's GUI will run with your service's privileges instead of the user's privileges.
That problems Session 0 , Interactive Services ,
Windows Service Allow Service To Interact With Desktop
on Windows 7 or Windows Vista
You can read this article
http://www.codeproject.com/KB/vista-security/SubvertingVistaUAC.aspx
I try explained here it's working on Windows 7
On Win2K, XP and Win2K3 the console user is logged on in Session 0, the same session the services live in. If a service is configured as interactive, it'll be able to show the UI on the user's desktop.
However, on Vista, no user can be logged on in Session 0. Showing UI from a service there is a bit trickier. You need to enumerate the active sessions using WTSEnumerateSessions API, find the console session and create the process as that user. Of course, you need also a token or user credentials to be able to do that. You can read more details about this process here.
I think as long as you have only one user logged in, it will automatically display on that user's desktop.
Anyway, be very careful when having a service start an exe.
If the write access to the folder with the exe is not restricted, any user can replace that exe with any other program, which will then be run with sytem rights. Take for example cmd.exe (available on all windows sytems). The next time the service tries to start your exe, you get a command shell with system rights...
If you launch a GUI from your service it will show up on the currently active desktop.
But only if you adjusted the service permissions: You need to allow it to interact with the desktop.
Important Services cannot directly interact with a user as of Windows Vista. Therefore, the techniques mentioned in the section titled Using an Interactive Service should not be used in new code.
This is taken from : http://msdn.microsoft.com/en-us/library/ms683502(VS.85).aspx
I'm developing a windows service, generating a report. This report has a template. This template is prepared in an excel file. This file is copied to the output folder.
While developing I launched the service like a console application and had no problems accessing this file.
Then I prepared a service installer. The service is installed under Local System account. So this excel template file is marked as content and copied to the installation directory together with the executable as well.
But when the service is launched excel appears to have no access to this file. The service is installed to c:\Program Files (x86)\Our Company\Service Name\. The target OS is Windows Server 2008. While testing I use Windows 7 and run into the same issue.
I use the following code to access excel.
using Excel = Microsoft.Office.Interop.Excel;
//...
Excel.Application xlApp = new Microsoft.Office.Interop.Excel.Application();
//the following line throws an exception
Excel.Workbook xlWorkBook = xlApp.Workbooks.Open(#"path");
I also tried to copy the excel template file to some temporary directory (where the service has the right to write - this is tested) and tryed to open it from there, but to no success (while this variant works good in a console application as well).
The error message sais:
Microsoft Office Excel cannot access the file /path/.
There are several possible reasons:
1. The file name or path does not exist.
2. The file is being used by another program.
3. The workbook you are trying to save has the same name as a currently open workbook.
How can I make the windows service access this excel template file? Or is there another alternative?
To safety run Office applications (Excel and others) under user service with Local system account you must know two important things:
1) In Windows Server 2008/2008 R2 you must manually create two folders:
C:\Windows\system32\config\systemprofile\desktop
C:\Windows\SysWow64\config\systemprofile\desktop (for x64 version only)
Without this folders you cannot correct run office Applications from Local SystemAccount
2) If you service is configured without desktop interaction then in the first time launched office application (Excel for example) freeze on user credentials dialog - you cannot see this window in this mode - to resolve this enable desctop interacting, switch to office window after you service run it and manually enter credeentials.
Other information there(use google translater to read).
There is a detailed MS knowledge base article titled Considerations for server-side Automation of Office. Some key excerpts:
User Identity: Office applications assume a user identity when the applications are run, even when Automation starts the
applications. The applications try to initialize toolbars, menus,
options, printers, and some add-ins based on settings in the user
registry hive for the user who launches the application. Many services
run under accounts that have no user profiles (such as the SYSTEM
account or the IWAM_[servername] accounts). Therefore, Office may not
initialize correctly on startup. In this situation, Office returns an
error on the CreateObject function or the CoCreateInstance function.
Even if the Office application can be started, other functions may not
work correctly if no user profile exists.
Interactivity with the desktop: Office applications assume that they are being run under an interactive desktop. In some
circumstances, applications may need to be made visible for certain
Automation functions to work correctly. If an unexpected error occurs,
or if an unspecified parameter is needed to complete a function,
Office is designed to prompt the user with a modal dialog box that
asks the user what the user wants to do. A modal dialog box on a
non-interactive desktop cannot be dismissed. Therefore, that thread
stops responding (hangs) indefinitely. Although certain coding
practices can help reduce the likelihood of this issue, these
practices cannot prevent the issue entirely. This fact alone makes
running Office Applications from a server-side environment risky and
unsupported.
Obviously, as has been pointed out in the comments, using the SYSTEM account is a mistake. You would need to run the service under an account that has a user profile.
But even when you fix that, the other bullet point will kill you. Office applications do indeed assume they are running under an interactive desktop. My advice is to abandon attempting to automate Office from a service. Use a library like Aspose instead. Or run the process on an interactive desktop.
I just faced the same problem.
I have made a .bat file where I called the .exe file.
finally, I called the .bat file from the task scheduler actions.
It just works fine.
I would like to download a file to the DownloadsFolder in a Windows Store App. And then I'd like to bring up a Windows Explorer open on the DownloadsFolder (actually on the folder I create in the DownloadsFolder)
But I can't figure out how to do it.
This stackoverflow question Launching a Desktop Application with a Metro-style app suggests using Launcher.LaunchUriAsync. But the documentation claims:
You cannot use this method to launch a URI in the local zone. For example, apps cannot use the file:/// protocol to access files on the local computer. Instead, you must use the Storage APIs to access files.
And indeed, I was trying to use the "file:" protocol to bring up the explorer window. When I did try this mechanism Launcher.LaunchIUriAsync fails.
If the browser can do this, why can't I?
Is there a way for me to bring up windows explorer, or is that outside the real of possibility?
I don't think you can launch the Windows Explorer from metro. One thing you can use, however, is the File Picker.
http://code.msdn.microsoft.com/windowsapps/File-picker-app-extension-0cb95155
If you're willing to have some non-Windows Store components in your solution, there is a workaround for this. Although you can't launch a process directly, you can always run a HTTP listener inside a Windows service which listens for commands from your sandboxed Windows Store (Metro-style) app and launches Explorer (or any other process) for you. A trivial way to do this would be a Web API service inside a Windows service - just implement the GET action in your controller and have arguments for the executable to launch and optionally executable arguments as well.
This is kind of doing an end-run around the sandbox security, though, so you might want to have a tailored Web API instead which just launches a pre-packaged set of apps (like Explorer or one of your own apps).
Of course, for consumer apps this is not a good solution because you can't just install everything from the Windows Store. For LOB apps, though, it's not a bad compromise because you typically have more control over the environment. This is a good way to surface some metrics or other data into a live tile and have your desktop app launch when the tile is clicked. Whether or not this makes for a good user experience is a totally different conversation.
BatRT allows you to run batch file commands from WinRT applications. It utilizes URI calls. This can be used to open up applications or perform file operations.
I am implementing a file system watcher, my requirement is to watch for a given local folder on a machine and then do a small task (for example open a certain page in web browser). The file(s) in the given directory would be generated randomly sometimes every two hours or four etc. This tool should be automated in the sense that a user does not have to start it. So my question is, Should I implement this in a windows service which always will be running or in a console application.Preference is to do it in a console application but then it would need to started by a user right? Please advice
You can automatically call any type of application (Console, Windows, etc.). What it gets down to with a Windows Service is whether you want it to be running before anyone logs in.
Only a Windows service runs while no one is logged in. A console application (while it can be set to run on login) must have someone log in in order to run.
I have a Windows service which I want to periodically execute an external program. I'm currently doing this the usual way
Process program = Process.Start(#"C:\mpewatch\db_parameters\DBParameters.exe");
This doesn't seem to be working. I'm executing this from a separate thread which is started in my service's OnStart handler. Is there any conceptual problem with this? Is it not possible to execute external programs from a service like this?
You can execute external programs from a service, but there are security issues. For example, your service may be running under an account which does not have read access to the folder where the external program resides, even if your interactive account does have that access.
For test purposes, try to configure the service to run under your interactive account. If the program is invoked as expected, then the problem with the original account is that it does not have sufficient privileges to run the program.
Your question didn't indicate the operating system.
On Windows XP, you can configure your Windows service to interact with the desktop by opening the service control panel, double-clicking your service, selecting the Log On tab, configuring the service to run as local system, and checking the checkbox. It's pretty straightforward. You might try testing with something like Notepad.exe just to see if you can get it working.
On Vista (and presumably Windows 7), however, you may be out of luck. I have read that the ability for Windows services to interact with the desktop has been removed in Vista. I forget what the terminology is, but basically services will run in "shell 0," whereas users will occupy "shell 1". User applications will be able to communicate with services and vice versa using technology like WCF, but services will not be able to communicate directly with the desktop. For example, any error boxes that pop up will have to be dealt with by swapping to "shell 0." Again, this is based on something I read a few months ago, and I haven't gone looking at it again. For me, I've structured my Windows service to be configured using WCF via a front-end app.
I'm sorry I don't have a link for you, but if your service will eventually have to migrate to a newer OS (or you are already there), this is something to check on.
Another critical consideration with Windows Services is that there is no GUI. Technically, there is an option to allow the service to interact with a local GUI, but you will not see it. This is due to services running as the Local System user.
Within a service, any modal dialog box (OK, Cancel, etc) is considered an error.