3

私の 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("~/"); の結果を取得するにはどうすればよいですか。スタートアップタスクで?

4

4 に答える 4

3

比較的手に入れてみませんか?sitesrootapprootの両方がデプロイされるドライブは、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
于 2012-02-22T13:28:36.030 に答える
3

コマンド プロンプトから icacls を使用する代わりに、Powershell スクリプトを使用します。Powershell を使用すると、IIS で Web サイトを列挙し、物理フォルダー パスを取得できます。

残念ながら、Powershell スクリプトをスタートアップ タスクとして設定することはできません。そのため、通常の CMD または BAT ファイルを作成し、このファイルで Powershell にスクリプトの実行を依頼する必要があります。

CMD ファイル:

PowerShell -ExecutionPolicy Unrestricted .\Setup.ps1 >> %TEMP%\Setup-DebugLog.txt 2>&1
exit /B 0

最初の行は Powershell スクリプトを実行し、すべての出力をファイル Setup-DebugLog.txt に保存します。2 行目は、CMD ファイルが Windows Azure に OK を返すことを確認するため、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."
}

まず、Powershell が IIS と対話できるようにする WebAdministration モジュールをインポートします。次に、Web サイトを列挙しようとします。しかし、ここに興味深い課題があります。Web サイトが IIS に展開される前に、スタートアップ タスクが実行されるためです。そのため、スタートアップ タスクをバックグラウンド タスクとして実行するように設定し、サイトがデプロイされるまで待つ必要があります。そのため、コードは Web サイトの列挙を試み、Web サイトが見つからない場合は 2 秒間待ってから再試行します。これを合計 20 秒間行い、その後タイムアウトします。Web サイトの準備ができている場合は、物理パスが検出され、FileSystemAccessRule が App_Data フォルダーの ACL に追加されます。必要に応じて、追加された権限を変更できます。このスクリプトは、IIS にサイトが 1 つだけ存在することを想定していることに注意してください。複数の Web サイトを展開する場合、

完全を期すために、に追加する必要がある XML を次に示しますServiceDefinition.csdef

<Startup>
  <Task commandLine="Setup.cmd" executionContext="elevated" taskType="background" />
</Startup>

と の両方Setup.cmdSetup.ps1Web サイトのルートに配置する必要があります。それらを Web サイトのサブフォルダーに配置したい場合は、それを行うことができますが、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 スクリプトを呼び出す行を変更する必要があります。

于 2013-06-03T10:16:56.587 に答える
2

アプリケーションのパスを取得する %ROLEROOT% という環境変数があります。

string appRoot = Environment.GetEnvironmentVariable("RoleRoot");

appRoot = Path.Combine(appRoot + @"\", @"approot\");

詳細については、こちらをご覧ください。

于 2011-06-18T16:19:39.877 に答える
1

いいえ、スタートアップ タスクから Web サイトのルートを Web ロールで取得する方法はないと思います。

于 2011-06-18T22:54:55.510 に答える