IIS 7.5 应用程序池使用错误的 %APPDATA% 作为自定义用户的身份标识。

15

我希望我的MVC3 Web应用程序能够访问%APPDATA%(例如,在Windows 7上的C:\Users\MyUsername\AppData\Roaming),因为我在那里存储配置文件。因此,我在IIS中创建了一个具有用户"MyUsername"身份的应用程序池,并通过使用该帐户登录来创建了该用户的配置文件,并打开了选项"加载用户配置文件"(默认情况下为true)。模拟用户被关闭。

现在我遇到了一个问题,就是在C#中使用%APPDATA%:

appdataDir = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)

问题是所得结果为c:\windows\system32\inetsrv,而不是C:\Users\MyUsername\AppData\Roaming

更新: 更确切地说,上述C#代码返回一个空字符串,因此Path.GetFullPath(Path.Combine(appdataDir, "MyAppName"))会在我的应用程序名称前面添加当前路径,从而导致c:\windows\system32\inetsrv\MyAppName

我知道我以前在Windows Server 2008 R2上使用相同的Web应用程序使其工作,现在我在我的Windows 7上使用相同的IIS主版本7.5时出现了这个问题。
我使用与以前相同的过程:创建一个新用户,登录该用户创建配置文件和APPDATA目录,然后使用此身份添加应用程序池,并最终将Web应用程序添加到该池中。

有什么想法吗?


你的应用程序池配置为经典模式还是集成模式? - Kev
我有同样的问题。特别奇怪的是,Environment.SpecialFolder.UserProfile的路径正常工作,如果我从那里构建到AppData文件夹的路径,它也能正常工作。 - Jason
5个回答

23
打开%WINDIR%\System32\inetsrv\config\applicationHost.config文件并查找<applicationPoolDefaults>。在<processModel>下,确保你没有setProfileEnvironment="false"的设置。如果有,请将其设置为true。

该值为 <processModel identityType="ApplicationPoolIdentity" /> - AndiDog
将其设置为 <processModel identityType="ApplicationPoolIdentity" loadUserProfile="true" setProfileEnvironment="true" /> - Amit Apple
2
这个答案解决了我的问题。 - anon
在我的情况下,只需要在特定的应用程序池中添加 setProfileEnvironment="true" 就足够了。不必更改默认条目中的 setProfileEnvironment 值。 - Heinzi
2
为什么在IIS管理器中LoadUserProfile是一个选项,但SetProfileEnvironment不是? - Triynko

5

3

最近我也经历了同样的问题。正如Amit所说,问题在于用户配置文件未加载。该设置适用于所有应用程序池,在applicationHost.config中进行配置(通常位于C:\Windows\System32\inetsrv\config\applicationHost.config)。如果您按照以下方式更新applicationPoolDefaults元素,它将起作用:

<applicationPoolDefaults managedRuntimeVersion="v4.0">
  <processModel identityType="ApplicationPoolIdentity" loadUserProfile="true" setProfileEnvironment="true" />
</applicationPoolDefaults>

我们已经在IIS 7.5上尝试过这个方法,并且在生产环境中也没有问题。

如果您想要自动化,可以尝试以下操作;

appcmd set config -section:system.applicationHost/applicationPools /applicationPoolDefaults.processModel.setProfileEnvironment:"true" /commit:apphost

或者如果您更喜欢使用powershell

Set-WebConfigurationProperty "/system.applicationHost/applicationPools/applicationPoolDefaults/processModel" -PSPath IIS:\ -Name "setProfileEnvironment" -Value "true"

希望这能帮助到您。

0

我也遇到了同样的问题。你有没有安装Visual Studio 11 beta?我最近安装了它,发现一些与我们代码兼容的4.0 .dll文件的差异。我仍在努力查找问题所在,但在那之前我并没有遇到这个问题。

编辑:

比较GetFolderPath(及相关内容)的4.0和4.5反编译源代码后,发现有差异。它们是否是问题的根源...我还不确定。

编辑2:以下是相关更改。我正在尝试两种方法,看看是否会得到不同的结果。[删除代码]

编辑3:

我现在尝试直接调用SHGetFolderPath,这正是.NET Framework最终要做的。它返回E_ACCESSDENIED(-2147024891 / 0x80070005)。我不知道在某些特定情况下为什么会出现这种情况,而在其他情况下却不会。

编辑4:

由于你得到了一个空字符串,你可能想要切换你的代码使用SHGetFolderPath,这样你就可以获得HResult,并至少知道到底发生了什么。

void Main() {
    Console.WriteLine( GetFolderPath( Environment.SpecialFolder.ApplicationData ) );
}

[System.Runtime.InteropServices.DllImport("shell32.dll")]
static extern int SHGetFolderPath(IntPtr hwndOwner, int nFolder, IntPtr hToken, uint dwFlags, StringBuilder pszPath);

private string GetFolderPath( Environment.SpecialFolder folder ) {
    var path = new StringBuilder( 260 );
    var hresult = SHGetFolderPath( IntPtr.Zero, (int) folder, IntPtr.Zero, 0, path );
    Console.WriteLine( hresult.ToString( "X" ) );

    return ( (object) path ).ToString( );
}

1
不,我已经安装了Visual Studio 2010,没有其他测试版。有哪些区别? - AndiDog
我也遇到了0x80070005(E_ACCESSDENIED)错误。会进一步调查。 - AndiDog

0

我已经加载了用户配置文件并遇到了同样的问题(我认为这个问题只会在Windows 7上出现)。 - AndiDog
根据您在原始问题中描述的内容,您确实创建了配置文件夹,但您没有采取必要的步骤来为IIS加载配置文件。如果您已经采取了这一步骤,请将其添加到您的描述中。如果没有,请阅读我提供的链接并按照说明操作。 - grahamesd
我在问题中提到我已经打开了该选项,所以这个解决方案似乎对我不起作用,抱歉。这可能与Windows 7有关。等我有时间了,我会在Windows 8上尝试一下,看看会发生什么。 - AndiDog
我认为你是对的。我在Win7 Pro和Win7 Enterprise上使用IIS尝试过,GetFolderPath返回一个空字符串。但在Win2008 R2上却能正常工作。我还尝试在Win7中将应用程序池标识更改为具有更高权限的帐户,然后得到了“C:\Windows\system32\config\systemprofile\AppData\Roaming”,这甚至不存在。所以我的结论与你的相同:它在Win7上不起作用。好消息是,在IIS Express中确实可以工作,因此您至少可以在Win7机器上进行开发。 - grahamesd

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接