Search code examples
c#azureprocessprocess.start

Process.Start Azure File Share


Now that everything for SMB 3.0 is setup for Azure file shares, it is easy to just open a new explorer window and navigate to \\myfileshare.file.core.windows.net\myfileshare. I have built a c# application that saves the username and password to an azure file share, to be used later on.

In order to make the application more user friendly (mostly will be used by SysAdmins) I want to add a File > Open Azure File Share button. This is where I am having trouble.

I will start with some given information : uncPath is the full that to the file share. Here is the code I have tried:

Process.Start(uncPath, username, password.ToSecureString(), ".");
--> Throws a Win32Exception, Username or Password incorrect 
--> (They are both correct, The Domain is throwing this off.)

I could never get around this issue, so I went another route. NET USE the File Share, then open it. This works, however I would like to unmap the share when the user exists the process. (I do not want to leave mapped drives laying around.) Here is the code i have tried:

/* --- MAP THE DRIVE --- */
Process p = new Process
{
    StartInfo = new ProcessStartInfo
    {
        FileName = "net.exe",
        Arguments = $"use {uncPath} /u:{username} {password}",
        RedirectStandardOutput = true,
        RedirectStandardError = true,
        UseShellExecute = false,
    }
};
p.Start();


/* --- OPEN THE UNC PATH --- */
Process azureP = new Process
{
    StartInfo =
        {
            FileName = "explorer.exe",
            Arguments = uncPath,
            UseShellExecute = false,
        },
    EnableRaisingEvents = true,
};
azureP.Start();

/* -- UNMAP THE DRIVE ON EXIT --- */
azureP.Exited += ((object proc, EventArgs procE) =>
{
    Process azurePExit = new Process
    {
        StartInfo = new ProcessStartInfo
        {
            FileName = "net.exe",
            Arguments = $"use {uncPath} /delete",
            RedirectStandardOutput = true,
            RedirectStandardError = true
        }
    };
});

As expected, azureP.Exited fires immediately, AND I UNDERSTAND WHY.

What would be the best way to open the azure file share?


Solution

  • What would be the best way to open the azure file share?

    In my opinion, the best way to access the file share in the local is using the SMB3.0 mount as disk.

    So I still suggest you could use command to mount and open it using windows explorer.

    But as your codes shows, the azureP process will not affect the explorer process.

    So the exit method will be fired immediately.

    Here is workaround.

    I suggest you could get the azureP process started explorer process id.

    Then you could use the Process.GetProcessesByName("explorer") method to get all the current explorer processes.

    Then you could write a while loop to check the selected processes has the opened the explorer according to the process id.

    If the process doesn't exist, then you could delete the mount disk and break the while.

    Notice:

    If the customer close the explorer, the process will not disappear immediately, it will wait for the windows collect it. It will take a few time.

    More details, you could refer to below codes:

            Process azureP = new Process
            {
                StartInfo =
             {
            FileName = "explorer.exe",
            Arguments = uncPath,
            UseShellExecute = false,
    
             },
                EnableRaisingEvents = true,
            };
    
            azureP.Start();
    
            azureP.WaitForExit();
            //find the open explorer process
            Process[] CurrentProcess1 = Process.GetProcessesByName("explorer");
            int Explorerprocessid = -1;
            foreach (var item in CurrentProcess1)
            {
                if (azureP.StartTime < item.StartTime)
                {
                    Console.WriteLine(item.Id);
                    Explorerprocessid = item.Id;
                }
            }
    
    
            while (true)
            {
                Thread.Sleep(5000);
                Process[] CurrentProcess2 = Process.GetProcessesByName("explorer");
                List<int> l1 = new List<int>();
                foreach (var item in CurrentProcess2)
                {
                    l1.Add(item.Id);
                }
                if (l1.Contains(Explorerprocessid))
                {
                    Console.WriteLine("Continue");
                }
                else
                {
                    //Delete the mount 
                    //Process azurePExit = new Process
                    //{
                    //    StartInfo = new ProcessStartInfo
                    //    {
                    //        FileName = "net.exe",
                    //        Arguments = $"use {uncPath} /delete",
                    //        RedirectStandardOutput = true,
                    //        RedirectStandardError = true
                    //    }
                    //};
                    Console.WriteLine("Break");
                    break;
                }
            }
    

    Result:

    1.When the program start running:

    enter image description here

    2.After closed the explorer:

    enter image description here