My project is a plugin to a much larger project. A bug in the larger project creates a file that will cause my application to crash. They are already aware of the issue and are addressing it, but in the meantime the only work around is to delete a certain file in the appdata directory for each user.
The plan is that during installation of the smaller plugin, to navigate to every user's appdata directory to delete a problematic file (if it exists). Is there any way to find each User's appdata directory. Remember this is an install, so we will have admin privileges. Some of the things I have seen is to use
WindowsIdentity.Impersonate(IntPtr someUser)
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)
Then it would just be a matter of somehow getting the IntPtr, which I am unsure how to get.
That is the best solution I have right now. So how do I get the IntPtr of each user? Or is there a better solution?
The next best that I can think of would simply be to go through all directories of C:\Users\eachUser\AppData\ and deleting the file as it exists. But then again, in XP that location would have to be C:\Documents and Settings\eachUser\Application Data\ and I would be creating operating system specific code. Suggestions?
From WindowsIdentity.Impersonate Method (IntPtr userToken):
IntPtr userToken is...
The handle of a Windows account token. This token is usually retrieved through a call to unmanaged code, such as a call to the Win32 API LogonUser function.
So, you can't do it this way unless you have all the usernames and passwords.
Edit: Why not delete the file at runtime for just the current user? Does your plugin have permission to do this?
Edit 2: You can use the installing user's directory from Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), and then use Directory.GetDirectories to find the other users that have a profile. Then, you can tack on the special folder name. Pretty round-about, but it might work in your "pinch".
Related
Im trying to get the Users/Shared folder location in Mac so that i can write common user data(license) to it.I tried using
System.IO.Path.Combine (Environment.GetFolderPath (Environment.SpecialFolder.CommonApplicationData));
But its returning the folder in which I'm logged in.I know that i need to place the common application data in the Application Support folder but i think root privilege is required for this.If there is a better way to write to that folder,please suggest.
UPDATE:
I tried doing
File.Copy ("myfile.rtf", "Users//Shared//ll.txt");
But i get this exception >> Destination directory not found: Users/Shared
In OS X the directory is simply /Users/Shared, and it's directly off the root of the volume. There's no need to do Environment.GetFolderPath...
If you want to have user data or application data that can be shared by multiple users (read+write) you'll either want to create your own directory:
/Users/Shared/MyApp
and/or you can use:
/Users/Shared/Library/Application Support/MyApp
This way your application can share user data and application settings with all users. The /Library/Application Support folder (not to be confused with the one shared one), is owned by the system and anything that needs to write to it must obtain permission. The contents are read only, even for admin level users — something you'll want to consider when deciding where to store shared application data.
I am developing a Windows Phone 8 application but am having a lot of issues with file access permission exceptions hindering the approval of my application when ever I try accessing files in the "local" folder (this only happens after the application has been signed by the WP store, not when deployed from Visual Studio). To solve this I have moved all file operations to IsolatedStorage and this seems to have fixed the problems.
I only have one problem left though. My application needs to make use of the file extension system to open external files and this seems to involve the file first being copied to the local folder where after I can then manually copy it into IsolatedStorage. I have no problem in implementing this but it seems that a file access permission exception also occurs once the system tries to copy the external file into the local folder.
The only way I think this can be solved is if I can direct the system to directly copy into IsolatedStorage but I cannot figure how to do this or if it is even possible. It seems as if though the SharedStorageAccessManager can only copy into a StorageFolder instance but I have no idea how to create one that is directed into IsolatedStorage, any ideas?
PS. Do you think that the Microsoft system might be signing my application with some incompetent certificate or something because there is not a hint of trouble when I deploy the application from Visual Studio, it only happens when Microsoft tests it or when I install it from the store using the Beta submission method.
Below is a screenshot of the catched exception being displayed in a messagebox upon trying to open a file from an email:
EDIT:
Just to make it even clearer, I do NOT need assistance in figuring out the normal practice of using a deep link uri to copy an external file into my application directory. I need help in either copying it directly into isolatedstorage or resolving the file access exception.
Listening for a file launch
When your app is launched to handle a particular file type, a deep link URI is used to take the user to your app. Within the URI, the FileTypeAssociation string designates that the source of the URI is a file association and the fileToken parameter contains the file token.
For example, the following code shows a deep link URI from a file association.
/FileTypeAssociation?fileToken=89819279-4fe0-4531-9f57-d633f0949a19
Upon launch, map the incoming deep link URI to an app page that can handle the file
// Get the file token from the URI
// (This is easiest done from a UriMapper that you implement based on UriMapperBase)
// ...
// Get the file name.
string incomingFileName = SharedStorageAccessManager.GetSharedFileName(fileID);
// You will then use the file name you got to copy it into your local folder with
// See: http://msdn.microsoft.com/en-us/library/windowsphone/develop/windows.phone.storage.sharedaccess.sharedstorageaccessmanager.copysharedfileasync(v=vs.105).aspx
SharedStorageAccessManager.CopySharedFileAsync(...)
I've inline the information on how to do this from MSDN http://msdn.microsoft.com/en-us/library/windowsphone/develop/jj206987(v=vs.105).aspx
Read that documentation and it should be clear how to use the APIs as well as how to setup your URI mapper.
Good luck :)
Ok I figured it out. The "install" directory is actually restricted access but for some reason the Visual Studio signing process leaves the app with enough permissions to access this folder. The correct procedure of determining a relative directory is not to use "Directory.GetCurrentDirectory()" but rather to use "ApplicationData.Current.LocalFolder". Hope this helps!
I am using Directory.Exists() in my windows service (that is programmed in C#, 3.5 framework)to check to see whether a particular directory exists in the drive. When I run in local machine it works fine, meaning I am able to access the directory.
But when I deploy the windows service on a Virtual Machine, and start the service, it is not able to find the directory even though the directory exists. The directory is mapped on as
Q: drive, Q:\\temp\\local\\ folder
But the windows services always returns false for the Directory.Exists().
However when I give C:\ drive in place of Q:\ it works, but does not work for a mapped drive. I have tried with the UNC path, and I have made sure the mapped drive have the administrative rights and infact the read, write and execute permission. But it still returns false.
Can anyone please tell me why? And how to resolve?
Make sure the drive is mapped under the same user as the Service is running. If you map the drive as user A, it is not automatically mapped for anyone else too.
Mapped drives are only restored during interactive login which services generally do not perform:
Map a network drive to be used by a service
Short version: You can't do it, use the full UNC path instead.
This is most probably a problem with privileges. Your Windows service is probably running under an account which doesn´t have enough privileges to access the network path.
This is a possible duplicate: Accessing mapped folder from a Windows Service written in C#
Another possible solution is to use impersonation, check it out:
http://msdn.microsoft.com/en-us/library/w070t6ka(v=vs.90).aspx
UPDATE
Came to think of it;
Try changing the identity of the application pool to a user with the same rights as your user.
As #Sriram pointed out the Directory.Exists() method will fail if any error occurs. What sort of exception do you get if you try to access the path?
Eg (for both mapped and UNC in case there is something going on there):
DirectoryInfo diMapped = new DirectoryInfo(#"Q:\temp\local\folder");
DirectoryInfo diUNC = new DirectoryInfo(#"\\servername\fnsw\tmp\126");
Note: Assuming that the white space before 'folder' in your path is a typo?
Steps to troubleshoot
Try accessing the network path manually in "Run" [WindowKey + R]
Try to access your map drive i.e.: M:\
Make sure you are the account owner of the mapping (mapping should be done under your account)
Go to Property and see if "Run As Administrator" is unchecked.
Remove mapping and re-add the mapping.
Make sure available offline (or sync offline) is turned off and folder is available from another computer.
Hope this helps!
I have a webapp which has read/write/execute access to an aliased directory. When I am in debug mode in Visual Studio, the following statement works:
Directory.Move("\\\\localhost\\Alias\\oldDirectory","\\\\localhost\\Alias\\newDirectory");
The net result is that, oldDirectory is now newDirectory in the aliased directory.
But, when I'm testing this code in pre-production, I have oldDirectory and newDirectory in the aliased directory. Directory.Move is now behaving as if it is only copying oldDirectory to newDirectory.
Why is this happening?
This is most likely a permissions issue.
The user account that is executing this command probably has Create / Write permissions but not Delete permissions in the aliased directory. I would check whether the user account that the program is executing under has Delete / Delete Subfolders and Files permissions.
Edit:
To test this theory, I would temporarily grant the Users group Full Control over the folder to see if the problem goes away.
Make sure the folder is not under write-protection and no process is accessing any files at the moment you are trying to move the folder.
Also check whether you gave the security permissions to the correct user, by verifing under which user account the applicationpool is running.
You might also want to consider developing on a local IIS to prevent such situations in the future (I've been there; not nice)
I believe that, instead of using Directory (which is static) I used DirectoryInfo which solved my problem. I think that the heart of the issue was that Directory does more security checks than an instance of DirectoryInfo does. I'm still unclear why this is, but it seemed to work.
This snippet works well if I try to write in a user directory but as soon as I try to write in Program Files, it just executes silently and the file has not been copied (no exception). If I try to copy the file in C:\ or in C:\Windows I catch an UnauthorizedAccessException.
Do you know another way to get the permissions to write in that directory or to make it work another way?
Any help greatly appreciated! Thanks
using(FileStream fs=File.Open(source, FileMode.Open)){ }
try
{
FileIOPermission fp = new FileIOPermission(FileIOPermissionAccess.Write,
AccessControlActions.Change, "C:\\Program Files\\MyPath");
fp.Demand(); //<-- no exception but file is not copied
File.Copy("C:\\Users\\teebot\\Documents\\File.xml","C:\\Program Files\\MyPath\\File.xml",true);
}
catch(SecurityExceptions)
{
throw(s);
}
catch(UnauthorizedAccessException unauthroizedException)
{
throw unauthroizedException;
}
If you are running under Vista then the system just redirects writes to the program files folder, this is done so old program that keep their configuration in the program directory will continue to work when the user is not an Admin (or UAC is enabled).
All you have to do is add a manifest to your program that specify the required access level, then the system assume your program is Vista-aware and turns off all those compatibility patches.
You can see an example of a manifest file on my blog at:
http://www.nbdtech.com/blog/archive/2008/06/16/The-Application-Manifest-Needed-for-XP-and-Vista-Style-File.aspx
(the focus of the post is on getting the right version of the common controls, but the Vista security declarations are also there)
Don't write in the Program Files folder.
That's a big no-no, and will especially cause problems when the day comes where your code runs in Vista or on a machine at a company where users only get standard security rather than admin rights. Use the Application Data folder instead.
Are you running on Vista? If so then you may be running into file system virtualization. This is a feature in 32 bit versions of Vista which allows a normal user to write to protected parts of the file system. It's a shim introduced to reduce the pain of the LUA features of Vista.
The short version is that the operating system will create a virtual file system for certain protected roots (such as program files). When a non-admin attempts to write to it, a copy will be created an editted instead of the original. When your user account attempts to look at the file it will see the edit.s Other user accounts will only see the original.
Longer Version: http://thelazyadmin.com/blogs/thelazyadmin/archive/2007/04/26/file-system-virtualization.aspx
Code access security grants or denies permissions to your code.
It can't be used to override permissions that are granted/denied to the current user.