This is a simple script to ping a vpn connection and reconnect should it
fail
this is nessesary since windows refuses to keep a connection nailed up?
i run pyinstaller this way
pyinstaller -w --noconfirm --hiddenimport=win32timezone --onefile
--console --icon=monitor.ico monitor.py
the code is below
simply put the python script runs fine when running the script directly
but i dont not want to put a full windows python3 environment on every
system.
thus the exe?
if there is a broken/missing file, dll etc etc then how does one debug
for that??
lots of googled explanations however none directly explain how the error
occurs and copying dll's around is all well and nice but again impractal
for each system?
nothing works.
running python 3.8 x32 (for win 7 / Server 2008 compatibility)
once the script is converted to exe is installs ok, but fails to start
returning a code 1053
or
C:\monitor>monitor install
Sending Message : Monitor Control Service Invoked
Event Sent
Installing service VPNConnectionMonitor
Service installed
C:\monitor>monitor start
Sending Message : Monitor Control Service Invoked
Event Sent
Starting service VPNConnectionMonitor
Error starting service: The service did not respond to the start or
control request in a timely fashion.
CODE
________________________________________________________________________
import os, sys, socket, struct, select, time
import logging, logging.handlers
import win32serviceutil
import servicemanager,win32evtlogutil,win32evtlog
import win32event,subprocess
import win32service,win32api,win32timezone
from multiprocessing import Process, freeze_support
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
from email.mime.text import MIMEText
from email.utils import COMMASPACE, formatdate
from email import encoders
#curr_path = os.path.dirname(os.path.abspath(__file__))
#configs_path = os.path.join(curr_path, 'configs', 'app_config.json')
#opc_configs_path = os.path.join(curr_path, 'configs', 'opc.json')
#log_file_path = os.path.join(curr_path, 'logs', 'application.log')
class commands:
def __init__(self,command) :
self.command = command
#print (self.command)
self.output = 'Error'
self.status = '255'
#sample
#rc, gopath = subprocess.getstatusoutput('ls -a')
print ('Running : %s' %command)
#sys.exit()
#a = subprocess.Popen([command],stdout=subprocess.PIPE,
stderr=subprocess.PIPE, shell=True)
a = subprocess.Popen([command],stdout=subprocess.PIPE,
stderr=subprocess.PIPE, shell=True)
stdout,stderr = a.communicate()
#print (stdout,stderr)
self.status, self.output = subprocess.getstatusoutput(self.command)
#print (self.status)
#print (self.output)
try:
self.cr = self.output.split('\n')
except :
self.cr = []
try:
self.count = len(self.cr)
except :
self.count = 0
self.status = int(self.status)
#return count=number of lines, cr = lines split, getoutput =
actual output returned, status = return code
return
#Email with attachment
class sendmail:
def __init__(self, send_from, send_to, send_subject, send_text,
send_files):
#send_from, send_to, send_subject, send_text, send_files):
#print ('lib.py sending email')
assert type(send_to)==list
assert type(send_files)==list
msg = MIMEMultipart()
msg['From'] = send_from
msg['To'] = COMMASPACE.join(send_to)
msg['Date'] = formatdate(localtime=True)
msg['Subject'] = send_subject
msg.attach( MIMEText(send_text) )
for f in send_files:
part = MIMEBase('application', "octet-stream")
part.set_payload( open(f,"rb").read() )
Encoders.encode_base64(part)
part.add_header('Content-Disposition', 'attachment;
filename="%s"' % os.path.basename(f))
msg.attach(part)
try : #Send Local?
print ('Sending Email to : %s' %send_to)
smtp = smtplib.SMTP('mail.scom.ca',587)
smtp.sendmail(send_from, send_to, msg.as_string())
smtp.close()
except :
smtp = smtplib.SMTP('mail.scom.ca',587)
print ('Sending Email to : %s' %send_to)
smtp.sendmail(send_from, send_to, msg.as_string())
smtp.close()
class send_event :
def __init__(self, message = 'Info', level = 'Info' ):
#base_dir = os.path.dirname(sys.argv[0])
#print len(base_dir)
#print base_dir
#dllname = os.path.join(base_dir, "win32service.pyd")
#print dllname
print ('Sending Message : %s' %message)
ntl = logging.handlers.NTEventLogHandler(message,
dllname="win32service.pyd")
logger = logging.getLogger("")
logger.setLevel(logging.DEBUG)
logger.addHandler(ntl)
if level == 'Error' or level == 'error' :
logger.error(message)
if level == 'Warn' or level == 'warn' :
logger.warn(message)
if level == 'Info' or level == 'info' :
logger.info(message)
print ('Event Sent')
class SMWinservice(win32serviceutil.ServiceFramework):
'''Base class to create winservice in Python'''
_svc_name_ = 'VPNConnectionMonitor'
_svc_display_name_ = 'VPN Connection Monitor'
_svc_description_ = 'Monitor and Keep PPTP / L2TP Online'
@classmethod
def parse_command_line(cls):
'''
ClassMethod to parse the command line
'''
#message = 'VPN Monitor Trying to %s ' %cls
#send_event (message, 'Info')
win32serviceutil.HandleCommandLine(cls)
def __init__(self, args):
'''
Constructor of the winservice
'''
win32serviceutil.ServiceFramework.__init__(self, args)
self.hWaitStop = win32event.CreateEvent(None, 0, 0, None)
socket.setdefaulttimeout(60)
def SvcStop(self):
'''
Called when the service is asked to stop
'''
send_event ('Stopping VPN Connection Monitor ', 'Info')
self.stop()
self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
win32event.SetEvent(self.hWaitStop)
send_event ('Stopping VPN Connection Monitor ', 'Info')
def SvcDoRun(self):
'''
Called when the service is asked to start
'''
try :
send_event ('Starting VPN Connection Monitor ', 'Info')
self.start()
servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE,
servicemanager.PYS_SERVICE_STARTED,
(self._svc_name_, ''))
send_event ('Starting VPN Connection Monitor (Main) ', 'Info')
except Exception as e :
exc_type, exc_obj, exc_tb = sys.exc_info()
fname =
os.path.split(exc_tb.tb_frame.f_code.co_filename)[1]
e = str(e) + '\n\n' + str(exc_type) + '\n' + str(fname)
+ '\n' + str(exc_tb.tb_lineno)
send_event (e, 'error')
self.main()
def start(self):
'''
Override to add logic before the start
eg. running condition
'''
pass
def stop(self):
'''
Override to add logic before the stop
eg. invalidating running condition
'''
pass
def main(self):
'''
Main class to be ovverridden to add logic ie actual programming
'''
x = 0
while x==0 :
LOCAL_IP = os.getenv('VPNIP')
RAS_CONNECT = os.getenv('VPN')
RAS_USERNAME = os.getenv('VPNUSER')
RAS_PASSWORD = os.getenv('VPNPASS')
freeze_support()
try :
RAS_TIMEOUT = os.getenv('VPN_TIME_OUT')
except :
pass
if RAS_TIMEOUT == None :
RAS_TIMEOUT = 300
try :
RAS_HEARTBEAT = os.getenv('VPN_HEART_BEAT')
if RAS_TIMEOUT == None :
RAS_HEARTBEAT = 0 #0 = off, 1=event, 2 = event & email
except :
pass
print ('Waiting %s Seconds' %RAS_TIMEOUT)
time.sleep(RAS_TIMEOUT)
print ('Checking : %s (%s) [%s %s]'
%(LOCAL_IP,RAS_CONNECT,RAS_USERNAME,RAS_PASSWORD) )
if RAS_HEARTBEAT == 1 or RAS_HEARTBEAT == 2: #send event
send_event ('Checking VPN Connection Heartbeat', 'Info')
if RAS_HEARTBEAT == 2 : #send email
sendmail ('[email protected]', ['[email protected]'],
'Checking : %s (%s) [%s]' %(LOCAL_IP,RAS_CONNECT,RAS_USERNAME),
'\n\nChecking : %s (%s) [%s]' %(LOCAL_IP,RAS_CONNECT,RAS_USERNAME),[])
a=commands('c:/windows/system32/ping -n 1 %s' %LOCAL_IP)
print ('Ping returned : %s' %a.output)
if 'Packets: Sent = 1, Received = 0, Lost = 1 (100% loss)'
in str(a.output) :
print ('Resetting Connection')
send_event ('Resetting (Stopping) Connection', 'warn')
command = ('C:\\Windows\\SysWOW64\\rasdial %s
/disconnect' %RAS_CONNECT)
a = commands(command)
print ('Reconect Status %s' %a.output )
#Now reset the rasdial service
command = ('c:\\windows\\system32\\sc queryex rasman')
a = commands(command)
print ('Rasdial Service Status %s' %a.output )
#go find the pid line
b = str(a.output) #.replace ('\n','')
#print (b)
b = b.split('\n')
#print (b)
for n in range (0,len(b)) :
d = b[n]
if 'PID' in d:
#print (d)
c = d.split(': ')[1]
#print (c)
break
if c == '0' : #is RAS running ?
print ('Skipping Taskkill on RAS Service - Not
Running ...')
else : # Yes kill it
command = ('c:\\windows\\system32\\taskkill /f /pid
%s' %c)
a = commands(command)
print ('RAS Service Stop Status %s' %a.output )
send_event ('Pausing for Re-Connect ...', 'Info')
time.sleep(5)
send_event ('Re-Connecting ....', 'Info')
command = ('C:\\Windows\\SysWOW64\\rasdial %s %s %s'
%(RAS_CONNECT,RAS_USERNAME,RAS_PASSWORD))
print ('Running : %s' %command)
a = commands(command)
print ('Reconect Status %s' %a.output )
sendmail ('[email protected]', ['[email protected]'],
'Reconect Status %s VPN User : %s' %(a.output,RAS_USERNAME),
'\n\nReconnect from VPN User : %s' %RAS_USERNAME, [])
else :
print ('Connection Up ...')
sendmail ('[email protected]', ['[email protected]'],
'Connection Up : %s (%s) [%s]' %(LOCAL_IP,RAS_CONNECT,RAS_USERNAME),
'\n\nConnection Up from VPN User : %s' %RAS_USERNAME, [])
# entry point of the module: copy and paste into the new module
# ensuring you are calling the "parse_command_line" of the new created class
#THIS IS THE ACTUAL TEST
if __name__ == '__main__':
send_event ('Monitor Control Service Invoked', 'Info')
#sys.exit()
SMWinservice.parse_command_line()
--
Happy Sunday !!!
Thanks - paul
Paul Kudla
004-1009 Byron Street South
Whitby, Ontario - Canada
L1N 4S3
Toronto 416.642.7266
Main 1.866.411.7266
Fax 1.888.892.7266
Email [email protected]
--
You received this message because you are subscribed to the Google Groups
"PyInstaller" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/pyinstaller/8cc8dc86-9072-e0eb-bc84-3256ff862484%40scom.ca.