У меня есть приложение, работающее на встроенной версии Windows 7. Оболочка Explorer заменяется Autohotkey, который затем запускает наше приложение.
Проблема в том, что наше приложение запускается слишком быстро, раньше Windows 'Сеть завершила запуск. Это приводит к тому, что запоминаемые сетевые интерфейсы не всегда доступны при запуске приложения. *
Есть ли гарантированный способ определить, что все доступные сети работают (надеюсь, проще, чем моя попытка)?
// STEP 1 Find the list of ethernet adapters that have a mac address
c := net_interfaces.RefreshAdapters;
tick_count := GetTickCount + 2000;
while (c < 11) and (GetTickCount < tick_count) do
begin
Sleep(100);
c := net_interfaces.RefreshAdapters;
end;
c := net_interfaces.RefreshAdapters(false);
LogMsg('Ethernet adapters found: '+c.ToString);
// STEP 2 Figure out what adapters are physically connected
tick_count := GetTickCount + 5000;
while (GetAdapterCount(false) < expected_interface_count) and (GetTickCount < tick_count) do
Sleep(100);
expected_interface_count := GetAdapterCount(false);
LogMsg('Ethernet adapters connected: ' + expected_interface_count.ToString);
// STEP 3 Populate the interface table with the correct number
tick_count := GetTickCount + 5000;
while (net_interfaces.Count < (expected_interface_count+1)) and (GetTickCount < tick_count) do
begin
net_interfaces.populate;
Sleep(100);
end;
// STEP 4 Check to see if we are waiting for DHCP
if net_interfaces.NetworkWaitingOnDHCP then
begin
fSplash.StetPB('Waiting on DHCP to be assigned');
tick_count := GetTickCount + 10000;
while (net_interfaces.NetworkWaitingOnDHCP) and (GetTickCount < tick_count) do
begin
net_interfaces.populate;
Sleep(100);
end;
end;
if net_interfaces.NetworkWaitingOnDHCP then
LogMsg('No DHCP address was assigned');
// STEP 5 Repopulate the interface table
net_interfaces.populate;
Шаг 1. Процедура «RefreshAdapters» использует код, найденный в этом сообщении, используя "GetIfTable". Delphi, как получить все локальные IP-адреса?
Шаг 2. GetAdapterCount использует следующую технику ...
function GetAdapterCount(LogFound: boolean): integer;
var
oBindObj : IDispatch;
oNetAdapters, oNetAdapter,
odnsAddr, oWMIService : OleVariant;
i, iValue : LongWord;
oEnum : IEnumVariant;
oCtx : IBindCtx;
oMk : IMoniker;
sFileObj : WideString;
begin
result := 0;
sFileObj := 'winmgmts:\\.\root\cimv2';
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_NetworkAdapter WHERE PhysicalAdapter=True AND MACAddress IS NOT NULL AND AdapterType IS NOT NULL AND NetConnectionStatus=2');
oEnum := IUnknown(oNetAdapters._NewEnum) as IEnumVariant;
while oEnum.Next(1, oNetAdapter, iValue) = 0 do begin
inc(result);
if logFound then
LogMsg('Connected adapters: ' + oNetAdapter.Caption);
oNetAdapter := Unassigned;
end;
odnsAddr := Unassigned;
oNetAdapters := Unassigned;
oWMIService := Unassigned;
end;
Шаг 3. " Заполните "список интерфейсов
procedure TInterfaces.populate;
var
err, BytesRet, i: integer;
fSocket: TSocket;
tmpInterfaceItm: TInterfaceItm;
nNumInterfaces: integer;
InterfaceList: Array[0..20] of INTERFACE_INFO;
begin
InitializeWinSock;
try
Clear;
fSocket := Socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
if fSocket = INVALID_SOCKET then exit
else
begin
err := WSAIoctl(fSocket, SIO_GET_INTERFACE_LIST, Nil, 0, @InterfaceList, sizeof(InterfaceList), @BytesRet, Nil, Nil);
if err <> SOCKET_ERROR then
begin
nNumInterfaces := BytesRet div sizeof(INTERFACE_INFO);
for i := 0 to nNumInterfaces-1 do
begin
tmpInterfaceItm := TInterfaceItm.Create;
Add(tmpInterfaceItm);
tmpInterfaceItm.in_interface_address := Psockaddr_in(@InterfaceList[i].iiAddress)^.sin_addr;
tmpInterfaceItm.in_interface_mask := Psockaddr_in(@InterfaceList[i].iiNetmask)^.sin_addr;
tmpInterfaceItm.in_interface_broadcast := CalculateBroadcastAddr(Psockaddr_in(@InterfaceList[i].iiAddress)^.sin_addr,
Psockaddr_in(@InterfaceList[i].iiNetmask)^.sin_addr);
tmpInterfaceItm.in_interface_sys_broadcast := Psockaddr_in(@InterfaceList[i].iiBroadcastAddress)^.sin_addr;
tmpInterfaceItm.interface_address := string(inet_ntoa(tmpInterfaceItm.in_interface_address));
tmpInterfaceItm.interface_mask := string(inet_ntoa(tmpInterfaceItm.in_interface_mask));
tmpInterfaceItm.interface_broadcast := string(inet_ntoa(tmpInterfaceItm.in_interface_broadcast));
end;
end;
CloseSocket(fSocket);
end;
finally
//UninitializeWinSock;
end;
end;
Шаг 4." NetworkWaitingOnDHCP "Проверьте, ждем ли мы DHCP
function TInterfaces.NetworkWaitingOnDHCP: Boolean;
var
i, j: Integer;
isUp: boolean;
begin
result := false;
for i := 0 to Count-1 do
begin
if (copy(trim(items[i].interface_address), 1, 7) = '169.254') then
begin
isUp := false;
net_interfaces.RefreshAdapters(false);
for j := 0 to High(Adapters) do
begin
if Adapters[j].sIpAddress = items[i].interface_address then
begin
isUp := Adapters[j].dwOperStatus > MIB_IF_OPER_STATUS_DISCONNECTED;
break;
end;
end;
if isUp then
begin
result := true;
break;
end;
end;
end;
end;