Sign in to follow this  
devronious

[.net] Vista and file creation/access...

Recommended Posts

devronious    108
I just upgraded to Vista 64bit OS and tried creating a file via:
[source lang=c#]
            FileInfo fi = new System.IO.FileInfo(fileName);
            System.IO.StreamWriter w = null;
            if (!fi.Exists) w = fi.CreateText();

But I get access errors for Vista. Can anyone explain or point me to the right direction for the handling of access and creation of files in Vista via c#? Thanks in advance, Devin

Share this post


Link to post
Share on other sites
Tape_Worm    2807
I too am running Vista x64.

I had no problems with that code. Are you sure it's crashing on that particular code snippet?

edit
Also, is fileName set to a file that already exists? If it is, are you sure you have permissions to that file? Or if it doesn't exist, are you sure you have permissions to write to that area?

[Edited by - Tape_Worm on May 13, 2008 9:50:05 AM]

Share this post


Link to post
Share on other sites
VizOne    598
Hi,

I'd guess its an access problem and that you are trying to create a file where you are not allowed to (as normal user), e.g. the program files dir. But Spodi is right, more details on the error would help.

Regards,
Andre

Share this post


Link to post
Share on other sites
devronious    108
I think you're right, I thought about it and I'm trying to creat a file in the c:\ directory and I bet it's not allowed due to permission rights. So if I need to change permission rights then how do I do that? Thanks guys.

-Devin

Share this post


Link to post
Share on other sites
VizOne    598
Hi,

Do you have to write to C:? If you want to dump some app specific data, use the user's AppData directories for that. See Environment.GetFolderPath and Environment.SpecialFolder.ApplicationData (or LocalApplicationData, depending on the importance of the data).

If you really, really need to write to C:, read on.

Changing permission sets (access control lists, ACLs) for file system objects can be done with the classes FileSecurity and DirectorySecurity, for an example see
http://blog.crowe.co.nz/archive/2007/08/25/c---An-example-of-setting-NTFS-Directory--File.aspx

The problem is: when the application is run under a non-admin user account, chances are that it is not allowed to change the ACLs for paths like c:. As admin you wouldn't have had access problems to that path in the first place. So, even if you know how to change the ACLs you will probably not allowed to do so, except you run your process with elevated rights (i.e. as the administrator). This will cause the enter-admin-password screen to appear. You can do that by either start the process as admin (Run as administrator) in the context menu of the app or programmatically. I did it once in an app, and the code related to that feature goes like this:


using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Security.Principal;
using System.Windows.Forms;
/// <summary>
///
/// </summary>
public class UacHelper {
#region Interop
internal const int BCM_FIRST = 0x1600; //Normal button
internal const int BCM_SETSHIELD = ( BCM_FIRST + 0x000C );

[DllImport( "user32" )]
public static extern UInt32 SendMessage
( IntPtr hWnd, UInt32 msg, UInt32 wParam, UInt32 lParam );
#endregion

internal static bool IsAdmin() {
WindowsIdentity id = WindowsIdentity.GetCurrent();
WindowsPrincipal p = new WindowsPrincipal( id );
return p.IsInRole( WindowsBuiltInRole.Administrator );
}

internal static void AddShieldToButton( Button b ) {
b.FlatStyle = FlatStyle.System;
SendMessage( b.Handle, BCM_SETSHIELD, 0, 0xFFFFFFFF );
}

internal static void RestartElevated( string arguments ) {
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.UseShellExecute = true;
startInfo.WorkingDirectory = Environment.CurrentDirectory;
startInfo.FileName = Application.ExecutablePath;
startInfo.Arguments = arguments;
startInfo.Verb = "runas";
try {
Process p = Process.Start( startInfo );
} catch ( Win32Exception ex ) {
return;
}

Application.Exit();
}
}



The core method is, of course, RestartElevated. Be aware though, that running an elevated process as security risks implied.


Regards,
Andre

Share this post


Link to post
Share on other sites
devronious    108
Cool, ya that makes total sense. I guess I don't want to use a directory that is going to cause problems with end users. I will learn about the app directories. I wasn't aware of that Environment.SpecialFolder.ApplicationData access yet.

When I access the folder it says: "C:\\Users\\Devin\\AppData\\Roaming". Where did it get the Roaming from?

-Devin

Share this post


Link to post
Share on other sites
VizOne    598
Environment.SpecialFolder.ApplicationData points to the Roaming folder,
Environment.SpecialFolder.LocalApplicationData points to the Local folder. Most often the difference is not that big, however, in network environments where your user profile is stored on a central server, the data in Roaming is the one that gets stored on the server wheres the Local data is only stored on the computer you are logged on to. So in general, Roaming is a reasonable choice. I only put log-files and other "volatile" data in the Local folder.

For both cases however you will want to create a subfolder for your application. Do not write to Roaming or Local directly, the users won't like that mess :-) In practice apps will create a subfolder with a reasonable name. E.g.,


using System;
using System.IO;

namespace AppData {
public class Program {
private static void Main() {
const string NameOfMyApp = "Cool App";

string appDataRoaming = Environment.GetFolderPath( Environment.SpecialFolder.ApplicationData );
string myAppDir = Path.Combine( appDataRoaming, NameOfMyApp );
if ( !Directory.Exists( myAppDir ) ) {
Directory.CreateDirectory( myAppDir );
}

using ( StreamWriter sw = new StreamWriter( Path.Combine( myAppDir, "test.txt" ) ) ) {
sw.WriteLine( "This is a test" );
}
}
}
}




This will create a 'Cool App' folder in Roaming and add a test.txt with a single line of text to it.

Edit: I found a nice explanation of Roaming vs Local: http://forums.techarena.in/showpost.php?p=3627010&postcount=4

Regards,
Andre

Share this post


Link to post
Share on other sites
devronious    108
Wow, that was very informative and perfect, thanks Andre!

Spodi, the error was of access rights to the folder. I didn't take a picture yet. It said I don't have permission to that file. A file which is not yet created and an error that occured when I tried to create it.

Share this post


Link to post
Share on other sites
remigius    1172
Quote:
Original post by devronious
Wow, that was very informative and perfect, thanks Andre!


Very useful stuff indeed, thanks for sharing it.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this