Can you run WebBrowser under a WCF service? - c#

I'm currently trying to move over a screen-scraping program (c# forms application) to a WCF service.
The screen-scraping program uses WebBrowser to grab info off several pages for which there is no API. I would like to know if you can run WebBrowser in a service let alone a form. I'm currently developing on XP to be release on Server 2003.
Currently when running unit test, I can only see the WebBrowser if it was made on the "Unit Test" side and even then I need to manually pop up MessageBox'es to get WebBrowser to stop from not navigating with a blank screen.
The program is being moved and split up since we are having multi-threading issues.

You would be better off using a headless browser like Phantom.js: http://www.phantomjs.org/. It offers significant features and has no problem being executed wherever you need like a regular command - line program.

In thinking about this, realize that each instance of the WebBrowser control is actually an instance of Internet Explorer. Your question then becomes one of having a service start multiple instances of Internet Explorer.
But Internet Explorer is an interactive application. It expects to control the keyboard and mouse when it has the focus.
Which keyboard and mouse do you want it to control when running in the server?
How many keyboards and mice does your server have?
You could find some way for the service to launch a Remote Desktop connection and start up your Windows Forms application. You could then have your Windows Forms application host a WCF service, and the two services could talk to each other. I have seen this sort of thing done when it was necessary to automate a specialized interactive program which could not be made into a service.

Related

Balloon Tooltip using Windows Service C#

I want to open a balloon tooltip using windows service.
I can do it in Windows Forms. Is it possible using windows service ?
I have implemented this service before and used a named pipe. Basically you create two applications.
A windows service projects which acts as the Named Pipe Server
A winforms application with a tray icon, a balloon and a Named Pipe Client
The windows service pushes messages towards the clients that are connected, could be multiple users on the systems running the winforms app.
The winforms app listens to messages on the pipe. Once the message comes in you can make the balloon pop up.
Here is a cool test project: https://www.codeproject.com/Tips/492231/Csharp-Async-Named-Pipes
Happy coding!
Not directly. A windows service does not run in the user's session, it runs in its own special "Service Session". Tooltips that show up in that session don't show up on the users desktop.
The way to get around this normally is to have a 2nd program that starts with the user's login and is not visible in the taskbar. That program uses some form of IPC (for example WCF) to talk to the service, the service can then tell the helper program to show a notification as needed.

How to navigate from browser to application in Citrix

I am currently developing an integration between a web app and a windows application, where everything works fine on standard setups. However, introducing Citrix to the equation complicates everything quite a bit.
The current solution
At the moment we have a POC (proof of concept) running with custom Uri Scheme registration to a little exe we have developed, and listing active instances with Global Atom (using this trick to list search all entries). This way, we can see if an instance of our application is running. If it is, we call it via SendMessage, and if not, we start the application in a new process, and wait for it to be ready, for us to call it.
The issues introduced with Citrix
Now, when using Citrix Desktop Sessions, we do not suspect we will run into any issues, but with Application Sessions (AKA XenApp) the Citrix documentation states: "URL redirection works only for desktop sessions, not application sessions.", and we have therefor run into a brick wall with our implementation. So to sum up, we now have issues with accomplishing the following steps:
Registering a custom URI Scheme handler: That might not at all be supported. The way we use it now, it points to an application on disk, but the Application is installed on a server.
Detecting if an instance is running: We do not know if Global Atoms are even possible in this setup, and I have been unable to find any documentation on this.
Calling a XenApp window with SendMessage: When running the simplest XenApp configuration we could reproduce, we can inspect the hosting process and get the handle to our application, but the application never gets the message sent at it.
Solving it within the current solution scope
Can the above scenario be accomplished in a Citrix environment using Application Sessions? If so, how? The tests I have performed so far, appears to confirm my suspicions that it is simply not supported within this setup.
Solving it in similar fassion
The POC we have developed is simple and modular, and changing how instances are located and communicated with is easily implemented and made configureable to our clients specific setup. It will then require other ways of detecting, launching and communiting with the primary application.
Just detecting a running application has proven difficult (another question hat has not yet been answered), and the Global Atoms approach does not seem to work.
Launching the app if it is not running, is something I have pretty much given up on, given how many different ways the app can be distributed in such a setup, so it will probably have to be a requirement that the application is already running.
Even though I can retrieve what the handle is for the mainwindow, I am not able to use SendMessage either in a Citrix setup. It simply does not process the message I am sending at it. Is that also something XenApp does not support? I could not find find any documentation on this. Alternative ideas to call into the hosted application are very welcome.
In the end the solution(s) was extremely simple for our citrix customers, as they could either:
Open our software first, launch a browser window from within (we have various links that opens browsers), and navigation now works flawlessly.
Customize a hosted browser application, to run in the same server environment as our software, and then our POC was able to launch our software as though it was a regular desktop environment.

How to have a program screenshot itself when ran as a windows service? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Screenshot of process under Windows Service
I am attempting to more or less emulate Infopath Form Services. So I want to be able to approve or disapprove forms via mobile devices (users will be notified via email). I have the ability to approve/disapprove forms, but the problem is that I need the ability to take screen shots of my program for detailed error reporting (in case something goes wrong during the approval process) (the screen shot process is implemented already). I need the ability to run the program on the server without any user logged in. That is where the problem comes in. If I run my program as a service, I dont get an interactive window, but I get the ability to have my program always run. So I need to be able to launch the program when the computer boots, and have it be able to screenshot itself.
Is there any way to have a windows service have an interactive window at boot, even if its drawn off screen and can never been seen by users, or a way to emulate/fake a window to my program so it can screenshot itself without actually needing an interactive window?
Also, my program is written on the .NET framework in c#
In addition to the fact the service have no desktop to render...
We did not implement rendering of InfoPath forms on the server the way you try because it simply will not work correctly. You can cheat for some time, but running an Office application in headless service mode on a server is simply bad idea. You will also run into interesting issues because user's identity will not match process identity (i.e. can't query ACL'ed data).
You options:
Drop InfoPath portion if you just need approval.
Go with existing solution for mobile forms. There is some support for mobile forms in Forms Services, and you can have very simple views specially for mobile devices if it works. There are also existing solutions for mobile rendering of InfoPath forms.
honestly implement rendering of forms. The XSN format is documented...
Render InfoPath on separate machines with logged on user one per user at a time...

How can I get the MainWindowHandle of a Windows 7 application running as user <foo> from within a service running as Local System?

I've created a service that runs as the Local System user. This service launches and monitors a Silverlight Out-of-browser application using native interop and the CreateProcessAsUser() method (to run it as the currently logged-in user, rather than Local System). I'm able to get a handle on the spawned Process and do things like Kill() it, however, I've become aware that the service is unable to get a handle to the main window of the child application because the child application is running as a different user. I'm running on Windows 7.
My end goal is to respond properly to when the Process stops responding (i.e. Process.Responding == false) so that I can kill the application and restart it. However, Process.Responding requires a handle to the main window of the process (Process.MainWindowHandle, to be exact), however, in this scenario, Process.MainWindowHandle always returns 0.
I'm stumped here. Is there any way for one user to get a window handle to a process running as another user in Win 7?
Thanks in advance for any and all help.
No, that's not possible. Windows Services are completely isolated from user-mode applications for security reasons. If you could get the handle to a window, you could manipulate and otherwise interact with that window, leaving open a huge security vulnerability.
More information is available here:
How can a Windows Service start a process when a Timer event is raised?
How can I run an EXE program from a Windows Service using C#?
windows service (allow service to interact with desktop)
Need suggestion on replacing Windows Service by invisible WinForm Application
Strictly speaking, what you're using the Windows Service for in the first place is bad design. It shouldn't be creating or launching any user-mode processes, or interacting with the user in any way. Remember that services run even when there is no user logged in! Thus, they shouldn't be starting applications.
A better solution is a simple background application, set to launch automatically when the user logs in. This background application could then launch the Silverlight application, monitor its state, and interact with it as necessary, because both would be running under the context of the same local user account. The effect is similar to a service, but without any of the drawbacks of isolation. The easiest way to do this in Visual Studio is to create a WinForms application (or possibly a WPF application, I have less experience in that area) that simply doesn't show any forms/windows.

Windows services with windows forms in the same process

I have a c# application that runs as a windows service controlling socket connections and other things.
Also, there is another windows forms application to control and configure this service (systray with start, stop, show form with configuration parameters).
I'm using .net remoting to do the IPC and that was fine, but now I want to show some real traffic and other reports and remoting will not meet my performance requirements. So I want to combine both applications in one.
Here is the problem:
When I started the form from the windows service, nothing happened. Googling around I've found that I have to right click the service, go to Log on and check the "Allow service to interact with desktop" option. Since I don't want to ask my users to do that, I got some code googling again to set this option in the user's regedit during installation time. The problem is that even setting this option, it doesn't work. I have to open the Log On options of the service (it is checked), uncheck and check again.
So, how to solve that? How is the best way to have a windows service with a systray control in the same process, available to any user logging in?
UPDATE: Thanks for the comments so far, guys. I agree it is better to use IPC and I know that it is bad to mix windows services and user interfaces. Even though, I want to know how to do that.
Two separate processes that communicate using your technology of choice. Services with UI is a bad idea. Don't go down this road - you'll regret it.
I've had very good results having service communication through a simple socket connection - document your service protocol well, keep it as simple as possible, and it'll be easier than you think.
In practice you should not couple your service with the management UI.
I agree with Greg. Perhaps you could examine a different IPC mechanism. Perhaps use sockets and your own protocol. Or, if your service control app can only control the service on the local machine, you can use named pipes (even faster).
Here is a way mixing up Services and Forms
http://www.codeproject.com/KB/system/SystemTrayIconInSvc.aspx
I figured out how to do this from this article (click on the "Change" link in the Methods table).
string wmiPath = "Win32_Service.Name='" + SERVICE_NAME + "'";
using (ManagementObject service = new ManagementObject(wmiPath))
{
object[] parameters = new object[11];
parameters[5] = true; // Enable desktop interaction
service.InvokeMethod("Change", parameters);
}
I have the solution in a few steps, this is the plan
we are not going to create a service project with a a windows form, instead we are going to create a visual studio solution that contains a windows service project, a windows form project and a setup project.
The idea is to have a database or a file or anything you are comfortable with storing data in which you would store the parameters your windows service will always use to run. So your windows service and your windows form application should be able to modify and retrieve data from it.
To the Main Form Of Your Windows Application drag and drop a NotifyIcon on the form, in the properties tab, browse and select an .ico image(You can sreate one in visual studio but that is another topic you can get on google or contact me) That it will display in the system tray when you run the application and the main form is active or shown, try it, run the application.
Add both of them as outputs in the setup project of the solution. To Add a project to a setup project they must be in the same solution. Right click the setup project in the solution explorer, highlight add and then select project output, add the windows service and the windows form outputs and you will see them in the solution explorer under the setup project.
adding a windows service goes further than this but that also is another topic google it
Creating shortcut for the windows application and adding it to the startup folder is also another topic google or contact me.
NOTE Program your form in such a way that the close button doesn't show and the form goes Me.visible = false and double clicking the icon in the system tray is the only way to set me.visible=true.that way anytime the computer starts up, your windows form application is also started and visible is immediately set to false but since it has a notifyicon with an icon image, it will show in the system tray and double clicking it makes the form visible to edit the settings that you are storing for the service, the service also starts automatically since you would have set it in setting up the service in the setup project.
my mail is iamjavademon#gmail.com for a better illustration using screen shots And explain in full
It is very simply - your need to create one thread for perform application events.
Like this( source code for C++ with CLR, but your can make this in C#):
ref class RunWindow{
public:
static void MakeWindow(Object^ data)
{
Application::EnableVisualStyles();
Application::SetCompatibleTextRenderingDefault(false);
Application::Run(gcnew TMainForm());
};
};
And create thread in main
int main(array<System::String ^> ^args)
{
bool bService = RunAsService(L"SimpleServiceWithIconInTrayAndWindow");
if (bService)
{
System::Threading::Thread ^thread = gcnew System::Threading::Thread(gcnew ParameterizedThreadStart(RunWindow::MakeWindow));
thread->Start();
ServiceBase::Run(gcnew simpleWinService());
Application::Exit();
}
else
{
Application::EnableVisualStyles();
Application::SetCompatibleTextRenderingDefault(false);
// Create the main window and run it
Application::Run(gcnew TMainForm());
}
return 0;
}
The main problems with interactive services are:
Security - other process could send it messages through its message pump, thereby gaining access to a SYSTEM/LOCAL process.
Incompleteness - an interactive service never sees shell messages, hence it can't interact with Notification Area icons.
We regularly use TCP and UDP connections to pass info from services to other exes, and, in some cases, MSMQ.

Categories

Resources