Is there any problems with creating a powershell runspace in an asp.net application and running commands?
I have a basic example working fine but I'm wondering if there are any pitfalls waiting for me.
I'm particularly wondering:
Is this an a light-weight inprocess operation or is it firing up another processes that could lead to unpredictable behaviour.
As long as you're not shelling out to powershell.exe explicitly, instead using Runspace and Pipeline objects directly, you can be assured it's fairly lightweight. Btw, if you are trying to interact with cmdlets through C#, only cmdlets that derive from PSCmdlet need a pipeline; ones that derive from Cmdlet directly can be called without a pipeline via the Invoke method. This is the most lightweight approach.
This should be OK. I've not done this in ASP.NET but I have hosted in-process with a desktop app. There is no external PowerShell process spun up unless you use background jobs. I think the Quest folks are also doing something like this with their Mobile Shell.
As I can see, others recommend using PowerShell. Well, personally, I would pay more attention. Why?
Each web request should be processed as quickly as possible and without any blocking. If the script contains commands that work with network, then there could be some timeouts (e.g. if the computer is not accessible). The processing thread will be blocked for all the time and can't serve any other web request. Then soon you might get Internal Server Error and similar responses.
Besides that (not proved) I suspect that PowerShell consumes more memory than similar code in C#.
I don't claim don't use Powershell, just pay attention ;)
Related
We are referencing a 3rd party proprietary CLI DLL in our .net project. This DLL is only an interface to their proprietary C++ library. Our project is an asp.net (MVC4/Web API) web application.
The C++ unmanaged library is rather unstable. Sometimes it crashes with e.g. dangling pointers. We have no way of solving it, and using this library is a first-class customer requirement.
When the application crashes, the application pool in IIS doesn't respond anymore. We have to restart it, and doing so takes a couple minutes (yes, that long!).
We would like to keep this unstable DLL from crashing our application. What's the best way of doing it? Can we keep the CLI DLL in a separate AppDomain? How?
Thanks in advance.
I think every answer to this question will be some kind of work around.
My workaround would be to not interact directly with the DLL from your web application.
Instead write your requests from the web application to either a Message Queue or a SQL table. You can then have another application such as a Windows Service which reads the requests, interacts with the DLL and then writes the results back for your web application to read.
I'm not saying that SQL / Message Queues are the right way, I'm more thinking of the general process flow.
I had this exact problem with a third party library that accessed protected memory for purposes of interacting with a hardware copy protection dongle. It worked fine in a console or winforms app, but crashed like crazy when called from an IIS application.
We tried several different things, some of which are mentioned in other answers on this page. But ultimately, the best solution for us was to us a very old technology - .Net Remoting. I know - it's somewhat frowned on these days. But it fit this particular need quite well.
The unstable code was placed in a Windows Service application. The web application made remoting calls to this service, which relayed the commands to the third-party library.
Now I'm sure you could do the same thing with WCF, sockets, etc. But remoting was quick and easy to setup, and since we only talk to the same server it works without opening any ports. It just talks on a named pipe.
It does mean a second service to install besides the web application, but that was acceptable in my particular use case.
If you did something similar, and the third-party code actually crashed the service, you could probably write some code in your main application to bring it back up.
So perhaps a process boundary is more useful than an App Domain when you have unstable code to wrangle.
I would first increase the IIS process recyling rate, maybe the the DLL code fails after a certain number of calls, or after the process reaches a certain amount of memory usage.
You can find information on the configuration of IIS 7.0 recycling options here: http://technet.microsoft.com/en-us/library/cc753179(v=ws.10).aspx
In your case I would recycle the process at a specific time, when you know there is less load on the application. And after a certain number of requests (lower than the default) to try and have "fresh" process most of the time.
The recycling process is graceful in the sense that the the old process is not terminated until the one that will replace it is ready, so there should be no noticeable downtime.
More information about the recycling mechanism here: http://technet.microsoft.com/en-us/library/cc745955.aspx
If the above does not solve the problem I would wrap the calls in my own code that manages the unstable DLL execution.
This code should recover from the failures for example by repeating the failing calls until a result is obtained and failing with a graceful error if it is not possible after a number of attempts.
Internally the calls to the unstable DLL could be made in a spawned thread or even the code could be in an new external executable that you could launch with Process.Start.
This last option has more overhead but it might be your only option. See this SO question for more information on this: How do you handle a thread that has a hung call?
I suggest following solution.
Wrap this dll with another web application. Can be one of the following ones. Since you already use web api, it is most suitable for you.
Simple ASMX Web Service
WCF Service
Asp.Net MVC - WEB Api Service
Control your p-invoke code so that you do not have any bug? See following articles.
The Black Art of P/Invoke and Marshaling in .NET
P/Invoke Revisited
Publish this application to IIS with different application pool.
Use standard techniques suggested before like. I suggest configure recycling IIS for both memory and scheduled times.
IIS process recycling rate
How to limit the memory used by an application in IIS?
I have an asp.net mvc 2 app, and I need to run a task (call WS, save into db) once a day. What is the suggested way for this? One thing, I have a feeling I would like to execute this task from within the webapp.
Does anyone have any suggestions:
I was considering .net quartz or regular System.Timers.Timer?
Does anyone see any problems?
Any other better solutions?
Thanks a lot
--MB
Why do you want to run this from the webapp? You have no way of even knowing if the webapp will be running at the required time. I would recommend you look at Windows Services
web apps are not the best host for a scheduled task. Unless you implement a system to keep the process awake, there's no chance to be sure your schedule will be executed.
Quartz.net is good for that.
It consists in a core module which you can use in your web app to save tasks and a server (windows service) module which executes your scheduled jobs.
I've recently implemented my own windows services and used Sql Server as storage for my scheduled jobs. Everything works pretty well, even if, I had to struggle a little bit to put things together.
The documentations is not always so clear.
Have a look at Quartz.Net, which is available as a NuGet package or from their site.
There are lots of examples of how to set these up, they are very flexible, you just have to define a class which implements IJob with a single Execute() method which gets fired by your choice of triggers.
You could also consider using Windows Workflow Foundation.
I am writing a web application in ASP.NET 3.5 that takes care of some basic data entry scenarios. There is also a component to the application that needs to continuously poll some data and perform actions based on business logic.
What is the best way to implement the "polling" component? It needs to run and check the data every couple of minutes or so.
I have seen a couple of different options in the past:
The web application starts a background thread that will always run while the web application does. (The implementation I saw started the thread in the Application_Start event.)
Create a windows service that is always running
What are the benefits to either of these options? Are there additional options?
I am leaning toward a windows service because it is separated and can run on a different server (more scalable) as well as there is more control over when it is started/stopped, etc. However, I feel like the compactness of having the "background" logic running in the process of the web application might make the entire solution more understandable.
I'd go for the separate Windows service primarily for the reasons you give:
You can run it on a different server if necessary.
You can start and stop it independently of the web site.
I'd also add that it could well have some impact on the performance of the web site itself - something you want to avoid.
The buzz-word here is "separation of concerns". The web site is concerned with presenting the data to the user, the service with checking the integrity of the data.
You can also update the web site and service independently of each other should you need to.
I was going to suggest that you look at a scheduled task and let Windows control when the process runs, but I re-read your question and noted that you wanted the checks to run every couple of minutes. The overhead of starting the process might be too great in this case - though some experimentation would probably prove this one way or the other.
If you use a scheduled task there's also the possibility that you could start the next check before the current one has finished - something you can code for if you're in complete control.
Why not just use a console app that has no ui? Can do all that the windows service can and is much easier to debug and maintain. I would not do a windows service unless you absolutely have to.
You might find that the SQL Server job scheduler sufficient for what you want.
Console application does not do well in this case. I wrote a TAPI application which has to stay in the background and intercept incoming calls. But it did it only once because the tapi manager got GCed and was never available for the second incoming call.
I need to create an ASP page (classic, not ASP.NET) which runs remote shell scripts on a UNIX server, then captures the output into variables in VBScript within the page itself.
I have never done ASP or VBScipt before. I have tried to google this stuff, but all I find are references to remote server side scripting, nothing concrete.
I could really use:
An elementary example of how this could be done.
Any other better alternatives to achieve this in a secure manner.
Are there any freeware/open source alternatives to these libraries?
Any examples?
If the shell scripts are normally run on a telnet session then you could screen scrape and parse the responses. There are commercial COM components out there such as the Dart telnet library: http://www.dart.com/pttel.aspx that would let you do this.
Either that or you could roll your own using AspSock http://www.15seconds.com/component/pg000300.htm
#Pascal, sadly I'm not aware of any F/OSS alternatives. We usually just buy in these types of libraries provided that they're not hugely expensive, and more often than not the cost is built into the customer's overall project cost.
If you had .NET on the server, you could build a COM wrapped component to do the heavy lifting around System.Net.Sockets.TcpClient. Just a thought.
Jeff has previously blogged about using the cache to perform "out of band" processing on his websites, however I was wondering what other techniques people are using to process these sorts of tasks?
Years ago, I saw Rob Howard describe a way to use an HttpModule to process tasks in the background. It doesn't seem as slick as using the Cache, but it might be better for certain circumstances.
This blog post has the details, and there are many others that capture the same information if you look around.
Windows Service
You may want to look at how DotNetNuke does it. I know it is written in VB.NET, but I retrofitted the code into C#. I was perusing the source and noticed they had a feature in their admin area to setup scheduled tasks. These tasks get setup thru the admin interface and stored in the database. When the site starts, thru the Global.asax file, they either created another thread to run this service that then runs the scheduled tasks at their scheduled time. I can't remember the exact logic, it's been a while, but it is definitely a good resource on how other people have done out of band processes for Asp.Net applications. This technique still keeps the logic within the Asp.Net application, but it runs out of band in my opinion.
if it's primarily data processing tasks and you're using MSSQL, how about scheduled SSIS tasks?
Scheduled tasks using http://www.codeproject.com/KB/cs/tsnewlib.aspx or schtasks.exe.
Quartz.NET
MSMQ
SQL Server jobs
Windows service
System.Threading.Timer or System.Timers.Timer
System.ComponentModel.BackgroundWorker
Asynchronous calls and callbacks
Scheduled tasks, or cron jobs.
The problem with scheduled tasks or cron jobs is that they don't share memory space with the web server. You could set up a scheduled task that requested pages from the web server, but that might create problems with long running tasks. It would be nice to have some low priority threads running on the actual ASP.Net application stack to do simple utility tasks like cleaning up caches, monitoring resources, and just to deal with general housekeeping.
Simple queue files along with a separate agent. For each type of out of band process write a separate agent .exe which watches a directory for queue files that include whatever data is needed to perform the specified process.
This may seem dirty but in the real world I find it gives a lot of flexibility, you aren't doing a lot of processing in ASP.net process space and you could easily adapt this style to farm processing out to cheap Linux servers running the agent process on Mono for when you start needing more RAM/CPU/disk.
If you are most comfortable with asp.net pages you can write a small app to handle your job and then "ping" the app with an outside service that monitors your web site. This will keep the app alive.