├── .gitignore ├── MANIFEST ├── docs ├── _build │ ├── .buildinfo │ ├── .doctrees │ │ ├── changes.doctree │ │ ├── contents.doctree │ │ ├── cookbook.doctree │ │ ├── environment.pickle │ │ ├── index.doctree │ │ ├── tutorial.doctree │ │ └── wmi.doctree │ ├── _sources │ │ ├── changes.txt │ │ ├── contents.txt │ │ ├── cookbook.txt │ │ ├── index.txt │ │ ├── tutorial.txt │ │ └── wmi.txt │ ├── _static │ │ ├── ajax-loader.gif │ │ ├── basic.css │ │ ├── comment-bright.png │ │ ├── comment-close.png │ │ ├── comment.png │ │ ├── contents.png │ │ ├── doctools.js │ │ ├── down-pressed.png │ │ ├── down.png │ │ ├── file.png │ │ ├── jquery.js │ │ ├── minus.png │ │ ├── navigation.png │ │ ├── plus.png │ │ ├── pygments.css │ │ ├── searchtools.js │ │ ├── sphinxdoc.css │ │ ├── underscore.js │ │ ├── up-pressed.png │ │ ├── up.png │ │ ├── websupport.js │ │ └── wmi.css │ ├── changes.html │ ├── contents.html │ ├── cookbook.html │ ├── genindex.html │ ├── index.html │ ├── objects.inv │ ├── py-modindex.html │ ├── search.html │ ├── searchindex.js │ ├── tutorial.html │ └── wmi.html ├── build.cmd ├── changes.rst ├── conf.py ├── contents.rst ├── cookbook.rst ├── index.rst ├── rebuild.cmd ├── themes │ └── wmi │ │ ├── static │ │ └── wmi.css │ │ └── theme.conf ├── tutorial.rst └── wmi.rst ├── readme.rst ├── release.cmd ├── setup.py ├── todo.txt ├── tox.ini ├── wmi.py ├── wmitest.cmd ├── wmitest.master.ini ├── wmitest.py └── wmiweb.py /.gitignore: -------------------------------------------------------------------------------- 1 | /wmi/trunk/*.pyc 2 | /wmi/trunk/__pycache__ 3 | /*.pyc 4 | /__pycache__ 5 | /.venv 6 | /build 7 | /dist 8 | /WMI.egg-info 9 | /.tox 10 | -------------------------------------------------------------------------------- /MANIFEST: -------------------------------------------------------------------------------- 1 | changelog.txt 2 | README.txt 3 | setup.py 4 | wmi.py 5 | wmitest.py 6 | wmiweb.py 7 | wmitest.cmd 8 | wmitest.master.ini 9 | -------------------------------------------------------------------------------- /docs/_build/.buildinfo: -------------------------------------------------------------------------------- 1 | # Sphinx build info version 1 2 | # This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. 3 | config: e1bba42fc8b271e02ca51edca65c2722 4 | tags: fbb0d17656682115ca4d033fb2f83ba1 5 | -------------------------------------------------------------------------------- /docs/_build/.doctrees/changes.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tjguk/wmi/7069a5f68c3129529082a10933c3c232d202d8fe/docs/_build/.doctrees/changes.doctree -------------------------------------------------------------------------------- /docs/_build/.doctrees/contents.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tjguk/wmi/7069a5f68c3129529082a10933c3c232d202d8fe/docs/_build/.doctrees/contents.doctree -------------------------------------------------------------------------------- /docs/_build/.doctrees/cookbook.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tjguk/wmi/7069a5f68c3129529082a10933c3c232d202d8fe/docs/_build/.doctrees/cookbook.doctree -------------------------------------------------------------------------------- /docs/_build/.doctrees/environment.pickle: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tjguk/wmi/7069a5f68c3129529082a10933c3c232d202d8fe/docs/_build/.doctrees/environment.pickle -------------------------------------------------------------------------------- /docs/_build/.doctrees/index.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tjguk/wmi/7069a5f68c3129529082a10933c3c232d202d8fe/docs/_build/.doctrees/index.doctree -------------------------------------------------------------------------------- /docs/_build/.doctrees/tutorial.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tjguk/wmi/7069a5f68c3129529082a10933c3c232d202d8fe/docs/_build/.doctrees/tutorial.doctree -------------------------------------------------------------------------------- /docs/_build/.doctrees/wmi.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tjguk/wmi/7069a5f68c3129529082a10933c3c232d202d8fe/docs/_build/.doctrees/wmi.doctree -------------------------------------------------------------------------------- /docs/_build/_sources/changes.txt: -------------------------------------------------------------------------------- 1 | .. module:: wmi 2 | 3 | Changes 4 | ======= 5 | 6 | 1.5 7 | --- 8 | 9 | * Drop support for Python 2.4. Supported versions are now: 2.5+ and 3.x 10 | 11 | * PEP8 compliance 12 | 13 | 1.4 14 | --- 15 | 16 | * Ensure moniker is correct when a parameter includes an embedded quote 17 | (Thanks to Wim Hoekman for the bug report) 18 | 19 | * Ensure :func:`from_time` copes with negative timezones 20 | (Thanks to Zlatko Lovevic for the bug report) 21 | 22 | * Pull back all fields for an event where none is specified 23 | (Thanks to Matt Kosek for the bug report and the detective work) 24 | 25 | * WMI now needs Python 2.4+. It wouldn't be impossible to continue to support older 26 | versions but it's increasingly onerous and 2.4 is now 5 years old. 27 | 28 | * Tests - WMI now comes with a unittest-based set of tests which have been run (and passed) 29 | against all versions of Python from 2.4 to 3.2 using pywin32 214. 30 | 31 | * Exception changes - :exc:`x_wmi` and its subclasses now store the underlying COM error as 32 | :attr:`x_wmi.com_error` instead of returning 33 | an equivalent string. This should help code which needs to know the exact error which 34 | occurred and should also make it easier for non-ASCII systems which were experiencing 35 | difficulties when the code attempted to manipulate non-decoded byte strings. 36 | 37 | * Specific trapping of uninitialised threads - like all COM-based code, WMI needs to be initialised if run 38 | inside a thread. If this isn't done, the error message is slightly obscure. The connection maker now 39 | traps this specific case and returns a specific exception: :exc:`x_wmi_uninitialised_thread`. 40 | 41 | * More specific checks for invalid connection combinations - certain combinations of identification 42 | and authentication are invalid when connection. A specific exception is now raised for these: 43 | :exc:`x_wmi_authentication`. 44 | 45 | * `keys` - each :class:`_wmi_object` now has a :attr:`_wmi_object.keys` attribute, inferred from the underlying 46 | WMI class definition, which is the list of attributes which uniquely define an instance of that class. 47 | 48 | * `associated_classes` - each :class:`_wmi_object` has an :attr:`_wmi_object.associated_classes` attribute which is 49 | a dictionary mapping the names of the other WMI classes which can be associated to this one to their 50 | :class:`_wmi_class` objects. This is most immediately of use in the wmiweb browser (qv) but can 51 | be used by client code. 52 | 53 | * By default, the :func:`WMI` connection function -- the one you call most often -- no longer looks to 54 | find the subclasses of a namespace. This makes for much faster startup times: altho' it was 55 | always possible to pass `find_classes=False` this was little known, and you now have to pass 56 | `find_classes=True` to get this functionality, or use the :attr:`_wmi_namespace.classes` attribute which 57 | is now calculated lazily, so things like IPython's attribute lookup still work. 58 | 59 | * wmiweb.py - the installation now ships with a small but functional web-based WMI browser. 60 | It uses only the stdlib WSGI server and makes it easy to explore any of the namespaces 61 | on the local or a remote machine. 62 | 63 | * Removed the rarely-used Win32 autoprefix: previously, if you tried for a class 64 | called `Process`, the module would try it again under `Win32_Process` if it failed 65 | first time round. This has now been removed to avoid the magic and because I certainly 66 | never use it, and I'm not aware of anyone who did. 67 | 68 | * Impersonation & Authentication levels now supported when connecting to a remote 69 | server with specific credentials. Thanks to Matt Mercer for sample code. 70 | 71 | * Documentation is now Sphinx-based. 72 | 73 | * Association classes no longer try to treat all their attributes as WMI classes. 74 | (Thanks to Miroslav Ježek for the bug report) 75 | 76 | * Setting a property's value now works again 77 | (Thanks to John Holcomb for the bug report and the detective work) 78 | 79 | 1.3 80 | --- 81 | 82 | * Support for IPython's getAttribute protocol (patch supplied by Igor Dvorkin) 83 | 84 | * Allow positional parameters for method calls. Previously, parameters had to 85 | be passed by keyword and failure to do so resulted in an obscure error message. 86 | 87 | * Allow extrinsic events to use the same watcher API as intrinsic ones. Under the 88 | covers these behave slightly differently. Intrinsic events now default to modification 89 | rather than creation. 90 | 91 | * Remove the restriction where an instantiated class didn't know its own namespace. 92 | -------------------------------------------------------------------------------- /docs/_build/_sources/contents.txt: -------------------------------------------------------------------------------- 1 | .. _contents: 2 | 3 | Contents 4 | ======== 5 | 6 | .. toctree:: 7 | :maxdepth: 2 8 | 9 | index 10 | tutorial 11 | cookbook 12 | wmi 13 | changes 14 | -------------------------------------------------------------------------------- /docs/_build/_sources/cookbook.txt: -------------------------------------------------------------------------------- 1 | wmi Cookbook 2 | ============ 3 | 4 | Introduction 5 | ------------ 6 | 7 | These examples assume you are using the `WMI module `_ from this site. The 8 | following are examples of useful things that could be done with this module on win32 machines. It hardly scratches 9 | the surface of WMI, but that's probably as well. 10 | 11 | The following examples, except where stated otherwise, all assume that you are connecting to the current machine. 12 | To connect to a remote machine, simply specify the remote machine name in the WMI constructor, and by the wonders 13 | of DCOM, all should be well:: 14 | 15 | import wmi 16 | c = wmi.WMI("some_other_machine") 17 | 18 | .. note:: 19 | The examples are designed to be complete and can be cut-and-pasted straight into a .py file, or 20 | even onto an open Python interpreter window (that's how I test them). Just 21 | select the code, including the final blank line, right-click [Copy], select your Python interpreter window, and 22 | right-click. 23 | 24 | Examples 25 | -------- 26 | 27 | List all running processes 28 | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 29 | 30 | :: 31 | 32 | import wmi 33 | c = wmi.WMI() 34 | 35 | for process in c.Win32_Process(): 36 | print(process.ProcessId, process.Name) 37 | 38 | 39 | List all running notepad processes 40 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 41 | 42 | :: 43 | 44 | import wmi 45 | c = wmi.WMI() 46 | 47 | for process in c.Win32_Process(name="notepad.exe"): 48 | print(process.ProcessId, process.Name) 49 | 50 | 51 | Create and then destroy a new notepad process 52 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 53 | 54 | :: 55 | 56 | import wmi 57 | c = wmi.WMI() 58 | 59 | process_id, return_value = c.Win32_Process.Create(CommandLine="notepad.exe") 60 | for process in c.Win32_Process(ProcessId=process_id): 61 | print(process.ProcessId, process.Name) 62 | 63 | result = process.Terminate() 64 | 65 | 66 | Show the interface for the .Create method of a Win32_Process class 67 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 68 | 69 | The wmi module tries to take the hard work out of WMI methods by querying the method for its in and out parameters, 70 | accepting the in parameters as Python keyword params and returning the output parameters as an tuple return value. 71 | The function which is masquerading as the WMI method has a __doc__ value which shows the input and return values. 72 | 73 | :: 74 | 75 | import wmi 76 | c = wmi.WMI() 77 | 78 | print(c.Win32_Process.Create) 79 | 80 | Show all automatic services which are not running 81 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 82 | 83 | :: 84 | 85 | import wmi 86 | c = wmi.WMI() 87 | 88 | stopped_services = c.Win32_Service(StartMode="Auto", State="Stopped") 89 | if stopped_services: 90 | for s in stopped_services: 91 | print(s.Caption, "service is not running") 92 | else: 93 | print "No auto services stopped" 94 | 95 | Show the percentage free space for each fixed disk 96 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 97 | 98 | :: 99 | 100 | import wmi 101 | c = wmi.WMI() 102 | 103 | for disk in c.Win32_LogicalDisk(DriveType=3): 104 | print(disk.Caption, "%0.2f%% free" % (100.0 * long(disk.FreeSpace) / long(disk.Size))) 105 | 106 | Run notepad, wait until it's closed and then show its text 107 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 108 | 109 | .. note:: 110 | This is an example of running a process and knowing when it's finished, not of manipulating text typed into 111 | Notepad. So I'm simply relying on the fact that I specify what file notepad should open and then examining the 112 | contents of that afterwards. 113 | 114 | This one won't work as shown on a remote machine because, for security reasons, processes started on a remote 115 | machine do not have an interface (ie you can't see them on the desktop). The most likely use for this sort of 116 | technique on a remote server to run a setup.exe and then, say, reboot once it's completed. 117 | 118 | :: 119 | 120 | import wmi 121 | c = wmi.WMI() 122 | 123 | filename = r"c:\temp\temp.txt" 124 | process = c.Win32_Process 125 | process_id, result = process.Create(CommandLine="notepad.exe " + filename) 126 | watcher = c.watch_for( 127 | notification_type="Deletion", 128 | wmi_class="Win32_Process", 129 | delay_secs=1, 130 | ProcessId=process_id 131 | ) 132 | 133 | watcher() 134 | print "This is what you wrote:" 135 | print open(filename).read() 136 | 137 | Watch for new print jobs 138 | ~~~~~~~~~~~~~~~~~~~~~~~~ 139 | 140 | :: 141 | 142 | import wmi 143 | c = wmi.WMI() 144 | 145 | print_job_watcher = c.Win32_PrintJob.watch_for( 146 | notification_type="Creation", 147 | delay_secs=1 148 | ) 149 | 150 | while 1: 151 | pj = print_job_watcher() 152 | print("User %s has submitted %d pages to printer %s" % \ 153 | (pj.Owner, pj.TotalPages, pj.Name)) 154 | 155 | Reboot a remote machine 156 | ~~~~~~~~~~~~~~~~~~~~~~~ 157 | 158 | .. note:: 159 | To do something this drastic to a remote system, the WMI script must take RemoteShutdown privileges, which means 160 | that you must specify them in the connection moniker. The WMI constructor allows you to pass in an exact moniker, 161 | or to specify the parts of it that you need. Use help on wmi.WMI.__init__ to find out more. 162 | 163 | :: 164 | 165 | import wmi 166 | # other_machine = "machine name of your choice" 167 | c = wmi.WMI(computer=other_machine, privileges=["RemoteShutdown"]) 168 | 169 | os = c.Win32_OperatingSystem(Primary=1)[0] 170 | os.Reboot() 171 | 172 | Show the IP and MAC addresses for IP-enabled network interfaces 173 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 174 | 175 | :: 176 | 177 | import wmi 178 | c = wmi.WMI() 179 | 180 | for interface in c.Win32_NetworkAdapterConfiguration(IPEnabled=1): 181 | print(interface.Description, interface.MACAddress) 182 | for ip_address in interface.IPAddress: 183 | print ip_address 184 | print() 185 | 186 | What's running on startup and from where? 187 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 188 | 189 | :: 190 | 191 | import wmi 192 | c = wmi.WMI() 193 | 194 | for s in c.Win32_StartupCommand(): 195 | print("[%s] %s <%s>" % (s.Location, s.Caption, s.Command)) 196 | 197 | Watch for errors in the event log 198 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 199 | 200 | :: 201 | 202 | import wmi 203 | c = wmi.WMI(privileges=["Security"]) 204 | 205 | watcher = c.watch_for( 206 | notification_type="Creation", 207 | wmi_class="Win32_NTLogEvent", 208 | Type="error" 209 | ) 210 | while 1: 211 | error = watcher() 212 | print("Error in %s log: %s" % (error.Logfile, error.Message)) 213 | # send mail to sysadmin etc. 214 | 215 | 216 | List registry keys 217 | ~~~~~~~~~~~~~~~~~~ 218 | 219 | .. note:: This example and the ones below use the convenience function :func:`Registry` 220 | which was added to the wmi package in its early days. It's exactly equivalent to:: 221 | 222 | import wmi 223 | r = wmi.WMI(namespace="DEFAULT").StdRegProv 224 | 225 | :: 226 | 227 | import _winreg 228 | import wmi 229 | 230 | r = wmi.Registry() 231 | result, names = r.EnumKey( 232 | hDefKey=_winreg.HKEY_LOCAL_MACHINE, 233 | sSubKeyName="Software" 234 | ) 235 | for key in names: 236 | print key 237 | 238 | Add a new registry key 239 | ~~~~~~~~~~~~~~~~~~~~~~ 240 | 241 | :: 242 | 243 | import _winreg 244 | import wmi 245 | 246 | r = wmi.Registry() 247 | result, = r.CreateKey( 248 | hDefKey=_winreg.HKEY_LOCAL_MACHINE, 249 | sSubKeyName=r"Software\TJG" 250 | ) 251 | 252 | Add a new registry value 253 | ~~~~~~~~~~~~~~~~~~~~~~~~ 254 | 255 | :: 256 | 257 | import _winreg 258 | import wmi 259 | 260 | r = wmi.Registry() 261 | result, = r.SetStringValue( 262 | hDefKey=_winreg.HKEY_LOCAL_MACHINE, 263 | sSubKeyName=r"Software\TJG", 264 | sValueName="ApplicationName", 265 | sValue="TJG App" 266 | ) 267 | 268 | Create a new IIS site 269 | ~~~~~~~~~~~~~~~~~~~~~ 270 | 271 | :: 272 | 273 | import wmi 274 | c = wmi.WMI(namespace="MicrosoftIISv2") 275 | 276 | # 277 | # Could as well be achieved by doing: 278 | # web_server = c.IISWebService(Name="W3SVC")[0] 279 | # 280 | for web_server in c.IIsWebService(Name="W3SVC"): 281 | break 282 | 283 | binding = c.new("ServerBinding") 284 | binding.IP = "" 285 | binding.Port = "8383" 286 | binding.Hostname = "" 287 | result, = web_server.CreateNewSite( 288 | PathOfRootVirtualDir=r"c:\inetpub\wwwroot", 289 | ServerComment="My Web Site", 290 | ServerBindings= [binding.ole_object] 291 | ) 292 | 293 | Show shared drives 294 | ~~~~~~~~~~~~~~~~~~ 295 | 296 | :: 297 | 298 | import wmi 299 | c = wmi.WMI() 300 | 301 | for share in c.Win32_Share(): 302 | print share.Name, share.Path 303 | 304 | Show print jobs 305 | ~~~~~~~~~~~~~~~ 306 | 307 | :: 308 | 309 | import wmi 310 | c = wmi.WMI() 311 | 312 | for printer in c.Win32_Printer(): 313 | print(printer.Caption) 314 | for job in c.Win32_PrintJob(DriverName=printer.DriverName): 315 | print(" ", job.Document) 316 | print() 317 | 318 | 319 | Show disk partitions 320 | ~~~~~~~~~~~~~~~~~~~~ 321 | 322 | :: 323 | 324 | import wmi 325 | c = wmi.WMI() 326 | 327 | for physical_disk in c.Win32_DiskDrive(): 328 | for partition in physical_disk.associators("Win32_DiskDriveToDiskPartition"): 329 | for logical_disk in partition.associators("Win32_LogicalDiskToPartition"): 330 | print(physical_disk.Caption, partition.Caption, logical_disk.Caption) 331 | 332 | 333 | Install a product 334 | ~~~~~~~~~~~~~~~~~ 335 | 336 | .. note:: 337 | Example is after a post by Roger Upole to the python-win32 mailing list 338 | 339 | :: 340 | 341 | import wmi 342 | c = wmi.WMI() 343 | 344 | c.Win32_Product.Install( 345 | PackageLocation="c:/temp/python-2.4.2.msi", 346 | AllUsers=False 347 | ) 348 | 349 | 350 | Connect to another machine as a named user 351 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 352 | 353 | .. note:: 354 | You cannot connect to your own machine this way, no matter how hard you try to 355 | obfuscate the server name. 356 | 357 | :: 358 | 359 | import wmi 360 | 361 | # 362 | # Using wmi module before 1.0rc3 363 | # 364 | connection = wmi.connect_server( 365 | server="other_machine", 366 | user="tim", 367 | password="secret" 368 | ) 369 | c = wmi.WMI(wmi=connection) 370 | 371 | # 372 | # Using wmi module at least 1.0rc3 373 | # 374 | c = wmi.WMI( 375 | computer="other_machine", 376 | user="tim", 377 | password="secret" 378 | ) 379 | 380 | 381 | Show a method's signature 382 | ~~~~~~~~~~~~~~~~~~~~~~~~~ 383 | 384 | :: 385 | 386 | import wmi 387 | c = wmi.WMI() 388 | for opsys in c.Win32_OperatingSystem(): 389 | break 390 | 391 | print(opsys.Reboot) 392 | print(opsys.Shutdown) 393 | 394 | 395 | Schedule a job 396 | ~~~~~~~~~~~~~~ 397 | 398 | .. note:: 399 | The WMI ScheduledJob class correponds to the AT Windows service (controlled through 400 | the "at" command). As far as I know, it is not related to the Scheduled Tasks mechanism, 401 | controlled by a control panel applet. 402 | 403 | :: 404 | 405 | import os 406 | import wmi 407 | 408 | c = wmi.WMI() 409 | one_minutes_time = datetime.datetime.now() + datetime.timedelta(minutes=1) 410 | job_id, result = c.Win32_ScheduledJob.Create( 411 | Command=r"cmd.exe /c dir /b c:\ > c:\\temp.txt", 412 | StartTime=wmi.from_time(one_minutes_time) 413 | ) 414 | print(job_id) 415 | 416 | for line in os.popen("at"): 417 | print line 418 | 419 | 420 | 421 | Run a process minimised 422 | ~~~~~~~~~~~~~~~~~~~~~~~ 423 | 424 | .. note:: Thanks to Keith Veleba for providing the question and code which prompted this example 425 | 426 | :: 427 | 428 | import wmi 429 | 430 | SW_SHOWMINIMIZED = 1 431 | 432 | c = wmi.WMI() 433 | startup = c.Win32_ProcessStartup.new(ShowWindow=SW_SHOWMINIMIZED) 434 | pid, result = c.Win32_Process.Create( 435 | CommandLine="notepad.exe", 436 | ProcessStartupInformation=startup 437 | ) 438 | print(pid) 439 | 440 | 441 | Find Drive Types 442 | ~~~~~~~~~~~~~~~~ 443 | 444 | :: 445 | 446 | import wmi 447 | 448 | DRIVE_TYPES = { 449 | 0 : "Unknown", 450 | 1 : "No Root Directory", 451 | 2 : "Removable Disk", 452 | 3 : "Local Disk", 453 | 4 : "Network Drive", 454 | 5 : "Compact Disc", 455 | 6 : "RAM Disk" 456 | } 457 | 458 | c = wmi.WMI() 459 | for drive in c.Win32_LogicalDisk(): 460 | print(drive.Caption, DRIVE_TYPES[drive.DriveType]) 461 | 462 | 463 | List Namespaces 464 | ~~~~~~~~~~~~~~~ 465 | 466 | :: 467 | 468 | import wmi 469 | 470 | def enumerate_namespaces(namespace=u"root", level=0): 471 | print level * " ", namespace.split("/")[-1] 472 | c = wmi.WMI(namespace=namespace) 473 | for subnamespace in c.__NAMESPACE(): 474 | enumerate_namespaces(namespace + "/" + subnamespace.Name, level + 1) 475 | 476 | enumerate_namespaces() 477 | 478 | 479 | Use WMI in a thread 480 | ~~~~~~~~~~~~~~~~~~~ 481 | 482 | .. note:: 483 | Note the use of pythoncom.Co(Un)initialize. WMI is a COM-based technology, 484 | so to use it in a thread, you must init the COM threading model. This applies 485 | also if you're running in a service, for example, which is implicitly threaded. 486 | 487 | :: 488 | 489 | import pythoncom 490 | import wmi 491 | import threading 492 | import time 493 | 494 | class Info(threading.Thread): 495 | def __init__(self): 496 | threading.Thread.__init__(self) 497 | def run(self): 498 | print('In Another Thread...') 499 | pythoncom.CoInitialize() 500 | try: 501 | c = wmi.WMI() 502 | for i in range(5): 503 | for process in c.Win32_Process(): 504 | print process.ProcessId, process.Name 505 | time.sleep(2) 506 | finally: 507 | pythoncom.CoUninitialize() 508 | 509 | if __name__ == '__main__': 510 | print('In Main Thread') 511 | c = wmi.WMI() 512 | for process in c.Win32_Process(): 513 | print(process.ProcessId, process.Name) 514 | Info().start() 515 | 516 | 517 | Monitor multiple machines for power events 518 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 519 | 520 | This is a demonstration of extrinsic events, threading and remote monitoring... all in one small package! The idea 521 | is that the power subsystem generates extrinsic events via its WMI provider whenever a machine enters or leaves 522 | suspend mode. Extrinsic events are useful because WMI doesn't have to poll for them so you shouldn't miss any. The 523 | multiple machines was just a practical example of using threads. 524 | 525 | .. note:: Note the use of CoInitialize and CoUninitialize in the thread control code. 526 | Note also the simplified use of :meth:`_wmi_class.watch_for` which will work for 527 | intrinsic and extrinsic events transparently. 528 | 529 | :: 530 | 531 | import pythoncom 532 | import wmi 533 | import threading 534 | import Queue 535 | 536 | class Server(threading.Thread): 537 | 538 | def __init__(self, results, server, user, password): 539 | threading.Thread.__init__(self) 540 | self.results = results 541 | self.server = server 542 | self.user = user 543 | self.password = password 544 | self.setDaemon(True) 545 | 546 | def run(self): 547 | pythoncom.CoInitialize() 548 | try: 549 | # 550 | # If you don't want to use explicit logons, remove 551 | # the user= and password= params here and ensure 552 | # that the user running *this* script has sufficient 553 | # privs on the remote machines. 554 | # 555 | c = wmi.WMI(self.server, user=self.user, password=self.password) 556 | power_watcher = c.Win32_PowerManagementEvent.watch_for() 557 | while True: 558 | self.results.put((self.server, power_watcher())) 559 | finally: 560 | pythoncom.CoUninitialize() 561 | 562 | # 563 | # Obviously, change these to match the machines 564 | # in your network which probably won't be named 565 | # after Harry Potter characters. And which hopefully 566 | # use a less obvious admin password. 567 | # 568 | servers = [ 569 | ("goyle", "administrator", "secret"), 570 | ("malfoy", "administrator", "secret") 571 | ] 572 | if __name__ == '__main__': 573 | power_events = Queue.Queue() 574 | for server, user, password in servers: 575 | print("Watching for", server) 576 | Server(power_events, server, user, password).start() 577 | 578 | while True: 579 | server, power_event = power_events.get() 580 | print(server, "=>", power_event.EventType) 581 | 582 | 583 | Find the current wallpaper 584 | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 585 | 586 | :: 587 | 588 | import wmi 589 | import win32api 590 | import win32con 591 | 592 | c = wmi.WMI() 593 | full_username = win32api.GetUserNameEx(win32con.NameSamCompatible) 594 | for desktop in c.Win32_Desktop(Name=full_username): 595 | print( 596 | desktop.Wallpaper or "[No Wallpaper]", 597 | desktop.WallpaperStretched, desktop.WallpaperTiled 598 | ) 599 | -------------------------------------------------------------------------------- /docs/_build/_sources/index.txt: -------------------------------------------------------------------------------- 1 | .. WinSys documentation master file, created by sphinx-quickstart on Fri Oct 31 15:35:06 2008. 2 | You can adapt this file completely to your liking, but it should at least 3 | contain the root `toctree` directive. 4 | 5 | WMI - Windows Management Instrumentation 6 | ======================================== 7 | 8 | What is it? 9 | ----------- 10 | 11 | Windows Management Instrumentation (WMI) is Microsoft's implementation of 12 | Web-Based Enterprise Management (WBEM), an industry initiative to provide 13 | a Common Information Model (CIM) for pretty much any information about a 14 | computer system. 15 | 16 | The Python WMI module is a lightweight wrapper on top of the pywin32 17 | extensions, and hides some of the messy plumbing needed to get Python to 18 | talk to the WMI API. It's pure Python and has been tested against all 19 | versions of Python from 2.5 to 3.4. It should work with any recent 20 | version of pywin32. 21 | 22 | 23 | Where do I get it? 24 | ------------------ 25 | 26 | * **PyPI**: https://pypi.python.org/pypi/WMI/ 27 | * **Github**: https://github.com/tjguk/wmi 28 | 29 | 30 | How do I install it? 31 | -------------------- 32 | 33 | :: 34 | 35 | pip install wmi 36 | 37 | 38 | How do I use it? 39 | ---------------- 40 | 41 | Have a look at the :doc:`tutorial` or the :doc:`cookbook`. As a quick 42 | taster, try this, to find all Automatic services which are not running 43 | and offer the option to restart each one:: 44 | 45 | import wmi 46 | 47 | c = wmi.WMI() 48 | for s in c.Win32_Service(StartMode="Auto", State="Stopped"): 49 | if raw_input("Restart %s? " % s.Caption).upper() == "Y": 50 | s.StartService() 51 | 52 | What's Changed? 53 | --------------- 54 | 55 | See the :doc:`changes` document 56 | 57 | Copyright & License? 58 | -------------------- 59 | 60 | * Copyright Tim Golden 2003 - 2015 61 | 62 | * Licensed under the (GPL-compatible) MIT License: 63 | http://www.opensource.org/licenses/mit-license.php 64 | 65 | Prerequisites 66 | ------------- 67 | 68 | If you're running a recent Python (2.5+) on a recent Windows (2k, 2k3, 2012, XP, Vista, 7, 8.x) 69 | and you have Mark Hammond's win32 extensions installed, you're probably 70 | up-and-running already. Otherwise... 71 | 72 | 73 | Python 74 | ~~~~~~ 75 | http://www.python.org/ 76 | 77 | pywin32 (was win32all) 78 | ~~~~~~~~~~~~~~~~~~~~~~ 79 | http://sourceforge.net/projects/pywin32/files/ 80 | 81 | Specifically, builds 154/155 fixed a problem which affected the WMI 82 | moniker construction. You can still work without this fix, but some 83 | more complex monikers will fail. (The current build is 219 so you're 84 | probably ok unless you have some very stringent backwards-compatible 85 | requirement). 86 | 87 | makepy 88 | ~~~~~~ 89 | (NB my own experience over several systems is that this 90 | step isn't necessary. However, if you have problems...) 91 | You may have to compile makepy support for some typelibs. The following 92 | are reported to be significant: 93 | 94 | * Microsoft WMI Scripting Library 95 | * WMI ADSI Extension Type Library 96 | * WMICntl Type Library 97 | 98 | If you've not done this before, start the PythonWin environment, select 99 | Tools > Com Makepy utility from the menu, select the library by name, and 100 | click [OK]. 101 | -------------------------------------------------------------------------------- /docs/_build/_sources/wmi.txt: -------------------------------------------------------------------------------- 1 | :mod:`wmi` -- Windows Management Instrumentation 2 | ================================================ 3 | 4 | .. automodule:: wmi 5 | 6 | Exceptions 7 | ---------- 8 | 9 | All COM-related exceptions are wrapped in :exc:`x_wmi` or one of its 10 | subclasses. Therefore you can safely trap :exc:`x_wmi` as a root 11 | exception. 12 | 13 | From v1.4 onwards exceptions now contain the underlying COM error 14 | (if any) as their :attr:`x_wmi.com_error` attribute:: 15 | 16 | import wmi 17 | 18 | try: 19 | c = wmi.WMI ("non-existent-machine") 20 | except wmi.x_wmi, x: # Py3+ except wmi.x_wmi as x: 21 | print "Exception number", x.com_error.hresult 22 | 23 | .. autoexception:: x_wmi 24 | .. autoexception:: x_wmi_invalid_query 25 | .. autoexception:: x_wmi_timed_out 26 | .. autoexception:: x_wmi_no_namespace 27 | .. autoexception:: x_access_denied 28 | .. autoexception:: x_wmi_authentication 29 | .. autoexception:: x_wmi_uninitialised_thread 30 | 31 | Support Classes & Functions 32 | --------------------------- 33 | 34 | These classes and functions are provided internally to the 35 | module to support various operations internally. Certain of 36 | them, in particular :func:`from_time` and :func:`to_time` 37 | could well be used externally. 38 | 39 | .. autoclass:: SelfDeprecatingDict 40 | .. autoclass:: ProvideConstants 41 | .. autofunction:: handle_com_error 42 | .. autofunction:: from_time 43 | .. autofunction:: to_time 44 | .. autofunction:: _set 45 | 46 | Implementation 47 | -------------- 48 | 49 | These functions & classes are part of the underlying implementation and you 50 | are not expected to call upon them explicitly. That said, it can be useful 51 | to know what's used and what you might use to assist in implementing some 52 | functionality not currently exposed. 53 | 54 | .. autoclass:: _wmi_method 55 | :members: 56 | 57 | .. automethod:: __init__ 58 | .. automethod:: __call__ 59 | 60 | .. autoclass:: _wmi_object 61 | :members: 62 | 63 | .. autoclass:: _wmi_class 64 | :members: 65 | 66 | .. autoclass:: _wmi_namespace 67 | :members: 68 | 69 | Main Entry Points 70 | ----------------- 71 | 72 | .. autofunction:: WMI 73 | .. autofunction:: connect_server 74 | .. autofunction:: Registry 75 | -------------------------------------------------------------------------------- /docs/_build/_static/ajax-loader.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tjguk/wmi/7069a5f68c3129529082a10933c3c232d202d8fe/docs/_build/_static/ajax-loader.gif -------------------------------------------------------------------------------- /docs/_build/_static/basic.css: -------------------------------------------------------------------------------- 1 | /* 2 | * basic.css 3 | * ~~~~~~~~~ 4 | * 5 | * Sphinx stylesheet -- basic theme. 6 | * 7 | * :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. 8 | * :license: BSD, see LICENSE for details. 9 | * 10 | */ 11 | 12 | /* -- main layout ----------------------------------------------------------- */ 13 | 14 | div.clearer { 15 | clear: both; 16 | } 17 | 18 | /* -- relbar ---------------------------------------------------------------- */ 19 | 20 | div.related { 21 | width: 100%; 22 | font-size: 90%; 23 | } 24 | 25 | div.related h3 { 26 | display: none; 27 | } 28 | 29 | div.related ul { 30 | margin: 0; 31 | padding: 0 0 0 10px; 32 | list-style: none; 33 | } 34 | 35 | div.related li { 36 | display: inline; 37 | } 38 | 39 | div.related li.right { 40 | float: right; 41 | margin-right: 5px; 42 | } 43 | 44 | /* -- sidebar --------------------------------------------------------------- */ 45 | 46 | div.sphinxsidebarwrapper { 47 | padding: 10px 5px 0 10px; 48 | } 49 | 50 | div.sphinxsidebar { 51 | float: left; 52 | width: 230px; 53 | margin-left: -100%; 54 | font-size: 90%; 55 | } 56 | 57 | div.sphinxsidebar ul { 58 | list-style: none; 59 | } 60 | 61 | div.sphinxsidebar ul ul, 62 | div.sphinxsidebar ul.want-points { 63 | margin-left: 20px; 64 | list-style: square; 65 | } 66 | 67 | div.sphinxsidebar ul ul { 68 | margin-top: 0; 69 | margin-bottom: 0; 70 | } 71 | 72 | div.sphinxsidebar form { 73 | margin-top: 10px; 74 | } 75 | 76 | div.sphinxsidebar input { 77 | border: 1px solid #98dbcc; 78 | font-family: sans-serif; 79 | font-size: 1em; 80 | } 81 | 82 | div.sphinxsidebar #searchbox input[type="text"] { 83 | width: 170px; 84 | } 85 | 86 | div.sphinxsidebar #searchbox input[type="submit"] { 87 | width: 30px; 88 | } 89 | 90 | img { 91 | border: 0; 92 | } 93 | 94 | /* -- search page ----------------------------------------------------------- */ 95 | 96 | ul.search { 97 | margin: 10px 0 0 20px; 98 | padding: 0; 99 | } 100 | 101 | ul.search li { 102 | padding: 5px 0 5px 20px; 103 | background-image: url(file.png); 104 | background-repeat: no-repeat; 105 | background-position: 0 7px; 106 | } 107 | 108 | ul.search li a { 109 | font-weight: bold; 110 | } 111 | 112 | ul.search li div.context { 113 | color: #888; 114 | margin: 2px 0 0 30px; 115 | text-align: left; 116 | } 117 | 118 | ul.keywordmatches li.goodmatch a { 119 | font-weight: bold; 120 | } 121 | 122 | /* -- index page ------------------------------------------------------------ */ 123 | 124 | table.contentstable { 125 | width: 90%; 126 | } 127 | 128 | table.contentstable p.biglink { 129 | line-height: 150%; 130 | } 131 | 132 | a.biglink { 133 | font-size: 1.3em; 134 | } 135 | 136 | span.linkdescr { 137 | font-style: italic; 138 | padding-top: 5px; 139 | font-size: 90%; 140 | } 141 | 142 | /* -- general index --------------------------------------------------------- */ 143 | 144 | table.indextable { 145 | width: 100%; 146 | } 147 | 148 | table.indextable td { 149 | text-align: left; 150 | vertical-align: top; 151 | } 152 | 153 | table.indextable dl, table.indextable dd { 154 | margin-top: 0; 155 | margin-bottom: 0; 156 | } 157 | 158 | table.indextable tr.pcap { 159 | height: 10px; 160 | } 161 | 162 | table.indextable tr.cap { 163 | margin-top: 10px; 164 | background-color: #f2f2f2; 165 | } 166 | 167 | img.toggler { 168 | margin-right: 3px; 169 | margin-top: 3px; 170 | cursor: pointer; 171 | } 172 | 173 | div.modindex-jumpbox { 174 | border-top: 1px solid #ddd; 175 | border-bottom: 1px solid #ddd; 176 | margin: 1em 0 1em 0; 177 | padding: 0.4em; 178 | } 179 | 180 | div.genindex-jumpbox { 181 | border-top: 1px solid #ddd; 182 | border-bottom: 1px solid #ddd; 183 | margin: 1em 0 1em 0; 184 | padding: 0.4em; 185 | } 186 | 187 | /* -- general body styles --------------------------------------------------- */ 188 | 189 | a.headerlink { 190 | visibility: hidden; 191 | } 192 | 193 | h1:hover > a.headerlink, 194 | h2:hover > a.headerlink, 195 | h3:hover > a.headerlink, 196 | h4:hover > a.headerlink, 197 | h5:hover > a.headerlink, 198 | h6:hover > a.headerlink, 199 | dt:hover > a.headerlink { 200 | visibility: visible; 201 | } 202 | 203 | div.body p.caption { 204 | text-align: inherit; 205 | } 206 | 207 | div.body td { 208 | text-align: left; 209 | } 210 | 211 | .field-list ul { 212 | padding-left: 1em; 213 | } 214 | 215 | .first { 216 | margin-top: 0 !important; 217 | } 218 | 219 | p.rubric { 220 | margin-top: 30px; 221 | font-weight: bold; 222 | } 223 | 224 | img.align-left, .figure.align-left, object.align-left { 225 | clear: left; 226 | float: left; 227 | margin-right: 1em; 228 | } 229 | 230 | img.align-right, .figure.align-right, object.align-right { 231 | clear: right; 232 | float: right; 233 | margin-left: 1em; 234 | } 235 | 236 | img.align-center, .figure.align-center, object.align-center { 237 | display: block; 238 | margin-left: auto; 239 | margin-right: auto; 240 | } 241 | 242 | .align-left { 243 | text-align: left; 244 | } 245 | 246 | .align-center { 247 | text-align: center; 248 | } 249 | 250 | .align-right { 251 | text-align: right; 252 | } 253 | 254 | /* -- sidebars -------------------------------------------------------------- */ 255 | 256 | div.sidebar { 257 | margin: 0 0 0.5em 1em; 258 | border: 1px solid #ddb; 259 | padding: 7px 7px 0 7px; 260 | background-color: #ffe; 261 | width: 40%; 262 | float: right; 263 | } 264 | 265 | p.sidebar-title { 266 | font-weight: bold; 267 | } 268 | 269 | /* -- topics ---------------------------------------------------------------- */ 270 | 271 | div.topic { 272 | border: 1px solid #ccc; 273 | padding: 7px 7px 0 7px; 274 | margin: 10px 0 10px 0; 275 | } 276 | 277 | p.topic-title { 278 | font-size: 1.1em; 279 | font-weight: bold; 280 | margin-top: 10px; 281 | } 282 | 283 | /* -- admonitions ----------------------------------------------------------- */ 284 | 285 | div.admonition { 286 | margin-top: 10px; 287 | margin-bottom: 10px; 288 | padding: 7px; 289 | } 290 | 291 | div.admonition dt { 292 | font-weight: bold; 293 | } 294 | 295 | div.admonition dl { 296 | margin-bottom: 0; 297 | } 298 | 299 | p.admonition-title { 300 | margin: 0px 10px 5px 0px; 301 | font-weight: bold; 302 | } 303 | 304 | div.body p.centered { 305 | text-align: center; 306 | margin-top: 25px; 307 | } 308 | 309 | /* -- tables ---------------------------------------------------------------- */ 310 | 311 | table.docutils { 312 | border: 0; 313 | border-collapse: collapse; 314 | } 315 | 316 | table.docutils td, table.docutils th { 317 | padding: 1px 8px 1px 5px; 318 | border-top: 0; 319 | border-left: 0; 320 | border-right: 0; 321 | border-bottom: 1px solid #aaa; 322 | } 323 | 324 | table.field-list td, table.field-list th { 325 | border: 0 !important; 326 | } 327 | 328 | table.footnote td, table.footnote th { 329 | border: 0 !important; 330 | } 331 | 332 | th { 333 | text-align: left; 334 | padding-right: 5px; 335 | } 336 | 337 | table.citation { 338 | border-left: solid 1px gray; 339 | margin-left: 1px; 340 | } 341 | 342 | table.citation td { 343 | border-bottom: none; 344 | } 345 | 346 | /* -- other body styles ----------------------------------------------------- */ 347 | 348 | ol.arabic { 349 | list-style: decimal; 350 | } 351 | 352 | ol.loweralpha { 353 | list-style: lower-alpha; 354 | } 355 | 356 | ol.upperalpha { 357 | list-style: upper-alpha; 358 | } 359 | 360 | ol.lowerroman { 361 | list-style: lower-roman; 362 | } 363 | 364 | ol.upperroman { 365 | list-style: upper-roman; 366 | } 367 | 368 | dl { 369 | margin-bottom: 15px; 370 | } 371 | 372 | dd p { 373 | margin-top: 0px; 374 | } 375 | 376 | dd ul, dd table { 377 | margin-bottom: 10px; 378 | } 379 | 380 | dd { 381 | margin-top: 3px; 382 | margin-bottom: 10px; 383 | margin-left: 30px; 384 | } 385 | 386 | dt:target, .highlighted { 387 | background-color: #fbe54e; 388 | } 389 | 390 | dl.glossary dt { 391 | font-weight: bold; 392 | font-size: 1.1em; 393 | } 394 | 395 | .field-list ul { 396 | margin: 0; 397 | padding-left: 1em; 398 | } 399 | 400 | .field-list p { 401 | margin: 0; 402 | } 403 | 404 | .refcount { 405 | color: #060; 406 | } 407 | 408 | .optional { 409 | font-size: 1.3em; 410 | } 411 | 412 | .versionmodified { 413 | font-style: italic; 414 | } 415 | 416 | .system-message { 417 | background-color: #fda; 418 | padding: 5px; 419 | border: 3px solid red; 420 | } 421 | 422 | .footnote:target { 423 | background-color: #ffa; 424 | } 425 | 426 | .line-block { 427 | display: block; 428 | margin-top: 1em; 429 | margin-bottom: 1em; 430 | } 431 | 432 | .line-block .line-block { 433 | margin-top: 0; 434 | margin-bottom: 0; 435 | margin-left: 1.5em; 436 | } 437 | 438 | .guilabel, .menuselection { 439 | font-family: sans-serif; 440 | } 441 | 442 | .accelerator { 443 | text-decoration: underline; 444 | } 445 | 446 | .classifier { 447 | font-style: oblique; 448 | } 449 | 450 | abbr, acronym { 451 | border-bottom: dotted 1px; 452 | cursor: help; 453 | } 454 | 455 | /* -- code displays --------------------------------------------------------- */ 456 | 457 | pre { 458 | overflow: auto; 459 | overflow-y: hidden; /* fixes display issues on Chrome browsers */ 460 | } 461 | 462 | td.linenos pre { 463 | padding: 5px 0px; 464 | border: 0; 465 | background-color: transparent; 466 | color: #aaa; 467 | } 468 | 469 | table.highlighttable { 470 | margin-left: 0.5em; 471 | } 472 | 473 | table.highlighttable td { 474 | padding: 0 0.5em 0 0.5em; 475 | } 476 | 477 | tt.descname { 478 | background-color: transparent; 479 | font-weight: bold; 480 | font-size: 1.2em; 481 | } 482 | 483 | tt.descclassname { 484 | background-color: transparent; 485 | } 486 | 487 | tt.xref, a tt { 488 | background-color: transparent; 489 | font-weight: bold; 490 | } 491 | 492 | h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt { 493 | background-color: transparent; 494 | } 495 | 496 | .viewcode-link { 497 | float: right; 498 | } 499 | 500 | .viewcode-back { 501 | float: right; 502 | font-family: sans-serif; 503 | } 504 | 505 | div.viewcode-block:target { 506 | margin: -1px -10px; 507 | padding: 0 10px; 508 | } 509 | 510 | /* -- math display ---------------------------------------------------------- */ 511 | 512 | img.math { 513 | vertical-align: middle; 514 | } 515 | 516 | div.body div.math p { 517 | text-align: center; 518 | } 519 | 520 | span.eqno { 521 | float: right; 522 | } 523 | 524 | /* -- printout stylesheet --------------------------------------------------- */ 525 | 526 | @media print { 527 | div.document, 528 | div.documentwrapper, 529 | div.bodywrapper { 530 | margin: 0 !important; 531 | width: 100%; 532 | } 533 | 534 | div.sphinxsidebar, 535 | div.related, 536 | div.footer, 537 | #top-link { 538 | display: none; 539 | } 540 | } -------------------------------------------------------------------------------- /docs/_build/_static/comment-bright.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tjguk/wmi/7069a5f68c3129529082a10933c3c232d202d8fe/docs/_build/_static/comment-bright.png -------------------------------------------------------------------------------- /docs/_build/_static/comment-close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tjguk/wmi/7069a5f68c3129529082a10933c3c232d202d8fe/docs/_build/_static/comment-close.png -------------------------------------------------------------------------------- /docs/_build/_static/comment.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tjguk/wmi/7069a5f68c3129529082a10933c3c232d202d8fe/docs/_build/_static/comment.png -------------------------------------------------------------------------------- /docs/_build/_static/contents.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tjguk/wmi/7069a5f68c3129529082a10933c3c232d202d8fe/docs/_build/_static/contents.png -------------------------------------------------------------------------------- /docs/_build/_static/doctools.js: -------------------------------------------------------------------------------- 1 | /* 2 | * doctools.js 3 | * ~~~~~~~~~~~ 4 | * 5 | * Sphinx JavaScript utilities for all documentation. 6 | * 7 | * :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. 8 | * :license: BSD, see LICENSE for details. 9 | * 10 | */ 11 | 12 | /** 13 | * select a different prefix for underscore 14 | */ 15 | $u = _.noConflict(); 16 | 17 | /** 18 | * make the code below compatible with browsers without 19 | * an installed firebug like debugger 20 | if (!window.console || !console.firebug) { 21 | var names = ["log", "debug", "info", "warn", "error", "assert", "dir", 22 | "dirxml", "group", "groupEnd", "time", "timeEnd", "count", "trace", 23 | "profile", "profileEnd"]; 24 | window.console = {}; 25 | for (var i = 0; i < names.length; ++i) 26 | window.console[names[i]] = function() {}; 27 | } 28 | */ 29 | 30 | /** 31 | * small helper function to urldecode strings 32 | */ 33 | jQuery.urldecode = function(x) { 34 | return decodeURIComponent(x).replace(/\+/g, ' '); 35 | } 36 | 37 | /** 38 | * small helper function to urlencode strings 39 | */ 40 | jQuery.urlencode = encodeURIComponent; 41 | 42 | /** 43 | * This function returns the parsed url parameters of the 44 | * current request. Multiple values per key are supported, 45 | * it will always return arrays of strings for the value parts. 46 | */ 47 | jQuery.getQueryParameters = function(s) { 48 | if (typeof s == 'undefined') 49 | s = document.location.search; 50 | var parts = s.substr(s.indexOf('?') + 1).split('&'); 51 | var result = {}; 52 | for (var i = 0; i < parts.length; i++) { 53 | var tmp = parts[i].split('=', 2); 54 | var key = jQuery.urldecode(tmp[0]); 55 | var value = jQuery.urldecode(tmp[1]); 56 | if (key in result) 57 | result[key].push(value); 58 | else 59 | result[key] = [value]; 60 | } 61 | return result; 62 | }; 63 | 64 | /** 65 | * small function to check if an array contains 66 | * a given item. 67 | */ 68 | jQuery.contains = function(arr, item) { 69 | for (var i = 0; i < arr.length; i++) { 70 | if (arr[i] == item) 71 | return true; 72 | } 73 | return false; 74 | }; 75 | 76 | /** 77 | * highlight a given string on a jquery object by wrapping it in 78 | * span elements with the given class name. 79 | */ 80 | jQuery.fn.highlightText = function(text, className) { 81 | function highlight(node) { 82 | if (node.nodeType == 3) { 83 | var val = node.nodeValue; 84 | var pos = val.toLowerCase().indexOf(text); 85 | if (pos >= 0 && !jQuery(node.parentNode).hasClass(className)) { 86 | var span = document.createElement("span"); 87 | span.className = className; 88 | span.appendChild(document.createTextNode(val.substr(pos, text.length))); 89 | node.parentNode.insertBefore(span, node.parentNode.insertBefore( 90 | document.createTextNode(val.substr(pos + text.length)), 91 | node.nextSibling)); 92 | node.nodeValue = val.substr(0, pos); 93 | } 94 | } 95 | else if (!jQuery(node).is("button, select, textarea")) { 96 | jQuery.each(node.childNodes, function() { 97 | highlight(this); 98 | }); 99 | } 100 | } 101 | return this.each(function() { 102 | highlight(this); 103 | }); 104 | }; 105 | 106 | /** 107 | * Small JavaScript module for the documentation. 108 | */ 109 | var Documentation = { 110 | 111 | init : function() { 112 | this.fixFirefoxAnchorBug(); 113 | this.highlightSearchWords(); 114 | this.initIndexTable(); 115 | }, 116 | 117 | /** 118 | * i18n support 119 | */ 120 | TRANSLATIONS : {}, 121 | PLURAL_EXPR : function(n) { return n == 1 ? 0 : 1; }, 122 | LOCALE : 'unknown', 123 | 124 | // gettext and ngettext don't access this so that the functions 125 | // can safely bound to a different name (_ = Documentation.gettext) 126 | gettext : function(string) { 127 | var translated = Documentation.TRANSLATIONS[string]; 128 | if (typeof translated == 'undefined') 129 | return string; 130 | return (typeof translated == 'string') ? translated : translated[0]; 131 | }, 132 | 133 | ngettext : function(singular, plural, n) { 134 | var translated = Documentation.TRANSLATIONS[singular]; 135 | if (typeof translated == 'undefined') 136 | return (n == 1) ? singular : plural; 137 | return translated[Documentation.PLURALEXPR(n)]; 138 | }, 139 | 140 | addTranslations : function(catalog) { 141 | for (var key in catalog.messages) 142 | this.TRANSLATIONS[key] = catalog.messages[key]; 143 | this.PLURAL_EXPR = new Function('n', 'return +(' + catalog.plural_expr + ')'); 144 | this.LOCALE = catalog.locale; 145 | }, 146 | 147 | /** 148 | * add context elements like header anchor links 149 | */ 150 | addContextElements : function() { 151 | $('div[id] > :header:first').each(function() { 152 | $('\u00B6'). 153 | attr('href', '#' + this.id). 154 | attr('title', _('Permalink to this headline')). 155 | appendTo(this); 156 | }); 157 | $('dt[id]').each(function() { 158 | $('\u00B6'). 159 | attr('href', '#' + this.id). 160 | attr('title', _('Permalink to this definition')). 161 | appendTo(this); 162 | }); 163 | }, 164 | 165 | /** 166 | * workaround a firefox stupidity 167 | */ 168 | fixFirefoxAnchorBug : function() { 169 | if (document.location.hash && $.browser.mozilla) 170 | window.setTimeout(function() { 171 | document.location.href += ''; 172 | }, 10); 173 | }, 174 | 175 | /** 176 | * highlight the search words provided in the url in the text 177 | */ 178 | highlightSearchWords : function() { 179 | var params = $.getQueryParameters(); 180 | var terms = (params.highlight) ? params.highlight[0].split(/\s+/) : []; 181 | if (terms.length) { 182 | var body = $('div.body'); 183 | window.setTimeout(function() { 184 | $.each(terms, function() { 185 | body.highlightText(this.toLowerCase(), 'highlighted'); 186 | }); 187 | }, 10); 188 | $('') 190 | .appendTo($('#searchbox')); 191 | } 192 | }, 193 | 194 | /** 195 | * init the domain index toggle buttons 196 | */ 197 | initIndexTable : function() { 198 | var togglers = $('img.toggler').click(function() { 199 | var src = $(this).attr('src'); 200 | var idnum = $(this).attr('id').substr(7); 201 | $('tr.cg-' + idnum).toggle(); 202 | if (src.substr(-9) == 'minus.png') 203 | $(this).attr('src', src.substr(0, src.length-9) + 'plus.png'); 204 | else 205 | $(this).attr('src', src.substr(0, src.length-8) + 'minus.png'); 206 | }).css('display', ''); 207 | if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) { 208 | togglers.click(); 209 | } 210 | }, 211 | 212 | /** 213 | * helper function to hide the search marks again 214 | */ 215 | hideSearchWords : function() { 216 | $('#searchbox .highlight-link').fadeOut(300); 217 | $('span.highlighted').removeClass('highlighted'); 218 | }, 219 | 220 | /** 221 | * make the url absolute 222 | */ 223 | makeURL : function(relativeURL) { 224 | return DOCUMENTATION_OPTIONS.URL_ROOT + '/' + relativeURL; 225 | }, 226 | 227 | /** 228 | * get the current relative url 229 | */ 230 | getCurrentURL : function() { 231 | var path = document.location.pathname; 232 | var parts = path.split(/\//); 233 | $.each(DOCUMENTATION_OPTIONS.URL_ROOT.split(/\//), function() { 234 | if (this == '..') 235 | parts.pop(); 236 | }); 237 | var url = parts.join('/'); 238 | return path.substring(url.lastIndexOf('/') + 1, path.length - 1); 239 | } 240 | }; 241 | 242 | // quick alias for translations 243 | _ = Documentation.gettext; 244 | 245 | $(document).ready(function() { 246 | Documentation.init(); 247 | }); 248 | -------------------------------------------------------------------------------- /docs/_build/_static/down-pressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tjguk/wmi/7069a5f68c3129529082a10933c3c232d202d8fe/docs/_build/_static/down-pressed.png -------------------------------------------------------------------------------- /docs/_build/_static/down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tjguk/wmi/7069a5f68c3129529082a10933c3c232d202d8fe/docs/_build/_static/down.png -------------------------------------------------------------------------------- /docs/_build/_static/file.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tjguk/wmi/7069a5f68c3129529082a10933c3c232d202d8fe/docs/_build/_static/file.png -------------------------------------------------------------------------------- /docs/_build/_static/minus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tjguk/wmi/7069a5f68c3129529082a10933c3c232d202d8fe/docs/_build/_static/minus.png -------------------------------------------------------------------------------- /docs/_build/_static/navigation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tjguk/wmi/7069a5f68c3129529082a10933c3c232d202d8fe/docs/_build/_static/navigation.png -------------------------------------------------------------------------------- /docs/_build/_static/plus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tjguk/wmi/7069a5f68c3129529082a10933c3c232d202d8fe/docs/_build/_static/plus.png -------------------------------------------------------------------------------- /docs/_build/_static/pygments.css: -------------------------------------------------------------------------------- 1 | .highlight .hll { background-color: #ffffcc } 2 | .highlight { background: #eeffcc; } 3 | .highlight .c { color: #408090; font-style: italic } /* Comment */ 4 | .highlight .err { border: 1px solid #FF0000 } /* Error */ 5 | .highlight .k { color: #007020; font-weight: bold } /* Keyword */ 6 | .highlight .o { color: #666666 } /* Operator */ 7 | .highlight .cm { color: #408090; font-style: italic } /* Comment.Multiline */ 8 | .highlight .cp { color: #007020 } /* Comment.Preproc */ 9 | .highlight .c1 { color: #408090; font-style: italic } /* Comment.Single */ 10 | .highlight .cs { color: #408090; background-color: #fff0f0 } /* Comment.Special */ 11 | .highlight .gd { color: #A00000 } /* Generic.Deleted */ 12 | .highlight .ge { font-style: italic } /* Generic.Emph */ 13 | .highlight .gr { color: #FF0000 } /* Generic.Error */ 14 | .highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */ 15 | .highlight .gi { color: #00A000 } /* Generic.Inserted */ 16 | .highlight .go { color: #333333 } /* Generic.Output */ 17 | .highlight .gp { color: #c65d09; font-weight: bold } /* Generic.Prompt */ 18 | .highlight .gs { font-weight: bold } /* Generic.Strong */ 19 | .highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ 20 | .highlight .gt { color: #0044DD } /* Generic.Traceback */ 21 | .highlight .kc { color: #007020; font-weight: bold } /* Keyword.Constant */ 22 | .highlight .kd { color: #007020; font-weight: bold } /* Keyword.Declaration */ 23 | .highlight .kn { color: #007020; font-weight: bold } /* Keyword.Namespace */ 24 | .highlight .kp { color: #007020 } /* Keyword.Pseudo */ 25 | .highlight .kr { color: #007020; font-weight: bold } /* Keyword.Reserved */ 26 | .highlight .kt { color: #902000 } /* Keyword.Type */ 27 | .highlight .m { color: #208050 } /* Literal.Number */ 28 | .highlight .s { color: #4070a0 } /* Literal.String */ 29 | .highlight .na { color: #4070a0 } /* Name.Attribute */ 30 | .highlight .nb { color: #007020 } /* Name.Builtin */ 31 | .highlight .nc { color: #0e84b5; font-weight: bold } /* Name.Class */ 32 | .highlight .no { color: #60add5 } /* Name.Constant */ 33 | .highlight .nd { color: #555555; font-weight: bold } /* Name.Decorator */ 34 | .highlight .ni { color: #d55537; font-weight: bold } /* Name.Entity */ 35 | .highlight .ne { color: #007020 } /* Name.Exception */ 36 | .highlight .nf { color: #06287e } /* Name.Function */ 37 | .highlight .nl { color: #002070; font-weight: bold } /* Name.Label */ 38 | .highlight .nn { color: #0e84b5; font-weight: bold } /* Name.Namespace */ 39 | .highlight .nt { color: #062873; font-weight: bold } /* Name.Tag */ 40 | .highlight .nv { color: #bb60d5 } /* Name.Variable */ 41 | .highlight .ow { color: #007020; font-weight: bold } /* Operator.Word */ 42 | .highlight .w { color: #bbbbbb } /* Text.Whitespace */ 43 | .highlight .mb { color: #208050 } /* Literal.Number.Bin */ 44 | .highlight .mf { color: #208050 } /* Literal.Number.Float */ 45 | .highlight .mh { color: #208050 } /* Literal.Number.Hex */ 46 | .highlight .mi { color: #208050 } /* Literal.Number.Integer */ 47 | .highlight .mo { color: #208050 } /* Literal.Number.Oct */ 48 | .highlight .sb { color: #4070a0 } /* Literal.String.Backtick */ 49 | .highlight .sc { color: #4070a0 } /* Literal.String.Char */ 50 | .highlight .sd { color: #4070a0; font-style: italic } /* Literal.String.Doc */ 51 | .highlight .s2 { color: #4070a0 } /* Literal.String.Double */ 52 | .highlight .se { color: #4070a0; font-weight: bold } /* Literal.String.Escape */ 53 | .highlight .sh { color: #4070a0 } /* Literal.String.Heredoc */ 54 | .highlight .si { color: #70a0d0; font-style: italic } /* Literal.String.Interpol */ 55 | .highlight .sx { color: #c65d09 } /* Literal.String.Other */ 56 | .highlight .sr { color: #235388 } /* Literal.String.Regex */ 57 | .highlight .s1 { color: #4070a0 } /* Literal.String.Single */ 58 | .highlight .ss { color: #517918 } /* Literal.String.Symbol */ 59 | .highlight .bp { color: #007020 } /* Name.Builtin.Pseudo */ 60 | .highlight .vc { color: #bb60d5 } /* Name.Variable.Class */ 61 | .highlight .vg { color: #bb60d5 } /* Name.Variable.Global */ 62 | .highlight .vi { color: #bb60d5 } /* Name.Variable.Instance */ 63 | .highlight .il { color: #208050 } /* Literal.Number.Integer.Long */ -------------------------------------------------------------------------------- /docs/_build/_static/searchtools.js: -------------------------------------------------------------------------------- 1 | /* 2 | * searchtools.js_t 3 | * ~~~~~~~~~~~~~~~~ 4 | * 5 | * Sphinx JavaScript utilties for the full-text search. 6 | * 7 | * :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. 8 | * :license: BSD, see LICENSE for details. 9 | * 10 | */ 11 | 12 | /** 13 | * helper function to return a node containing the 14 | * search summary for a given text. keywords is a list 15 | * of stemmed words, hlwords is the list of normal, unstemmed 16 | * words. the first one is used to find the occurance, the 17 | * latter for highlighting it. 18 | */ 19 | 20 | jQuery.makeSearchSummary = function(text, keywords, hlwords) { 21 | var textLower = text.toLowerCase(); 22 | var start = 0; 23 | $.each(keywords, function() { 24 | var i = textLower.indexOf(this.toLowerCase()); 25 | if (i > -1) 26 | start = i; 27 | }); 28 | start = Math.max(start - 120, 0); 29 | var excerpt = ((start > 0) ? '...' : '') + 30 | $.trim(text.substr(start, 240)) + 31 | ((start + 240 - text.length) ? '...' : ''); 32 | var rv = $('
').text(excerpt); 33 | $.each(hlwords, function() { 34 | rv = rv.highlightText(this, 'highlighted'); 35 | }); 36 | return rv; 37 | } 38 | 39 | 40 | /** 41 | * Porter Stemmer 42 | */ 43 | var Stemmer = function() { 44 | 45 | var step2list = { 46 | ational: 'ate', 47 | tional: 'tion', 48 | enci: 'ence', 49 | anci: 'ance', 50 | izer: 'ize', 51 | bli: 'ble', 52 | alli: 'al', 53 | entli: 'ent', 54 | eli: 'e', 55 | ousli: 'ous', 56 | ization: 'ize', 57 | ation: 'ate', 58 | ator: 'ate', 59 | alism: 'al', 60 | iveness: 'ive', 61 | fulness: 'ful', 62 | ousness: 'ous', 63 | aliti: 'al', 64 | iviti: 'ive', 65 | biliti: 'ble', 66 | logi: 'log' 67 | }; 68 | 69 | var step3list = { 70 | icate: 'ic', 71 | ative: '', 72 | alize: 'al', 73 | iciti: 'ic', 74 | ical: 'ic', 75 | ful: '', 76 | ness: '' 77 | }; 78 | 79 | var c = "[^aeiou]"; // consonant 80 | var v = "[aeiouy]"; // vowel 81 | var C = c + "[^aeiouy]*"; // consonant sequence 82 | var V = v + "[aeiou]*"; // vowel sequence 83 | 84 | var mgr0 = "^(" + C + ")?" + V + C; // [C]VC... is m>0 85 | var meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$"; // [C]VC[V] is m=1 86 | var mgr1 = "^(" + C + ")?" + V + C + V + C; // [C]VCVC... is m>1 87 | var s_v = "^(" + C + ")?" + v; // vowel in stem 88 | 89 | this.stemWord = function (w) { 90 | var stem; 91 | var suffix; 92 | var firstch; 93 | var origword = w; 94 | 95 | if (w.length < 3) 96 | return w; 97 | 98 | var re; 99 | var re2; 100 | var re3; 101 | var re4; 102 | 103 | firstch = w.substr(0,1); 104 | if (firstch == "y") 105 | w = firstch.toUpperCase() + w.substr(1); 106 | 107 | // Step 1a 108 | re = /^(.+?)(ss|i)es$/; 109 | re2 = /^(.+?)([^s])s$/; 110 | 111 | if (re.test(w)) 112 | w = w.replace(re,"$1$2"); 113 | else if (re2.test(w)) 114 | w = w.replace(re2,"$1$2"); 115 | 116 | // Step 1b 117 | re = /^(.+?)eed$/; 118 | re2 = /^(.+?)(ed|ing)$/; 119 | if (re.test(w)) { 120 | var fp = re.exec(w); 121 | re = new RegExp(mgr0); 122 | if (re.test(fp[1])) { 123 | re = /.$/; 124 | w = w.replace(re,""); 125 | } 126 | } 127 | else if (re2.test(w)) { 128 | var fp = re2.exec(w); 129 | stem = fp[1]; 130 | re2 = new RegExp(s_v); 131 | if (re2.test(stem)) { 132 | w = stem; 133 | re2 = /(at|bl|iz)$/; 134 | re3 = new RegExp("([^aeiouylsz])\\1$"); 135 | re4 = new RegExp("^" + C + v + "[^aeiouwxy]$"); 136 | if (re2.test(w)) 137 | w = w + "e"; 138 | else if (re3.test(w)) { 139 | re = /.$/; 140 | w = w.replace(re,""); 141 | } 142 | else if (re4.test(w)) 143 | w = w + "e"; 144 | } 145 | } 146 | 147 | // Step 1c 148 | re = /^(.+?)y$/; 149 | if (re.test(w)) { 150 | var fp = re.exec(w); 151 | stem = fp[1]; 152 | re = new RegExp(s_v); 153 | if (re.test(stem)) 154 | w = stem + "i"; 155 | } 156 | 157 | // Step 2 158 | re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/; 159 | if (re.test(w)) { 160 | var fp = re.exec(w); 161 | stem = fp[1]; 162 | suffix = fp[2]; 163 | re = new RegExp(mgr0); 164 | if (re.test(stem)) 165 | w = stem + step2list[suffix]; 166 | } 167 | 168 | // Step 3 169 | re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/; 170 | if (re.test(w)) { 171 | var fp = re.exec(w); 172 | stem = fp[1]; 173 | suffix = fp[2]; 174 | re = new RegExp(mgr0); 175 | if (re.test(stem)) 176 | w = stem + step3list[suffix]; 177 | } 178 | 179 | // Step 4 180 | re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/; 181 | re2 = /^(.+?)(s|t)(ion)$/; 182 | if (re.test(w)) { 183 | var fp = re.exec(w); 184 | stem = fp[1]; 185 | re = new RegExp(mgr1); 186 | if (re.test(stem)) 187 | w = stem; 188 | } 189 | else if (re2.test(w)) { 190 | var fp = re2.exec(w); 191 | stem = fp[1] + fp[2]; 192 | re2 = new RegExp(mgr1); 193 | if (re2.test(stem)) 194 | w = stem; 195 | } 196 | 197 | // Step 5 198 | re = /^(.+?)e$/; 199 | if (re.test(w)) { 200 | var fp = re.exec(w); 201 | stem = fp[1]; 202 | re = new RegExp(mgr1); 203 | re2 = new RegExp(meq1); 204 | re3 = new RegExp("^" + C + v + "[^aeiouwxy]$"); 205 | if (re.test(stem) || (re2.test(stem) && !(re3.test(stem)))) 206 | w = stem; 207 | } 208 | re = /ll$/; 209 | re2 = new RegExp(mgr1); 210 | if (re.test(w) && re2.test(w)) { 211 | re = /.$/; 212 | w = w.replace(re,""); 213 | } 214 | 215 | // and turn initial Y back to y 216 | if (firstch == "y") 217 | w = firstch.toLowerCase() + w.substr(1); 218 | return w; 219 | } 220 | } 221 | 222 | 223 | /** 224 | * Search Module 225 | */ 226 | var Search = { 227 | 228 | _index : null, 229 | _queued_query : null, 230 | _pulse_status : -1, 231 | 232 | init : function() { 233 | var params = $.getQueryParameters(); 234 | if (params.q) { 235 | var query = params.q[0]; 236 | $('input[name="q"]')[0].value = query; 237 | this.performSearch(query); 238 | } 239 | }, 240 | 241 | loadIndex : function(url) { 242 | $.ajax({type: "GET", url: url, data: null, success: null, 243 | dataType: "script", cache: true}); 244 | }, 245 | 246 | setIndex : function(index) { 247 | var q; 248 | this._index = index; 249 | if ((q = this._queued_query) !== null) { 250 | this._queued_query = null; 251 | Search.query(q); 252 | } 253 | }, 254 | 255 | hasIndex : function() { 256 | return this._index !== null; 257 | }, 258 | 259 | deferQuery : function(query) { 260 | this._queued_query = query; 261 | }, 262 | 263 | stopPulse : function() { 264 | this._pulse_status = 0; 265 | }, 266 | 267 | startPulse : function() { 268 | if (this._pulse_status >= 0) 269 | return; 270 | function pulse() { 271 | Search._pulse_status = (Search._pulse_status + 1) % 4; 272 | var dotString = ''; 273 | for (var i = 0; i < Search._pulse_status; i++) 274 | dotString += '.'; 275 | Search.dots.text(dotString); 276 | if (Search._pulse_status > -1) 277 | window.setTimeout(pulse, 500); 278 | }; 279 | pulse(); 280 | }, 281 | 282 | /** 283 | * perform a search for something 284 | */ 285 | performSearch : function(query) { 286 | // create the required interface elements 287 | this.out = $('#search-results'); 288 | this.title = $('

' + _('Searching') + '

').appendTo(this.out); 289 | this.dots = $('').appendTo(this.title); 290 | this.status = $('

').appendTo(this.out); 291 | this.output = $('