Environment.GetFolderPath(Environment.SpecialFolders.ApplicationData) returns C: - c#

I have encountered a very strange behavior on the computer of one of my clients and I cannot find any clue as to why it happens:
When the application calls Environment.GetFolderPath(Environment.SpecialFolders.ApplicationData)
the return value will be C:.
This is of course wrong, his AppData directory is the usual C:\Users\.....\AppData\Roaming and also his variable %APPDATA% points to exactly that directory.
Can anybody shed light on why this could possibly happen?
EDIT: The code...
LogFilePath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + #"\ReportsAddin";
if (!Directory.Exists(LogFilePath) && Properties.Settings.Default.Logging == true)
{
try
{
Directory.CreateDirectory(LogFilePath);
}
catch (Exception ex)
{
// ...
}
}
The exception thrown then says that it cannot create a directory consisting of a blank string or blank spaces. Investigating with some output showed that the AppData folder returning from that call is C: when in fact it should be the user's real AppData folder.

The actual path for the folder identified by Environment.SpecialFolder.ApplicationData depends on the current user (who started the program).
Make sure the program runs under a user account for which the ApplicationData folder exists.
If your program runs under e.g. a local system account you may want to use another directory.
Instead of Environment.SpecialFolder.ApplicationData you could use Environment.SpecialFolder.CommonProgramFiles or Environment.SpecialFolder.CommonProgramFilesX86.

Related

C# Windows Service Enviroment.GetFolderPath() returning empty string

The question is pretty straight forward, I am making a Windows Service Program and the enviroment.getfolderpath isnt working.
Here is the code I have
string savePath = AppDomain.CurrentDomain.BaseDirectory; // this works
string savePath2 = Environment.GetFolderPath(Environment.SpecialFolder.Desktop); // this returns an empty string...but why?
The documentation says
The path to the specified system special folder, if that folder
physically exists on your computer; otherwise, an empty string ("").A
folder will not physically exist if the operating system did not
create it, the existing folder was deleted, or the folder is a virtual
directory, such as My Computer, which does not correspond to a
physical path.
When running the Service as a Local System it doesn't run with any specific user permissions. Hence the GetFolderPath is returning empty because it is not able to recognize the path Desktop for LocalSystem.
You can either use Environment.SpecialFolder.CommonDesktopDirectory which will give C:\Users\Public\Desktop or
run the service with a specific user (in my case it's sampleuser) which will give the output as C:\Users\sampleuser\Desktop

Creating a folder on the desktop

I want to create a folder on my current user's desktop folder, however; I keep getting an access denied message. I have full write permissions under my profile in IIS.
string activeDir = #"C:\Users\dmm\Desktop\";
string newPath = System.IO.Path.Combine(activeDir, "mySubDir");
System.IO.Directory.CreateDirectory(newPath);
Any help would be appreciated.
Try using the built in objects to get the desktop path, and let .NET also handle the path building for the new folder. You will also want to check if the directory exists first.
string newFolder = "abcd1234";
string path = System.IO.Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.Desktop),
newFolder
);
if(!System.IO.Directory.Exists(path)) {
try {
System.IO.Directory.CreateDirectory(path);
} catch (IOException ie) {
Console.WriteLine("IO Error: " + ie.Message);
} catch (Exception e) {
Console.WriteLine("General Error: " + e.Message);
}
}
When you deploy an application on IIS by default it is executed with ApplicationPoolIdentity. Which is virtual user created and named as IIS AppPool\YourPoolName If this virtual user does not have write access to your desktop. You get that exception.
You have two options.
Give ApplicationPoolIdentity user write access to Desktop directory.
goto Desktop folder and add user IIS AppPool\YourPoolName with write access :
Change pool Identity to user which has write access to directory.
Go
IIS->Application Pools -> Your AppPool ->Advanced Settings -> Identity
->
Select Custom Account and click set button. and there you enter your windows user credentials.
I would recommend first option.
There are many to consider here, first of them being that your application is an ASP.NET application, and every current user will be different. If your application — just assume — runs correctly on your machine, it will never run on hosting environment because they do not grant write permissions to special folders and user accounts.
That said, you need to work in physical paths in order to create your directories.
var path = "C:\\Users\\afzaa\\Desktop\\";
var folder = Path.Combine(path, "folder");
Directory.CreateDirectory(folder);
The result of the above code is,
As you can see, the code properly works and has no issue at all in execution.
There are few things to note:
Your application has read/write permissions. Check IIS for that.
Your code can actually lookup the path you are trying to access. That applies to any folder inside Desktop too, a sub folder may have special permissions applied.
Do not do this, write the content online in your hosting domain. Users have different accounts and structures for folders and thus this will not work — Desktop path is different.
If you want to users to download the file, simply stream the file down and let them save it where they want to.
https://forums.asp.net/t/1807775.aspx?Create+e+New+Folder+Access+Denied+
https://answers.microsoft.com/en-us/windows/forum/windows_xp-files/unable-to-create-the-folder-new-folder-access-is/ac318218-a7b2-4ee2-b301-2ad91856050b
.NET MVC Access denied when trying to create Directory
If you ran your logic from an IIS application, you should use Server.MapPath:
System.IO.Directory.CreateDirectory(Server.MapPath(newPath));

C# Could not find a part of the path with Directory.GetDirectories

I'm trying to make an application that copies volume to a selected location in the computer.
The volume is an external hard disk that includes a copy of my previous computer C volume.
First of all, when I tried to copy the directories and the files I made an recursive function that gets the directories and the files and copy them to the new location, the recursive function gets the directories with Directory.GetDirectories function, after I get the sub directories I make the same function to get the sub directories of the sub directories and keeps doing that untill there are no directories to get, all works fine but when I tried to use the application on my volume I got an infiniate loop with "Application Data" folder, that means that the GetDirectories function found "Application Data" folder in the previous "Application Data" again and again.
In order to fix that I checked if the path does not include "Application Data\Application Data" and just the I used the GetDirectories function.
Maybe that solution caused the problem I'm going to ask about.
The problem is that when I use the function GetDirectories I get an exception: "Could not find a part of the path" but my code looks like this:
if(Directory.Exist(path))
{
string[] subdirs = Directory.GetDirectories(path);
}
So how is that possible that the Exist function finds the folder but the GetDirectories function does not find it?
By the way, the application works properly on directories that are not part of windows system.
So what is the problem? And how can I solve it or how can I make copy application that will copy C volume?
Thanks a lot
From Microsoft support:
A service that runs under a LocalSystem account or under a local user
account can only access mapped drives that the service creates. Mapped
drives are stored for each logon session. If a service runs under a
LocalSystem account or under a local user account that does not create
certain mapped drives, the service cannot access these mapped drives.
Additionally, a service that runs under a local user account that
creates certain mapped drives also receives a new set of mapped drives
if you log off and then you log on again as the same local user.
There is a workaround but it not necessary, just use try-catch for those libs:
if(Directory.Exist(path))
{
try
{
string[] subdirs = Directory.GetDirectories(path);
}
catch (Exception ex)
{
}
}
Or, alternatively, use Directory.GetDirectories SearchOptions so you can disclude certin sub-directories.

Method Directory.GetDirectories failures

Very odd that I am experiencing a occasional errors when calling the GetDirectories() method.
This started happening when our IT dept remotely moved some folders to my local machine. This error only occurs when navigating through these folders using C#.
Error Message: 'Access to the path 'C:\Users\XXXX\XXXXX is denied'
Code:
public static string[] GetDirectoryInfo(string path)
{
if (Directory.Exists(path))
{
//This call is failing on the new folder.
return Directory.GetDirectories(path);
}
return new string[0];
}
Not very complicated, correct?
Navigating with Windows Explorer, the folder isn't present.
In the CMD prompt I can change directory to this folder; following up with the DIR command I get the error 'File not found'.
I am guessing
the problem is a Win32 issue and something didn't get cleaned up when the folder was moved. I have no idea how to correct the issue, except for digging through decompiled System.IO classes; which I will do if I don't get a solution.
Your code is probably trying to access hidden folders that are not accessible to your account/role.
The easiest solution is to catch the UnauthorizedAccessException and just eat it, so it essentially skips the directory, like this:
public static string[] GetDirectoryInfo(string path)
{
if (Directory.Exists(path))
{
try
{
//This call is failing on the new folder.
return Directory.GetDirectories(path);
}
catch(UnauthorizedAccessException unAuthEx)
{
// Do nothing to eat exception
}
}
return new string[0];
}
This occurs when the software tries to access folders which have been restricted by the windows for security reasons like for example :
C:\Users\Default (This path is not accessible by your code)
Another reason would be that your application is trying to access folders which are not really folders like
My Music
My Pictures
If you are trying to read all the folders in a specific drive, then you can make some exception to handle these directories, another thing that MIGHT help you is to run your application as administrator.

Access to path **** is denied

I know there is a ton of stuff on this already and have tried a few things but have had no luck in fixing it.
I have a C# program that has built an XML Document and im trying to save it to a folder thats in MyDocuments. I am getting the folliwing exception when calling the XMLDoc.Save function.
Access to the path 'C:\Users\Ash\Documents\ConfigOutput' is denied
I have visual studio running as administrator. Any thoughts on how to fix it?
I have tried saving onto the desktop and into the C:\ folder aswell.
I am using windows 7.
Running the built executable also doesnt seem to work.
Apologies guys it seems I was being stupid. I had indeed not added a filename to the output path. I'll not delete the question incase anyone else gets done by this gotcha! Thanks for all the help/comments.
There are a few possibilities:
ConfigOutput is a folder
ConfigOutput is a file that is in use (opened)
You're not logged in as User 'Ash'
You should not normally have to run as Admin to write to your own Documents folder.
You need to check and get permission to that directory/file your writing.. for that
use Security namesapce
var permissionSet = new PermissionSet(PermissionState.None);
var writePermission = new FileIOPermission(FileIOPermissionAccess.Write, pathToFolder);
permissionSet.AddPermission(writePermission);
if (permissionSet.IsSubsetOf(AppDomain.CurrentDomain.PermissionSet))
{
// do your stuff
}
else
{
// alternative stuff
}
It looks like you're not specifying a filename and therefore it can't create a file with the same name as an existing directory - so try changing your path to:
C:\Users\Ash\Documents\ConfigOutput\Out.xml
Try run your app as administrator.
If you want to debug your app, start your Visual Studio as administrator also.
To force app start as administrator take a look at this thread:
How do I force my .NET application to run as administrator?
P.S. Check if your file is not already opened by another FileStream or etc.
I don't know if this makes a difference, but you may want to specify the folder in a relative rather than absolute manner: Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) will provide you with the path of the current user's documents. Check if it's different from the one you provide.
If so, you may need to run the app under a different user or administrator as others have pointed out. Obviously one user isn't allowed to just save files into another user's documents folder.
For me when I debug my app from Visual Studio the documents folder is the same as the user I'm currently logged in as and running Visual Studio under.
You could try <requestedExecutionLevel
level="asInvoker"
uiAccess="true|false"/> first and progressively move to highestAvailable and requireAdministrator.
Alternatively, demand the permissions, catch the exception and print it out:
try {
FileIOPermission fileIOPermission = new FileIOPermission(FileIOPermissionAccess.AllAccess, myDocFolderFile);
fileIOPermission.Demand();
} catch (SecurityException se) {
Debug.WriteLine(se.ToString());
}

Categories