4

ここに画像の説明を入力

Microsoft アカウントを使用して Windows 8 にログインしているユーザーのアクティブな電子メール/ID を見つけようとしています。これは、認証されたローカル アカウントではないと想定しています。

  • Windowsストアアプリではなく、WPFデスクトップC#アプリケーションからそれを見つけようとしています
  • me ショートカットなど、Live SDK が関連する可能性があることがわかりましたが、この API を本格的な .NET アプリケーションから使用できるかどうかはわかりませんか?
4

3 に答える 3

8

警告: 文書化されていない動作が始まります。このコードは、Microsoft が Windows Update をプッシュするたびに破損する可能性があります。

ユーザー トークンが作成されると、"Microsoft Account\YourAccountId" という名前のグループがユーザー トークンに追加されます。これを使用して、アクティブなユーザーの Microsoft アカウントを見つけることができます。

文書化されていない行動は終了します

現在のユーザーのグループ名を一覧表示する API は次のとおりです。

  • プロセス トークンを取得するための OpenProcessToken GetCurrentProcess TOKEN_QUERY
  • トークン内のグループを取得するための GetTokenInformation TokenGroups
  • グループ名を取得するための LookupAccountSid

System.Security.Principal クラスを使用して例を作成する方がはるかに簡単です。

public static string GetAccoutName()
{
    var wi= WindowsIdentity.GetCurrent();
    var groups=from g in wi.Groups                       
               select new SecurityIdentifier(g.Value)
               .Translate(typeof(NTAccount)).Value;
    var msAccount = (from g in groups
                     where g.StartsWith(@"MicrosoftAccount\")
                     select g).FirstOrDefault();
    return msAccount == null ? wi.Name:
          msAccount.Substring(@"MicrosoftAccount\".Length);
}
于 2014-05-31T20:55:01.023 に答える
0
  1. レジストリ エディターを開き、次の場所に移動します。

    HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList

  2. ProfileList キーの下に、SID が表示されます。それぞれを個別に選択することで、値のエントリを見て、その特定の SID に関連付けられているユーザー名を確認できます。

于 2013-11-02T10:42:10.793 に答える
0

Sheng によって説明された方法 (トークンを使用) を参照すると、現在の MS アカウント ID を取得するために作成した Delphi のコードは次のとおりです。

function GetNameFromSid(ASid: Pointer): string;
var
  snu: SID_NAME_USE;

  szDomain, szUser : array [0..50] of Char;
  chDomain, chUser : Cardinal;
begin
    chDomain := 50;
    chUser   := 50;

    if LookupAccountSid(nil, ASID, szUser, chUser, szDomain, chDomain, snu) then
      Result := string(szDomain) + '\' + string(szUser);
end;

function GetUserGroups(AStrings: TStrings): Boolean;
var
  hAccessToken       : tHandle;
  ptgGroups          : pTokenGroups;
  dwInfoBufferSize   : DWORD;
  psidAdministrators : PSID;
  int                : integer;            // counter
  blnResult          : boolean;            // return flag

  ProcessId: Integer;
  hWindow, hProcess, TokenHandle: THandle;
  si: Tstartupinfo;
  p: Tprocessinformation;

const
  SECURITY_NT_AUTHORITY: SID_IDENTIFIER_AUTHORITY =
    (Value: (0,0,0,0,0,5)); // ntifs
  SECURITY_BUILTIN_DOMAIN_RID: DWORD = $00000020;
  DOMAIN_ALIAS_RID_ADMINS: DWORD = $00000220;
  DOMAIN_ALIAS_RID_USERS : DWORD = $00000221;
  DOMAIN_ALIAS_RID_GUESTS: DWORD = $00000222;
  DOMAIN_ALIAS_RID_POWER_: DWORD = $00000223;


begin
  Result := False;
  p.dwProcessId := 0;

  hWindow := FindWindow('Progman', 'Program Manager');
  GetWindowThreadProcessID(hWindow, @ProcessID);
  hProcess := OpenProcess (PROCESS_ALL_ACCESS, FALSE, ProcessID);
  if OpenProcessToken(hProcess, TOKEN_QUERY, TokenHandle) then
  begin
    GetMem(ptgGroups, 1024);
    try
      blnResult := GetTokenInformation( TokenHandle, TokenGroups,
                                        ptgGroups, 1024,
                                        dwInfoBufferSize );
      CloseHandle( TokenHandle );

      if blnResult then
      begin
        for int := 0 to ptgGroups.GroupCount - 1 do
          AStrings.Add(GetNameFromSid(ptgGroups.Groups[ int ].Sid));
      end;
    finally
      FreeMem( ptgGroups );
    end;
  end;
end;

function GetCurrnetMSAccoundId: string;
const
  msAccStr = 'MicrosoftAccount\';
var
  AGroups: TStrings;
  i: Integer;
begin
  Result := '';
  AGroups := TStringList.Create;
  try
    GetUserGroups(AGroups);
    for i := 0 to AGroups.Count-1 do
      if Pos(msAccStr, AGroups[i]) > 0 then
      begin
        Result := Copy(AGroups[i], Length(msAccStr)+1, Length(AGroups[i])-Length(msAccStr));
        Break;
      end;
  finally
    AGroups.Free;
  end;
end;
于 2017-01-04T09:36:39.353 に答える