![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Как включить/выключить подключение по локальной сети? Варианты... [Win2k, WinXP]
AlexTitov © (2008-04-28 13:25:00)Реально зашел в тупик, т.к. ни один известный мне метод полноценно не работает.
Нужно из программы включать/выключать сетевое подключение, например "Подключение по локальной сети".
Итак, пойдем по порядку:
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);
// test := ConnectionName;
for I := 0 to ControlPanel.Items.Count - 1 do
begin
FolderItem := ControlPanel.Items.Item(I);
// ShowMessage(FolderItem.Name);
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);
// ShowMessage(FolderItem.Name);
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
// showmessage(LANConnection.Verbs.Item(I).Name);
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, но с ним ничего не получается (просто ничего не происходит, даже ошибок) и информации по нему найти я не смог.
Очень прошу помощи, может есть какие-нибудь еще варианты как можно из программы включить/выключить сетевое подключение?
Заранее спасибо.
DVM (2008-04-29 22:39:00) [1]не проще вызвать netsh?
ZENsan (2008-04-29 15:30:00) [2]Folder.GetPath даёт этот гуид если что..
AlexTitov (2008-04-29 12:16:00) [3]Спасибо, сейчас попробую этот вариант.
ZENsan (2008-04-29 11:00:00) [4]Меню Enable/Disable - всегда первое.. и проверять его номер думаю даже может не стоит..
А для проверки имени {BA126ADB-2166-11D1-B1D0-00805FC1270E} - у тебя GUID есть..
ZENsan (2008-04-29 10:49:00) [5]
procedure TForm37.Button1Click(Sender: TObject);
var
Fol, Net: Folder;
Cpl, Con: FolderItem;
i, j, v: Integer;
begin
try
Fol := Shell.NameSpace(ssfCONTROLS);
for i := 0 to Fol.Items.Count - 1 do
begin
Cpl := Fol.Items.Item(i);
if Cpl.Name = 'Network Connections' then
begin
Memo1.Lines.Add(Cpl.Name);
for v := 0 to Cpl.Verbs.Count - 1 do
Memo1.Lines.Add(Cpl.Verbs.Item(v).Name);
Net := Cpl.GetFolder as Folder;
Memo1.Lines.Add('Connections:');
for v := 0 to Net.Items.Count - 1 do
begin
Memo1.Lines.Add(Net.Items.Item(v).Name);
if Net.Items.Item(v).Name = 'Internet' then
begin
Con := Net.Items.Item(v);
for j := 0 to Con.Verbs.Count - 1 do
begin
Memo1.Lines.Add(Con.Verbs.Item(j).Name);
if Con.Verbs.Item(j).Name = 'Disa&ble' then
Con.Verbs.Item(j).DoIt;
end;
end;
end;
Memo1.Lines.Add('======================');
end;
end;
finally
Fol := nil;
Cpl := nil;
Net := nil;
Con := nil;
end;
end;
Не вижу проблемы... всё работает как часы
ZENsan (2008-04-29 10:29:00) [6]http://support.microsoft.com/default.aspx?scid=kb;EN-US;Q311272