Python Wi-Fi API не работает при запуске в качестве службы Windows - PullRequest
0 голосов
/ 01 октября 2019

Я написал код Python, который отключается и подключается к точке доступа, и она работает нормально. Я попытался превратить его в службу Windows, но интерфейс API не работает. Я не уверен, почему.

Вот мой сценарий

desired_ssid = 'SSID HERE'
desired_key = 'XXXXXXX'

def ConnectionStatus(number):
    if number == 0:
        return 'DISCONNECTED'
    elif number == 1:
        return 'SCANNING'
    elif number == 2:
        return 'INACTIVE'
    elif number == 3:
        return 'CONNECTING'
    elif number == 4:
        return 'CONNECTED'

class AppServerSvc(win32serviceutil.ServiceFramework):
    _svc_name_ = "WifiMonitor"
    _svc_display_name_ = "Wifi Monitor"
    _svc_description_ = "This service monitors the wifi interface for a working network connection, restarting it if need be"

    def __init__(self, args):
        win32serviceutil.ServiceFramework.__init__(self, args)
        self.hWaitStop = win32event.CreateEvent(None, 0, 0, None)

    def SvcStop(self):
        self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
        win32event.SetEvent(self.hWaitStop)

    def SvcDoRun(self):
        self.ReportServiceStatus(win32service.SERVICE_RUNNING)
        servicemanager.LogMsg(
           servicemanager.EVENTLOG_INFORMATION_TYPE,
           servicemanager.PYS_SERVICE_STARTED,
           (self._svc_name_, ""),
        )
        try:
            self.Main()
        except Exception as e:
            servicemanager.LogErrorMsg("Error: " + str(e))

    def Main(self):
        rc = None
        wifi = pywifi.PyWiFi()
        ifaces = wifi.interfaces()
        #Print all the interfaces
        servicemanager.LogInfoMsg("\n".join([i.name() for i in ifaces]))
        iface = ifaces[0]


        while rc != win32event.WAIT_OBJECT_0:
            attempts = 0
            while not self.ConnectedToInternet() and attempts < 4:
                self.ToggleWifi(iface)
                attempts = attempts + 1
            #Wait thirty seconds before checking again
            rc = win32event.WaitForSingleObject(self.hWaitStop, 30000)

    def ToggleWifi(self, iface):
        try:
            servicemanager.LogInfoMsg(f"{ConnectionStatus(iface.status())}")
            iface.disconnect()
            time.sleep(2)
            iface.scan()
            #According to api have to wait a bit before calling scan_results()
            time.sleep(8)
            selected_profile = None
            scan_results = iface.scan_results()
            servicemanager.LogInfoMsg("\n".join([prof.ssid for prof in scan_results]))
            #loop through scan results to find desired AP
            for prof in scan_results:
                if prof.ssid == desired_ssid:
                    selected_profile = prof
                    selected_profile.key = desired_key
                    break
            #connect works when debugging script but doesn't seem to do anything when run as service
            iface.connect(selected_profile)
            time.sleep(2)
            servicemanager.LogInfoMsg(f"{ConnectionStatus(iface.status())}")
        except Exception as e:
            servicemanager.LogErrorMsg("Error: " + str(e))

    def ConnectedToInternet(self, url="http://www.google.com/", timeout=5):
        try:
            _ = requests.head(url, timeout=timeout)
            return True
        except requests.ConnectionError:
            pass
        return False

if __name__ == "__main__":
    if len(sys.argv) == 1:
        servicemanager.Initialize()
        servicemanager.PrepareToHostSingle(AppServerSvc)
        servicemanager.StartServiceCtrlDispatcher()
    else:
        win32serviceutil.HandleCommandLine(AppServerSvc)

Я вижу, что при запуске в качестве службы все интерфейсы регистрируются в средстве просмотра событий, а также всеточки доступа. Так что сервис не работает вообще. Он просто не подключается к точке доступа, когда я вызываю connect ().

Это как-то связано с различиями в разрешениях при запуске его как службы по сравнению с сценарием? (Я превращаю скрипт в исполняемый файл, используя pyinstaller).

Windows 10, x64

РЕДАКТИРОВАТЬ:

Я использую эту библиотеку для Wi-Fi API https://github.com/awkman/pywifi

...