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

Posted

技术标签:

【中文标题】IIS 7.5 应用程序池为自定义用户使用错误的 %APPDATA% 作为标识【英文标题】:IIS 7.5 application pool uses wrong %APPDATA% for custom user as identity 【发布时间】:2012-03-18 09:45:54 【问题描述】:

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

现在我遇到的问题是 %APPDATA%(在 C# 中):

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 上使用相同的主要版本 7.5 的 IIS 时遇到了这个问题。 我使用与以前相同的过程:创建一个新用户,以该用户身份登录以创建配置文件和 APPDATA 目录,然后添加具有此身份的应用程序池,最后将 Web 应用程序添加到此池中。

有什么想法吗?

【问题讨论】:

您的应用程序池是配置为经典模式还是集成模式? 我也有同样的问题。特别奇怪的是 Environment.SpecialFolder.UserProfile 的路径工作正常,如果我从那里建立 AppData 文件夹的路径,它就可以工作。 【参考方案1】:

应用程序池 - 您的应用程序池 - 高级设置 ...

流程模型 - 加载用户配置文件集 True。

它对我有帮助。

取自 https://blogs.msdn.microsoft.com/vijaysk/2009/03/08/iis-7-tip-3-you-can-now-load-the-user-profile-of-the-application-pool-identity/

【讨论】:

【参考方案2】:

我最近遇到了同样的问题。正如 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"

希望对你有帮助

【讨论】:

【参考方案3】:

打开您的%WINDIR%\System32\inetsrv\config\applicationHost.config 并查找&lt;applicationPoolDefaults&gt;。在&lt;processModel&gt; 下,确保您没有setProfileEnvironment="false"。如果这样做,请将其设置为 true。

【讨论】:

值为&lt;processModel identityType="ApplicationPoolIdentity" /&gt; 设置为&lt;processModel identityType="ApplicationPoolIdentity" loadUserProfile="true" setProfileEnvironment="true" /&gt; 这个答案是为我解决问题的答案。 在我的例子中,将setProfileEnvironment="true"添加到特定的应用程序池就足够了。无需更改默认条目中的setProfileEnvironment 值。 为什么在 IIS 管理器中 LoadUserProfile 是一个选项,而 SetProfileEnvironment 不是?【参考方案4】:

问题在于您的 IIS 设置。答案就在这里:Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) returns String.Empty

【讨论】:

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

我遇到了同样的问题。您是否偶然安装了 Visual Studio 11 测试版?我最近这样做了,我注意到与 4.0 兼容的 .dll 与我们的代码的工作方式存在一些差异。我仍在尝试确定问题所在,但在此之前我没有遇到此问题。

编辑:

比较了4.0和4.5的GetFolderPath(及相关)的反编译源后,有区别。它们是否是问题的根源……我还不确定。

编辑 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( );

【讨论】:

不,我安装了 Visual Studio 2010,没有其他测试版。有哪些区别? 我也收到 0x80070005 (E_ACCESSDENIED)。将尝试进行更多调查。

以上是关于IIS 7.5 应用程序池为自定义用户使用错误的 %APPDATA% 作为标识的主要内容,如果未能解决你的问题,请参考以下文章

自定义异步 HTTP 处理程序仅在 IIS 7.5 集成模式下生成错误 500 - 为啥?

IIS 7.5 即使在禁用时也使用模拟

IIS 7.5 中的 Windows 身份验证失败

无法从另一个 7.5 连接到 IIS 7.5

IIS 7.5 Windows 身份验证失败,除非代码文件共享给最终用户

使用 IIS 7.5 进行表单身份验证 - 未授权