什么决定Path.GetTempPath()的返回值?


73

当前,我曾经Path.GetTempPath()想出将日志文件写入哪里,但是最近我遇到了一个用户的计算机,该计算机返回的路径不是我所期望的。

通常,返回的路径是C:\ Documents and Settings \ [userid] \ Local Settings \ Temp, 但在这种情况下,它是C:\ Temp

通常这不是问题,但是由于某种原因,相关用户无权写入C:\ Temp

我仔细检查了环境变量,并且USER环境变量按预期指向C:\ Documents and Settings \ [userid] \ Local Settings \ Temp,而SYSTEM环境变量指向C:\ WINNT \ Temp

那么...从哪里Path.GetTempPath()获得价值呢?组策略?注册表?

我已经谷歌搜索,但无济于事。


8
+1快速,干净,清晰的好问题-欢迎来到StackOverflow
Nick Craver

如果您需要始终对用户可写的安全点,请查看隔离的存储:msdn.microsoft.com/zh-cn/library/bdts8hk0.aspx
marc_s 2010年

1
@marc_s:除非启用了FIPS,否则在尝试使用IsolatedStorage时会出现异常
adrianbanks 2010年

@adrian:很有趣-感谢您的指导。第一次我听到这样的消息(可能是自从在欧洲以来,我们对“ FIPS”之类的东西并不十分在意。)
marc_s 2010年

Answers:


62

(使用Reflector)Path.GetTempPath()最终调用Win32函数GetTempPath(来自kernel32.dll)。此状态的MDSN文档:

GetTempPath函数按以下顺序检查是否存在环境变量,并使用找到的第一个路径:

  • 由TMP环境变量指定的路径。
  • TEMP环境变量指定的路径。
  • USERPROFILE环境变量指定的路径。
  • Windows目录。

请注意,他们还指出,它不会检查路径是否实际存在或是否可以写入,因此您可能最终尝试将日志文件写入不存在的路径或无法访问的路径。 。


好答案!清晰,简洁,准确地提供我需要的信息。没想到要检查Win32函数文档...非常感谢。安迪
安迪·布莱克曼

1
的最新文档Path.GetTempPath()在“备注”下具有非常相似的内容。
chwarr 2014年

情况并非如此,我只是回显了我的环境变量,在系统属性中检查了它们,并完成了Path.GetTempPath()的修改:imgbox.com/L1CDsEBe
Tod

17

免责声明:不是答案-而是重要的阅读内容!

意识到您需要清理临时文件非常重要,因为当您在单个目录中命中65536时,框架将不再创建,并且您的应用程序会崩溃!

它们会累积数月之久,然后您会收到如下消息:

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():

当您尝试构建时,TFS会为您提供:

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

您需要做的就是浏览Path.GetTempPath()文件夹并调用del tmp*

注意:如果您使用ASP.NET应用程序创建临时文件,则其temp目录可能与当前登录用户不同。

如果有疑问(或感到恐慌),只需创建一个aspx页面以打印出正在使用的位置:

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

对我来说,运行的时候为NetworkService我得到

 C:\Windows\TEMP\

作为AppPool(名为www.example.com)运行时,路径可能为:

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

PS。我认为即使以后删除文件也可能会发生这种情况,因为文件名会增加。


11
今天早上进入办公室,生产系统停滞了。事实证明,我们的一名开发人员正在使用Path.GetTempFileName()生成随机文件名以供其他地方使用。他不知道它也在c:\ windows \ temp中创建了一个零字节文件。系统必须尝试创建其65537th文件!此评论节省了我们数小时的停机时间。感谢2年前发布!
cjuk

1
对于将来的检查:我记得Path.GetTempFileName()方法只返回“ _00001.tmp”之类的内容,并且每次调用都增加1。如果文件不存在,则返回“ _00001.tmp”。如果存在,则抛出error..So,更好的是要保持干净临时文件名缓存{只是当你不需要它了,只是删除文件} ..希望它能帮助
sihirbazzz

为了安全起见,我希望将其保留在32000个文件以下;-)我仍然没有弄清楚为什么立即删除我的tmp文件并没有真正删除它-并且没有正在运行的备份或病毒防护可能导致锁定文件。
Simon_Weaver

感谢今天随机投票的人。我检查了一下,然后又达到了31480个文件!
Simon_Weaver

2

我注意到GetTempPath()如果是控制台应用程序,则可以带回本地用户的Documents&Settings \ user \ Local Settings \ Temp路径,并且注意到它可以带回C:\ WINDOWS \ Temp(在服务器上)。从客户端运行Web应用程序。在前一种情况下,没什么大不了的-运行该应用程序的帐户拥有该文件夹的权限。在后者中,如果App Pool Identity帐户(或您可能用于模拟Web应用程序的Web.config文件中的帐户)没有权限访问C:\ WINDOWS \ Temp,这可能是一件大事服务器(这不是很大的机会)。因此,对于我的控制台应用程序而言,毫无疑问,将临时文件写入何处,将字符串硬编码到INI文件中对我来说是最好的,也是最简单的;对于Web应用程序,将其硬编码在Web上。

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;
}

并这样称呼它:

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

只需使用“ tempFolderPath”,而不是之前使用Path.GetTempPath()的位置即可。这个功能很棒,我在我的代码中使用它代替了这个邪恶的GetTempPath()方法,所以我知道我的应用程序可以做它需要做的事情,因为ASP Temp Files文件夹应该具有其操作所需的所有权限( DOMAIN \ NETWORK SERVICE和App Pool ID帐户需要完全控制)。tempFolderPath以斜杠结尾,因此只需直接与变量/文件名连接即可获得正确的路径。

汤姆

PS您需要添加2个名称空间才能使该功能正常工作:System.IO和System.Reflection


2

请尝试使用以下方法确定您的数据的合适位置:

Environment.GetFolderPath(Environment.SpecialFolder folder);

哪里有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,
}

2

如果你正在使用C#MacOS使用Mono Framework,然后通过返回的值Path.GetTempPath()是环境变量的值TMPDIR

运行echo $TMPDIR通常会返回如下值:

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.