在 InnoSetup 安装程序中获取用户主体名称 (UPN)?

Get User Principal Name (UPN) In InnoSetup Installer?

在 InitializeSetup() 函数以及其他操作中,当安装程序为 运行 时,我希望安装程序检索当前的 UPN。 UserName 变量还不够。我还尝试过使用 WTSQuerySessionInformation() 函数在此处讨论的方法,但它们似乎 return 不是我想要的。根据组织和设置,UPN 应该经常 return 某种我正在寻找的电子邮件地址。有人可以阐明如何 return 完整的 UPN 值作为字符串吗?谢谢。

编辑:

我也尝试过 GetUserNameExW() 函数将值 8 作为输入传递给 UserNamePrincipal,但是我 return 似乎是一个空值。

function GetUserNameExW(NameFormat: Integer; lpNameBuffer: string; var nSize: DWORD): Boolean;
  external 'GetUserNameExW@secur32.dll stdcall';
var
  NumChars: DWORD;
  OutStr: string;
  name: string;

begin
  SetLength(OutStr, NumChars);
  GetUserNameExW(8, OutStr, NumChars);
  name := Copy(OutStr,1,NumChars);

我自己设法解决了这个问题,但仍然不能 100% 确定为什么我之前的迭代会导致奇怪的行为。

基本上,我必须在之前添加一个 if 检查:

if GetUserNameExW(8, OutStr, NumChars) then

调用 GetUserNameExW 以获取当前用户的 userPrincipalName (UPN) 属性的正确代码如下所示:

function GetUserNameExW(NameFormat: Integer; lpNameBuffer: string; var nSize: DWORD): Boolean;
  external 'GetUserNameExW@secur32.dll stdcall';

function GetUserPrincipalName(): string;
var
  NumChars: DWORD;
  OutStr: string;
begin
  result := '';
  NumChars := 0;
  if (not GetUserNameExW(8, '', NumChars)) and (DLLGetLastError() = 234) then
  begin
    SetLength(OutStr, NumChars);
    if GetUserNameExW(8, OutStr, NumChars) then
      result := Copy(OutStr, 1, NumChars);
  end;
end;

NameFormat参数的值8对应EXTENDED_NAME_FORMAT枚举中的NameUserPrincipal,值234为API值 ERROR_MORE_DATA.

然而——正如我在评论中指出的——如果你正在寻找一个电子邮件地址,这将不是执行此操作的代码,因为 userPrincipalName (UPN) 是一个单独的用户属性 (事实上,在许多(如果不是大多数)组织中,UPN 与用户的电子邮件地址不同)。此外,如果您假设 UPN 与用户的电子邮件地址之一相同,这也是一个错误的假设,因为 UPN 的值通常不在用户的有效电子邮件地址列表中。

关键是,如果您正在寻找一种可靠的方法来为用户获取有效的电子邮件地址,UPN 不会给您一个。