Jak uzyskać folder tymczasowy dla bieżącego użytkownika

395

Obecnie używam następującej funkcji, aby uzyskać ścieżkę folderu tymczasowego dla bieżącego użytkownika:

string tempPath = System.IO.Path.GetTempPath();

Na niektórych komputerach daje mi tymczasową ścieżkę do folderu bieżącego użytkownika, na przykład:

C: \ Documents and Settings \ administrator \ Local Settings \ Temp \

Na niektórych komputerach daje mi ścieżkę folderów temp systemu, np .:

C: \ Windows \ TEMP

Dokumentacja MSDN mówi również, że powyższe API zwraca folder tymczasowy bieżącego systemu.

Czy jest dostępny inny interfejs API, który daje mi ścieżkę folderu tymczasowego bieżącego użytkownika w następujący sposób:

C: \ Documents and Settings \ administrator \ Local Settings \ Temp \

Anoop
źródło
2
Zachowanie System.Environment.GetEnvironmentVariable („TEMP”) jest takie samo jak GetTempPath (). Na moim komputerze dla konta „administrator” oba API zwraca „C: \ WINDOWS \ TEMP”, ale dla konta „Usługa sieciowa” oba API zwracają „C: \ Documents and Settings \ Network Service \ Local Settings \ Temp \”.
Anoop
1
Być może rzeczywiście konto administratora ma folder tymczasowy C: \ Windows \ Temp?
Helen
2
Czy jest jakiś konkretny powód, dla którego chcesz uzyskać tymczasową ścieżkę w folderze C: \ Documents and Settings \ always?
Noldorin
11
FYI: jeśli nie chcą folder System temp, a nie autora (jeśli jest ustawione) można użyć Environment.GetEnvironmentVariable ( "temp", EnvironmentVariableTarget.Machine)
piers7
1
W przeszłości często korzystałem z folderów tymczasowych i nigdy nie dbałem o to, gdzie to było, dopóki może się zdarzyć, że dysk nie zostanie całkowicie zużyty. Czy nie ma sensu folder tymczasowy do tymczasowego użytku - symbol zastępczy śmieci? Dlaczego nie może być nieznany i obsługiwany przez API? Czy powinieneś użyć konfigurowalnej, dobrze znanej lokalizacji zamiast temp?
barrypicker

Odpowiedzi:

405

System.IO.Path.GetTempPath()jest tylko opakowaniem dla natywnego wywołania GetTempPath(..)w Kernel32.

Zajrzyj na http://msdn.microsoft.com/en-us/library/aa364992(VS.85).aspx

Skopiowano z tej strony:

Funkcja GetTempPath sprawdza istnienie zmiennych środowiskowych w następującej kolejności i używa pierwszej znalezionej ścieżki:

  • Ścieżka określona przez zmienną środowiskową TMP.
  • Ścieżka określona przez zmienną środowiskową TEMP.
  • Ścieżka określona przez zmienną środowiskową USERPROFILE.
  • Katalog Windows.

Nie jest dla mnie do końca jasne, czy „katalog Windows” oznacza katalog tymczasowy w systemie Windows, czy sam katalog Windows. Zrzucanie plików tymczasowych do samego katalogu systemu Windows brzmi jak niepożądany przypadek, ale kto wie.

Więc łącząc tę ​​stronę ze swoim postem, zgaduję, że albo jedna ze zmiennych TMP, TEMP, albo USERPROFILE dla Twojego administratora wskazuje na ścieżkę systemu Windows, albo nie są one ustawione, a powrót do ścieżki temp Windows.

Niall Connaughton
źródło
14
TEMPZmienna będzie ustawiona w dwóch miejscach: dla samego użytkownika, a na komputerze lokalnym. Jeśli nie jest ustawiony dla użytkownika, użyty zostanie komputer lokalny, a to zawsze jest ustawione w instalacji domyślnej. Dlatego wyszukiwanie zwykle zatrzymuje się na drugim etapie. W testowaniu, czy TMP, TEMPi USERPROFILEsą unieważnione, to faktycznie nie spadnie z powrotem do %SystemRoot%( C:\Windows\).
Bob
1
Kod wykonywany w usługach systemu Windows działających w „systemie lokalnym” lub w aplikacjach uruchomionych przez taką usługę folder C: \ Windows \ Temp jest czasem używany jako folder tymczasowy.
NineBerry
1
Dokumentacja z twojego linku mówi: „Zwrócony ciąg kończy się odwrotnym ukośnikiem, na przykład„ C: \ TEMP ”. Ale ich przykład tak naprawdę nie kończy się odwrotnym ukośnikiem.
dcp
Nie masz gwarancji, że będziesz mieć uprawnienia do zapisu ścieżki zwróconej przez tę funkcję w aplikacji. A jeśli zamiast tego spróbowałeś IsolatedStorage?
Jan
35

NIE używaj tego:

System.Environment.GetEnvironmentVariable("TEMP")

Zmienne środowiskowe można zastąpić, więc TEMPzmienna niekoniecznie jest katalogiem.

Prawidłowym sposobem jest użycie System.IO.Path.GetTempPath()jak w zaakceptowanej odpowiedzi.

Helen
źródło
34
@ImmortalBlue Ponieważ niekoniecznie jest to katalog tymczasowy. Prawidłowym sposobem na uzyskanie katalogu tymczasowego jest wywołanie System.IO.Path.GetTempPath().
David Heffernan
9
Wiem, że to dość stare, ale pomyślałem, że zostawię notatkę dla każdego, kto jest ciekawy: Nie tylko nie musi to być katalog tymczasowy, jak powiedział @DavidHeffernan, ale po prostu nie masz pojęcia, co to jest. Chociaż nie jest to tak duży problem z .NET, to jest uważane za złą praktykę, ponieważ każdy złośliwy użytkownik mógł zmienić tę zmienną środowiskową w celu wykorzystania twojego programu. Jeśli korzystasz z uprawnień administratora, a złośliwe oprogramowanie może zmieniać kod podczas jego wykonywania, może on na przykład wykonywać shellcode jako administrator, ponieważ jest przechowywany w TEMP.
sraboy
Istnieją 2 główne różnice między GetEnvironmentVariable("TEMP")i GetTempPath(). GetTempPath()najpierw sprawdza zmienną „TMP”, następnie „TEMP”, a na końcu „USERPROFILE”. Jeśli nie znajdziesz żadnej z nich, zwraca ścieżkę do folderu Windows. Gwarantuje również, że zwraca prawidłową ścieżkę, ale nie gwarantuje, że ścieżka istnieje.
Logman
Ale to właśnie robi zaakceptowana odpowiedź, jeśli nie masz zmiennej TMP (domyślny scenariusz w najnowszych wersjach systemu Windows), prawda?
PRMan
1
GetTempPathi tak opiera się na zmiennych środowiskowych, jeśli czytasz dokumentację jądra, więc jak zauważył użytkownik Logman, nie ma powodu, aby nie używać GetEnvironmentVariable... oba mają tę samą słabość.
AnorZaken,
22

Mam ten sam wymóg - chcemy umieścić dzienniki w określonym katalogu głównym, który powinien istnieć w środowisku.

public static readonly string DefaultLogFilePath = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);

Jeśli chcę połączyć to z podkatalogiem, powinienem móc użyć Path.Combine( ... ).

GetFolderPathMetoda ma przeciążenia dla specjalnych opcji folderów, które pozwala kontrolować, czy określona ścieżka być tworzone lub po prostu zweryfikowane.

IAbstract
źródło
-8

próbować

Environment.GetEnvironmentVariable("temp");
Ikke
źródło