Run console application (.exe) from within ASP.NET application (IIS 7,5) - asp.net

I have an ASP.NET application on Windows 2008 R2 (.NET Framework 4.0, IIS 7.5) and I want to run a console application when I click a button on a web page. Here is the code:
protected void btnUpdate_Click(object sender, EventArgs e)
{
string fileLocation = #"D:\DTDocs\App_Code\LoadDTDocsXML.exe";
ProcessStartInfo oStartInfo = new ProcessStartInfo();
oStartInfo.FileName = fileLocation;
oStartInfo.UseShellExecute = false;
Process.Start(oStartInfo);
}
When I run ASP.NET application from within Visual Studio 2010 (with its internal IIS), the console application run Ok. But when I run the ASP.NET application outside the VS 2010, I haven't an error but the console application doesn't make his job (it must create an xml file on the disk).
I think the problem is the configuration of IIS 7.5, I don't know exact to which account I must give access rights to the folders involved in my console application.
In IIS 7.5, I set Physical Path Credential for Specific User = my windows account, but that not solve the problem.
Thanks.

Just to add to the other 2 answers - Do you really need to run an exe from your webserver?
I've had to do it in the past and it's almost always the option of last resort - It weakens your security considerably (Now all someone has to do to run executables on your system is find a single flaw in your code) and has a whole host of other problems (the webserver isn't "logged on" to the server so it doesn't have a desktop, impersonation is a real pain in the a$$ to get working properly (assuming you're going to run the executable with different permissions to the webserver), etc.
If there's any other way to accomplish your goal, it'll almost certainly be simpler.
An option we went for was to have a new app with a WCF endpoint that the webserver can communicate with. So, when someone pushes the button, the WS call's our app via WCF and tells it to run various commands. This way, you've got:
Clean seperation between web and console code.
A dodgy console app won't take down the webserver & vice-versa
If the console app is long-running, this allows you to stagger your releases for website/console app so that you don't kill the app mid-execution just because you need up upodate some CSS and publish.
Huge security benefits - web server can't run executables even if compromised.
The WCF app will be able to closely examine requests to decide if they're valid before execution.
Be aware that however you do it, if someone malicious works out what's going on and can kick off the process, they could probably DoS you with almost zero effort - Make sure that this method is locked down TIGHT.
Edit: having read your comments above, I think you're hitting the "desktop" issue. When launching an executable from the server, the app will never be visible to the logged on user as the logged on user's desktop isn't accessible from IIS and vice-versa. This is very similar to the issue of having a GUI on a windows service.
This may also be of interest.

the first problem I see is security/file access. when running from within VS the server and client are the same machine under your credentials. when run in testing/production environment the server and client are physically different machines and IIS will run the website under restricted permissions. therefore there is a very good chance that IIS cannot access the file at D:... because of security.
the next issue is running a console app from the website. console is another form of UI just like html and a WPF. personally I wouldn't execute the console from the web (unless there was no other choice). I would integrate the API into the web application. 2 UIs sharing the same logic.

ASP.NET Dev Server runs under credentials of current user (it's you).
IIS 7.5 runs ASP.NET applications under user specified in application pool settings -- usually ApplicationPoolIdentity (to which you can refer as user "IIS AppPool\[ApplicationPoolName]", when configuring file permissions). You can also change it to "Network Service" (Default value in IIS 7.0).
Please check, which identity is configured for your application pool, and give this user required permissions.

Related

Access denied when try to create or view directory, asp.net

I have an Asp.net application that handles the function of creating a directory and then viewing that directory (on the network).
Dim di As DirectoryInfo = New DirectoryInfo (Me.lblPath.Text)
di.Create()
Process.Start(Me.lblPath.Text)
Both creating and viewing the directory work perfectly from Visual Studio... but when I run the compiled asp.net application it shows me "access denied" in both cases.
[Win32Exception (0x80004005): Access denied]
The folder where the subdirectories are created is on the network and is shared for everyone.
Please help!
Actually, if you check, the folder probably was created. It really depends on the user you using to run the application pool.
However, then 2nd part?
Process.Start(Me.lblPath.Text)
That is not allowed anymore. Server running process (such as IIS) are in general not allowed to shell launch system apps.
So, you can get your code to create the folders. But, IIS is a service, and such running services as a general rule can't start (shell) execute things like windows explorer in this case.
You might try giving the application pool user rights to do this, but from what I can tell, by default, running IIS services, that service can't start such programs.
You can CERTAINLY do this on your development computer, since you running VS, and it runs + launches IIS express as a context as you the super user and owner of that computer.
but, on a real server, running IIS? Nope, in general this is not allowed. Quite sure this hole was plugged around 2008. In think in server 2012, you COULD set security to make this work (I believe some kind of rights to a console_0 user.
but, after 2012, even that option was removed.
So, such code? Yes, it will work during deployment on your development computer. but a server system, running IIS is locked down, and to my knowledge, you can't execute or run such processes.
Put in a try/catch, and send the error out to a extra text box on that page - you see the web does generate a error.

Can't run exe from classic ASP script on IIS 7.5

I am attempting to upgrade an existing system from Windows XP Professional / IIS 5.1 to Windows 7 Ultimate (32-bit) / IIS 7.5. The original system ran a classic ASP website (only available to the localhost) that used 'ASPExec' to launch desktop applications on the local machine (.bat, .cmd, .exe, etc). Under Windows 7 Ultimate / IIS 7.5, the applications fail to launch from the ASP page.
As tests (The end goal is not to launch notepad), I have tried:
<%
Set Executor = Server.CreateObject("ASPExec.Execute")
Executor.Application = "notepad.exe"
Executor.ShowWindow = True
strResult = Executor.ExecuteWinApp
%>
I have also tried:
<%
Set wshell = CreateObject("WScript.Shell")
wshell.run "notepad.exe"
Set wshell = Nothing
%>
Both methods will cause notepad.exe to show in the Windows Process list, but fail to launch the application on the desktop. This is true for any .exe I try to run, and .bat or .cmd files simply fail to do anything.
With IIS 5.1, the original author of the ASP application used the "Allow Service to Interact with the Desktop" option on the "IIS Admin" service and "World Wide Web Publishing" service to make this work. All issues aside with allowing desktop interactive services, IIS 7 no longer uses the "IIS Admin" service, so this is not an option.
I am looking for either a workaround from the Windows/IIS side or another option in ASP that might acheive the same desired end result.
You won't be able to do this with Windows 7/IIS 7.5. The reason this worked was because you were running IIS5.1. Back in the days of IIS5.0/5.1 you had three different process models:
In Process (or Low Isolation mode) - where every site ran inside the inetinfo.exe process
Pooled Process - sites ran in an external surrogate process inside COM+
Out of Process (or High Isolation mode) - where each site runs inside it's own COM+ process
Most likely your IIS5.1 instance is configured to run in "In Process" mode and under the SYSTEM account. Because you can configure the IIS service to interact with the desktop, and because your Classic ASP script is being executed inside this process it is able to launch executables and they appear on the desktop.
In IIS7 life is different. Your code will run inside an application pool process which is spun up on demand. There is no way to configure pool processes (w3wp.exe) and allow them to interact with the desktop, even if running under the local system account.
Also unlike IIS6 you can't configure IIS7 to behave as if it's IIS5; IIS7 is a bottom up rewrite with a new architecture.
A possible workaround would be to write a simple WCF service with a HTTP endpoint that starts when the user logs on (hosted in a Windows app that hides or minimises itself to the notification area). You could then make calls to this service from your Classic ASP code using something like MSXML2.ServerXMLHttp and get the WCF service to launch these processes on your behalf.
This archived copy of chapter 29 of Keith Brown's "The .NET Developers Guide to Windows Security" explains the machinations involved in getting a service application to interact with the desktop:
The .NET Developers Guide to Windows Security - chapter 29 - How to Display a User Interface from a Daemon (source: archive.org)
Quote:
Option one is to get yourself into the interactive window station, and
option two is to have a process already in the interactive window
station display a UI for you.
An easy way to put a daemon in the interactive window station
(WinSta0) so it can have its own user interface is to package it as a
service that runs as SYSTEM and check the box that says, "Allow
service to interact with the desktop." This tells the SCM to launch
your service process in the SYSTEM logon session (WhatIsALogonSession)
and to attach your process to WinSta0 instead of the noninteractive
window station in which the SYSTEM daemons normally run,
Service-0x0-0x3e7$.
This is what you probably have already on your XP box. But as I explained, there is no way to configure worker processes to do this because you can't configure the "Allow service to interact with the desktop." flag, even though you can configure a pool to run as the local SYSTEM account. When the book was written this applied to Windows 2000/2003. With the advent of Windows Vista/2008 and onwards you have the added complication of UAC and getting past that as well.
What you should consider instead is option two: Use two processes
instead of just one. One process must be launched in the interactive
user's logon session and WinSta0. It should contain all the user
interface elements you need, and it can connect to your daemon process
using any secure form of interprocess communication you're comfortable
with
This is essentially what I've suggested.

ASP.NET error log

Every time the ASP.NET application in question throws an error the Global.asax writes to an error file: logs\error.log. The ASP.NET applications works using Windows authentication.
I am able to write to the log file when debugging using Visual Studio, however it does not work when the application is deployed in the live environment. How do I find out what user account I need to give access to: logs/error.log?
The application is deployed on a Windows 2003 Server with IIS6. Microsoft.NET 3.5.
You would have to give the required permissions to the network service account. This link might be able to help you out.
Windows Server 2003 defaults to the "Network Service" account.
This can be verified by opening IIS (expand the computer if needed), expand the "Application Pools" folder, right click on the pool used by your web app, and go to the Identity tab.
FYI: Windows Server 2008 uses the IIS_IUSER instead of Network Services.
I hope that logs folder is a virtual directory setup outside the web site directory.
Otherwise every time you deploy the entire solution you will overwrite the logs folder and its content.
Microsoft has a tool for monitoring file access that can be useful for troubleshooting permission issues.
Process Monitor - http://technet.microsoft.com/en-us/sysinternals/bb896645
You will also want to check if your application is using windows authentication & identity impersonation since that can change the identity the application is executing with when enabled.

System.Diagnostics.Process.Start not work from an IIS

When I run System.Diagnostics.Process.Start from my console application it works but the same code when I run from my web service hosted in IIS doesn't work.
Is it some thing to do with ASP.Net privileges?? if yes how can I configure it from my C# code.
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/en-us/library/0w4h05yb.aspx
- Give permission for ASP.NET worker process account
to interact with desktop or allow ASP.NET worker process to run in SYSTEM account.
To know how to allow worker process to run in SYSTEM account
and to know the default permissions of ASPNET account, check this article
INFO: Process and Request Identity in ASP.NET: http://support.microsoft.com/default.aspx?scid=kb;en-us;317012
- Enable IIS Admin Service to interact with desktop
To configure this, follow this steps.
a. Open Control Panel and follow these steps:
For Windows NT: click Services.
For Windows 2000, Windows XP, and .NET Server: click Administrative Tools, and then click Services.
b. Double-click IIS Admin Service.
c. On the Log On tab, select the Allow Service to Interact with Desktop check box.
Remember to run IIS Admin Service as a local system.
d. Stop and restart the IIS Admin Service.
Changing the AppPool worked for me.
IIS > Application Pools
Select Advance Setting for the website
Change Identity to LocalSystem
Restart IIS
I had a similar problem, and the ability to access the desktop from the service wasn't the problem. It worked fine when not impersonating another user, but when trying to run the process as a different user it failed.
The first thing to do when it won't start is find out all the information you can about the problem. The first question is whether Process.Start returned true or false. Secondly, did you get any kind of exception when trying to start the process.
Before you can investigate fully it relevant to know whether Process.Start was run using UseShellExecute or not - this has to be false for impersonation, but otherwise you can choose whether to use it and it calls different Win32 functions depending on this setting.
If you're doing a process that needs to run as another user, don't bother trying to use .NET impersonation - the StartInfo username, password, domain are what you need to set. However, under IIS you've got some additional lockdown, and the only solution I found on Windows Server 2008 actually involved some Win32 calls and implementations of abstract security libraries. Many of the scenarios you can run into are outlined here: http://asprosys.blogspot.co.uk/2009/03/perils-and-pitfalls-of-launching.html
The sample code from that page shows how to call the library and add Windows Station and Desktop access to a user before starting a process as that user. This was what I needed to get Process.Start to work from IIS, having ruled out UAC, DEP and any other three letter acronym I could think of ;)
I had tried upper solutions but didn't work for me. What I need was, a command should run via Windows Command Prompt as Administration.
Below the codes that didn't work but need to execute:
Process sysProcess = new Process();
sysProcess.StartInfo.FileName = "cmd.exe";
sysProcess.StartInfo.Verb = "runas";
sysProcess.StartInfo.CreateNoWindow = true;
sysProcess.StartInfo.RedirectStandardInput = true;
sysProcess.StartInfo.RedirectStandardOutput = true;
sysProcess.StartInfo.RedirectStandardError = true;
sysProcess.StartInfo.UseShellExecute = false;
sysProcess.Start();
sysProcess.StandardInput.WriteLine("cal.exe");
sysProcess.StandardInput.Flush();
sysProcess.StandardInput.Close();
//localProcess.WaitForExit();
sysProcess.StandardOutput.ReadToEnd();
Solution:
It was an API project and when I Enable SSL from project's properties and debug tab (see, Image 1 and Image 2).
Image 1:
Visual Studio 2019
Image 2:
Visual Studio 2022
This solution will works on any Web App projects.
If you are application is running windows 7 then you can't. basically services running session 0 and user desktop running session 1 so you can't communicate from session 0 to session 1. even if you try to communicate from win logon process (which is used to start the user session for every new user) you can't get some local information (browser settings like local storaage information)
For me what is working is something like this:
ProcessStartInfo psi = new ProcessStartInfo();
psi.UseShellExecute = true;
psi.LoadUserProfile = true;
psi.WorkingDirectory = sender.Server.MapPath("../");// This line solved my problem
psi.FileName = sender.Server.MapPath("../myexecutable.exe");
psi.Arguments = "Myargument1 Myargument2";
Process.Start(psi);
`

Execute a dll function in ASP.Net Bin not working, II7

I am developing a remote control application where a client (aspx page in a browser) can request a server to "launch a notepad" (for testing purpose, for real life, turning off a light bulb, etc). So I created a dll with a simple function for launching the notepad (on the server side) and dropped this dll in the root bin folder.
It worked fine when the aspx page is running under ASP.NET development server (launched from Visual Studio). But when I tested the same aspx page under a FireFox browser, it did not work (launch the notepad) even though it did call for the same function (I stepped through in debugger).
Is this a permission issue? How do I set this up in IIS manager, or even better in web.config?
Please help.
Yes, it sounds like a permission issue.
The application pool in IIS 7 that your site is running under is probably using the default identity, which is the most restrictive. You can change the identity in IIS Manager by right-clicking on the app pool (probably called DefaultAppPool) and selecting Advanced Settings. From there change the Identity value to Local Service or Network Service. If neither of those work, making it Local System should allow your page to work.
I assume the Visual Studio integrated web server runs under the context of the account you are logged in with on the machine, which likely has a lot more rights.
When you say:
it did not work (launch the notepad)
Did you mean it through an exception or you didn't see a notepad window open. If it was a permissions issue I would expect you that you would get an exception. Chris is right on when he says:
The application pool in IIS 7 that
your site is running under is probably
using the default identity, which is
the most restrictive.
and
I assume the Visual Studio integrated
web server runs under the context of
the account you are logged in with on
the machine, which likely has a lot
more rights.
and if this is a permissions issue he is right on. However, the user your running under (when not debugging in Visual Studio) most likely cannot access the desktop of the logged in user. Maybe you should try your test with an app that doesn't need to interact with the desktop.

Resources