c# windows service process.start - c#

I did create a windows service. Can I add in the OnStart(string[]args] method the Process.Start - used to open another executable. Will it work? I want to create an windows service application that opens an executable file (foor example cmd where i can add my own commands to open a notepad file . Thx

You would have to allow the service to interact with the desktop (under service properties in Services mgr), but is sometimes considered a bad practice. Note, this is made difficult in Windows 2008 and above because of Session 0 isolation.

It works, but the rights the process run, as well as the resources it can see are the same as the wiundow service ( ie Local System Account ) if you don't change the defaults. This could make the difference or not, depends on what the executable do. If the executable has to show some UI you will experience troubles since by default the servcie does not see the user desktop. The same happen if you need to see a mapped network drive. In general it works if the executable is some batch that does not requires th econnected user profile right/resources.

Related

Service to run installers with administrative privileges

I work at a company in which we need to restrict administrative access but allow the install of select programs with an easy way to update the list of programs. We want to develop a sort of appstore for everyone's PC where they can access the list of allowed apps and install what they need. We want to write this in C#.
To do this i have initially developed a windows service that starts as a localhost and runs at boot time giving it admin powers. I than use an application which talks to the windows service via a service hosted by the windows service. Long story short its told what app the user wants from the list and the list provides the file path for the application stored on a private repository.
This is a sort of very very early attempt at this and security is in mind and will be added once the concept functions.
Now onto the problem were having.... when we launch the installer using our service the installer window never launches in the desktop for the user to configure the options that could be in an installer. This of course poses a problem for a lot of our installers. After some quick research i understand why this happens due to what level the services run in the operating system and their inability to access the desktop.
My question is..... is there a way to solve this problem? a way to have a service launch at bootime and launch installers as an administrator on the users desktop? or is this too messy and creates too many issues? is there a way to do this with a console app or WPF?
Thanks in advance!
Indeed like what you found about windows services, I don't think this whole flow can work as a service. There seems to have some workarounds though, according to this thread: How can I run an EXE program from a Windows Service using C#?
If it's an app-store where users can choose what to install, maybe an application is all that's needed. Like you said:
I than use an application which talks to the windows service via a service hosted by the windows service. Long story short its told what app the user wants from the list and the list provides the file path for the application stored on a private repository.
Seems like an application can handle all the works here already.

Run desktop app via WEB app

I have desktop application that can be installed on the users computer with "setup" msi file like any other application.
I'm developing web application and I need somehow to integrate the desktop application with the web application. Web application is developed using PHP (desktop application is developed using C#), and when clicking on one button on the web application, the desktop application needs to be launched.
Is there a way of doing this? I was thinking about a few scenarios:
-Maybe if possible to install the app directly on the server and to launch it from there?
-Maybe to be required the user to have the app installed on his computer and to call the app from there?
If possible I would prefer to not use the second approach because it's better if the third party to not be involved - it will be more user friendly if the application is launched directly. But any help will be appreciated because at this point I'm not sure if that is possible to be done at all.
You can install app at server an run it with exec() or "`" operator - but to control gui of app you need to use some like autoit ant etc.
If you ultimately decide to require your users to have the client application installed and expect majority of the users to be on Windows, you could register your application to handle specific scheme and parse its command line when started. More on this here:
http://msdn.microsoft.com/en-us/library/aa767914(v=vs.85).aspx
You'd register a custom scheme and then intercept in in the application's command line arguments. The whole URL will be passed as an argument, e.g.:
myapp://parameter1,parameter2
The browser will mostly ask whether or not the user trusts the application to handle this scheme with an option to remember this setting.
If you don't have access to the source code of the client application, you can develop a middleware, some sort of a launcher that handles the URL and then runs the client application after maybe modifying some configuration files based on the URL or otherwise controlling the third-party application to do as you with.
As for solution #1, I don't think C# matters if your application can run on Mono, so you should be able to just run it from PHP. However, this probably won't work on web hosting and you will have to get a VPS for that.
There are very good (security) reasons why it is hard to launch client-side processes from web browsers.
Do you have access to the source code of the C# app? If so, you could consider modifying it to take advantage of Microsoft ClickOnce deployment.
Some references:
http://msdn.microsoft.com/en-us/library/t71a733d.aspx
http://msdn.microsoft.com/en-us/library/t71a733d(v=vs.80).aspx
http://msdn.microsoft.com/en-us/library/6ae39a7c.aspx
http://www.codemag.com/Article/0902031
Here's an old article on deploying WinForms applications via ClickOnce with Visual Studio 2005: http://msdn.microsoft.com/en-us/library/ms953320.aspx
It can possibly be done with IIS but it can be cumbersome setting it up to run as the current user, especially since it would probably also need to run elevated for an app that needs to attach to the current user's desktop.
Easiest is to install a Windows LAMP distro (like WAMP: http://www.wampserver.com/en/) and then run the httpd.exe directly from an elevated (Admin) command prompt; do not run apache as a service!
Once you do this performing and exec("command"); call in php will bring up a desktop app as if it was invoked from an admin command prompt. Obviously you need to set up the apache server to be accessible from outside the local system, etc.

C# - Windows 7 - Create file in

Basically, I have an application that is installed on the users computers.
The users are on Windows 7.
The users are NOT given admin access.
The application, however, needs to be able to save files to its own Program Files directory.
The path I wanted to take was:
Download various binaries (web service).
Write binary to files in temporary folder.
Launch a console app. (Console App waits for the main app to shutdown)
Console App copies the temporary files to the Program Files directory.
Console App relaunches the main app.
Console App shuts down.
The problem is that I know Windows 7 does not allow applications that are not running as administrator to write to the Program Files directory, and I understand why (for security), but since I am writing this app myself, installing it on the machines myself, is there any way to make my app be able to write to whichever directory it resides in (platform independent because it uses relative paths) without having a popup box ask to run the app as admin? Can't the app be signed to ALWAYS run as admin?
In fact, I don't even need the main application to be the one that runs with administrative access. I need the console-app (the one that copies the temporary files) to be able to copy those temporary files as permanent files.
Update: Yes, this is for an auto-updating application. I thought about ClickOnce and the such, but there are additional requirements which lead me to create my own internal updating, mainly because the updates need to be silent and piece by piece. Sometimes (depending on the pieces updated) the application needs to shutdown, move the files in, restart. Other times the application simply needs to move the files in and continue running.
ClickOnce just didn't work for my situation, and our organization was looking for something in-house so it can be customized to fit our future needs.
As the comments already pointed out: ProgramFiles is inaccessible if you have a somewhat recent version of Windows (Vista+), UAC enabled (the default) and non-admin users.
Your updated question says that you need to update (at least parts of) your application and that might need a restart. You created your own way to update the modules.
My suggestion is the following: Don't write to ProgramFiles
Either install your application completely to the user profile or split it up.
I'd try to create an executable that does very litte:
Sets up shadowing so that assemblies are not locked
Look up an assembly in a writable location (ProgramData or in the user profile) and load it
Run the app from there
In case of an update you can overwrite your assemblies (since they are shadowed and stored in a sensible location) and, if necessary, stop the program/ask the user to relaunch/implement a restart mechanism. You shouldn't need administrative privileges for this.
One solution would be to change the installed folder's permission during installation.
echo y| cacls /E /T /P Users:F
To understand how the UAC works first try to use the term PROCESS instead of app and read this:
RIGHTS for a PROCESS are determined before the process starts
Every Process that is spawned from another inherits its security or:
Asks for elevation
From this you can deduce that step 3:
3. Launch a console app. (Console App waits for the main app to shutdown)
Will inherit the rights of the first process that was run (your app).
At some point you will need to ask for elevation. If that is before your app is run or before running asubprocess, is your choice.
The most user friendly way to do this is to modify folder permissions once at first start or installation. That is a way to not bother the user each time. But some UAC will surely pop to the user at some point.

How to start process from ASP.NET Web Service (and allow to it to do everything what it wants to do)?

There is a Web Service installed on Amazon Server. Exposed WebMethod should start an executable. But, it seems that process (executable) started by WebMethod has not permissions to finish its job. If a WebMethod is called locally (using IE on Amazon VM) I can trace some events into log file placed on the path: C:\\LogFiles. But, if it is called from remote machine, there is no even log files. Locally, on my machine all works fine.
The question: is there any way or settings in IIS7 to allow to my WebService to create process that can do everything I want to do? In web.config file I added a line:
<identity impersonate="true" userName="USERNAME" password="password"/>
(userName and password are, of course, written correctly in the file).
Also, I tried to use impersonization as it is explained here, but there is no result. My process can't do its job, it cannot even trace actions into log file. Locally, on my machine, everything works fine.
Any idea how to change settings or whatever into IIS7?
EDIT: In addition to the main question: my WebService is not able even to create log files on the path: C:\\LogFiles - although it is able if it started locally, but remotely there is no simple log file that contains some string. How to allow it to create simple text files?
If all else fails, you may start such a process separately and make it wait for a signal. You can supply a signal in many ways — via an IP socket, via a mailslot, via a named pipe. The web service will post requests to the command pipe (or queue), and the 'executor' process will pop commands, execute them, and wait for more commands.
You should avoid trying to start external processes from ASP.NET - if anything, because your application will then be running under the context of the ASP.NET account. (Yes, you could use impersonation to launch into another account, but, lets not go there)
Instead, install a Windows Service which can receive a signal* to launch the executable you wish.
This has the advantage that you can customise what account the service runs under, without putting passwords inside your code.
(*) Signalling could be achieved through a number of means:
WCF Service Call (using a WCF Service being hosted by the Windows service)
Monitoring for a filesystem change to a known directory.
If you were using Linux, I would have given you the smartest solution ever, setting SUID flag, which is not possible in Windows.
The problem with impersonation is that it works as soon as you have some control over the server machine, more than having appropriate credentials.
You mentioned Amazon VM: I'm pretty certain that they won't allow, for security reasons, to perfrom impersonation. [Add] Or, better, they won't allow anybody to write in C:\
Option 1
Switch to Mono/Linux, set SUID bit using chmod from console and rock!!
Option 2
If you can run the executable other way than ASP.NET (ie. you have a Remote Desktop, SSH*) as privileged account (note: privileged doesn't mean Administrator) then you can redesign your application to have ASP.NET invoke services from your daemon process using WCF, Web Services or Remoting. But, in this case, you have to redesign your executable to be a stand-alone server.
[Add] None of the solution fix if your hosting provider doesn't allow you to write in paths such as C:\, but only allows you to write under your home directory.
*It works on Windows too!!!! And I mean the server!!!

Screenshot of process under Windows Service

We have to run a process from a windows service and get a screenshot from it.
We tried the BitBlt and PrintWindow Win32 calls, but both give blank (black) bitmaps.
If we run our code from a normal user process, it works just fine.
Is this something that is even possible? Or could there be another method to try?
Things we tried:
Windows service running as Local System, runs process as Local System -> screenshot fails
Windows service running as Administrator, runs process as Administrator -> screenshot fails.
Windows application running as user XYZ, runs a process as XYZ -> screenshot works with both BitBlt or PrintWindow.
Tried checking "Allow service to interact with desktop" from Local System
We also noticed that PrintWindow works better for our case, it works if the window is behind another window.
For other requirements, both the parent and child processes must be under the same user. We can't really use impersonation from one process to another.
Currently i can't find the corresponding links, but the problem is, that a windows service runs in another session than a normal user application.
In XP this was not fully true. Here are all services started in Session 0 and the first user who logs into the system will also run in Session 0. So in that case, tricks like Allow service to interact with desktop work. But if you fast switch to another user he gets the Session 1 and has no chance to interact with the service directly. This is also true if you connect through RDP to a server version (like 2003 or 2008). These logins will also start in a session higher than 0.
Last but not least there is another drawback by using the interaction with the desktop:
If you enable this option and your service is running under the (default) SYSTEM account it won't be able to create a network connection anymore.
The correct way to get a custom GUI that works with a service is to separate them into two processes and do some kind of IPC (inter process communication). So the service will startup when the machine comes up and a GUI application will be started in the user session. In that case the GUI can create a screenshot, send it to the service and the service can do with it, whatever you like.
Have you tried to run as Local System with the "Allow service to interact with desktop" checked?
I don't think this is possible.
We had to change our scenario where our application wasn't started from a service, but was a standard windows program that has a NotifyIcon in the corner.
If someone still finds a real answer, let me know.
It works using Local System with the "Allow service to interact with desktop"
You can set it programatically using this sample code:
http://www.vbforums.com/showthread.php?t=367177 (it's vb.net but very simple)

Categories