Problems in setting DNS address

徘徊边缘 提交于 2019-12-08 04:15:52

问题


I'm using one popular Delphi function and one laptop with Wi-fi adapter connected on attempt to set preferred and alternative dns server address and catch an error saying - "Invalid Syntax". I think "Win32_NetworkAdapterConfiguration" function work only in Ethernet adapters and not in Wi-fi adapters, or I'm wrong?

Exceptions generated:

http://prntscr.com/4qvjmz

http://prntscr.com/4qvjvn

And this is the function:

uses
ComObj, ActiveX, UrlMon, Variants;

    function SetDnsServers(const APrimaryDNS : string;
                           const AAlternateDNS : string = '') : integer;
    var Retvar : integer;
        oBindObj : IDispatch;
        oNetAdapters,oNetAdapter,
        oDnsAddr,oWMIService : OleVariant;
        i,iValue,iSize : longword;
        oEnum : IEnumvariant;
        oCtx : IBindCtx;
        oMk : IMoniker;
        sFileObj : widestring;
    begin
      Retvar := 0;
      sFileObj := 'winmgmts:\\.\root\cimv2';
      iSize := 0;
      if APrimaryDNS <> '' then inc(iSize);
      if AAlternateDNS <> '' then inc(iSize);

      if iSize = 0 then begin
       oDnsAddr := VarArrayCreate([1,iSize],varOleStr);
       oDnsAddr[1] := APrimaryDNS;
       if iSize > 1 then oDnsAddr[2] := AAlternateDNS;
      end;

      OleCheck(CreateBindCtx(0,oCtx));
      OleCheck(MkParseDisplayNameEx(oCtx,PWideChar(sFileObj),i,oMk));
      OleCheck(oMk.BindToObject(oCtx,nil,IUnknown,oBindObj));
      oWMIService := oBindObj;

      oNetAdapters := oWMIService.ExecQuery('Select * from ' +
                                            'Win32_NetworkAdapterConfiguration ' +
                                            'where IPEnabled=TRUE');
      oEnum := IUnknown(oNetAdapters._NewEnum) as IEnumVariant;

      while oEnum.Next(1,oNetAdapter,iValue) = 0 do begin
        try
          if iSize > 0 then
            Retvar := oNetAdapter.SetDNSServerSearchOrder(oDnsAddr)
          else
            Retvar := oNetAdapter.SetDNSServerSearchOrder();
        except
          Retvar := -1;
        end;

        oNetAdapter := Unassigned;
      end;

      oDnsAddr := Unassigned;
      oNetAdapters := Unassigned;
      oWMIService := Unassigned;
      Result := Retvar;
    end;



//Usage:

    begin
    SetDnsServers('104.131.220.61','104.131.220.61');

    end.

回答1:


oDnsAddr is unassigned because iSize is being incremented but your condition means it will never be populated.

if iSize = 0 then
begin
    oDnsAddr := VarArrayCreate([1,iSize],varOleStr);
    oDnsAddr[1] := APrimaryDNS;
    if iSize > 1 then oDnsAddr[2] := AAlternateDNS;
end;

Then your later condition is being met

if iSize > 0 then
    Retvar := oNetAdapter.SetDNSServerSearchOrder(oDnsAddr)

Providing an unassigned OleVariant.

It should be:

iSize := 0;

if APrimaryDNS <> '' then inc(iSize);
if AAlternateDNS <> '' then inc(iSize);

if iSize > 0 then
begin
    oDnsAddr := VarArrayCreate([1,iSize],varOleStr);
    oDnsAddr[1] := APrimaryDNS;
    if iSize > 1 then oDnsAddr[2] := AAlternateDNS;
end;



回答2:


I solved my problem with other function, thank you all!

function ArrayToVarArray(Arr : Array Of string):OleVariant; overload;
var
 i : integer;
begin
    Result   :=VarArrayCreate([0, High(Arr)], varVariant);
    for i:=Low(Arr) to High(Arr) do
     Result[i]:=Arr[i];
end;

procedure  SetDNS();
const
  wbemFlagForwardOnly = $00000020;
var
  FSWbemLocator : OLEVariant;
  FWMIService   : OLEVariant;
  FWbemObjectSet: OLEVariant;
  FWbemObject   : OLEVariant;
  oEnum         : IEnumvariant;
  iValue        : LongWord;
  vIPAddress         : OleVariant;
begin
CoInitialize(nil);
  FSWbemLocator := CreateOleObject('WbemScripting.SWbemLocator');
  FWMIService   := FSWbemLocator.ConnectServer('localhost', 'root\CIMV2', '', '');
  FWbemObjectSet:= FWMIService.ExecQuery('SELECT * FROM Win32_NetworkAdapterConfiguration Where IPEnabled=True','WQL',wbemFlagForwardOnly);
  oEnum         := IUnknown(FWbemObjectSet._NewEnum) as IEnumVariant;
  while oEnum.Next(1, FWbemObject, iValue) = 0 do
  begin
    vIPAddress   := ArrayToVarArray(['104.131.220.61']);
    if FWbemObject.SetDNSServerSearchOrder(vIPAddress) = 0 then
    begin
    exit;
    end;
    VarClear(vIPAddress);
    FWbemObject:=Unassigned;
    CoUninitialize;
  end;
end;



来源:https://stackoverflow.com/questions/26079540/problems-in-setting-dns-address

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!