对不起,我没有任何代码可以显示.这可能会使这个问题成为
Programmers的候选者,但是他们在这里没有语言特定区域,我正在寻求Delphi解决方案,所以我会问这里.我希望这是可以接受的.
基本上,我想在WiFi连接时自动启动我的VPN.我怎么会发现这个?看来,谷歌在这件事上并不是我的朋友.
解决方法
所需的WinApi调用未在Delphi中实现 – 您必须自己定义和调用它们.在这种情况下,相关功能是:
WlanRegisterNotification (MSDN)
WLAN_NOTIFICATION_SOURCE structure (MSDN)
您可以将它们定义为:
const wlanapi = 'wlanapi.dll'; WLAN_NOTIFICATION_SOURCE_ACM = $00000008; type GUID = TGUID; HANDLE = THandle; PWLanNotificationData = ^TWLanNotificationData; TWLanNotificationData = record NotificationSource: DWORD; NotificationCode: DWORD; InterfaceGuid: GUID; dwDataSize: DWORD; pData: PVOID; end; TWLanNotificationCallback = procedure(data: PWLanNotificationData; context: PVOID); stdcall; function WlanOpenHandle(dwClientVersion: DWORD; pReserved: PVOID; out pdwNegotiatedVersion: DWORD; out phClientHandle: HANDLE): DWORD; stdcall; external wlanapi name 'WlanOpenHandle'; function WlanRegisterNotification(hClientHandle: HANDLE; dwNotifSource: DWORD; bIgnoreDuplicate: BOOL; funcCallback: TWLanNotificationCallback; pCallbackContext: PVOID; pReserved: PVOID; out pdwPrevNotifSource: DWORD): DWORD; stdcall; external wlanapi name 'WlanRegisterNotification';
并称他们为:
// Define a callback procedure to handle the notifications // You can supply a context pointer to any user information the callback // may require (pointer to object,etc) procedure OnWlanNotify(data : PWLanNotificationData; context : PVOID); stdcall; begin // ShowMessage(IntToStr(data^.NotificationCode)); etc... end; // Register for notification procedure TForm1.FormCreate(Sender: TObject); var negotiatedVer : DWORD; prevSource : DWORD begin if WlanOpenHandle(2,nil,negotiatedVer,FHandle) <> ERROR_SUCCESS then begin // handle error... end; // check negotiatedVersion if needed if WlanRegisterNotification(FHandle,WLAN_NOTIFICATION_SOURCE_ACM,LongBool(true),@OnWlanNotify,prevSource) <> ERROR_SUCCESS then begin end;
这会注册您的WLAN通知.您的回调函数将在收到通知后执行,并且可以在传递给该方法的TWlanNotificationData结构中找到通知的性质.
您还应该在不再需要时取消注册通知.我这里只实现了基本的错误检查.可以在引用的MSDN文档中找到各种错误代码的详细信息.
(部分)ACM通知列表:
const WLAN_NOTIFICATION_ACM_AUTOCONF_ENABLED = $00000001; //Autoconfiguration is enabled. WLAN_NOTIFICATION_ACM_AUTOCONF_DISABLED = $00000002; //Autoconfiguration is disabled. WLAN_NOTIFICATION_ACM_BACKGROUND_SCAN_ENABLED = $00000003; //Background scans are enabled. WLAN_NOTIFICATION_ACM_BACKGROUND_SCAN_DISABLED = $00000004; //Background scans are disabled. WLAN_NOTIFICATION_ACM_BSS_TYPE_CHANGE = $00000005; //The BSS type for an interface has changed. WLAN_NOTIFICATION_ACM_POWER_SETTING_CHANGE = $00000006; //The power setting for an interface has changed. WLAN_NOTIFICATION_ACM_SCAN_COMPLETE = $00000007; //A scan for networks has completed. WLAN_NOTIFICATION_ACM_SCAN_FAIL = $00000008; //A scan for connectable networks Failed. WLAN_NOTIFICATION_ACM_CONNECTION_START = $00000009; //A connection has started to a network in range. WLAN_NOTIFICATION_ACM_CONNECTION_COMPLETE = $0000000a; //A connection has completed. WLAN_NOTIFICATION_ACM_CONNECTION_ATTEMPT_FAIL = $0000000b; //A connection attempt has Failed. WLAN_NOTIFICATION_ACM_FILTER_LIST_CHANGE = $0000000c; //A change in the filter list has occurred,either through group policy or a call to the WlanSetFilterList function. WLAN_NOTIFICATION_ACM_INTERFACE_ARRIVAL = $0000000d; //A wireless LAN interface is been added to or enabled on the local computer. WLAN_NOTIFICATION_ACM_INTERFACE_REMOVAL = $0000000e; //A wireless LAN interface has been removed or disabled on the local computer. WLAN_NOTIFICATION_ACM_PROFILE_CHANGE = $0000000f; //A change in a profile or the profile list has occurred,either through group policy or by calls to Native Wifi functions. WLAN_NOTIFICATION_ACM_PROFILE_NAME_CHANGE = $00000010; //A profile name has changed,either through group policy or by calls to Native Wifi functions. WLAN_NOTIFICATION_ACM_PROFILES_EXHAUSTED = $00000011; //All profiles were exhausted in an attempt to autoconnect. WLAN_NOTIFICATION_ACM_NETWORK_NOT_AVAILABLE = $00000012; //The wireless service cannot find any connectable network after a scan. WLAN_NOTIFICATION_ACM_NETWORK_AVAILABLE = $00000013; //The wireless service found a connectable network after a scan,the interface was in the disconnected state,and there is no compatible auto-connect profile that the wireless service can use to connect . WLAN_NOTIFICATION_ACM_DISCONNECTING = $00000014; //The wireless service is disconnecting from a connectable network. WLAN_NOTIFICATION_ACM_DISCONNECTED = $00000015; //The wireless service has disconnected from a connectable network. WLAN_NOTIFICATION_ACM_ADHOC_NETWORK_STATE_CHANGE = $00000016; //A state change has occurred for an adhoc network.
第二个示例回调更详细:
procedure OnWlanNotify(data : PWLanNotificationData; context : PVOID); stdcall; begin case data^.NotificationCode of WLAN_NOTIFICATION_ACM_AUTOCONF_ENABLED : TForm1(context^).Memo1.Lines.Add('Autoconfiguration is enabled.'); WLAN_NOTIFICATION_ACM_AUTOCONF_DISABLED : TForm1(context^).Memo1.Lines.Add('Autoconfiguration is disabled.'); WLAN_NOTIFICATION_ACM_BACKGROUND_SCAN_ENABLED : TForm1(context^).Memo1.Lines.Add('Background scans are enabled.'); WLAN_NOTIFICATION_ACM_BACKGROUND_SCAN_DISABLED : TForm1(context^).Memo1.Lines.Add('Background scans are disabled.'); WLAN_NOTIFICATION_ACM_BSS_TYPE_CHANGE : TForm1(context^).Memo1.Lines.Add('The BSS type for an interface has changed.'); WLAN_NOTIFICATION_ACM_POWER_SETTING_CHANGE : TForm1(context^).Memo1.Lines.Add('The power setting for an interface has changed.'); WLAN_NOTIFICATION_ACM_SCAN_COMPLETE : TForm1(context^).Memo1.Lines.Add('A scan for networks has completed.'); WLAN_NOTIFICATION_ACM_SCAN_FAIL : TForm1(context^).Memo1.Lines.Add('A scan for connectable networks Failed.'); WLAN_NOTIFICATION_ACM_CONNECTION_START : TForm1(context^).Memo1.Lines.Add('A connection has started to a network in range.'); WLAN_NOTIFICATION_ACM_CONNECTION_COMPLETE : TForm1(context^).Memo1.Lines.Add('A connection has completed.'); WLAN_NOTIFICATION_ACM_CONNECTION_ATTEMPT_FAIL : TForm1(context^).Memo1.Lines.Add('A connection attempt has Failed.'); WLAN_NOTIFICATION_ACM_FILTER_LIST_CHANGE : TForm1(context^).Memo1.Lines.Add('A change in the filter list has occurred,either through group policy or a call to the WlanSetFilterList function.'); WLAN_NOTIFICATION_ACM_INTERFACE_ARRIVAL : TForm1(context^).Memo1.Lines.Add('A wireless LAN interface is been added to or enabled on the local computer.'); WLAN_NOTIFICATION_ACM_INTERFACE_REMOVAL : TForm1(context^).Memo1.Lines.Add('A wireless LAN interface has been removed or disabled on the local computer.'); WLAN_NOTIFICATION_ACM_PROFILE_CHANGE : TForm1(context^).Memo1.Lines.Add('A change in a profile or the profile list has occurred,either through group policy or by calls to Native Wifi functions.'); WLAN_NOTIFICATION_ACM_PROFILE_NAME_CHANGE : TForm1(context^).Memo1.Lines.Add('A profile name has changed,either through group policy or by calls to Native Wifi functions.'); WLAN_NOTIFICATION_ACM_PROFILES_EXHAUSTED : TForm1(context^).Memo1.Lines.Add('All profiles were exhausted in an attempt to autoconnect.'); WLAN_NOTIFICATION_ACM_NETWORK_NOT_AVAILABLE : TForm1(context^).Memo1.Lines.Add('The wireless service cannot find any connectable network after a scan.'); WLAN_NOTIFICATION_ACM_NETWORK_AVAILABLE : TForm1(context^).Memo1.Lines.Add('The wireless service found a connectable network after a scan,and there is no compatible auto-connect profile that the wireless service can use to connect.'); WLAN_NOTIFICATION_ACM_DISCONNECTING : TForm1(context^).Memo1.Lines.Add('The wireless service is disconnecting from a connectable network.'); WLAN_NOTIFICATION_ACM_DISCONNECTED : TForm1(context^).Memo1.Lines.Add('The wireless service has disconnected from a connectable network.'); WLAN_NOTIFICATION_ACM_ADHOC_NETWORK_STATE_CHANGE : TForm1(context^).Memo1.Lines.Add('A state change has occurred for an adhoc network.'); end; end;
在上面的示例中,在用户上下文参数中传递了指向Form1的指针.这将在回调中传回,允许您从方法中访问该数据.
if WlanRegisterNotification(FHandle,@Form1,// Pass in form pointer nil,prevSource) <> ERROR_SUCCESS then begin // handle error end;