redirecting cmd.exe to httpresponse
i had to solve an interesting problem today and it involved the ability to fire off command line processes from a web UI on IIS. since this was a 'triage' situation, i had a very short time to work out the details. i remembered that .NET exposes the Process and ProcessStartInfo objects that give you quite a bit of control over spawning command shells. with a little poking about, i was able to create a simple ASP.NET page that does the trick.
NOTE:
i made sure to place the ASPX page in a folder that requires a successful Windows auth to make sure only auth'ed users can run the script. it's an internal site, so there's reduced risk of hacking, but it's still a bit dicey to do this.
here's a simple example that will run a small batch file:
<%@ Page Language="C#" %>
<%@ Import Namespace="System.Diagnostics" %>
<%@ Import Namespace="System.IO" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
void Submit(object sender, EventArgs args)
{
string fmt_html = "<pre>{0}</pre>";
string batch_cmd = @"cmd.exe";
string working_dir = @"z:\jobs\";
string batch_job = @"z:\jobs\dirlist.bat";
string output = "";
// set up process to redirect std in/out
ProcessStartInfo psi = new ProcessStartInfo(batch_cmd);
psi.WorkingDirectory = working_dir;
psi.RedirectStandardOutput = true;
psi.RedirectStandardInput = true;
psi.RedirectStandardError = true;
psi.UseShellExecute = false;
try
{
// execute the job
using (StreamReader batch_rdr = File.OpenText(batch_job))
{
using (Process proc = Process.Start(psi))
{
using (StreamReader std_out = proc.StandardOutput)
{
using (StreamWriter std_in = proc.StandardInput)
{
// direct batch file to std_in
while (!batch_rdr.EndOfStream)
{
std_in.WriteLine(batch_rdr.ReadLine());
}
std_in.WriteLine("EXIT");
// stream std_out to a string.
output = std_out.ReadToEnd().Trim();
}
}
}
}
}
catch (Exception ex)
{
output = ex.Message;
}
// Write out the results.
results.Text = String.Format(fmt_html, output);
}
</script>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>simple batch job</title>
</head>
<body>
<form runat="server">
<div><asp:Button Text="Run" OnClick="Submit" runat="server" /></div>
<div><asp:Label ID="results" runat="server" /></div>
</form>
</body>
</html>
the output looks something like this:
Microsoft Windows [Version 5.2.3790] (C) Copyright 1985-2003 Microsoft Corp. Z:\jobs\>dir c:\ /B AUTOEXEC.BAT CONFIG.SYS Documents and Settings Inetpub Program Files WINDOWS Z:\jobs>EXIT