问题
I have an azure cloud service which I am attempting to upgrade for high availability and I have subscribed to the Microsoft Azure File Service preview which has been enabled in the preview portal. I have created a new storage account and can see the storage account now has a Files endpoint located at:
https://<account-name>.file.core.windows.net/
Within my web role I have the following code which looks to see if a share called scorm is created and if not it creates it:
public static void CreateCloudShare()
{
CloudStorageAccount account = CloudStorageAccount.Parse(System.Configuration.ConfigurationManager.AppSettings["SecondaryStorageConnectionString"].ToString());
CloudFileClient client = account.CreateCloudFileClient();
CloudFileShare share = client.GetShareReference("scorm");
share.CreateIfNotExistsAsync().Wait();
}
This works without issue. My problem is that I am unsure as to how to map the CloudShare that has been created as a virtual directory within my cloud service. On a single instance I was able to do this:
public static void CreateVirtualDirectory(string VDirName, string physicalPath)
{
try
{
if (VDirName[0] != '/')
VDirName = "/" + VDirName;
using (var serverManager = new ServerManager())
{
string siteName = RoleEnvironment.CurrentRoleInstance.Id + "_" + "Web";
//Site theSite = serverManager.Sites[siteName];
Site theSite = serverManager.Sites[0];
foreach (var app in theSite.Applications)
{
if (app.Path == VDirName)
{
// already exists
return;
}
}
Microsoft.Web.Administration.VirtualDirectory vDir = theSite.Applications[0].VirtualDirectories.Add(VDirName, physicalPath);
serverManager.CommitChanges();
}
}
catch (Exception ex)
{
System.Diagnostics.EventLog.WriteEntry("Application", ex.Message, System.Diagnostics.EventLogEntryType.Error);
//System.Diagnostics.EventLog.WriteEntry("Application", ex.InnerException.Message, System.Diagnostics.EventLogEntryType.Error);
}
}
I have looked and seen that it is possible to map this via powershell but I am unsure as to how I could call the code within my web role. I have added the following method to run the powershell code:
public static int ExecuteCommand(string exe, string arguments, out string error, int timeout)
{
Process p = new Process();
int exitCode;
p.StartInfo.FileName = exe;
p.StartInfo.Arguments = arguments;
p.StartInfo.CreateNoWindow = true;
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardError = true;
p.Start();
error = p.StandardError.ReadToEnd();
p.WaitForExit(timeout);
exitCode = p.ExitCode;
p.Close();
return exitCode;
}
I know that the command I have to run is:
net use z: \\<account-name>.file.core.windows.net\scorm /u:<account-name> <account-key>
How can I use this from within my web role? My web role code is as follows but does not seem to be working :
public override bool OnStart()
{
try
{
CreateCloudShare();
ExecuteCommand("net.exe", "user " + userName + " " + password + " /add", out error, 10000);
ExecuteCommand("netsh.exe", "firewall set service type=fileandprint mode=enable scope=all", out error, 10000);
ExecuteCommand("net.exe", " share " + shareName + "=" + path + " /Grant:" + userName + ",full", out error, 10000);
}
catch (Exception ex)
{
System.Diagnostics.EventLog.WriteEntry("Application", "CREATE CLOUD SHARE ERROR : " + ex.Message, System.Diagnostics.EventLogEntryType.Error);
}
return base.OnStart();
}
回答1:
Our blog post Persisting connections to Microsoft Azure Files has an example of referencing Azure Files shares from web and worker roles. Please see the "Windows PaaS Roles" section and also take a look at the note under "Web Roles and User Contexts".
回答2:
The library RedDog.Storage makse it really easy to mount a drive in your Cloud Service without having to worry about P/Invoke:
Install-Package RedDog.Storage
After the package is installed, you can simply use the extension method "Mount" on your CloudFileShare:
public class WebRole : RoleEntryPoint
{
public override bool OnStart()
{
// Mount a drive.
FilesMappedDrive.Mount("P:", @"\\acc.file.core.windows.net\reports", "sandibox",
"key");
// Unmount a drive.
FilesMappedDrive.Unmount("P:");
// Mount a drive for a CloudFileShare.
CloudFileShare share = CloudStorageAccount.Parse(CloudConfigurationManager.GetSetting("StorageConnectionString"))
.CreateCloudFileClient()
.GetShareReference("reports");
share.Mount("P:");
// List drives mapped to an Azure Files share.
foreach (var mappedDrive in FilesMappedDrive.GetMountedShares())
{
Trace.WriteLine(String.Format("{0} - {1}", mappedDrive.DriveLetter, mappedDrive.Path));
}
return base.OnStart();
}
}
More information: http://fabriccontroller.net/blog/posts/using-the-azure-file-service-in-your-cloud-services-web-roles-and-worker-role/
来源:https://stackoverflow.com/questions/24960184/mapping-an-azure-file-service-cloudfileshare-as-a-virtual-directory-on-each-inst