Реально зашел в тупик, т.к. ни один известный мне метод полноценно не работает.
Нужно из программы включать/выключать сетевое подключение, например "Подключение по локальной сети".
Итак, пойдем по порядку:
1. WMI. В Win32_NetworkAdapter есть Enable/Disable, но, как написано на MSDN - это только для Windows Vista. Проверил, так оно и есть :( Не подходит, нужно поддерживать как минимум Windows 2000/XP/Vista.
2. Выключение/включение устройства (сетевой платы). Этот вариант уже более-менее работает на нужных версиях Windows, но не подходит, т.к. это совсем другое, чем пункты выключить/включить сетевое подключение. Даже при выключенном сетевом подключении я в WMI вижу нужную информацию, но если я удалю устройство - то я уже ничего не смогу показать, как-будто ни одной сетевой платы и нет.
3. ShellAPI. Смысл в том, что программа будет незаметно нажимать пункты контекстного меню включить/выключить для нужного подключения. На текущий момент это единственный работающий способ, который я смог найти. НО, использовать его совсем нет желания, т.к. считаю этот способ кривым. Аргументирую: в зависимости от языка интерфейса Windows пункты названы по-разному. Чтобы было понятнее, то вот код:
function ToggleLAN(const ConnectionName: string): Boolean;
const
EnableVerb = 'В&ключить';
DisableVerb = '&Отключить';
LANEnable: Boolean = True;
var
ShellApp: Shell32_tlb.Shell;
ControlPanel: Shell32_tlb.Folder;
FolderItem: Shell32_tlb.FolderItem;
NetworkFolder: Shell32_tlb.Folder;
LANConnection: Shell32_tlb.FolderItem;
EnableVerbItem, DisableVerbItem, Verb : Shell32_tlb.FolderItemVerb;
I,K: Integer;
begin
Result := False;
ShellApp := CoShell.Create;
ControlPanel := ShellApp.NameSpace(ssfCONTROLS);
for I := 0 to ControlPanel.Items.Count - 1 do
begin
FolderItem := ControlPanel.Items.Item(I);
if (FolderItem.Name = 'Сетевые подключения') or
(FolderItem.Name = 'Network and Dial-up Connections') or
(FolderItem.Name = 'Network and Sharing Center') then
begin
NetworkFolder := FolderItem.GetFolder as Folder;
Break;
end;
end;
if NetworkFolder = nil then
begin
Result := False;
Exit;
end;
for I := 0 to NetworkFolder.Items.Count - 1 do
begin
FolderItem := NetworkFolder.Items.Item(I);
if FolderItem.Name = ConnectionName then
begin
LANConnection := FolderItem;
Break;
end;
end;
if LANConnection = nil then
begin
Result := False;
Exit;
end;
for I := 0 to LANConnection.Verbs.Count - 1 do
begin
if LANConnection.Verbs.Item(I).Name = EnableVerb then
begin
EnableVerbItem := LANConnection.Verbs.Item(I);
EnableVerbItem.DoIt;
Break;
Result := True;
end
else if LANConnection.Verbs.Item(I).Name = DisableVerb then
begin
DisableVerbItem := LANConnection.Verbs.Item(I);
DisableVerbItem.DoIt;
Break;
Result := True;
end;
end;
4. Использование MIB_IF_ADMIN_STATUS_UP и MIB_IF_ADMIN_STATUS_DOWN. Тесты и документация показали, что эти способы работают, НО, при этом очень криво. Если я устанавливаю MIB_IF_ADMIN_STATUS_DOWN, то никакие пакеты через сетевую карту не идут, но при этом в системе/WMI/моей программе она имеет статус "подключено". Нарыл еще MIB_IF_OPER_STATUS_CONNECTED, но с ним ничего не получается (просто ничего не происходит, даже ошибок) и информации по нему найти я не смог.
Очень прошу помощи, может есть какие-нибудь еще варианты как можно из программы включить/выключить сетевое подключение?
Заранее спасибо.