如何使用Delphi查找Windows用户(不是当前用户)的个人资料目录?

3

这个问题可能很简单,我正在尝试使用以下代码:

var
 lpProfileDir            : tChar;
 lpProfileSize           : Cardinal;
 token                   : tHandle;
 GuestDir,GuestUser      : String;

begin
 GuestUser:=RadioGroup1.Items[RadioGroup1.ItemIndex];
 if LogonUser(PChar(GuestUser), nil, nil, LOGON32_LOGON_SERVICE, LOGON32_PROVIDER_DEFAULT, token) then
  begin
    SetLength(GuestDir, MAX_PATH);
    ZeroMemory(@GuestDir[1], MAX_PATH);
    lpProfileSize:=MAX_PATH;
    if GetUserProfileDirectoryA(token, PChar(GuestDir), lpProfileSize) then
     begin
       ShowMessage(GuestDir);
    ...

现在,这返回当前用户的个人资料目录。请注意,我想在Windows XP/Vista/7/8下使用此应用程序。

1
说“Windows用户”时,您指的是哪个用户?您是否需要特定用户的配置文件夹(例如从您代码中的变量“GuestUser”)? - Andrei Galatyn
毫无意义的ZeroMemory。字符串和动态数组都被初始化为零。而且,你调用的函数会分配缓冲区。它会覆盖你的初始化。 - David Heffernan
Andrei: 测试用例中的GuestUser是'Guest' David: 我知道了,我在网上找到了这段代码,以为那是正确的方法。 - modzsi
安德烈:简而言之,是的。 - modzsi
1个回答

4
尝试使用GetUserProfileDirectory替代SHGetFolderPath。以下是一个示例(你需要在UserEnv.dll中获取GetUserProfileDirectory绑定):
if LogonUser(PChar(GuestUser), 0, 0, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, token) then 
begin
  SetLength(GuestDir, MAX_PATH);
  ZeroMemory(@GuestDir[1], MAX_PATH);
  if Succeeded(GetUserProfileDirectoryA(token, PChar(GuestDir), MAX_PATH)) then 
    ShowMessage(GuestDir); 
end;

你能提供一个简单的例子吗?我好像无法让它工作...谢谢! - modzsi
@modzsi 你需要为 UserEnv.dll 创建绑定,就像这个链接中的 http://read.pudn.com/downloads62/ebook/218392/UserEnv.pas__.htm 那样。 - Sedat Kapanoglu
今天我放弃了...也许明天再试试。现在我只是做了这个:if SUCCEEDED(SHGetFolderPath(0,CSIDL_PERSONAL,0,SHGFP_TYPE_CURRENT,@path[0])) then GuestDir := StringReplace(path,GetUserNameFromWindows,GuestUser,[rfReplaceAll]) - modzsi
1
使用LOGON32_LOGON_SERVICE而不是LOGON32_LOGON_INTERACTIVE,对于所有帐户都可以正常工作... 谢谢! - modzsi
在Windows 10中,使用空密码时,LogonUser始终会因错误ERROR_LOGON_FAILURE而失败。 - Bruno Haible

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接