Asp.net 为什么appcmd.exe解锁配置在Azure emulator上不起作用?

Asp.net 为什么appcmd.exe解锁配置在Azure emulator上不起作用?,asp.net,azure,iis,ssl,ssl-certificate,Asp.net,Azure,Iis,Ssl,Ssl Certificate,我最近升级到了Azure 2.1 SDK,现在在compute emulator上运行时,我的web.config在web角色中遇到了一个问题。我的web.config包含以下内容: <location path="api"> <system.webServer> <security> <access sslFlags="Ssl, SslRequireCert, SslNegotiateCert" /> </s

我最近升级到了Azure 2.1 SDK,现在在compute emulator上运行时,我的
web.config
在web角色中遇到了一个问题。我的
web.config
包含以下内容:

<location path="api">
  <system.webServer>
    <security>
      <access sslFlags="Ssl, SslRequireCert, SslNegotiateCert" />
    </security>
  </system.webServer>
  <system.web>
    <authorization>
      <allow users="*" />
    </authorization>
  </system.web>
</location>
SET APPCMD=%windir%\system32\inetsrv\appcmd.exe
IF EXIST APPCMD GOTO :INUSUALPLACE
SET APPCMD="%ProgramFiles%\IIS Express\appcmd.exe"
:INUSUALPLACE
%APPCMD% unlock config /section:system.webServer/security/access
如果没有这个,你会得到一个500.19的错误。直到最近,此启动任务始终成功地防止了该错误,使我的SSL配置能够正常工作

但它不再工作了,据我所知,这是在我切换到2.1 SDK时发生的。顺便说一句,此web角色中的所有其他内容都起作用-只有在尝试访问SSL配置设置所应用的
/api/
路径下的服务时,我才会出错。这是500.19。(500当然是“内部服务器错误”,但.19表示是配置错误。)

据我所知,这是因为解锁此配置部分的尝试不再有效。我这样说的原因是,如果我找到Azure emulator创建的
applicationHost.config
文件(在
C:\Users\\AppData\Local\dftmp\Resources\\temp\temp\RoleTemp
中),并手动编辑它,将
安全性
元素的
Deny
替换为
允许
,我就不再收到错误,并且可以成功使用需要客户端证书的服务

当然,这并不是解决问题的办法——每次在emulator中运行应用程序时,都会重新生成这个
applicationHost.config
(每次都会更改确切的位置)。每次在本地调试应用程序时,我需要某种方法来可靠地自动解锁此配置部分。这就是appcmd.exe应该做的,但它似乎已经停止工作了

我确实想到,问题可能是它正在获取IIS版本的
appcmd.exe
,即使Azure SDK现在使用IIS express。我不确定它们是否是不同的程序,因此我尝试在启动命令末尾添加以下内容:

"%ProgramFiles%\IIS Express\appcmd.exe" unlock config /section:system.webServer/security/access
这将显式运行IIS Express副本。但这似乎没有什么区别

在任何人要求之前,启动任务肯定正在运行。在与
applicationHost.config
相同的文件夹中,我看到一个
WaHostBootstrapper.log
文件,其中包含(除其他外)以下行:

[00025156:00018324, 2013/08/30, 22:15:03.033, INFO ] Executing Startup Task type=0 rolemodule=(null) cmd="c:\dev\mm\DevInt\src\Mm.Cloud\csx\Debug\roles\Mm.Web\approot\bin\Startup\EnableClientCerts.cmd" 
[00025156:00018324, 2013/08/30, 22:15:03.034, INFO ] Executing "c:\dev\mm\DevInt\src\Mm.Cloud\csx\Debug\roles\Mm.Web\approot\bin\Startup\EnableClientCerts.cmd" .
[00025156:00018324, 2013/08/30, 22:15:03.221, INFO ] Program "c:\dev\mm\DevInt\src\Mm.Cloud\csx\Debug\roles\Mm.Web\approot\bin\Startup\EnableClientCerts.cmd"  exited with 0. Working Directory = c:\dev\mm\DevInt\src\Mm.Cloud\csx\Debug\roles\Mm.Web\approot\bin
这表示我的
EnableClientCerts.cmd
(调用
appcmd.exe
的脚本)运行时没有错误

我不完全清楚
appcmd.exe
如何知道应该配置哪个特定网站。有几个-我已经在这个盒子上安装了IIS,并且还配置了一个与Azure无关的IIS Express站点。是否可能无法配置正确的目标

另外,我在
WaHostBootstrapper.log
中看到了一些此类错误:

[00025156:00018324, 2013/08/30, 22:15:03.033, ERROR] <- WapGetEnvironmentVariable=0x800700cb

[00025156:000183242013/08/30,22:15:03.033,错误]结果表明,当模拟器启动启动任务时,它已经设置了
APPCMD
变量。此外,它设置它不仅是为了引用
AppCmd.exe
,它还包括一个指向正确配置文件的命令行开关:

“C:\Program Files\IIS Express\appcmd.exe”/apphostconfig:“C:\Users\Ian\AppData\Local\dftmp\Resources\1217ef49-a59a-4e18-8ebc-27d06a78cbd5\temp\temp\RoleTemp\applicationHost.config”

因此,如果启动脚本只使用
%APPCMD%
,而没有首先尝试设置它,它将应用于正确的实例。我的脚本无法工作,因为它自行决定了AppCmd.exe的位置,并最终修改了IIS或IIS Express的全局设置,这两种设置似乎都不会对Azure Emulator承载的IIS实例产生任何影响。(我猜这是最近行为上的变化,可能与Azure SDK 2.1中支持非升级开发的新功能有关。)

让我担心的是,我找不到任何文档提到这个预定义的
APPCMD
变量。我只是通过在启动命令脚本中添加以下内容才发现它:

%SystemRoot%\system32\WindowsPowerShell\v1.0\powershell.exe "gci env: | format-list"  > c:\temp\env.log
我临时添加了它并运行了web角色,它提供了所有环境变量的完整转储。查看该列表,只有
APPCMD
变量包含正确配置所需的信息。但是关于启动任务的文档似乎建议直接指向
AppCmd.exe
的IIS副本-本文只是对路径进行硬编码。我想,如果我在模拟器中启用了完整IIS的使用,那就行了,但我真的不想这么做


因此,尽管这个解决方案有效(并且似乎是唯一可行的解决方案,考虑到启动任务的环境),但它让我感到紧张,因为它是一个未记录的特性。因此,如果您偶然发现了这个答案,请小心-它可能不可靠。

您知道该变量是否也存在于云中,还是仅存在于模拟器中?它似乎存在于云中-此脚本在模拟器和云中都起作用。但这与我有关,因为它没有文档记录。我最终得到了这个“先决条件”:如果没有定义APPCMD,则设置APPCMD=%SystemRoot%\system32\inetsrv\APPCMD.exe