是否有本地化安全的方法来获取 SYSTEM 帐户的 AppData 目录?
Posted
技术标签:
【中文标题】是否有本地化安全的方法来获取 SYSTEM 帐户的 AppData 目录?【英文标题】:Is there a localization-safe way to get the SYSTEM account's AppData directory? 【发布时间】:2019-04-16 18:39:49 【问题描述】:我知道我可以使用GetSystemDirectory()
来获取C:\Windows\System32
的目录,但我想知道是否有办法在下面获取此目录路径,无论操作系统如何本地化或我是否以普通用户或系统帐户:
C:\Windows\System32\config\systemprofile\AppData\Local\TEMP
或者至少到C:\Windows\System32\config\systemprofile\AppData
我尝试在SHGetFolderPath()
中使用SHGFP_TYPE_DEFAULT
而不是SHGFP_TYPE_CURRENT
选项,但这将返回当前正在运行的用户目录,而不是在不作为SYSTEM 运行时返回SYSTEM。
void GetUserLocalTempPath(std::wstring& input_parameter)
HWND folder_handle = 0 ;
WCHAR temp_path[MAX_PATH];
auto get_folder = SHGetFolderPath(
folder_handle, CSIDL_LOCAL_APPDATA, NULL, SHGFP_TYPE_DEFAULT, temp_path
);
if (get_folder == S_OK)
input_parameter = static_cast<const wchar_t*>(temp_path);
input_parameter.append(L"\\TEMP");
CloseHandle(folder_handle);
【问题讨论】:
不清楚什么是问题/问题。您可以按原样获取文件路径 不清楚您对@RbMm 的不清楚之处。您是说本地化无关紧要,并且始终使用英语吗? 但是函数返回给你的文件系统路径。照原样。你想要什么本地化? 不,正确的方法是使用CSIDL_LOCAL_APPDATA
或 SHGetKnownFolderPath
和带有本地系统令牌的 FOLDERID_LocalAppData
或运行/模拟本地系统时。你不需要硬编码L"\\config\\systemprofile\\AppData"
但 SHGetFolderPath(0, CSIDL_LOCAL_APPDATA, 0, SHGFP_TYPE_CURRENT, temp_path)
例如(如果您以 LocalSystem 身份运行)您如何使用 folder_handle
不正确 - 这是 hwnd 并且仅在参数中。 CloseHandle(folder_handle);
当然错了
【参考方案1】:
您需要在SYSTEM
帐户下运行一个进程才能查询SYSTEM
配置文件。
创建一个以SYSTEM
运行的单独服务。需要时,让它调用SHGetFolderPath(CSIDL_LOCAL_APPDATA)
或SHGetKnownFolderPath(FOLDERID_LocalAppData)
,为用户令牌指定NULL
,以便查询调用用户(即SYSTEM
)的配置文件(或者,只需使用GetTempPath()
,其中will also work in this context) .
然后,该服务可以通过您想要的任何与会话无关的 IPC 机制(管道、套接字等)将该路径传递回您的主应用程序。
附注:
在将temp_path
分配给input_parameter
时,您不需要进行类型转换。 temp_path
将隐式衰减为wchar_t*
指针,该指针可以按原样传递给std::wstring::operator=()
作为输入的const wchar_t*
指针。
而不是手动使用input_parameter.append(L"\\TEMP")
(如果您使用GetTempPath()
,则根本不需要),您应该考虑使用PathCchCombineEx()
(或相关)或SHGetFolderPathAndSubDir()
。让操作系统为您处理附加内容。
您使用 HWND
作为输入调用 CloseHandle()
,这是错误的,因为它需要 HANDLE
代替(但在您的情况下这是一个无操作,因为 HWND
为 NULL,所以只需完全删除CloseHandle()
)。显然,您没有在启用STRICT Type Checking 的情况下编译您的项目,否则编译器会阻止将HWND
传递给HANDLE
参数。
【讨论】:
感谢您提及STRICT
!我会检查一下:)【参考方案2】:
Remy Lebeau's answer 是以编程方式执行此操作的正确方法。但是,它可能超出您 的要求;如果您需要此功能的原因不需要多代操作系统支持,您可能不想跳过所有这些障碍。因此,如果您使用的是 Windows 10,那么现在执行此操作似乎是安全的。也就是说,我不推荐它,因为它的基本缺点。这只是一个简单的草率解决方法,因此使用风险自负。
我没有任何关于这个潜在解决方案寿命的支持文档,只有轶事反馈和一些个人测试。
我从几个人那里听说重要的操作系统系统目录没有本地化。我将 Windows 10 Pro Japanese 映像作为虚拟机安装到 Hyper-V 主机上。将字符串 C:\Windows\System32\config\systemprofile\AppData
粘贴并输入到日语资源管理器地址栏中工作正常,如下所示,
这里的要点是,在您获得系统目录的值之后(我们不能假设C:\WINODWS\system32
),您应该能够用简单的英语对其余部分进行硬编码。这是一个可以为您完成此任务的示例应用程序:
#define STRICT
#include <Windows.h>
#include <wchar.h>
#include <memory>
int wmain()
static constexpr const wchar_t * SystemProfileAppData_RemainingPath
= L"\\config\\systemprofile\\AppData";
wchar_t system_path_buffer[MAX_PATH];
const std::size_t winapi_worked = GetSystemDirectory(system_path_buffer, MAX_PATH);
if (winapi_worked)
const std::size_t system32_offset = wcsnlen_s(system_path_buffer, MAX_PATH);
const std::size_t appdata_offset = wcsnlen_s(SystemProfileAppData_RemainingPath, MAX_PATH);
const std::size_t path_bytes_size = (appdata_offset + system32_offset) * sizeof(wchar_t);
memcpy_s(
&system_path_buffer[system32_offset],
path_bytes_size,
SystemProfileAppData_RemainingPath,
path_bytes_size
);
wprintf_s(L"SYSTEM's AppData is here: %s\r\n", system_path_buffer);
return 0;
return 1;
SYSTEM's AppData is here: C:\WINDOWS\system32\config\systemprofile\AppData
【讨论】:
以上是关于是否有本地化安全的方法来获取 SYSTEM 帐户的 AppData 目录?的主要内容,如果未能解决你的问题,请参考以下文章
是否有一个等效的 REST API 函数来获取 Paypal 帐户的余额,类似于 NVP 获取余额 API? [关闭]