2009-09-12 8 views
5

Je travaille sur la mise à jour de l'une de nos applications. Il doit utiliser .NET 2.0. Une partie crée un fichier sur le bureau en utilisantEnregistrer le fichier sur le bureau sous Vista/Windows 7 dans .NET 2.0

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

Mais je reçois un UnauthorizedAccessException dans Windows 7 (et Vista aussi, je suppose, bien que je ne l'ai pas testé encore que). J'ai regardé en élévation (pas pour l'ensemble du programme, mais pour un assemblage séparé qui créerait le fichier et effectuerait des actions dessus); Cependant, cela semble nécessiter .NET 3.0 ou 3.5. Est-il possible d'accéder au dossier Desktop en utilisant .NET 2.0? (Exiger que le programme soit exécuté en tant qu'administrateur n'est pas non plus une option)

(J'ai fait une recherche, et la seule question proche de ce que je demande est la suivante: File creation fails in standard account (Vista) mais il est question d'élever l'application entière et n'est pas .NET 2.0 spécifique, donc je crois que ce n'est pas un doublon)

EDIT:
Wow, j'étais vraiment stupide. Cela fonctionne vraiment bien. J'essayais de créer un fichier appelé C: \ Users \ MyUser \ Desktop. Oops. Désolé pour la confusion.

EDIT: Voici le texte de l'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: 
+0

Je pense que vous devriez publier une erreur complète exception.ToString() avec trace complète, car cela ne semble pas problème avec le compte administrateur ou non. Environment.GetFolderPath retournera toujours le bureau correct pour l'utilisateur actuel qui exécute le programme et l'utilisateur actuel a toujours un accès complet au bureau pour créer/supprimer le fichier sur le chemin du bureau. Cependant, nous l'avons fait sur Vista pour un compte non administrateur et cela fonctionne, pour Windows 7, je vais tester bientôt, mais je vous demande toujours de poster la trace détaillée de la pile. –

+0

Il obtient le bon dossier de bureau pour l'utilisateur actuel, mais je devine que Win7 n'autorise pas les programmes à modifier quoi que ce soit là. Je publierai toujours l'exception complète, cependant. – NickAldwin

+0

@Nick: l'ironie de ceci est, j'ai généré exactement la même exception quand j'ai essayé de reproduire votre problème. Je n'ai pas copié-collé votre code, mais j'ai écrit quelque chose de similaire et j'ai obtenu l'exception, puis je l'ai modifié en ajoutant un nom de fichier réel au chemin pour le faire fonctionner. Je n'ai jamais remarqué que ton code faisait la même chose. En général, j'essaie de mettre un saut de ligne dans mes exemples de code pour ne pas avoir la barre de défilement horizontale, sinon il est plus facile de rater des choses comme ça. – MusiGenesis

Répondre

14

Le problème est dans ce code

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

Réécrivons dans les étapes qui se produisent réellement

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

Ce que vous essayez de faire ici n'est pas créer un fichier sur le bureau, vous essayez de créer le dossier de bureau lui-même. Le dossier du bureau existe déjà, vous obtenez une erreur.

Ce que vous devez faire est de créer un fichier à l'intérieur le dossier de bureau. Vous pouvez utiliser Path.Combine pour ce faire, comme ceci:

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

Vous pouvez également changer le FileMode à OpenOrCreate, ou gérer vos exceptions - par exemple si le code est exécuté deux fois, et le fichier existe déjà sur le deuxième tentative, de sorte que vous ne serez pas en mesure de le créer une seconde fois

+0

Tout à fait l'erreur stupide à faire. – NickAldwin

+1

J'ai le même problème que l'OP, mais j'ai utilisé votre solution et cela me donne toujours la même erreur. Aurais-je besoin de changer de permission? Je cours un windoze 8.1 – lorddarq

Questions connexes