2009-09-12 8 views
5

Pracuję nad aktualizacją jednej z naszych aplikacji. Musi używać .NET 2.0. Jedną część tworzy plik na pulpicie przy użyciuZapisz plik na pulpit w Vista/Windows 7 w .NET 2.0

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

Ale otrzymuję UnauthorizedAccessException w Windows 7 i Vista (też jestem przy założeniu, choć nie zostały jeszcze przetestowane, że). Zajrzałem do elewacji (nie dla całego programu, ale dla osobnego zespołu, który utworzyłby plik i wykonał na nim akcje); jednak wydaje się to wymagać .NET 3.0 lub 3.5. Czy istnieje sposób na uzyskanie dostępu do folderu Desktop przy użyciu .NET 2.0? (Wymaganie, aby program był uruchamiany jako Administrator, również nie wchodzi w grę)

(Zrobiłem wyszukiwanie, a jedyne pytanie bliskie temu, o które pytam, brzmi: File creation fails in standard account (Vista), ale mówi się o podniesieniu całej aplikacji i nie jest specyficzne dla .NET 2.0, więc wierzę, że to nie jest duplikatem)

EDIT:
Wow, ja będąc naprawdę głupie. To faktycznie działa dobrze. Próbowałem utworzyć plik o nazwie C: \ Users \ MyUser \ Desktop. Ups. Przepraszam za zamieszanie.

EDIT: Oto tekst z wyjątkiem:

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

Myślę, że powinieneś opublikować pełny wyjątek błędu.ToString() z pełnym śledzeniem, ponieważ to nie brzmi problem z kontem administratora, czy nie. Environment.GetFolderPath zawsze zwraca poprawny pulpit dla bieżącego użytkownika, który uruchamia program, a bieżący użytkownik ma zawsze pełny dostęp do pulpitu, aby utworzyć/usunąć plik na ścieżce pulpitu. Jednak zrobiliśmy to na vista dla konta innego niż admin i działa, dla Windows 7 wkrótce będę testować, ale nadal nalegam, aby opublikować szczegółowy ślad stosu. –

+0

Otrzymuje właściwy folder na pulpicie dla bieżącego użytkownika, ale domyślam się, że Win7 nie zezwala programom na modyfikowanie czegokolwiek. Wciąż jednak opublikuję pełny wyjątek. – NickAldwin

+0

@Nick: ironia tego jest, wygenerowałem dokładnie ten sam wyjątek, gdy próbowałem odtworzyć twój problem. Nie skopiowałem ani nie wkleiłem kodu, ale napisałem coś podobnego i otrzymałem wyjątek, a następnie zmieniłem go, dodając rzeczywistą nazwę pliku do ścieżki, aby działał. Nigdy nie zauważyłem, że twój kod zrobił to samo. Zwykle próbuję umieścić kreskę linii w próbkach kodu, aby nie uzyskać poziomego paska przewijania - w przeciwnym razie łatwiej jest ominąć takie rzeczy. – MusiGenesis

Odpowiedz

14

Problem jest w tym kodzie

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

Załóżmy przepisać go na schodach, które faktycznie nastąpią

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

To, co próbujesz tutaj zrobić, nie tworzy pliku na pulpicie, próbujesz utwórz sam folder na pulpicie. Folder na pulpicie oczywiście już istnieje, więc pojawia się błąd.

Należy utworzyć plik w folderze na pulpicie w folderze. Można użyć Path.Combine to zrobić w następujący sposób:

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

Można też zmienić FileMode do OpenOrCreate lub obsługiwać wyjątki - jeśli na przykład kod jest uruchamiany dwa razy, a plik będzie już istnieć na druga próba, więc nie będziesz w stanie stworzyć go po raz drugi

+0

Całkiem głupi błąd. – NickAldwin

+1

Mam taki sam problem z OP, ale użyłem twojego rozwiązania i nadal daje mi ten sam błąd. Czy muszę zmienić pozwolenie? Uruchomę windę 8.1 – lorddarq