Environment.GetFolderPath() returns an empty string on Windows 8
I’ve been working on an OWIN based website on Windows 8 with IIS 8 Express, and hosting it on Server 2008 R2 with IIS 7.5. I also have my server setup with ARR to forward a subdomain to my local copy of IIS 8.5 so I can view whatever I’m working on from the internet if needed. Last night I needed to do just that so I pointed this site to my project folder, loaded it up, and then saw the all to familiar yellow screen of death.
The stack trace pointed to this line in the code:
Access to the path ‘AppName’ is denied.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.UnauthorizedAccessException: Access to the path ‘AppName’ is denied.
ASP.NET is not authorized to access the requested resource. Consider granting access rights to the resource to the ASP.NET request identity. ASP.NET has a base process identity (typically {MACHINE}ASPNET on IIS 5 or Network Service on IIS 6 and IIS 7, and the configured application pool identity on IIS 7.5) that is used if the application is not impersonating. If the application is impersonating via , the identity will be the anonymous user (typically IUSR_MACHINENAME) or the authenticated request user.
To grant ASP.NET access to a file, right-click the file in File Explorer, choose “Properties” and select the Security tab. Click “Add” to add the appropriate user or group. Highlight the ASP.NET account, and check the boxes for the desired access.
private static string GetDefaultPath(){ var path = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData); path = Path.Combine(path, "AppName");
Directory.CreateDirectory(path);
return path;}
Getting To The Bottom Of It
After some debugging and asking on JabbR it turns out there are two issues at play here.
The first issue was I didn’t have Load User Profile set to True for the App Pool I was using.
This will drop you into C:\Windows\System32\config\systemprofile\AppData\Local, not C:\Users\AppPoolName\AppData\Local
like I was expecting.
I found numerous sites saying just this, but even when I set this to true I was continuing to get an empty string back from Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)
.
The second issue is IIS 8, or 8.5 if you’re on Windows 8.1, has changed how Load User Profile works by default.
So even though I was setting this to true, IIS wasn’t honoring it fully.
Thanks goes to David Fowler for pointing me to the fix, which is to change setProfileEnvironment
to true
in %WINDIR%\System32\inetsrv\config\applicationHost.config
like so:
<configuration> <system.applicationHost> <applicationPools> <add name="DefaultAppPool" managedRuntimeVersion="v4.0" /> <add name="ASP.NET v4.0" managedRuntimeVersion="v4.0" /> <add name=".NET v4.5" managedRuntimeVersion="v4.0" managedPipelineMode="Integrated" /> <!-- ... --> <applicationPoolDefaults managedRuntimeVersion="v4.0"> <processModel identityType="ApplicationPoolIdentity" loadUserProfile="true" setProfileEnvironment="true" idleTimeout="00:00:00" /> </applicationPoolDefaults> </applicationPools> </system.applicationHost></configuration>
Bonus Chatter
I actually ran into this issue about 6 months ago while working on Kudu, who mention it in their development documentation. I can’t say for sure, but I think the Windows 8.1 update switched this back to false so there’s a chance this issue may pop back up when doing an OS upgrade.