我正在使用Azure文件服务来保存安装在角色实例上的程序可以访问的某些文件。
我已设法使用PowerShell脚本通过远程桌面将驱动器映射到文件服务共享。但是,当我尝试执行相同的脚本时,在辅助角色的OnStart()中,它不起作用。我无法弄清楚出了什么问题。
所以,这就是我的工作:
public override bool OnStart()
{
ServicePointManager.DefaultConnectionLimit = 12;
_slsPath = RoleEnvironment.GetLocalResource("StartupLocalStorage").RootPath;
var settingstring = CloudConfigurationManager.GetSetting("StorageConnectionString");
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(settingstring);
var blobClient = storageAccount.CreateCloudBlobClient();
CloudBlobContainer container = blobClient.GetContainerReference("zipfiles");
ICloudBlob blob = container.GetBlobReferenceFromServer("Program.zip");
//copy blob from cloud to local gallery
blob.DownloadToFile(_slsPath + "Program.zip", FileMode.Create);
// get powershell script for mounting drive
blob = container.GetBlobReferenceFromServer("mountdrive.ps1");
blob.DownloadToFile(_slsPath + "mountdrive.ps1", FileMode.Create);
// small exe for executing powershell script for mounting drive
blob = container.GetBlobReferenceFromServer("Programinstaller.exe");
blob.DownloadToFile(_slsPath + "Programinstaller.exe", FileMode.Create);
ZipFile.ExtractToDirectory(_slsPath + @"\Program.zip", _slsPath);
var share = storageAccount
.CreateCloudFileClient()
.GetShareReference("someshare");
share.CreateIfNotExists();
var filesPath = @"Z:\Folder";
// Mounting drive
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.CreateNoWindow = false;
startInfo.UseShellExecute = false;
startInfo.RedirectStandardOutput = true;
startInfo.FileName = _slsPath + @"Programinstaller.exe";
startInfo.WindowStyle = ProcessWindowStyle.Normal;
startInfo.Arguments = _slsPath + @"\ " + filesPath;
// Start the process with the info we specified.
// Call WaitForExit and then the using statement will close.
using (Process exeProcess = Process.Start(startInfo))
{
int count = 0;
var res = exeProcess.StandardOutput.ReadLine();
System.IO.File.WriteAllText(_slsPath + @"ResultOfDriveMount.txt", res + Environment.NewLine);
while (count < 30)
{
Thread.Sleep(1000);
res = exeProcess.StandardOutput.ReadLine();
System.IO.File.AppendAllText(_slsPath + @"ResultOfDriveMount.txt", res + Environment.NewLine);
count++;
}
}
}
好的,所以,Programinstaller.exe就是这样:
static void Main(string[] args)
{
Console.WriteLine(args[0]);
Thread t = new Thread(() =>
{
ExecutePowerShell(args[0] + "mountdrive.ps1", args[0]);
});
t.Start();
Thread.Sleep(20000);
InstallProgram(args[0], args[1]);
}
private static void ExecutePowerShell(string scriptfile, string SlsPath)
{
RunspaceConfiguration runspaceConfiguration = RunspaceConfiguration.Create();
Runspace runspace = RunspaceFactory.CreateRunspace(runspaceConfiguration);
runspace.Open();
RunspaceInvoke scriptInvoker = new RunspaceInvoke(runspace);
Pipeline pipeline = runspace.CreatePipeline();
//Here's how you add a new script with arguments
Command myCommand = new Command(scriptfile);
//CommandParameter testParam = new CommandParameter("key", "value");
//myCommand.Parameters.Add(testParam);
pipeline.Commands.Add(myCommand);
// Execute PowerShell script
var results = pipeline.Invoke();
foreach (var res in results)
System.IO.File.WriteAllText(SlsPath + @"ResultOfPowerShell.txt", res.ToString());
}
/// <summary>
/// Launch the legacy application with some options set.
/// </summary>
static void InstallProgram(string folderPath, string pathTwo)
{
// Use ProcessStartInfo class
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.CreateNoWindow = false;
startInfo.UseShellExecute = false;
startInfo.RedirectStandardOutput = true;
startInfo.FileName = folderPath + @"ProgramAuthor.ProgramName.exe";
startInfo.WindowStyle = ProcessWindowStyle.Normal;
startInfo.Arguments = folderPath + [someargument] + pathTwo;
try
{
// Start the process with the info we specified.
// Read output lines, store to txt
using (Process exeProcess = Process.Start(startInfo))
{
int count = 0;
var result = exeProcess.StandardOutput.ReadLine();
System.IO.File.WriteAllText(folderPath + @"ResultOfProgramInstall.txt", result + Environment.NewLine);
while (count < 300)
{
Thread.Sleep(1000);
result = exeProcess.StandardOutput.ReadLine();
System.IO.File.AppendAllText(folderPath + @"ResultOfProgramInstall.txt", result + Environment.NewLine);
count++;
}
}
}
catch (Exception ex)
{
System.IO.File.WriteAllText(folderPath + @"Error2.txt", ex.Message + " ... " + ex.StackTrace);
}
}
Ps1文件是这样的:
Set-Executionpolicy -Scope CurrentUser -ExecutionPolicy UnRestricted
cmdkey /add:[account].file.core.windows.net /user:[account] /pass:[key]
net use z: \\[account].file.core.windows.net\someshare
奇怪的是,运行从blob下载的Programinstaller.exe文件,从命令提示符 - 使用相同的参数 - 在worker角色的远程桌面中,将挂载映射的驱动器并安装程序。但是在部署之后从代码调用相同的文件(即从OnStart())不会安装驱动器。执行ProgramAuthor.ProgramFile.exe,并尝试在映射的驱动器中安装,但它从未映射,因此失败。
这是怎么回事?