I am trying to get Network Statistics for my Windows 7 system using PyWin32.
The steps I followed:
1) Run COM MakePy utility and than select network list manager 1.0
type library under type library.
2) Above process generated this python file.
Now the problem I am facing is after the above two steps what should be my next step. I tried a couple of things like:
I copied the CLSID = IID('{DCB00000-570F-4A9B-8D69-199FDBA5723B}') line from the above generated python file and used it like
>>> import win32com
>>> obj = win32com.client.gencache.GetClassForCLSID("{DCB00000-570F-4A9B-8D69-199FDBA5723B}")
>>> obj.GetConnectivity()
Traceback (most recent call last):
File "<interactive input>", line 1, in <module>
TypeError: unbound method GetConnectivity() must be called with INetworkListManager instance as first argument (got nothing instead)
When I do obj.method() it show a list of all available method.
So, now I have no idea what to do or how to proceed and what is the general process of using Type library with pywin32.
The above task is just a part of learning process on how to use PyWin32,COM MakePy utility.
Is this even achievable using pywin32.?
You'll need to use win32com.client.Dispatch to actually create the object.
Also, the class you start with is the CoClass, in this case
class NetworkListManager(CoClassBaseClass): # A CoClass
is the one you want.
win32com.client.Dispatch('{DCB00C01-570F-4A9B-8D69-199FDBA5723B}')
works here.
Many of these Dispatch classes have a human readable dotted name as an alias, although
this particular one doesn't seem to.
Related
I'm writing a simple email filter to work upon Outlook incoming messages on Windows 10, and seek to code it up in Python using the win32com library, under Anaconda. I also seek to avoid using magic numbers for the "Inbox" as I see in other examples, and would rather use constants that should be defined under win32com.client.constants. But I'm running into simple errors that are surprising:
So, I concocted the following simple code, loosely based upon https://stackoverflow.com/a/65800130/257924 :
import sys
import win32com.client
try:
outlookApp = win32com.client.Dispatch("Outlook.Application")
except:
print("ERROR: Unable to load Outlook")
sys.exit(1)
outlook = outlookApp.GetNamespace("MAPI")
ofContacts = outlook.GetDefaultFolder(win32com.client.constants.olFolderContacts)
print("ofContacts", type(ofContacts))
sys.exit(0)
Running that under an Anaconda-based installer (Anaconda3 2022.10 (Python 3.9.13 64-bit)) on Windows 10 errors out with:
(base) c:\Temp>python testing.py
Traceback (most recent call last):
File "c:\Temp\testing.py", line 11, in <module>
ofContacts = outlook.GetDefaultFolder(win32com.client.constants.olFolderContacts)
File "C:\Users\brentg\Anaconda3\lib\site-packages\win32com\client\__init__.py", line 231, in __getattr__
raise AttributeError(a)
AttributeError: olFolderContacts
Further debugging indicates that the __dicts__ property is referenced by the __init__.py in the error message above. See excerpt of that class below. For some reason, that __dicts__ is an empty list:
class Constants:
"""A container for generated COM constants."""
def __init__(self):
self.__dicts__ = [] # A list of dictionaries
def __getattr__(self, a):
for d in self.__dicts__:
if a in d:
return d[a]
raise AttributeError(a)
# And create an instance.
constants = Constants()
What is required to have win32com properly initialize that constants object?
The timestamps on the init.py file show 10/10/2021 in case that is relevant.
The short answer is to change:
outlookApp = win32com.client.Dispatch("Outlook.Application")
to
outlookApp = win32com.client.gencache.EnsureDispatch("Outlook.Application")
The longer answer is that win32com can work with COM interfaces in one of two ways: late- and early-binding.
With late-binding, your code knows nothing about the Dispatch interface ie. doesn't know which methods, properties or constants are available. When you call a method on the Dispatch interface, win32com doesn't know if that method exists or any parameters: it just sends what it is given and hopes for the best!
With early-binding, your code relies on previously-captured information about the Dispatch interface, taken from its Type Library. This information is used to create local Python wrappers for the interface which know all the methods and their parameters. At the same time it populates the Constants dictionary with any constants/enums contained in the Type Library.
win32com has a catch-all win32com.client.Dispatch() function which will try to use early-binding if the local wrapper files are present, otherwise will fall back to using late-binding. My problem with the package is that the caller doesn't always know what they are getting, as in the OP's case.
The alternative win32com.client.gencache.EnsureDispatch() function enforces early-binding and ensures any constants are available. If the local wrapper files are not available, they will be created (you might find them under %LOCALAPPDATA%\Temp\gen_py\xx\CLSID where xx is the Python version number, and CLSID is the GUID for the Type Library). Once these wrappers are created once then the generic win32com.client.Dispatch() will use these files.
My goal is to automate configuring firewalls on CentOS 7 machines using Python.
The OS comes with firewalld, so that's what I'm using. I looked into it and found that it uses dbus (I've never heard of or dealt with any of this - please correct me if anything I say is incorrect.)
I found this documentation for how to control dbus processes using Python:
http://dbus.freedesktop.org/doc/dbus-python/doc/tutorial.txt
I checked and the version of Python that comes with the OS includes the dbus module, so it seems like a promising start.
That document suggests that I needed to learn more about what firewalld exposes via the dbus interface. So I did some more research and found this:
https://www.mankier.com/5/firewalld.dbus
The first document says I need to start out with a "well-known name". Their example for such a thing was org.freedesktop.NetworkManager. The second document is titled firewalld.dbus, so I figured that was as good a name as any to try since the document doesn't explicitly give a name anywhere else.
The first document also says I need a name for an object path. Their example is /org/freedesktop/NetworkManager. The second document has an object path of /org/fedoraproject/FirewallD1.
I put those together and tried using the first method the first document suggested, SystemBus's get_object():
>>> from dbus import SystemBus
>>> bus = SystemBus()
>>> proxy = bus.get_object('firewalld.dbus', '/org/fedoraproject/FirewallD1')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib64/python2.7/site-packages/dbus/bus.py", line 241, in get_object
follow_name_owner_changes=follow_name_owner_changes)
File "/usr/lib64/python2.7/site-packages/dbus/proxies.py", line 248, in __init__
self._named_service = conn.activate_name_owner(bus_name)
File "/usr/lib64/python2.7/site-packages/dbus/bus.py", line 180, in activate_name_owner
self.start_service_by_name(bus_name)
File "/usr/lib64/python2.7/site-packages/dbus/bus.py", line 278, in start_service_by_name
'su', (bus_name, flags)))
File "/usr/lib64/python2.7/site-packages/dbus/connection.py", line 651, in call_blocking
message, timeout)
dbus.exceptions.DBusException:
org.freedesktop.DBus.Error.ServiceUnknown:
The name firewalld.dbus was not provided by any .service files
I also gave org.fedoraproject.FirewallD1 a try as the first parameter but ended up with a similar error message.
Why are these not working? Is there some way I can discover what the proper names are? It mentions ".service files" at the end of the error message... where would such a file be located?
Edit: Found several ".service files" by using find / -name *.service. One of them is at /usr/lib/systemd/system/firewalld.service... seems pretty promising so I'll check it out.
Edit 2: It's a rather short file... only about 10 lines. One of them says BusName=org.fedoraproject.FirewallD1. So I'm not sure why it said the name was not provided by any .service files... unless it's not using this file for some reason?
If the unit file says:
BusName=org.fedoraproject.FirewallD1
Then maybe you should try using that as your bus name:
>>> import dbus
>>> bus = dbus.SystemBus()
>>> p = bus.get_object('org.fedoraproject.FirewallD1', '/org/fedoraproject/FirewallD1')
>>> p.getDefaultZone()
dbus.String(u'FedoraWorkstation')
I figured this out based on the fact that this:
>>> help(bus.get_object)
Says that the get_object call looks like:
get_object(self, bus_name, object_path, introspect=True, follow_name_owner_changes=False, **kwargs)
I was trying to use the os.mknod function in Python 3.5.0 in Windows 7, however I find the error:
Traceback (most recent call last):
File "<pyshell#1>", line 1, in <module>
os.mknod
AttributeError: module 'os' has no attribute 'mknod'
I guess it's supposed to be there, since https://docs.python.org/3/library/os.html doesn't say anything about limited availability. Is there another option to use for a similar function in Windows? I'm just looking to create an empty file in a specific path, and I was thinking calling open(path, 'w') is kinda ugly for this.
I don't know if this might be a version specific problem since I've never used Python in Windows before.
Since commit in 2016, this is now documented:
Availability: Unix.
I'm new here and on Python World (although learning kind of quickly...), and just stumbled uppon the same issue.
My suggestion: for now, I would just go with the following and turn a blind eye on it...
with open('name_your_file.extention', 'w') as an_alias_for_it:
pass
In the end, it's not neat, but will be naturally "portable" among POSIX and NT systems.
I'm trying to write some VERY trivial thing in pycharm.
Problem:
sourceText = ""
with open("lang.txt", "rt") as sourceFile:
sourceText = sourceFile.readall()
print sourceText
when I enter "." after "sourceFile", I get popup that offers me "readall()" method. However, when I attempt to run the script, I get"
Traceback (most recent call last):
....languages/languages.py", line 4, in <module>
sourceText = sourceFile.readall()
AttributeError: 'file' object has no attribute 'readall'
The method is documented (I get popup, can get documentation for this method using Ctrl+Q) but it seems to be inaccessible.
I'm a bit confused.
I'd like to either:
Not receive any popups for inaccessible methods in pycharm.
Or figure out why I can't see it despite it being documented.
Advice?
I'm using windows 7 64 bit, and have two python 2.7.9 installations (32bit and 64bit), with 64bit being in path 1st. Pycharm is 4.0.5 community edition.
You are correct that readall is documented for the io module, but it's complaining about file, which does not have that method. You want the read() method to read all the data in the file in one large clump. You could also use readlines() which well return a list. I have the Pro 3.4 edition of PyCharm and it does not do this. I would report this as a bug to PyCharm.
I'm interested in experimenting with python. I know I can inspect and inject local and global variables into a frame using frame.f_locals and frame.f_globals, but I am now itching to create a full call stack.
What is keeping me from just changing the stack information is the fact that python doesn't allow me to change it.
I have actually considered programmatically transforming the python module I am using, in order to simulate winding the stack. But I am aware it is a terrible solution because client code usage of if, while, with and try would easily break my code.
I've also looked at manipulating frame.f_back, to no avail. It's read-only.
>>> import sys
...
... frm = sys._getframe()
...
... frm.f_back = None
Traceback (most recent call last):
File "<pyshell#4>", line 5, in <module>
frm.f_back = None
TypeError: readonly attribute
What I'm trying to do
As an experiment, I'm trying to implement fork() across a network.
I'm aware stackless python may have what I want, but it's still impossible to change the frame.f_back attribute.
Have a look on Online Python Tutor (http://www.pythontutor.com/). What it does is that it captures frames during execution to create visualization of python code. So, you could use the captured frames.
>>> type(sys._getframe())()
TypeError: cannot create 'frame' instances
Sorry.
You should look at the AST module and the symtable module