Importing WMI in a child Thread throws an error

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • kyosohma@gmail.com

    Importing WMI in a child Thread throws an error

    Hi,

    I am trying to create a post logon script which does various tasks,
    like setup a printer based on location. While most of it works very
    fast, I have a second Python script that I run that scans the PC using
    WMI (among other things) and writes the following to a database: Name,
    Username, Machine, IP, Login Date,CPU,Memory .

    The problem I have is that since I import WMI, it takes a long time
    and we have users complaining about it. So I stuck the import
    statement into a separate thread and set it to a daemon so it could do
    its thing in the background and the rest of the script would finish
    and exit.

    Unfortunately, I get the following error when I do this:

    Exception in thread Thread-1:
    Traceback (most recent call last):
    File "C:\Python24\li b\threading.py" , line 444, in __bootstrap
    self.run()
    File "C:\Python24\li b\threading.py" , line 424, in run
    self.__target(* self.__args, **self.__kwargs )
    File "//serverName/Scripts/PostLogon_MT.py ", line 35, in InvThread
    import db_inventory
    File "\\serverName\P ythonPackages\U tilities\db_inv entory.py", line
    3, in ?
    import wmi
    File "C:\Python24\li b\site-packages\wmi.py ", line 204, in ?
    obj = GetObject ("winmgmts:" )
    File "C:\Python24\li b\site-packages\win32c om\client\__ini t__.py",
    line 73, in GetObject
    return Moniker(Pathnam e, clsctx)
    File "C:\Python24\li b\site-packages\win32c om\client\__ini t__.py",
    line 88, in Moniker
    moniker, i, bindCtx = pythoncom.MkPar seDisplayName(P athname)
    com_error: (-2147221020, 'Invalid syntax', None, None)

    If I import the module without using threading, it works fine, but
    takes forever. Even after it threw that error above, the process
    didn't stop and I had to kill it with a control+C.

    I am using Windows XP with Python 2.4. Thanks for any help you can
    give.

    Mike

  • Tim Golden

    #2
    Re: Importing WMI in a child Thread throws an error

    kyosohma@gmail. com wrote:
    The problem I have is that since I import WMI, it takes a long time
    and we have users complaining about it. So I stuck the import
    statement into a separate thread and set it to a daemon so it could do
    its thing in the background and the rest of the script would finish
    and exit.
    Two things:

    1) If you run WMI in a thread, you'll need to call
    pythoncom.CoIni tialize first:

    <code>
    import pythoncom
    import wmi

    pythoncom.CoIni tialize ()
    c = wmi.WMI ()
    #
    # do things
    #
    pythoncom.CoUni nitialize ()
    </code>

    2) If you need a bit of speed running WMI, see the post
    I sent a few days ago to someone else:



    TJG

    Comment

    • kyosohma@gmail.com

      #3
      Re: Importing WMI in a child Thread throws an error

      On Feb 27, 3:32 pm, Tim Golden <m...@timgolden .me.ukwrote:
      kyoso...@gmail. com wrote:
      The problem I have is that since I import WMI, it takes a long time
      and we have users complaining about it. So I stuck the import
      statement into a separate thread and set it to a daemon so it could do
      its thing in the background and the rest of the script would finish
      and exit.
      >
      Two things:
      >
      1) If you run WMI in a thread, you'll need to call
      pythoncom.CoIni tialize first:
      >
      <code>
      import pythoncom
      import wmi
      >
      pythoncom.CoIni tialize ()
      c = wmi.WMI ()
      #
      # do things
      #
      pythoncom.CoUni nitialize ()
      </code>
      >
      2) If you need a bit of speed running WMI, see the post
      I sent a few days ago to someone else:
      >

      >
      TJG
      Thanks! This works for my problem. It appears to cut the real time
      required for my script to run by 30-50%. I tried to figure out how to
      apply your answer to the other fellow, but I am actually querying WMI
      for the amount of RAM and the CPU type and I just don't see how to use
      your example in these cases. I am new to the WMI paradigm.

      Thanks again,

      Mike

      Comment

      • Tim Golden

        #4
        Re: Importing WMI in a child Thread throws an error

        kyosohma@gmail. com wrote:
        On Feb 27, 3:32 pm, Tim Golden <m...@timgolden .me.ukwrote:
        >kyoso...@gmail .com wrote:
        >>The problem I have is that since I import WMI, it takes a long time
        >>and we have users complaining about it. So I stuck the import
        >>statement into a separate thread and set it to a daemon so it could do
        >>its thing in the background and the rest of the script would finish
        >>and exit.
        >Two things:
        >>
        >1) If you run WMI in a thread, you'll need to call
        >pythoncom.CoIn itialize first:
        >>
        ><code>
        >import pythoncom
        >import wmi
        >>
        >pythoncom.CoIn itialize ()
        >c = wmi.WMI ()
        >#
        ># do things
        >#
        >pythoncom.CoUn initialize ()
        ></code>
        >>
        >2) If you need a bit of speed running WMI, see the post
        >I sent a few days ago to someone else:
        >>
        >http://mail.python.org/pipermail/pyt...ry/005550.html
        >>
        >TJG
        >
        Thanks! This works for my problem. It appears to cut the real time
        required for my script to run by 30-50%. I tried to figure out how to
        apply your answer to the other fellow, but I am actually querying WMI
        for the amount of RAM and the CPU type and I just don't see how to use
        your example in these cases. I am new to the WMI paradigm.
        If you want to post some specific code examples, I'm
        happy to talk you through possible optimisations.

        TJG

        Comment

        • kyosohma@gmail.com

          #5
          Re: Importing WMI in a child Thread throws an error

          On Feb 28, 3:08 pm, Tim Golden <m...@timgolden .me.ukwrote:
          kyoso...@gmail. com wrote:
          On Feb 27, 3:32 pm, Tim Golden <m...@timgolden .me.ukwrote:
          kyoso...@gmail. com wrote:
          >The problem I have is that since I import WMI, it takes a long time
          >and we have users complaining about it. So I stuck the import
          >statement into a separate thread and set it to a daemon so it could do
          >its thing in the background and the rest of the script would finish
          >and exit.
          Two things:
          >
          1) If you run WMI in a thread, you'll need to call
          pythoncom.CoIni tialize first:
          >
          <code>
          import pythoncom
          import wmi
          >
          pythoncom.CoIni tialize ()
          c = wmi.WMI ()
          #
          # do things
          #
          pythoncom.CoUni nitialize ()
          </code>
          >
          2) If you need a bit of speed running WMI, see the post
          I sent a few days ago to someone else:
          >>
          TJG
          >
          Thanks! This works for my problem. It appears to cut the real time
          required for my script to run by 30-50%. I tried to figure out how to
          apply your answer to the other fellow, but I am actually querying WMI
          for the amount of RAM and the CPU type and I just don't see how to use
          your example in these cases. I am new to the WMI paradigm.
          >
          If you want to post some specific code examples, I'm
          happy to talk you through possible optimisations.
          >
          TJG
          Sorry I didn't reply right away. Here's the straight WMI code I'm
          using:

          c = wmi.WMI()
          for i in c.Win32_Compute rSystem():
          mem = int(i.TotalPhys icalMemory)
          compname = i.Name
          for i in c.Win32_Process or ():
          cputype = i.Name

          This code was wrapped in your CoInitialize com objects.

          Let me know if you need more code.

          Mike

          Comment

          • Tim Golden

            #6
            Re: Importing WMI in a child Thread throws an error

            >If you want to post some specific code examples, I'm
            >happy to talk you through possible optimisations.
            >>
            >TJG
            >
            Sorry I didn't reply right away. Here's the straight WMI code I'm
            using:
            >
            c = wmi.WMI()
            for i in c.Win32_Compute rSystem():
            mem = int(i.TotalPhys icalMemory)
            compname = i.Name
            for i in c.Win32_Process or ():
            cputype = i.Name
            Well, don't know how much gain you'll get, but yo
            could try the following quickies:

            <code>
            import wmi
            c = wmi.WMI (find_classes=F alse)

            for i in c.Win32_Compute rSystem (
            ['TotalPhysicalM emory', 'Name']
            ):
            mem = int (i.TotalPhysica lMemory)
            compnam = i.Name

            for i in c.Win32_Process or (['Name']):
            cputype = i.Name

            </code>

            If you were going to repeat these often (say, in
            a loop, which doesn't seem likely given you
            examples) you might gain a few nanosecs by
            pulling the attribute lookup outside the loop:

            <code>
            import wmi
            c = wmi.WMI (find_classes=F alse)

            ComputerSystem = c.Win32_Compute rSystem
            Processor = c.Win32_Process or

            while True:
            for computer_system in ComputerSystem (...): ...
            for processor in Processor (...): ...

            </code>

            But, as everyone else on this list will tell you,
            there's no point in optimising unless you know you
            need to to, and unless you know where :-) That's
            what modules like timeit profiler are for.

            TJG

            Comment

            Working...