-1

This code change IP address with no problems

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  SetStaticIP();
Const
wbemFlagForwardOnly = $00000020;
var
FSWbemLocator : OLEVariant;
FWMIService   : OLEVariant;
FWbemObjectSet: OLEVariant;
FWbemObject   : OLEVariant;
oEnum         : IEnumvariant;
iValue        : LongWord;
vIPAddress         : OleVariant;
vSubnetMask        : OleVariant;
vDefaultIPGateway  : OleVariant;
vGatewayCostMetric : OleVariant;
begin
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(['192.168.2.22']);
vSubnetMask  := ArrayToVarArray(['255.255.255.0']);
if FWbemObject.EnableStatic(vIPAddress, vSubnetMask) = 0 then
begin
  vDefaultIPGateway  := ArrayToVarArray(['192.168.2.2']);
  vGatewayCostMetric := ArrayToVarArray(['1']);
  FWbemObject.SetGateways(vDefaultIPGateway,vGatewayCostMetric);
end;

VarClear(vIPAddress);
VarClear(vSubnetMask);
VarClear(vDefaultIPGateway);
VarClear(vGatewayCostMetric);
FWbemObject:=Unassigned;
end;
end;

But i want to let user input the (IP, Subnet, Gateway) So I changed the code like this

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  SetStaticIP(IP, Subnet, Gateway: array of string);
Const
wbemFlagForwardOnly = $00000020;
var
FSWbemLocator : OLEVariant;
FWMIService   : OLEVariant;
FWbemObjectSet: OLEVariant;
FWbemObject   : OLEVariant;
oEnum         : IEnumvariant;
iValue        : LongWord;
vIPAddress         : OleVariant;
vSubnetMask        : OleVariant;
vDefaultIPGateway  : OleVariant;
vGatewayCostMetric : OleVariant;
begin
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(IP);
vSubnetMask  := ArrayToVarArray(Subnet);
if FWbemObject.EnableStatic(vIPAddress, vSubnetMask) = 0 then
begin
  vDefaultIPGateway  := ArrayToVarArray(Gateway);
  vGatewayCostMetric := ArrayToVarArray(['1']);
  FWbemObject.SetGateways(vDefaultIPGateway,vGatewayCostMetric);
end;

VarClear(vIPAddress);
VarClear(vSubnetMask);
VarClear(vDefaultIPGateway);
VarClear(vGatewayCostMetric);
FWbemObject:=Unassigned;
end;
end;

But it doesn't work anymore I found that I have to convert the input text to array of string , so i did it like this

procedure TForm1.BtnApplyClick(Sender: TObject);
var
IP, Subnet, Gateway: array of string;
I: Integer;
begin
    SetLength(IP, EdtIP.GetTextLen);
    for I := 0 to EdtIP.GetTextLen do IP[I] := Copy(EdtIP.Text, I, 1);

    SetLength(Subnet, EdtSubnet.GetTextLen);
    for I := 0 to EdtSubnet.GetTextLen do Subnet[I] := Copy(EdtIP.Text, I, 1);

    SetLength(Gateway, EdtGateway.GetTextLen);
    for I := 0 to EdtGateway.GetTextLen do Gateway[I] := Copy(EdtIP.Text, I, 1);

SetStaticIP(IP, Subnet, Gateway);
end;

But it still didn't work, I can't find where I did mistake! Any idea to get this code work?

RRUZ
  • 134,889
  • 20
  • 356
  • 483
Master
  • 328
  • 3
  • 10
  • Slightly off-topic: I would seriously look at checking and reporting if the IP address is already in use before changing it based on user (error-prone) input. – Ron Maupin Sep 09 '15 at 06:43

2 Answers2

1

Use open array constructors like this:

procedure TForm1.BtnApplyClick(Sender: TObject);
begin
  SetStaticIP([EdtIP.Text], [EdtSubnet.Text], [EdtGateway.Text]);
end;

This is the most concise way to call your function.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • I tried it but it didn't work it should be 'array of string' and then convert it to 'array of variant' – Master Sep 10 '15 at 17:14
  • Not so. This compiles given the code in the question. The function is declared like this: `procedure SetStaticIP(IP, Subnet, Gateway: array of string);` it's right there in the question. Do you want to learn or not? Or are you happy with your answer? – David Heffernan Sep 10 '15 at 17:53
  • 1
    What do you think?? did you test it before you comment here?? 'procedure SetStaticIP' will call 'function ArrayToVarArray(Arr : Array Of string):OleVariant;' and this function required 'array of string' to work, change it to anything else and it will not work so please test it before your next helpful comment! and thank you for time – Master Sep 14 '15 at 00:47
  • The function is declared like this: `procedure SetStaticIP(IP, Subnet, Gateway: array of string);` Is it plausible that you don't know what those parameters are? That they are known as open arrays? – David Heffernan Sep 14 '15 at 03:26
  • 1
    I know what is it, in first place i used it but when run the application it didn't make any change to the (IP, Subnet, Gateway or DNS) so i kept trying for hours till i found this is the only way make it works, you can test it by yourself, please test it and tell me if it works for you – Master Sep 14 '15 at 09:16
  • For me it still doesn't work, Maybe I have problem with Rad Studio or something else? should try I reinstall it? – Master Sep 15 '15 at 23:06
0

I found the answer

procedure TForm1.BtnApplyClick(Sender: TObject);
var
  IP, Subnet, Gateway: array of string;
begin
    SetLength(IP, 1);
    SetLength(Subnet, 1);
    SetLength(Gateway, 1);

    IP[0] := EdtIP.Text ;
    Subnet[0] := EdtSubnet.Text ;
    Gateway[0] := EdtGateway.Text ;

    SetStaticIP(IP, Subnet, Gateway);
end;
Master
  • 328
  • 3
  • 10