Hey guys,
So I have another problem. I need to check out a file from PVCS from an ASP.NET webpage. In order to do so I spawn a process that calls a batch file which sets some environment variables and then calls the pvcs command get.exe to get the file. This all works great when I run it on my local machine, but as soon as I deploy to the server all hell breaks lose. The website impersonates the main user, this happens in the web.config (still not sure if relevant).
After trial and error, I narrowed down the problem to communication with shared drives. PVCS drive is mapped in the server. So I made a small batch script that only does a cd to a directory on this shared drive and it failed. Code is simply "cd Z:/work/".
Google gave some answers and more questions still. Apparently impersonation and shared drives simply do not work. But I'm not certain if that pertains to spawned process using C# Process class. Though, given that the webpage works perfectly in my machine without impersonation, this might have something to do with it. C# spawned processes have limited permissions, but I don't think this is the problem since my code is failing in doing a simple cd Z:\work\.
So I created a console app which does the check out (same code as the webpage) and it worked in the web server without a problem. The problem only occurs when I spawned the process from the webpage in the webserver. I made some dummy code to test.
I even tried to call the console app from the website, but that still doesn't work.
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void btnCheckout_Click(object sender, EventArgs e)
{
Command cmd = new Command(@"cmd", @"/c testpath.bat");
cmd.execute();
lblError.Text = cmd.stderr;
lblOutput.Text = cmd.stdout;
}
}
public class Command
{
// Private members
private Process process;
private int timeout;
// Public members
public string stderr { get; private set; }
public string stdout { get; private set; }
public string exception { get; private set; }
public bool done { get; private set; }
public int exitLevel { get; private set; }
/// <summary>
/// Construct a Command object that will be executed in a Windows environment.
/// </summary>
/// <param name="args">the command to execute in command prompt</param>
/// <param name="timeout">This is optional and consists of the time in milliseconds to wait for the command to finish. Default is 10 seconds.</param>
public Command(string exec, string args, string workingDir="", int timeout = 5000)
{
this.timeout = timeout;
this.exception = "";
process = new Process();
if (!string.IsNullOrEmpty(workingDir))
process.StartInfo.WorkingDirectory = workingDir;
process.StartInfo.FileName = exec;
process.StartInfo.Arguments = args;
process.StartInfo.UseShellExecute = false;
process.StartInfo.CreateNoWindow = true;
process.StartInfo.RedirectStandardError = true;
process.StartInfo.RedirectStandardOutput = true;
process.OutputDataReceived += process_OutputDataReceived;
}
void process_OutputDataReceived(object sender, DataReceivedEventArgs e)
{
if (!string.IsNullOrEmpty(e.Data))
{
stdout = e.Data;
}
}
public void execute()
{
try
{
process.Start();
process.BeginOutputReadLine(); // Note that the following three lines in any
stderr = process.StandardError.ReadToEnd(); // other order will deadlock.
process.WaitForExit(timeout);
}
catch (Exception e)
{
exception = e.Message;
Debug.WriteLine(e.Message + "\n" + e.StackTrace);
}
Thread.Sleep(1000);
}
}
Does anybody have any clue what my problem is?