c# .net environment-variables special-folders

c# - ¿Qué determina el valor de retorno de Path.GetTempPath()?



.net environment-variables (6)

Actualmente, uso Path.GetTempPath() para descubrir dónde escribir mis archivos de registro, pero recientemente encontré una máquina de usuario donde la ruta de acceso no era la que esperaba.

Por lo general, la ruta devuelta es C: / Documents and Settings / [ID de usuario] / Configuración local / Temp, pero en este caso, era C: / Temp

Esto normalmente no sería un problema, pero por alguna razón el usuario en cuestión no tenía acceso para escribir en C: / Temp

Comprobé dos veces las variables de entorno, y la variable de entorno USER apuntaba como se esperaba a C: / Documents and Settings / [ID de usuario] / Configuración local / Temp , mientras que la variable de entorno SYSTEM apuntaba a C: / WINNT / Temp .

Entonces ... ¿de dónde viene Path.GetTempPath() obteniendo su valor? Política de grupo? ¿Registro?

He buscado en Google, pero fue en vano.


Descargo de responsabilidad: ¡No es una respuesta, pero es una lectura importante!

Es muy importante darse cuenta de que necesita borrar sus archivos temporales porque cuando llegue a 65536 en un solo directorio, el framework no creará más y ¡su aplicación explotará!

Se acumularán durante meses y meses y luego recibirás un mensaje como este:

System.IO.IOException: The file exists. at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath) at System.IO.__Error.WinIOError() at System.IO.Path.InternalGetTempFileName(Boolean checkHost) at System.IO.Path.GetTempFileName():

y TFS le dará esto cuando intente compilar:

TF215097: An error occurred while initializing a build for build definition XXXXX: The file exists.

Todo lo que debe hacer es navegar a la carpeta Path.GetTempPath() y llamar a del tmp*

Nota: si tiene una aplicación ASP.NET que crea archivos temporales, su directorio temporal probablemente será diferente al usuario registrado actualmente.

En caso de duda (o en estado de pánico) simplemente cree una página aspx para imprimir la ubicación que está utilizando:

TempPath.aspx <%@ Page Language="C#"%> Temp path: <%= System.IO.Path.GetTempPath() %>

Para mí cuando se ejecuta como NetworkService me sale

C:/Windows/TEMP/

Cuando se ejecuta como una AppPool (llamada www.example.com) la ruta puede ser:

C:/Users/www.example.com/AppData/Local/Temp

PD. Creo que esto puede suceder incluso si elimina el archivo después porque el nombre del archivo aumenta.


(Usando Reflector) Path.GetTempPath() finalmente llama a la función GetTempPath Win32 (desde kernel32.dll). Los documentos MDSN para este estado:

La función GetTempPath comprueba la existencia de variables de entorno en el siguiente orden y utiliza la primera ruta encontrada:

  • La ruta especificada por la variable de entorno TMP.
  • La ruta especificada por la variable de entorno TEMP.
  • La ruta especificada por la variable de entorno USERPROFILE.
  • El directorio de Windows.

Tenga en cuenta que también indican que no verifica si la ruta existe o en qué se puede escribir , por lo que puede terminar tratando de escribir sus archivos de registro en una ruta que no existe o en la que no puede acceder .


Intente utilizar lo siguiente para determinar un buen lugar para sus datos:

Environment.GetFolderPath(Environment.SpecialFolder folder);

Donde Specialfolder

// Summary: // Specifies enumerated constants used to retrieve directory paths to system // special folders. [ComVisible(true)] public enum SpecialFolder { // Summary: // The logical Desktop rather than the physical file system location. Desktop = 0, // // Summary: // The directory that contains the user''s program groups. Programs = 2, // // Summary: // The directory that serves as a common repository for documents. Personal = 5, // // Summary: // The "My Documents" folder. MyDocuments = 5, // // Summary: // The directory that serves as a common repository for the user''s favorite // items. Favorites = 6, // // Summary: // The directory that corresponds to the user''s Startup program group. Startup = 7, // // Summary: // The directory that contains the user''s most recently used documents. Recent = 8, // // Summary: // The directory that contains the Send To menu items. SendTo = 9, // // Summary: // The directory that contains the Start menu items. StartMenu = 11, // // Summary: // The "My Music" folder. MyMusic = 13, // // Summary: // The directory used to physically store file objects on the desktop. DesktopDirectory = 16, // // Summary: // The "My Computer" folder. MyComputer = 17, // // Summary: // The directory that serves as a common repository for document templates. Templates = 21, // // Summary: // The directory that serves as a common repository for application-specific // data for the current roaming user. ApplicationData = 26, // // Summary: // The directory that serves as a common repository for application-specific // data that is used by the current, non-roaming user. LocalApplicationData = 28, // // Summary: // The directory that serves as a common repository for temporary Internet files. InternetCache = 32, // // Summary: // The directory that serves as a common repository for Internet cookies. Cookies = 33, // // Summary: // The directory that serves as a common repository for Internet history items. History = 34, // // Summary: // The directory that serves as a common repository for application-specific // data that is used by all users. CommonApplicationData = 35, // // Summary: // The System directory. System = 37, // // Summary: // The program files directory. ProgramFiles = 38, // // Summary: // The "My Pictures" folder. MyPictures = 39, // // Summary: // The directory for components that are shared across applications. CommonProgramFiles = 43, }


Llama a la función GetTempPath . La documentación explica qué variables de entorno verifica.


Me di cuenta de que GetTempPath () puede devolver los documentos y la configuración del usuario local / user / Local Settings / Temp path si se trata de una aplicación de consola, y notó que puede devolver C: / WINDOWS / Temp (en el servidor) si es aplicación web que se ejecuta desde un cliente. En el primer caso, no es gran cosa: la cuenta que ejecuta la aplicación tiene los derechos sobre esa carpeta. En este último caso, tal vez sea un gran problema si la cuenta de Identidad del conjunto de aplicaciones (o la cuenta que puede usar para suplantar en el archivo Web.config para la aplicación web) no tiene privilegios para C: / WINDOWS / Temp en el servidor (que es una gran posibilidad de que no lo haga). Por lo tanto, para mis aplicaciones de consola, así no hay duda de dónde se escriben los archivos temporales, la codificación de una cadena en un archivo INI es la mejor y más fácil para mí, y para una aplicación web, codificarla en la web.config y obtenerlo usando ConfigurationManager.AppSettings ["myKey"] funciona, o si es una aplicación web, use esta función para enviar el archivo a las carpetas de archivos temporales de ASP y trabajar con él allí:

public static string findFileDirectory(string file) { // Get the directory where our service is being run from string temppath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); // Ensure proper path notation so we can add the INI file name if (!temppath.EndsWith(@"/")) temppath += @"/"; return temppath; }

y llámalo así:

string tempFolderPath = findFileDirectory("Web.config"); tempFolderPath = tempFolderPath.Replace(@"//", @"/");

y simplemente use "tempFolderPath" en lugar de usar Path.GetTempPath () antes. Esta función funciona increíble y la uso en mi código en lugar de este malvado método GetTempPath (), así que sé que mi aplicación puede hacer lo que debe hacer, ya que la carpeta ASP Temp Files debería tener todos los permisos necesarios para sus operaciones ( El servicio DOMAIN / NETWORK y la cuenta ID del conjunto de aplicaciones necesitan control total). tempFolderPath termina en una barra inclinada, por lo que simplemente concat directamente con su variable / nombre de archivo para obtener la ruta correcta.

-Tom

PD. Necesita agregar 2 espacios de nombres para hacer que esa función funcione: System.IO y System.Reflection


Si está utilizando C# en MacOS utilizando Mono Framework entonces el valor devuelto por Path.GetTempPath() es el valor de la variable de entorno TMPDIR .

Ejecutando echo $TMPDIR generalmente devuelve valor como:

/var/folders/{2 character random-string}/{random-string}/T