Сохранить файл на рабочий стол в Vista / Windows 7 в .NET 2.0 - PullRequest
5 голосов
/ 12 сентября 2009

Я работаю над обновлением одного из наших приложений. Он должен использовать .NET 2.0. Одна часть создает файл на рабочем столе, используя

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

Но я получаю исключение UnauthorizedAccessException в Windows 7 (и, я полагаю, и в Vista, хотя я еще этого не проверял). Я посмотрел на повышение прав (не для всей программы, а для отдельной сборки, которая создаст файл и выполнит над ним действия); Однако для этого требуется .NET 3.0 или 3.5. Есть ли способ получить доступ к папке «Рабочий стол» с помощью .NET 2.0? (Требование, чтобы программа запускалась от имени администратора, также не вариант)

(Я выполнил поиск, и единственный вопрос, близкий к тому, что я спрашиваю, заключается в следующем: Не удается создать файл в стандартной учетной записи (Vista) , однако речь идет о возврате всего приложения и не Специфично для .NET 2.0, поэтому я считаю, что это не дубликат)

EDIT:
Вау, я был действительно тупым. Это на самом деле работает нормально. Я пытался создать файл с именем C: \ Users \ MyUser \ Desktop. К сожалению. Извините за путаницу.

РЕДАКТИРОВАТЬ: Вот текст исключения:

  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 Ответ

14 голосов
/ 14 сентября 2009

Проблема в этом коде

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

Давайте перепишем его на этапы, которые на самом деле произойдут

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

Здесь вы пытаетесь не создать файл на рабочем столе, а пытаться создать папку рабочего стола . Папка рабочего стола, очевидно, уже существует, поэтому вы получаете сообщение об ошибке.

Что вам нужно сделать, это создать файл внутри папки рабочего стола. Для этого вы можете использовать Path.Combine, например:

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

Возможно, вы также захотите изменить FileMode на OpenOrCreate или обработать ваши исключения - если, например, код выполняется дважды, а файл уже существует со второй попытки, поэтому вы не сможете его создать. второй раз

...