在Jscript中获取给定用户的特殊文件夹路径
如何为当前用户以外的特定用户获取本地设置或本地Appdata等shell文件夹的路径?
How to get the path of a shell folder like "Local Settings" or "Local Appdata" for a specific user other than the current user?
虽然有一些方法可以在Windows脚本宿主中获取特殊文件夹路径— WshShell.SpecialFolders
和 Shell.NameSpace
—它们只返回当前用户的路径。获取其他用户的特殊文件夹路径有点棘手。
While there are methods for getting special folder paths in Windows Script Host — WshShell.SpecialFolders
and Shell.NameSpace
— they return paths for the current user only. Getting other users' special folder paths is a bit tricky.
执行此操作的正确方法是使用Windows API SHGetKnownFolderPath
功能(或 SHGetFolderPath
在Vista之前)。但问题是,Windows Script Host不支持调用WinAPI函数,因此要在脚本中使用这些函数,您必须通过自定义编写的COM组件公开它们。
The proper way to do this is to use the Windows API SHGetKnownFolderPath
function (or SHGetFolderPath
on Windows versions prior to Vista). But the problem is, Windows Script Host doesn't support calling WinAPI functions, so to make use of these functions in your script you'll have to expose them via a custom-written COM component.
另一种可能但未记录的解决方案是从该用户的注册表配置单元中读取特殊文件夹路径,特别是 HKEY_USERS \< user_SID> \软件\ Microsoft \ Windows \ CurrentVersion \Explorer \用户Shell文件夹
密钥。
Another possible but undocumented solution is to read the special folder paths from that user's registry hive, specifically, the HKEY_USERS\<user_SID>\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders
key.
用户外壳文件夹
键中的路径通常使用%USERPROFILE%
环境变量指定;因此,要获得完全限定的路径,您必须使用 HKEY_LOCAL_MACHINE \ SOFTWARE \ Microoft \ Windows中的
key。 ProfileImagePath
值替换此变量NT \ CurrentVersion \ProfileList \< user_SID>
The paths in the User Shell Folders
key are typically specified using the %USERPROFILE%
environment variable; so to get fully-qualified paths you'll have to substitute this variable with the ProfileImagePath
value from the HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\<user_SID>
key.
此外, HKEY_USERS \< ; user_SID>
密钥仅在相应用户当前登录时可用。对于一般解决方案,您必须将用户的配置单元(< UserProfile> \ antuser.dat )加载到临时注册表项中(例如, HKEY_USERS \Temp
)并从该键读取值。
Also, the HKEY_USERS\<user_SID>
key is only available when the corresponding user is currently logged on. For a general solution, you would have to load the user's hive (<UserProfile>\ntuser.dat) into a temporary registry key (say, HKEY_USERS\Temp
) and read values from this key instead.
下面是演示如何完成任务的示例JScript代码。在Windows 7和Vista上,您可能需要以管理员身份运行脚本,具体取决于您的UAC设置。
Below is sample JScript code that demonstrates how your task can be accomplished. On Windows 7 and Vista, you may need to run the script as Administrator depending on your UAC settings.
注意:不鼓励使用此方法,正如Raymond Chen在他的文章漫长而悲伤的故事中所解释的那样。 Shell文件夹键。无法保证它将继续在未来的Windows版本中运行。
NOTE: This method is discouraged, as Raymond Chen explains in his article The long and sad story of the Shell Folders key. There's no guarantee it will keep working in future versions of Windows.
var strUser = "foo";
var strDomain = "bar";
// If the account is local, domain name = computer name:
// var strDomain = getComputerName();
var strSID = getSID(strUser, strDomain);
var strProfilePath = getProfilePath(strSID);
// Load the user's registry hive into the HKEY_USERS\Temp key
var strTempKey = "Temp";
loadHKUHive(strTempKey, strProfilePath + "\\ntuser.dat");
// Get unexpanded path, e.g. %USERPROFILE%\AppData\Roaming
//var strAppData = getAppData(strSID);
var strAppData = getAppData(strTempKey);
WScript.Echo(strAppData);
// Expand the previous value to a fully-qualified path, e.g. C:\Users\foo\AppData\Roaming
strAppData = strAppData.replace(/%USERPROFILE%/i, strProfilePath);
WScript.Echo(strAppData);
// Unload the user's registry hive
unloadHKUHive(strTempKey);
function getComputerName() {
var oShell = new ActiveXObject("WScript.Shell");
return oShell.ExpandEnvironmentStrings("%COMPUTERNAME%");
}
function getSID(strUser, strDomain) {
var oAccount = GetObject("winmgmts:root/cimv2:Win32_UserAccount.Name='" + strUser + "',Domain='" + strDomain + "'");
return oAccount.SID;
}
function getProfilePath(strSID) {
var oShell = new ActiveXObject("WScript.Shell");
var strValue = oShell.RegRead("HKLM\\Software\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\" + strSID + "\\ProfileImagePath");
return strValue;
}
function getAppData(strSID) {
var oShell = new ActiveXObject("WScript.Shell");
var strValue = oShell.RegRead("HKEY_USERS\\" + strSID + "\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders\\AppData");
return strValue;
}
function loadHKUHive(strKeyName, strHiveFile) {
var oShell = new ActiveXObject("WScript.Shell");
oShell.Run("reg load HKU\\" + strKeyName + " " + strHiveFile, 0, true);
}
function unloadHKUHive(strKeyName) {
var oShell = new ActiveXObject("WScript.Shell");
oShell.Run("reg unload HKU\\" + strKeyName, 0, true);
}