2009-09-12 9 views
5

Estoy trabajando en la actualización de una de nuestras aplicaciones. Debe usar .NET 2.0. Una porción crea un archivo en el escritorio usandoGuardar archivo en escritorio en Vista/Windows 7 en .NET 2.0

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

Pero me sale un UnauthorizedAccessException en Windows 7 (y Vista también, estoy suponiendo, aunque no he probado que todavía). Miré hacia la elevación (no para todo el programa, sino para un ensamblaje separado que crearía el archivo y realizaría acciones sobre él); sin embargo, eso parece requerir .NET 3.0 o 3.5. ¿Hay alguna manera de obtener acceso a la carpeta de escritorio con .NET 2.0? (Exigir que el programa se ejecute como administrador tampoco es una opción)

(Hice una búsqueda, y la única pregunta cercana a lo que estoy preguntando es esto: File creation fails in standard account (Vista), sin embargo, se trata de elevar toda la aplicación y no se .NET 2.0 específica, por lo que creo que esto no es un duplicado)

EDIT:
Wow, que estaba siendo muy tonta. Esto realmente funciona bien. Estaba intentando crear un archivo llamado C: \ Users \ MyUser \ Desktop. Oops. Perdón por la confusion.

EDIT: He aquí el texto de la excepción:

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: 
+0

Creo que debe publicar el error completo exception.ToString() con seguimiento completo, porque esto no suena un problema con la cuenta de administrador o no. Environment.GetFolderPath siempre devolverá el escritorio correcto para el usuario actual que ejecuta el programa y el usuario actual siempre tendrá acceso completo al escritorio para crear/eliminar un archivo en la ruta del escritorio. Sin embargo, hicimos esto en Vista para una cuenta que no es de administrador y funciona, para Windows 7 lo probaré pronto, pero aún así insisto en que publique el seguimiento detallado de la pila. –

+0

Obtiene la carpeta de escritorio correcta para el usuario actual, pero supongo que Win7 no permite que los programas modifiquen nada allí. Aun así, publicaré la excepción completa. – NickAldwin

+0

@Nick: la ironía de esto es que generé exactamente la misma excepción cuando traté de reproducir su problema. No copié y pegué el código, pero escribí algo similar y obtuve la excepción, y luego lo cambié agregando un nombre de archivo real a la ruta para que funcione. Nunca me di cuenta de que tu código hizo lo mismo. Normalmente intento poner un salto de línea en las muestras de mi código para no obtener la barra de desplazamiento horizontal; de lo contrario, es más fácil pasar por alto cosas como esta. – MusiGenesis

Respuesta

14

El problema está en el código

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

Vamos a reescribir en los pasos que realmente ocurrirá

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

Lo que intenta hacer aquí no es crear un archivo en el escritorio, está tratando de crea la carpeta del escritorio en sí. La carpeta de escritorio obviamente ya existe, así que obtienes un error.

Lo que necesita hacer es crear un archivo dentro de la carpeta del escritorio. Puede utilizar Path.Combine para hacer esto, así:

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

También es posible que desee cambiar el FileMode a OpenOrCreate, o manejar sus excepciones - si por ejemplo el código se ejecuta dos veces, y ya existirá el archivo en el segundo intento, por lo que no podrá crearlo por segunda vez

+0

Bastante el error tonto de hacer. – NickAldwin

+1

Tengo el mismo problema que OP, pero he utilizado su solución y aún así me da el mismo error. ¿Debería cambiar el permiso? Estoy ejecutando un windoze 8.1 – lorddarq

Cuestiones relacionadas