Coffeehouse Thread

3 posts

ASP.NET and Network Drives Help

Back to Forum: Coffeehouse
  • pavone

    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?

  • itsnotabug

    instead of mapped drives, can you use fqdn?

     

    the who is the app pool identity running under?

     

    *edit*

    also, which user are you intending to have access to the shared drive? the impersonated end-user? network service? the app pool identity? you have to decide this first and verify those permissions on the shared folder. if your intention is the impersonated end-user you may have to set up delegation/kerberos for multi-hop credential passing.

  • blowdart

    Mapped drives are specific to a logged in user, so that's not going to work, as impersonation doesn't log in a user in such a way that drives map.

    Also impersonation doesn't "hop" over a process boundary, so when you try to access a remote resource impersonation will not escape to that connection.

    So, rather than trying to run the PVCS command line (I am seriously shocked people still use PVCS!) you could try an SDK if they offer one?

Comments closed

Comments have been closed since this content was published more than 30 days ago, but if you'd like to continue the conversation, please create a new thread in our Forums, or Contact Us and let us know.