Nvapi how to use it in python3? - python

Hello I'm trying to set three parameters using ctypes,
import ctypes
brightness = 52
contrast = 27
gamma = 1.40
def setBrightness(brightness):
nvapi = ctypes.WinDLL("nvapi64.dll")
handle = ctypes.c_uint()
nvapi.NvAPI_Initialize()
nvapi.NvAPI_GetPhysicalGPUsFromDisplay(ctypes.byref(handle))
nvapi.NvAPI_GPU_SetBrightness(handle.value, ctypes.c_uint(brightness))
nvapi.NvAPI_Unload()
def setContrast(contrast):
nvapi = ctypes.WinDLL("nvapi64.dll")
handle = ctypes.c_uint()
nvapi.NvAPI_Initialize()
nvapi.NvAPI_GetPhysicalGPUsFromDisplay(ctypes.byref(handle))
nvapi.NvAPI_GPU_SetContrast(handle.value, ctypes.c_uint(contrast))
nvapi.NvAPI_Unload()
def setGamma(gamma):
nvapi = ctypes.WinDLL("nvapi64.dll")
handle = ctypes.c_uint()
nvapi.NvAPI_Initialize()
nvapi.NvAPI_GetPhysicalGPUsFromDisplay(ctypes.byref(handle))
nvapi.NvAPI_GPU_SetGamma(handle.value, ctypes.c_float(gamma))
nvapi.NvAPI_Unload()
setBrightness(brightness)
setContrast(contrast)
setGamma(gamma)
but I'm getting:
File "C:\Python38\lib\ctypes\__init__.py", line 391, in __getitem__
func = self._FuncPtr((name_or_ordinal, self))
AttributeError: function 'NvAPI_Initialize' not found
How can I fix this?
I'm trying to set parameters.

Related

NameError and AttributeError when attempting to run code that uses Sage Math in Python

I have the following SageMath code, which works perfectly in CoCalc:
def mean_x(factor, values):
return sum([cos(2*pi*v/factor) for v in values])/len(values)
def mean_y(factor, values):
return sum([sin(2*pi*v/factor) for v in values])/len(values)
def calculatePeriodAppeal(factor, values):
mx = mean_x(factor, values)
my = mean_y(factor, values)
appeal = sqrt(mx^2+my^2)
return appeal
def calculateBestLinear(factor, values):
mx = mean_x(factor, values).n()
my = mean_y(factor, values).n()
y0 = factor*atan2(my,mx)/(2*pi).n()
err = 1-sqrt(mx^2+my^2).n()
return [factor*x + y0, err]
def calculateGCDAppeal(factor, values):
mx = mean_x(factor, values)
my = mean_y(factor, values)
appeal = 1 - sqrt((mx-1)^2+my^2)/2
return appeal
testSeq = [0,125,211,287,408,520,650,735,816,942,1060]
gcd = calculateGCDAppeal(x, testSeq)
agcd = find_local_maximum(gcd,2,100)
print(agcd)
plot(gcd,(x, 2, 100))
The output is the best approximate greatest common divisor of the numbers from testSeq, along with a plot.
How can I use this code in Python?
Here is the current Python version, which does not yet work:
import numpy as np
import sage as sm
def mean_x(factor, values):
return sum([np.cos(2*np.pi*v/factor) for v in values])/len(values)
def mean_y(factor, values):
return sum([np.sin(2*np.pi*v/factor) for v in values])/len(values)
def calculatePeriodAppeal(factor, values):
mx = mean_x(factor, values)
my = mean_y(factor, values)
appeal = np.sqrt(mx**2+my**2)
return appeal
def calculateBestLinear(factor, values):
mx = mean_x(factor, values).n()
my = mean_y(factor, values).n()
y0 = factor*np.atan2(my,mx)/(2*np.pi).n()
err = 1-np.sqrt(mx**2+my**2).n()
return [factor*x + y0, err]
def calculateGCDAppeal(factor, values):
mx = mean_x(factor, values)
my = mean_y(factor, values)
appeal = 1 - np.sqrt((mx-1)**2+my**2)/2
return appeal
testSeq = [0,125,211,287,408,520,650,735,816,942,1060]
gcd = calculateGCDAppeal(x, testSeq)
agcd = sm.find_local_maximum(gcd,2,100)
print(agcd)
The errors I get are:
Traceback (most recent call last):
File "<ipython-input-805-d2a8b405fd43>", line 30, in <module>
gcd = calculateGCDAppeal(x, testSeq)
NameError: name 'x' is not defined
I don't understand this because because this code works in CoCalc.
Traceback (most recent call last):
File "<ipython-input-803-80cdeb0485a5>", line 33, in <module>
agcd = sm.find_local_maximum(gcd,2,100)
AttributeError: module 'sage' has no attribute 'find_local_maximum'
...but I know that SageMath has the function find_local_maximum.
If I use numerical.optimize.find_local_maximum instead, I get:
Traceback (most recent call last):
File "<ipython-input-842-949de8b03df5>", line 34, in <module>
agcd = sm.numerical.optimize.find_local_maximum(gcd,2,100)
AttributeError: module 'sage' has no attribute 'numerical'
I don't know how to add the "numerical" attribute.
First of all, there is no definition of x anywhere in this code. In addition, the syntax of find_local_maximum is sage.numerical.optimize.find_local_maximum not sage.find_local_maximum (from the SageMath documentation)
When Sage starts, it imports a lot of things.
When using Python, you need to import them yourself.
In particular, Sage defines x when it starts.
To import it if using Python:
from sage.calculus.predefined import x
Find this out using the import_statements function
in a Sage session.
The quick workaround is the catch-all
from sage.all import *
but it's good practice to import only what is needed.
See the answer to this related question
How can I translate this SageMath code to run in Python?

Attribute Error. Can not access attributes in Class

I'm trying to call a class Pager in my main function in Python. When I run the program it gives me an error:
Traceback (most recent call last): File "lab4.py", line 113, in <module>
main() File "lab4.py", line 34, in main
demandPager.processRef(p, clock, rand) File "/Users/kiranbhimani/Desktop/OSLab4/Pager.py", line 16, in processRef
desiredPage = Pager.frameTable.findPageById(testId, process.getProcessId())
**AttributeError: class Pager has no attribute 'frameTable'**
How can I access frameTable? If I insert "self" as a parameter, I can't call the class. It says processRef requires 4 arguments but only 3 are given.
I'm not sure what is going on here. Thank you in advance!
class Pager:
def __init__(self, machineSize, pageSize):
self.machineSize = machineSize
self.pageSize = pageSize
self.frameTable = FrameTable(int(machineSize/pageSize))
#staticmethod
def processRef(process, clock, randreader):
ref = int(process.currentReference)
testId = int(ref / Page.size)
#print Pager.machineSize
desiredPage = Pager.frameTable.findPageById(testId, process.getProcessId())
if (isHit(desiredPage, process)):
desiredPage.addRefdWord(ref)
else:
if (not frameTable.isFull()):
frameTable.addPage(process, testId, ref)
else:
pageToEvict = findPageToReplace(replacementAlgo, randreader)
frameTable.evictPage(pageToEvict)
frameTable.addPage(process, testId, ref)
desiredPage = frameTable.lastPageAdded
desiredPage = frameTable.lastPageAdded
desiredPage.setIfLoaded(true)
process.incrNumPageFaults()
desiredPage.timeLastUsed = clock
frameTable.updateTimes()
This is the main function:
from Process import Process
from Page import Page as Page
from Pager import Pager
from FrameTable import FrameTable
import sys
runningProcesses = []
finishedProcesses = []
def main():
#read input
machineSize = int(sys.argv[1])
pageSize = int(sys.argv[2])
processSize = int(sys.argv[3])
jobMix = int(sys.argv[4])
numOfRefPerProcess = int(sys.argv[5])
replacementAlgo = (sys.argv[6])
demandPager = Pager(machineSize, pageSize)
Page.size = pageSize
Process.size = processSize
setProc(jobMix)
demandPager.replacementAlgo = replacementAlgo
index = 0
clock = 0
while(len(runningProcesses) > 0):
p = runningProcesses[index]
for i in range(3):
demandPager.processRef(p, clock, rand)
p.setCurrentReference(p.calcNextReference(rand))
p.incrRefsMade()
clock+=1
if (p.getRefsMade() == numRefPerProcess):
finishedProcesses.add(p)
runningProcesses.remove(p)
index-=1
break
if (index == numProcesses-1):
index = 0
else:
index+=1
print "printing....."
printOutput(args)
You tried to access a class property frameTable, but this class has no added properties at all. Objects of the class have properties of machineSize, FrameSize, and pageTable -- that's one of each for every object you instantiate.
For instance, there will be a demandPager.frameTable once you hit the creation command, but you haven't given any properties (other than the built-ins) to Pager as a class.
Perhaps you want to use self
desiredPage = self.frameTable.findPageById(testId, process.getProcessId())

Python,Ctypes - WindowsError: access violation

I'm developing instrument drivers for testing at work. It's first developed in
C using the IVI/Visa standard. I am then using a python wrapper for a dll of the C to use the functions in the python environment. However with the current one I am getting an error:
Traceback (most recent call last):
File "D:/CAS/Development/LvDrivers/Python/Python_wrapper/ADIag81110a.py", line 1362, in <module>
PGEN.ConfigureTransitionCoupling(1, "1")
File "D:/CAS/Development/LvDrivers/Python/Python_wrapper/ADIag81110a.py", line 1305, in ConfigureTransitionCoupling
ADIag81110aLib().ADIag81110a_ConfigureTransitionCoupling( self.vi, transitionEnabling , channelName )
WindowsError: exception: access violation reading 0x00000031
It happens with any function I use from the C. All of the functions work correctly when they are ran directly in C. He is is the C definition of that function:
ViStatus _VI_FUNC ADIag81110a_ConfigureTransitionCoupling (ViSession vi,
ViInt32 transitionEnabling, ViChar channelName[])
{
ViStatus error = VI_SUCCESS;
checkErr( Ivi_LockSession (vi, VI_NULL));
viCheckParm(Ivi_SetAttributeViInt32 (vi, channelName, ADIAG81110A_ATTR_TRANSITION_COUPLING,
0, transitionEnabling), 2, "Transition Coupling");
Error:
Ivi_UnlockSession (vi, VI_NULL);
return error;
}
The python might seem a little complicated but i'll only be posting the code that I feel is relevant to declaration of the ConfigureTransitionCoupling function that I'm using as an example and the ctypes declarations:
import os
import visa_exceptions
from visa_messages import completion_and_error_messages
from vpp43_constants import *
from vpp43_types import *
from ctypes import cdll
if os.name == 'nt':
from ctypes import windll
else:
from ctypes import CFUNCTYPE as FUNCTYPE
import warnings
class Singleton(object):
def __new__(cls, *args, **kwds):
it = cls.__dict__.get("__it__")
if it is not None:
return it
cls.__it__ = it = object.__new__(cls)
it.init(*args, **kwds)
return it
class ADIag81110a_lib(Singleton):
def __call__(self, force_cdecl=False):
if self.__lib is None or self.__cdecl_lib is None:
self.load_library()
if force_cdecl:
return self.__cdecl_lib
return self.__lib
def init(self):
self.__lib = self.__cdecl_lib = None
def load_library(self, path=None):
if os.name == 'nt':
path = "C:\Program Files (x86)\IVI Foundation\IVI\Bin\ADIag81110a_32.dll"
self.__lib = windll.LoadLibrary(path)
self.__cdecl_lib = cdll.LoadLibrary(path)
elif os.name == 'posix':
if not path:
path = "please put path to unix/linix here"
self.__lib = self.__cdecl_lib = cdll.LoadLibrary(path)
else:
self.__lib = self.__cdecl_lib = None
raise visa_exceptions.OSNotSupported, os.name
self.__initialize_library_functions()
return None
def __initialize_library_functions(self):
self.__set_argument_types("ADIag81110a_ConfigureTransitionCoupling", [ ViSession , ViInt32 , ViChar ])
def __set_argument_types(self, inst_function, types, force_cdecl=False, may_be_missing=True):
if force_cdecl:
library = self.__cdecl_lib
else:
library = self.__lib
try:
getattr(library, inst_function).argtypes = types
except AttributeError:
if not may_be_missing:
raise
ADIag81110aLib = ADIag81110a_lib()
class ADIag81110a():
def ConfigureTransitionCoupling(self , transitionEnabling , channelName ):
ADIag81110aLib().ADIag81110a_ConfigureTransitionCoupling( self.vi, transitionEnabling , channelName )
if __name__ == '__main__':
#This initilises the communication with the instrument
PGEN = ADIag81110a("GPIB0::10::INSTR")
test = PGEN.ReadOutputImpedance("1")
print test
I have looked at other people posting about their error and I feel they are using C-types in a different way to me so I am unable to apply their solutions.
Any help is appreciated. This is also my first post on stack overflow so feel free to point out any issues with my post :)

Cocos2d: AttributeError: 'Director' object has no attribute '_window_virtual_width'

We are using the cocos2d framework to create a game. We're completely new to this framework, so we cannot get the director object to work as we are expecting. Here is our code skeleton:
from cocos.director import director
from cocos.layer import base_layers
import sys
import math
import os
import pyglet
import cocos
world_width = 1000
world_height = 1000
class NetworkMap(cocos.layer.ScrollableLayer):
def __init__(self, world_width, world_height):
self.world_width = world_width
self.world_height = world_height
super(NetworkMap, self).__init__()
bg = ColorLayer(170,170,0,255,width=500,height=500)
self.px_width = world_width
self.px_height = world_height
self.add(bg,z=0)
class TestScene(cocos.scene.Scene):
def __init__(self):
super(TestScene,self).__init__()
def on_enter():
director.push_handlers(self.on_cocos_resize)
super(TestScene, self).on_enter()
def on_cocos_resize(self, usable_width, usable_height):
self.f_refresh_marks()
def main():
scene = TestScene()
director.init(world_width, world_height, do_not_scale=True)
world_map = NetworkMap(world_width, world_height)
scroller = cocos.layer.ScrollingManager()
scroller.add(world_map)
scene.add(scroller)
director.run(scene)
So for some reason the director doesn't have all the attributes we want.
Our stack trace is:
Traceback (most recent call last):
File "map.py", line 49, in <module>
main()
File "map.py", line 39, in main
scene = TestScene()
File "map.py", line 29, in __init__
super(TestScene,self).__init__()
File "/usr/local/lib/python2.7/dist-packages/cocos2d-0.5.5-py2.7.egg/cocos/scene.py", line 95, in __init__
super(Scene,self).__init__()
File "/usr/local/lib/python2.7/dist-packages/cocos2d-0.5.5-py2.7.egg/cocos/cocosnode.py", line 114, in __init__
self.camera = Camera()
File "/usr/local/lib/python2.7/dist-packages/cocos2d-0.5.5-py2.7.egg/cocos/camera.py", line 56, in __init__
self.restore()
File "/usr/local/lib/python2.7/dist-packages/cocos2d-0.5.5-py2.7.egg/cocos/camera.py", line 76, in restore
width, height = director.get_window_size()
File "/usr/local/lib/python2.7/dist-packages/cocos2d-0.5.5-py2.7.egg/cocos/director.py", line 522, in get_window_size
return ( self._window_virtual_width, self._window_virtual_height)
AttributeError: 'Director' object has no attribute '_window_virtual_width'
You need to initialise the director before you instantiate your first scene. The director is the global object that initialises your screen, sets up the Cocos2D framework, etc.
I found a few other errors:
You need to change ColorLayer to be fully qualified, e.g. cocos.layer.ColorLayer.
on_enter needs to have self as the first argument.
You need to define f_refresh_marks in your TestScene class.
Here's a working copy of the code. (Working, in the sense that it does not throw errors, not that it does any sort of scrolling.)
from cocos.director import director
from cocos.layer import base_layers
import sys
import math
import os
import pyglet
import cocos
world_width = 1000
world_height = 1000
class NetworkMap(cocos.layer.ScrollableLayer):
def __init__(self, world_width, world_height):
self.world_width = world_width
self.world_height = world_height
super(NetworkMap, self).__init__()
bg = cocos.layer.ColorLayer(170,170,0,255,width=500,height=500)
self.px_width = world_width
self.px_height = world_height
self.add(bg,z=0)
class TestScene(cocos.scene.Scene):
def __init__(self):
super(TestScene,self).__init__()
def on_enter(self):
director.push_handlers(self.on_cocos_resize)
super(TestScene, self).on_enter()
def on_cocos_resize(self, usable_width, usable_height):
self.f_refresh_marks()
def f_refresh_marks(self):
pass
def main():
director.init(world_width, world_height, do_not_scale=True)
scene = TestScene()
world_map = NetworkMap(world_width, world_height)
scroller = cocos.layer.ScrollingManager()
scroller.add(world_map)
scene.add(scroller)
director.run(scene)
if __name__ == '__main__': main()
I had the same issue (with a very similar stack trace) and it was because I was trying to create a layer before calling director.init(). Moving director.init() to earlier in the code fixed it for me.

Accessing unregistered COM objects from python via a registered TLB

I have three pieces of code that i'm working with at the moment:
A closed source application (Main.exe)
A closed source VB COM object implemented as a dll (comobj.dll)
Code that I am developing in Python
comobj.dll hosts a COM object (lets say, 'MainInteract') that I would like to use from Python. I can already use this object perfectly fine from IronPython, but due to other requirements I need to use it from regular Python. I believe the best method here is to use win32com, but I can't quite make any headway at all.
First, some working IronPython code:
import clr
import os
import sys
__dir__ = os.path.dirname(os.path.realpath(__file__))
sys.path.insert(0, __dir__)
sys.path.append(r"C:\Path\To\comobj.dll") #This is where the com object dll actually is
clr.AddReferenceToFileAndPath(os.path.join(__dir__, r'comobj_1_1.dll')) #This is the .NET interop assembly that was created automatically via SharpDevelop's COM Inspector
from comobj_1_1 import clsMainInteract
o = clsMainInteract()
o.DoStuff(True)
And now the code that I attempted in regular Python:
>>> import win32com.client
>>> win32com.client.Dispatch("{11111111-comobj_guid_i_got_from_com_inspector}")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Python26\lib\site-packages\win32com\client\__init__.py", line 95, in Dispatch
dispatch, userName = dynamic._GetGoodDispatchAndUserName(dispatch,userName,clsctx)
File "C:\Python26\lib\site-packages\win32com\client\dynamic.py", line 104, in _GetGoodDispatchAndUserName
return (_GetGoodDispatch(IDispatch, clsctx), userName)
File "C:\Python26\lib\site-packages\win32com\client\dynamic.py", line 84, in _GetGoodDispatch
IDispatch = pythoncom.CoCreateInstance(IDispatch, None, clsctx, pythoncom.IID_IDispatch)
pywintypes.com_error: (-2147221164, 'Class not registered', None, None)
I have also attempted using the friendly name of the TLB:
>>> import win32com.client
>>> win32com.client.Dispatch("Friendly TLB Name I Saw")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Python26\lib\site-packages\win32com\client\__init__.py", line 95, in Dispatch
dispatch, userName = dynamic._GetGoodDispatchAndUserName(dispatch,userName,clsctx)
File "C:\Python26\lib\site-packages\win32com\client\dynamic.py", line 104, in _GetGoodDispatchAndUserName
return (_GetGoodDispatch(IDispatch, clsctx), userName)
File "C:\Python26\lib\site-packages\win32com\client\dynamic.py", line 84, in _GetGoodDispatch
IDispatch = pythoncom.CoCreateInstance(IDispatch, None, clsctx, pythoncom.IID_IDispatch)
pywintypes.com_error: (-2147221005, 'Invalid class string', None, None)
In fact, the only success I've had was this:
import pythoncom
tlb = pythoncom.LoadRegTypeLib("{11111111-comobj_guid_i_got_from_com_inspector}",1,1,0)
>>> tlb
<PyITypeLib at 0x00AD7D78 with obj at 0x0025EDF0>
>>> tlb.GetDocumentation(1)
(u'clsMainInteract', None, 0, None)
But i'm not sure how to go from there to getting an object. I think my problem is that I need to load the dll into my process and get it to register itself with my process's COM source, so I can properly CoCreateInstance / win32com.client.Dispatch() on it.
I have also seen Activation Contexts referenced, especially when talking about 'no registration COM', but typically in a sentences like "Windows will create a context for you if you specify the right stuff in your .manifest files". I'd like to avoid manifest files if possible, as one would be required in the same folder as the (closed source) COM object dll, and i'd rather not drop any files in that directory if I can avoid it.
Thanks for the help.
What I did to access Free Download Manager's type library was the following:
import pythoncom, win32com.client
fdm = pythoncom.LoadTypeLib('fdm.tlb')
downloads_stat = None
for index in xrange(0, fdm.GetTypeInfoCount()):
type_name = fdm.GetDocumentation(index)[0]
if type_name == 'FDMDownloadsStat':
type_iid = fdm.GetTypeInfo(index).GetTypeAttr().iid
downloads_stat = win32com.client.Dispatch(type_iid)
break
downloads_stat.BuildListOfDownloads(True, True)
print downloads_stat.Download(0).Url
The code above will print the URL of the first download.
Here is a method I devised to load a COM object from a DLL. It was based on a lot of reading about COM, etc. I'm not 100% sure about the last lines, specifically d=. I think that only works if IID_Dispatch is passed in (which you can see if the default param).
In addition, I believe this code leaks - for one, the DLL is never unloaded (use ctypes.windll.kernel32.FreeLibraryW) and I believe the COM ref counts for the initial class factory are off by one, and thus never get released. But still, this works for my application.
import pythoncom
import win32com.client
def CreateInstanceFromDll(dll, clsid_class, iid_interface=pythoncom.IID_IDispatch, pUnkOuter=None, dwClsContext=pythoncom.CLSCTX_SERVER):
from uuid import UUID
from ctypes import OleDLL, c_long, byref
e = OleDLL(dll)
clsid_class = UUID(clsid_class).bytes_le
iclassfactory = UUID(str(pythoncom.IID_IClassFactory)).bytes_le
com_classfactory = c_long(0)
hr = e.DllGetClassObject(clsid_class, iclassfactory, byref(com_classfactory))
MyFactory = pythoncom.ObjectFromAddress(com_classfactory.value, pythoncom.IID_IClassFactory)
i = MyFactory.CreateInstance(pUnkOuter, iid_interface)
d = win32com.client.__WrapDispatch(i)
return d
For a useful utility module that wraps the object-from-DLL case, as well as others, see https://gist.github.com/4219140
__all__ = (
####### Class Objects
#CoGetClassObject - Normal, not wrapped
'CoDllGetClassObject', #Get ClassObject from a DLL file
####### ClassFactory::CreateInstance Wrappers
'CoCreateInstanceFromFactory', #Create an object via IClassFactory::CreateInstance
'CoCreateInstanceFromFactoryLicenced', #Create a licenced object via IClassFactory2::CreateInstanceLic
###### Util
'CoReleaseObject', #Calls Release() on a COM object
###### Main Utility Methods
#'CoCreateInstance', #Not wrapped, normal call
'CoCreateInstanceLicenced', #CoCreateInstance, but with a licence key
###### Hacky DLL methods for reg-free COM without Activation Contexts, manifests, etc
'CoCreateInstanceFromDll', #Given a dll, a clsid, and an iid, create an object
'CoCreateInstanceFromDllLicenced', #Given a dll, a clsid, an iid, and a license key, create an object
)
IID_IClassFactory2 = "{B196B28F-BAB4-101A-B69C-00AA00341D07}"
from uuid import UUID
from ctypes import OleDLL, WinDLL, c_ulong, byref, WINFUNCTYPE, POINTER, c_char_p, c_void_p
from ctypes.wintypes import HRESULT
import pythoncom
import win32com.client
import logging
log = logging.getLogger(__name__)
def _raw_guid(guid):
"""Given a string GUID, or a pythoncom IID, return the GUID laid out in memory suitable for passing to ctypes"""
return UUID(str(guid)).bytes_le
proto_icf2_base = WINFUNCTYPE(HRESULT,
c_ulong,
c_ulong,
c_char_p,
c_ulong,
POINTER(c_ulong),
)
IClassFactory2__CreateInstanceLic = proto_icf2_base(7, 'CreateInstanceLic', (
(1, 'pUnkOuter'),
(1 | 4, 'pUnkReserved'),
(1, 'riid'),
(1, 'bstrKey'),
(2, 'ppvObj'),
), _raw_guid(IID_IClassFactory2))
#--------------------------------
#--------------------------------
def _pc_wrap(iptr, resultCLSID=None):
#return win32com.client.__WrapDispatch(iptr)
log.debug("_pc_wrap: %s, %s"%(iptr, resultCLSID))
disp = win32com.client.Dispatch(iptr, resultCLSID=resultCLSID)
log.debug("_pc_wrap: %s (%s)", disp.__class__.__name__, disp)
return disp
def CoCreateInstanceFromFactory(factory_ptr, iid_interface=pythoncom.IID_IDispatch, pUnkOuter=None):
"""Given a factory_ptr whose interface is IClassFactory, create the instance of clsid_class with the specified interface"""
ClassFactory = pythoncom.ObjectFromAddress(factory_ptr.value, pythoncom.IID_IClassFactory)
i = ClassFactory.CreateInstance(pUnkOuter, iid_interface)
return i
def CoCreateInstanceFromFactoryLicenced(factory_ptr, key, iid_interface=pythoncom.IID_IDispatch, pUnkOuter=None):
"""Given a factory_ptr whose interface is IClassFactory2, create the instance of clsid_class with the specified interface"""
requested_iid = _raw_guid(iid_interface)
ole_aut = WinDLL("OleAut32.dll")
key_bstr = ole_aut.SysAllocString(unicode(key))
try:
obj = IClassFactory2__CreateInstanceLic(factory_ptr, pUnkOuter or 0, c_char_p(requested_iid), key_bstr)
disp_obj = pythoncom.ObjectFromAddress(obj, iid_interface)
return disp_obj
finally:
if key_bstr:
ole_aut.SysFreeString(key_bstr)
#----------------------------------
def CoReleaseObject(obj_ptr):
"""Calls Release() on a COM object. obj_ptr should be a c_void_p"""
if not obj_ptr:
return
IUnknown__Release = WINFUNCTYPE(HRESULT)(2, 'Release', (), pythoncom.IID_IUnknown)
IUnknown__Release(obj_ptr)
#-----------------------------------
def CoCreateInstanceLicenced(clsid_class, key, pythoncom_iid_interface=pythoncom.IID_IDispatch, dwClsContext=pythoncom.CLSCTX_SERVER, pythoncom_wrapdisp=True, wrapas=None):
"""Uses IClassFactory2::CreateInstanceLic to create a COM object given a licence key."""
IID_IClassFactory2 = "{B196B28F-BAB4-101A-B69C-00AA00341D07}"
ole = OleDLL("Ole32.dll")
clsid_class_raw = _raw_guid(clsid_class)
iclassfactory2 = _raw_guid(IID_IClassFactory2)
com_classfactory = c_void_p(0)
ole.CoGetClassObject(clsid_class_raw, dwClsContext, None, iclassfactory2, byref(com_classfactory))
try:
iptr = CoCreateInstanceFromFactoryLicenced(
factory_ptr = com_classfactory,
key=key,
iid_interface=pythoncom_iid_interface,
pUnkOuter=None,
)
if pythoncom_wrapdisp:
return _pc_wrap(iptr, resultCLSID=wrapas or clsid_class)
return iptr
finally:
if com_classfactory:
CoReleaseObject(com_classfactory)
#-----------------------------------------------------------
#DLLs
def CoDllGetClassObject(dll_filename, clsid_class, iid_factory=pythoncom.IID_IClassFactory):
"""Given a DLL filename and a desired class, return the factory for that class (as a c_void_p)"""
dll = OleDLL(dll_filename)
clsid_class = _raw_guid(clsid_class)
iclassfactory = _raw_guid(iid_factory)
com_classfactory = c_void_p(0)
dll.DllGetClassObject(clsid_class, iclassfactory, byref(com_classfactory))
return com_classfactory
def CoCreateInstanceFromDll(dll, clsid_class, iid_interface=pythoncom.IID_IDispatch, pythoncom_wrapdisp=True, wrapas=None):
iclassfactory_ptr = CoDllGetClassObject(dll, clsid_class)
try:
iptr = CoCreateInstanceFromFactory(iclassfactory_ptr, iid_interface)
if pythoncom_wrapdisp:
return _pc_wrap(iptr, resultCLSID=wrapas or clsid_class)
return iptr
finally:
CoReleaseObject(iclassfactory_ptr)
def CoCreateInstanceFromDllLicenced(dll, clsid_class, key, iid_interface=pythoncom.IID_IDispatch, pythoncom_wrapdisp=True, wrapas=None):
iclassfactory2_ptr = CoDllGetClassObject(dll, clsid_class, iid_factory=IID_IClassFactory2)
try:
iptr = CoCreateInstanceFromFactoryLicenced(iclassfactory2_ptr, key, iid_interface)
if pythoncom_wrapdisp:
return _pc_wrap(iptr, resultCLSID=wrapas or clsid_class)
return iptr
finally:
CoReleaseObject(iclassfactory2_ptr)

Categories