1

I have an ASP.NET web application running within IIS. The app pool and the web application are both set to run as a user I created (not NETWORKSERVICE). This user has all the proper permissions (like a pseudo-administrator).

The application calls Process.Start() with a magnet URI. There is an application installed on the webserver which can automatically launch and begin processing the magnet URI. If I enter the magnet URI into the webserver's "Run" box, everything works as expected: the application launches and begins processing the URI in the background. The same happens if I debug the application from within Visual Studio - it works as expected because the IIS Express instance is also running within the same session.

When I invoke the process from my web application when it's in IIS, though, it doesn't throw any exceptions or errors, but it doesn't invoke the application. I'm assuming this is because IIS is executing the application from within a different session that the application lives in, so the application cannot respond to the URI invocation, so the process just quits.

How can I change this line of code to run within the same context as a desktop session so that the application can respond to and process the URI appropriately?

Process.Start("magnet:?xt=urn:btih:0123456789ABCDEF");

If the desktop session does not exist (e.g. that user has not logged into the server), I would expect some sort of catchable exception to be thrown so that a friendly error could be displayed on the website.

qJake
  • 16,821
  • 17
  • 83
  • 135
  • You might find something in the Event Log to explain what is going wrong. Information about accessing the desktop from a service, a similar problem, is [here](http://msdn.microsoft.com/en-us/library/ms683502%28VS.85%29.aspx). – HABO May 21 '14 at 02:21
  • Since it's a risky thing (as you can imagine, not everyone want everyone to be able to launch desktop app from a web client...), it can be quite difficult to setup. Plus you're trying to invoke something that's integrated to the Windows Shell (behind the magnet uri) which adds a level of complexity to diagnose (typically the shell often eats all errors to not disturb the end-user...). First things first: can you launch the application using the .exe path, not the uri? Help available here on SO: http://stackoverflow.com/questions/4679561/system-diagnostics-process-start-not-work-fom-an-iis – Simon Mourier May 23 '14 at 16:00
  • @SimonMourier No, I've tried that already, the program is designed specifically *not* to do that (I have no idea why, but I've already read up on it and it's not possible). – qJake May 23 '14 at 17:13
  • Well, you could try with another desktop program, like notepad for example. That's the first step. – Simon Mourier May 24 '14 at 10:04

3 Answers3

3

ASP.NET Web page and server control code executes in the context of the ASP.NET worker process on the Web server. If you use the Start method in an ASP.NET Web page or server control, the new process executes on the Web server with restricted permissions. The process does not start in the same context as the client browser, and does not have access to the user desktop. http://msdn.microsoft.com/de-de/library/e8zac0ca.aspx

When you use Process.Start on IIS 7+, it would start a new process as a service in a 'Session 0' and you can't do anything interactive with that session even you will login with same account on the server. You can however see the process running in the Task Manager (Show processes from all users).

If magnet links are not associated then you can just pass the magnet link as an argument

Process.Start("C:\...\Torrent.exe", "magnet:?...")

If process of the associated exe does not start at all - redirect its output (example) and see what was the problem.

In general, running an external process from web applications is not a good idea and you could consider either a Scheduled Task or Windows Service that polls a common storage repository to see if a batch job should be run and execute your application from there.

Example:

  1. Use aspx to write "magnet:?xt=..." to a text file (c:\magnet.txt)
  2. Create a .bat file with the following content

    FOR /F %%x IN (c:\\magnet.txt) DO START %%x
    DEL /F c:\magnet.txt
    
  3. Create a scheduled task that opens the .bat file e.g. every minute

Done!

Community
  • 1
  • 1
user2316116
  • 6,726
  • 1
  • 21
  • 35
  • The application I'm using does not accept URIs as arguments to its process (it won't let you do what you posted), I've already tried that with no success. I like the idea of storing the requests and polling for them... It's a hack, and doesn't answer the question directly, but if there is no solution to this problem, it's a good "Plan B". – qJake May 23 '14 at 17:12
  • Did you try to redirect the output and did you check if process runs in the Task Manager? – user2316116 May 23 '14 at 17:18
  • The application is already running on the desktop session. Launching a URI should "wake" the application and have it process the URI. Like I said, it handles this all normally and correctly if it's executed in the same session (like through the Windows Run box), it's when the application lives in IIS that there's a problem. And I don't believe when you launch a URI that there's any stdio happening, since it's not a process by itself. – qJake May 23 '14 at 17:58
  • As I mentioned above you cannot communicate to a desktop session. See example with .bat file that should help. – user2316116 May 23 '14 at 19:14
  • This was the method I ended up using, although I recommend @Noseratio's answer [here](http://stackoverflow.com/a/23831029/334053) instead since a WCF service is more reliable. I also opted for Powershell instead of just a batch file. – qJake May 27 '14 at 18:04
1

You can try creating a dedicated regular user account on your server, then use

Process.Start(fileName, userName, password, domain)

to start your process under that user credentials.

Another idea, create a self-hosted WCF service and run it under a logged-in desktop user session. The WCF service would start your "magnet:" app. Call the WCF service from your ASP.NET code (via localhost).

noseratio
  • 59,932
  • 34
  • 208
  • 486
0

Instead of Process.Start() try using CreateProcessWithLogonW. Similar question answered in SO: Process.Start() under asp.net?

Community
  • 1
  • 1
Saibal
  • 802
  • 6
  • 15