Save File to Desktop in Vista/Windows 7 in .NET 2.

2019-01-25 18:38发布

I'm working on updating one of our applications. It must use .NET 2.0. One portion creates a file on the Desktop using

FileStream fs = new FileStream(Environment.GetFolderPath
    (Environment.SpecialFolder.DesktopDirectory), FileMode.Create);

But I get an UnauthorizedAccessException in Windows 7 (and Vista too, I'm assuming, though I haven't tested that yet). I looked into elevation (not for the entire program, but for a separate assembly which would create the file and perform actions on it); however that seems to require .NET 3.0 or 3.5. Is there any way to gain access to the Desktop folder using .NET 2.0? (Requiring the program to be run as an Administrator is also not an option)

(I did a search, and the only question close to what I'm asking is this: File creation fails in standard account (Vista) however it is talking about elevating the entire app and is not .NET 2.0 specific, so I believe this isn't a duplicate)

EDIT:
Wow, I was being really dumb. This actually works fine. I was trying to create a file called C:\Users\MyUser\Desktop. Oops. Sorry for the confusion.

EDIT: Here's the text of the exception:

  System.UnauthorizedAccessException was unhandled
  Message="Access to the path 'C:\\Users\\MyUser\\Desktop' is denied."
  Source="mscorlib"
  StackTrace:
       at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
       at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy)
       at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options, String msgPath, Boolean bFromProxy)
       at System.IO.FileStream..ctor(String path, FileMode mode)
       at MyProgram.Prog.SaveDiagnostic(String filename, String text) in C:\Source\MyProgram\Prog.cs:line 95
       at MyProgram.Form1.buttonGenDiagnostic_Click(Object sender, EventArgs e) in C:\Source\MyProgram\Form1.cs:line 4729
       at System.Windows.Forms.Control.OnClick(EventArgs e)
       at System.Windows.Forms.Button.OnClick(EventArgs e)
       at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
       at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
       at System.Windows.Forms.Control.WndProc(Message& m)
       at System.Windows.Forms.ButtonBase.WndProc(Message& m)
       at System.Windows.Forms.Button.WndProc(Message& m)
       at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
       at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
       at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
       at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
       at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, Int32 reason, Int32 pvLoopData)
       at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
       at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
       at System.Windows.Forms.Application.Run(Form mainForm)
       at Northwoods.CRM.Import.Form1.Main(String[] args) in I:\WebProspect\Source\Northwoods.CRM.Import\Form1.cs:line 2616
       at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
       at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
       at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
       at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Threading.ThreadHelper.ThreadStart()
  InnerException: 

1条回答
走好不送
2楼-- · 2019-01-25 19:01

The problem is in this code

FileStream fs = new FileStream(Environment.GetFolderPath
    (Environment.SpecialFolder.DesktopDirectory), FileMode.Create);

Let's rewrite it into the steps that actually will occur

var desktopFolder = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);
var fs = new FileStream(desktopFolder, FileMode.Create);

What you're trying to do here is not create a file on the desktop, you are trying to create the desktop folder itself. The desktop folder obviously already exists, so you get an error.

What you need to do is create a file inside the desktop folder. You can use Path.Combine to do this, like this:

var desktopFolder = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);
var fullFileName = Path.Combine(desktopFolder, "Test.txt");
var fs = new FileStream(fullFileName, FileMode.Create);

You may also want to change the FileMode to OpenOrCreate, or handle your exceptions - if for example the code runs twice, and the file will already exist on the second try, so you won't be able to create it a second time

查看更多
登录 后发表回答