2010年7月13日

コンピュータ名を取得する

一時ファイル名の一部として使うなど、コンピュータ名を取得したい状況というのはそれなりにあると思います。そこでまずGetComputerName(ja)でNetBIOS名を取得してみます。
uses
  Windows, SysUtils;

function GetComputerName: String;
var
  Size: DWORD;
begin

  { Adjust buffer size }
  Size := MAX_COMPUTERNAME_LENGTH + 1;
  SetLength(Result,Size);

  { Get computer name }
  if Windows.GetComputerName(PChar(Result),Size) = False then
  begin
    RaiseLastOSError;
  end;
  SetLength(Result,Size);

end;

次にGetComputerNameEx(ja)(Windows 2000以降であれば使用可能)でDNSホスト名や完全修飾DNS名を取得してみます。まずはWindows.pasにGetComputerNameEx(W)と第1パラメータのCOMPUTER_NAME_FORMATの定義がWindows.pasに存在しない(Delphi 2010にはあるのかな?)ので用意します。
type
{$Z4}
  _COMPUTER_NAME_FORMAT = (ComputerNameNetBIOS,
                           ComputerNameDnsHostname,
                           ComputerNameDnsDomain,
                           ComputerNameDnsFullyQualified,
                           ComputerNamePhysicalNetBIOS,
                           ComputerNamePhysicalDnsHostname,
                           ComputerNamePhysicalDnsDomain,
                           ComputerNamePhysicalDnsFullyQualified,
                           ComputerNameMax);
  {$EXTERNALSYM _COMPUTER_NAME_FORMAT}
  COMPUTER_NAME_FORMAT  = _COMPUTER_NAME_FORMAT;
  {$EXTERNALSYM COMPUTER_NAME_FORMAT}
  TComputerNameFormat   = COMPUTER_NAME_FORMAT;

function GetComputerNameExW(NameType: COMPUTER_NAME_FORMAT; lpBuffer: PWideChar;
                            var nSize: DWORD): BOOL; stdcall;
  external kernel32 name 'GetComputerNameExW';
  {$EXTERNALSYM GetComputerNameExW}

そしてこれを
uses
  Windows, SysUtils;

function GetComputerNameEx(NameType: TComputerNameFormat): String;
var
{$IFDEF Unicode}
  Buffer: String;
{$ELSE}
  Buffer: WideString;
{$ENDIF}
  Size: DWORD;
begin

  { Adjust buffer size }
  Size := 0;
  GetComputerNameExW(NameType,nil,Size);
  SetLength(Buffer,Size);

  { Get computer name }
  if GetComputerNameExW(NameType,PWideChar(Buffer),Size) = False then
  begin
    RaiseLastOSError;
  end;
  SetLength(Buffer,Size);
  Result := Buffer;

end;

という形で呼び出します。1回目のGetComputerNameExではlpBufferをNULLに、nSizeを0にすることでバッファに必要なサイズ(終端のNUL文字を含む)を取得し、2回目のGetComputerNameExで実際のコンピュータ名を取得するのですが、GetComputerNameExA(ANSI版)ではlpBufferをNULLにしても正常にバッファサイズを取得できないため、GetComputerNameExW(Unicode版)を使用しています。

0 件のコメント: