approot和siteroot在Azure中

我的Azure Web角色需要能够删除存储在App_Data子文件夹中的临时本地文件。我想在Azure提升的启动任务中使用ICACLS,以允许IIS如下执行此操作: ICACLS App_Data / grant \“ IIS_IUSRS \” :( OI)(CI)F 但是,我的启动任务在以下位置执行: E:\\ approot \\ bin 而Web应用程序实际终止并从其执行的根文件夹似乎是: E:\\ sitesroot \\ 0 我不愿意硬编码此路径,以防Microsoft更改此路径。是否有办法从启动任务中获取此路径,还是可以依靠此目标? 要在ASPX中对此进行测试,请添加:
Label1.Text = \"MapPath: \" + Server.MapPath(\"~/\");
Label2.Text = \"RoleRoot: \" + Environment.GetEnvironmentVariable(\"RoleRoot\");
在已部署的实例上运行此命令时,我得到: MapPath:E:\\ sitesroot \\ 0 \\ RoleRoot: 即RoleRoot为空。 那么如何获取Server.MapPath(\“〜/ \”);的结果?在启动任务中?     
已邀请:
        不,我认为从启动任务开始,没有一种方法可以使您的网站成为Web角色的根。     
        为什么不相对地得到它?部署了siteroot和approot的驱动器似乎在E:\\和F:\\之间切换,但是我认为现在假设它们将被部署为同级文件夹是比较安全的选择。 这是我们要从sitesroot文件夹复制文件的启动任务:
xcopy \"../../sitesroot/0/bin\" \"../../sitesroot/1/bin\" /y /i /S
xcopy \"../../sitesroot/0/bin\" \"../../sitesroot/2/bin\" /y /i /S
xcopy \"../../sitesroot/0/bin\" \"../../sitesroot/3/bin\" /y /i /S
xcopy \"../../sitesroot/0/bin\" \"../../sitesroot/4/bin\" /y /i /S
xcopy \"../../sitesroot/0/bin\" \"../../sitesroot/5/bin\" /y /i /S
    
        不要使用命令提示符中的icacls,而是使用Powershell脚本,因为Powershell允许您枚举IIS中的网站并获取物理文件夹路径。 不幸的是,您无法将Powershell脚本设置为启动任务。因此,您必须创建一个常规的CMD或BAT文件,然后在该文件中要求Powershell执行您的脚本。 CMD文件:
PowerShell -ExecutionPolicy Unrestricted .\\Setup.ps1 >> %TEMP%\\Setup-DebugLog.txt 2>&1
exit /B 0
第一行执行Powershell脚本,并将所有输出保存到文件Setup-DebugLog.txt。第二行确保CMD文件将OK返回给Windows Azure,因此Azure知道启动脚本中一切正常。 这是我用来在App_Data文件夹上设置文件夹权限的Powershell脚本:
Import-Module WebAdministration
cd IIS:\\Sites
$dir = Get-ChildItem
$timeout = 0
while ($dir -eq $NULL -and $timeout -lt 11)
{
    \"IIS Site not ready. Waiting for 2 seconds...\"
    [System.Threading.Thread]::Sleep(2000)
    $timeout++
    $dir = Get-ChildItem
}

if ($dir -eq $NULL)
{
    \"IIS Site still not ready. Aborting.\"
}
else
{
    \"IIS site ready.\"
    Set-Location $dir.physicalPath
    \"Location is $($dir.physicalPath)\"
    $acl = (Get-Item App_Data).GetAccessControl(\"Access\")
    $rule = New-Object System.Security.AccessControl.FileSystemAccessRule(\"Network Service\", \"Modify, Write\", \"ContainerInherit, ObjectInherit\", \"None\", \"Allow\")
    $acl.AddAccessRule($rule)
    Set-Acl App_Data $acl
    \"Permission added.\"
}
首先导入WebAdministration模块,该模块允许Powershell与IIS进行交互。然后,它尝试枚举网站。但是,这是一个有趣的挑战。因为,在将网站部署到IIS之前,将运行启动任务。因此,您需要将启动任务设置为作为后台任务运行,然后等待站点已部署。因此,该代码尝试枚举网站,如果找不到网站,则等待2秒钟,然后再次尝试。它总共执行20秒钟,然后超时。 如果网站已准备就绪,则将找到物理路径,并将FileSystemAccessRule添加到App_Data文件夹的ACL。您可以修改添加的权限以适合您的需求。 请注意,此脚本期望IIS中只有1个站点。如果您部署多个网站,则此脚本可能不起作用,您将不得不修改代码。 为了完整起见,这是您应该添加到
ServiceDefinition.csdef
中的XML:
<Startup>
  <Task commandLine=\"Setup.cmd\" executionContext=\"elevated\" taskType=\"background\" />
</Startup>
Setup.cmd
Setup.ps1
都应放在网站的根目录中。如果希望将它们放置在网站的子文件夹中,则可以这样做,但随后必须将Task元素中的commandLine属性更新为\“ Subfolder \\ Setup.cmd \”,然后您需要在CMD文件中更新Powershell文件的路径:
PowerShell -ExecutionPolicy Unrestricted .\\Subfolder\\Setup.ps1 >> %TEMP%\\Setup-DebugLog.txt 2>&1
另外,请注意,在Powershell v1和v2之间调用Powershell脚本存在一些差异。如果我没记错的话,Windows Azure上的Windows 2008运行Powershell v1,而Windows 2008 R2和更高版本运行Powershell v2。因此,如果您在Azure上使用Windows 2008,则需要更改调用Powershell脚本的行,因为在设置执行策略方面存在一些差异。     
        有一个名为%ROLEROOT%的环境变量,它获取应用程序的路径。
string appRoot = Environment.GetEnvironmentVariable(\"RoleRoot\");

appRoot = Path.Combine(appRoot + @\"\\\", @\"approot\\\");
在此处了解更多信息。     

要回复问题请先登录注册