%AppData% 和 %LocalAppData% 的区别?

2018-10-07 10:44:56 +08:00
 szzhiyang

Windows 上的 %AppData%%LocalAppData% 的本质区别是什么?

我应该将应用程序的配置文件存放到哪个文件夹中呢?

14484 次点击
所在节点    程序员
26 条回复
geelaw
2018-10-08 01:00:53 +08:00
@ryh #3 @roshad #4

你们提到的是 WinRT API,这是完全不同的模型。WinRT roaming app data 是存在于 Isolated Storage 里面的 RoamingState 和 Settings 里面的,每个 app 的 isolated storage 在目前的情况下默认位置是 %LOCALAPPDATA%\Packages\<Package Family Name> 下。

@ggsimidar #5 他们说的和 %APPDATA% 漫游无关。

@sobigfish #8 我个人的看法是不会。

Roaming user profile 是 Windows domain 的功能,工作原理就是登录的时候从服务器 copy user profile 里面可以 roam 的部分( user profile 通常是 %USERPROFILE%,但是并不是每个内容都可以 roam ),注销的时候把可以 roam 的部分复制到 domain controller。这在很慢的网络环境下是不可能的(例如离开了通过 Ethernet 连入公司网络的情况),此外,应该避免用户同时登录 forest 里面的多台电脑。

我曾经在 Microsoft 有账户,但我没有观察这些数据是否 roam 过。这个功能的使用频率在逐渐降低。更多阅读材料请见

https://blogs.msdn.microsoft.com/oldnewthing/20050630-20/?p=35143/

@szzhiyang 回到楼主的问题,如果你不是为了企业开发软件,你的 app data 基本上不可能 roam。从逻辑上来说,你应该如此选择存放的位置:%APPDATA% 存和机器无关的数据,且不能太大。%LOCALAPPDATA% 存和机器有关的数据、从云同步的数据、大的数据以及任何删除都没有实际损失的数据。

举个例子,Outlook 把用户的 mail signature 存在 %APPDATA%\Microsoft\Signatures 里,但是用户邮箱的缓存数据存在 %LOCALAPPDATA%\Microsoft\Outlook 里面。前者是因为 mail signature 没有一个统一的云服务,如果用户刚好在启用了 roaming profiles 的 domain 里,则用户可以享受在公司里换电脑之后不需要重新设置签名档的好处。后者是因为,首先邮箱数据的缓存可能很大,其次,邮箱的缓存是一个删除了也没有损失的内容(可以重新从服务器下载),最后,邮箱缓存是从邮件服务器(例如 Exchange Server )来的,逻辑上就不需要用 roaming profile 同步。

最后:不要用 APPDATA 和 LOCALAPPDATA 去访问这两个文件夹。使用 SHGetKnownFolderPath (.NET 的 System.Environment.GetFolderPath )。

@Vhc #10

%AppData% = 用户的漫游数据
%UserProfile% = 用户配置文件夹,现在通常是 C:\Users\用户名,默认情况下用户的 known folders 是这个文件夹的子文件夹,但是用户可以修改
%AllUsersProfile% = 所有用户的配置文件夹,注意这不是公用文件夹,修改需要管理员权限,但是创建新文件和修改自己创建的文件不需要(每个用户自动有自己创建的文件夹、文件的全部控制权)
%ProgramFiles% = 整机软件应该默认被安装到的位置,如果你运行在 WoW 64 上,则自动变成 (x86) 版本,如果你是 x64/x86 系统的 x64/x86 进程,则通常是 C:\Program Files
%SystemRoot% = 系统的目录,通常是 C:\Windows
%SystemDrive% = 系统所在的驱动器字母,通常是 C:
%Temp% = %Tmp% = 当前会话(注销之前)的临时文件夹,注意,同一个用户多次登录系统,每次可能有不同的临时文件夹(该情况多见于 Windows Server )

我觉得这几个东西就没有什么相像的地方。为什么 TEMP 和 TMP 都有呢?兼容性。https://blogs.msdn.microsoft.com/oldnewthing/20150417-00/?p=44213/

此外,能使用 API 就不要用环境变量。因为使用环境变量有可能被启动你的进程骗(这可以是好事也可以是坏事)。
RainyH2O
2018-10-08 06:47:40 +08:00
@ysc3839 所以说很多软件安装过程里出现的给所有用户安装和给当前用户安装就是使用的这些环境变量不同么?安装后能再修改这个设置么(比如把给当前用户安装的切换成所有用户安装)?
geelaw
2018-10-08 09:09:23 +08:00
@RainyH2O #22 当然不是。

Designed for Windows 的软件需要在 Uninstall a program 里面出现。如果给全部用户安装,你需要把信息写进 HKLM,如果给当前用户安装,你需要写进 HKCU。有些软件会注册 COM 对象 /接口,安装到哪里决定了是写到 HKLM\SOFTWARE\Classes 还是 HKCU\Software\Classes。

安装后修改这个设置最常见、通用和简单的方法是卸载再重新安装。

此外 #21 已经提到,能用 API 就不要用环境变量。最后,那些位置一般是默认安装位置,很多软件可以修改安装位置的。
RainyH2O
2018-10-08 18:35:01 +08:00
@geelaw 那 Windows 区分 HKLM 和 HKCU 主要目的是什么?把软件配置写到注册表不同的地方是为了支持域管理还是多用户?
geelaw
2018-10-08 23:35:21 +08:00
@RainyH2O #24 多用户。HKLM 只有管理员等高权限者才可写入。HKCU 是 HKEY_USERS 对应当前用户的 subkey 的映射。

您这个问题很奇怪,因为所有现代的操作系统都有一种区分当前用户的资产和当前机器的资产的功能,注册表里的 key 相当于文件系统的 folder,在一个 hierarchical 的数据存储中无祖先后代关系的节点表示这种区别理解上就很自然,而且还可以利用 ACL 继承的便利。
RainyH2O
2018-10-09 08:07:56 +08:00
@geelaw 主要是对于 Windows 的设计哲学感到一些迷惑,查过文档又找不到解释,就打破砂锅问到底确认一下自己的猜测了。Windows 这样繁复的设计感觉就是想引导用户尽可能少动用管理员权限,特别是管理员权限还区分最高权限 SYSTEM 和较低权限 Administration 这样的进一步细分,不像 Unix 仅仅区分 root 和非 root 这样直观,似乎一切都是想把高级别的权限隐藏起来,与之相对应的部分包管理器却又违背这一理念提供这类细化的权限管理选项,两种落差反就使我产生了些许困惑,想来还是 Windows 对于包管理标准问题解决不彻底的历史遗留问题把。总归还是多谢指教了。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/495304

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX