0

I want to break PumpWaitingMessages for every one hour and check for any unread mails and I tried with following code.

However, if I increase time.time()-starttime>10 then my outlook is hanging and not able to progress, Sometimes I am even able to get following error:

This is related to How to continuously monitor a new mail in outlook and unread mails of a specific folder in python

 pTraceback (most recent call last):
 File "final.py", line 94, in <module>
 outlook_open=processExists('OUTLOOK.EXE')
 File "final.py", line 68, in processExists
 print('process "%s" is running!' % processname)
 IOError: [Errno 0] Error

Please check the code and help me to resolve this.

 import win32com.client
 import ctypes # for the VM_QUIT to stop PumpMessage()
 import pythoncom
 import re
 import time
 import os
 import subprocess
 import pyodbc

 class Handler_Class(object):

    def __init__(self):
      # First action to do when using the class in the DispatchWithEvents     
      outlook=self.Application.GetNamespace("MAPI")
      inbox=outlook.Folders['mymail@gmail.com'].Folders['Inbox']
      messages = inbox.Items
      print "checking Unread mails"
      # Check for unread emails when starting the event   
      for message in messages:
         if message.UnRead:
           print message.Subject.encode("utf-8") # Or whatever code you wish to execute.
           message.UnRead=False

    def OnQuit(self):
       # To stop PumpMessages() when Outlook Quit
       # Note: Not sure it works when disconnecting!!
       print "Inside handler onQuit"
       ctypes.windll.user32.PostQuitMessage(0)

    def OnNewMailEx(self, receivedItemsIDs):
      # RecrivedItemIDs is a collection of mail IDs separated by a ",".
      # You know, sometimes more than 1 mail is received at the same moment.
      for ID in receivedItemsIDs.split(","):
          mail = self.Session.GetItemFromID(ID)
          subject = mail.Subject
          print subject.encode("utf-8")
          mail.UnRead=False
          try: 
            command = re.search(r"%(.*?)%", subject).group(1)
            print command # Or whatever code you wish to execute.
          except:
            pass

 # Function to check if outlook is open
 def processExists(processname):
   tlcall = 'TASKLIST', '/V', '/FI', 'imagename eq %s' % processname
   # shell=True hides the shell window, stdout to PIPE enables
   # communicate() to get the tasklist command result
   tlproc = subprocess.Popen(tlcall, shell=True, stdout=subprocess.PIPE)
   # trimming it to the actual lines with information
   tlout = tlproc.communicate()[0].strip().split('\r\n')
   # if TASKLIST returns single line without processname: it's not running
   if len(tlout) > 1 and processname in tlout[-1]:
      if "Not Responding" in tlout[2]:
         print('process "%s" is not responding' % processname)
         os.system("taskkill /f /im  outlook.exe")
         return False
      print('process "%s" is running!' % processname)
      return True
   else:
      print('process "%s" is NOT running!' % processname)
      return False

# Loop 
while True:
  try:
     outlook_open = processExists('OUTLOOK.EXE') 
  except: 
     outlook_open = False
  #If outlook opened then it will start the DispatchWithEvents
  if outlook_open == True:
     outlook = win32com.client.DispatchWithEvents("Outlook.Application", Handler_Class)
     while True:
         starttime=time.time()
         while (int(time.time()-starttime)<10):
             pythoncom.PumpWaitingMessages()    
         ctypes.windll.user32.PostQuitMessage(0)     
         outlook_open=processExists('OUTLOOK.EXE')
         if outlook_open == False:
             break
         #Handler_Class.__init__(outlook)
         # To not check all the time (should increase 10 depending on your needs)
  if outlook_open == False:
     print "outlook not opened"
     os.startfile("outlook")
  time.sleep(10)
Ishara Madhawa
  • 3,549
  • 5
  • 24
  • 42
sireesha
  • 135
  • 1
  • 2
  • 11
  • Your question is not clear to me, first if you do `time.time()-starttime>10` it's normal that outlook is hanging as you don't go in this `while` loop and then your code performed `outlook_open=processExists('OUTLOOK.EXE')` all the time. In your code it's `int(time.time()-starttime)<10` and it works fine, you just have to do `int(time.time()-starttime)<3600` to check for an hour – Ben.T Apr 18 '18 at 13:18
  • your question about break `PumpWaitingMessages`, you mean that you don't exist the loop `while (int(time.time()-starttime)<10)` if you quit yourself Outlook? – Ben.T Apr 18 '18 at 13:21
  • when i keep `int(time.time()-starttime)<3600` my outlook and code both are hanging after some time and get an error "IOError: [Errno 0] Error" when i press enter – sireesha Apr 19 '18 at 05:51
  • I am able to exit the loop .. my question is Let say i am monitor outlook for new mails using `PumpWaitingMessages` .. after one hour i want to check for any unread mails and then process it. Once done it should check again for new mails using `PumpWaitingMessages` ... this process should go on in a loop ... – sireesha Apr 19 '18 at 05:58
  • this part where `#Handler_Class.__init__(outlook) ` in my code ... need to be replace with some logic so that it calls `_init_ ` to check again for unread mails – sireesha Apr 19 '18 at 06:01

1 Answers1

0

So to check your unread email at the place of #Handler_Class.__init__(outlook) just do:

win32com.client.DispatchWithEvents("Outlook.Application", Handler_Class)

(no need of assignment really). But I don't see the point in your code because the rest of the time you are monitoring for incoming email with pythoncom.PumpWaitingMessages() and can do the same thing.

For your problem with outlook is hanging, not sure what is the problem, I try to run it myself few hours and it works. Maybe to reduce some CPU use (this might be your problem depending on your computer), you can try to add a time.sleep() in your loop while such as:

while (int(time.time()-starttime)<100):
    pythoncom.PumpWaitingMessages()
    time.sleep(0.1)

And while I'm answering, I don't think that both ctypes.windll.user32.PostQuitMessage(0) you have in your code are necessary anymore with pythoncom.PumpWaitingMessages(), they were used to stop pythoncom.PumpMessages(). I had no difference in behavior with or without.

Let me know

Ben.T
  • 29,160
  • 6
  • 32
  • 54