mirror of
https://github.com/aykhans/AzSuicideDataVisualization.git
synced 2025-07-02 22:30:48 +00:00
first commit
This commit is contained in:
@ -0,0 +1 @@
|
||||
# This is a Python package
|
238
.venv/Lib/site-packages/win32comext/axscript/client/debug.py
Normal file
238
.venv/Lib/site-packages/win32comext/axscript/client/debug.py
Normal file
@ -0,0 +1,238 @@
|
||||
import traceback, sys, string
|
||||
|
||||
import win32com.server.util
|
||||
from win32com.util import IIDToInterfaceName
|
||||
from win32com.client.util import Enumerator
|
||||
from win32com.server.exception import COMException
|
||||
import pythoncom
|
||||
from .framework import trace
|
||||
from win32com.axdebug import axdebug, gateways, contexts, stackframe, documents, adb
|
||||
from win32com.axdebug.codecontainer import SourceCodeContainer
|
||||
from win32com.axdebug.util import _wrap, _wrap_remove
|
||||
import win32com.client.connect
|
||||
import win32api, winerror
|
||||
import os
|
||||
|
||||
try:
|
||||
os.environ["DEBUG_AXDEBUG"]
|
||||
debuggingTrace = 1 # Should we print "trace" output?
|
||||
except KeyError:
|
||||
debuggingTrace = 0
|
||||
|
||||
|
||||
def trace(*args):
|
||||
"""A function used instead of "print" for debugging output."""
|
||||
if not debuggingTrace:
|
||||
return
|
||||
print(win32api.GetCurrentThreadId(), end=" ")
|
||||
for arg in args:
|
||||
print(arg, end=" ")
|
||||
print()
|
||||
|
||||
|
||||
# Note that the DebugManager is not a COM gateway class for the
|
||||
# debugger - but it does create and manage them.
|
||||
class DebugManager:
|
||||
_debugger_interfaces_ = [axdebug.IID_IActiveScriptDebug]
|
||||
|
||||
def __init__(self, scriptEngine):
|
||||
self.scriptEngine = scriptEngine
|
||||
self.adb = adb.Debugger()
|
||||
self.rootNode = None
|
||||
self.debugApplication = None
|
||||
self.ccProvider = documents.CodeContainerProvider()
|
||||
try:
|
||||
self.scriptSiteDebug = scriptEngine.GetScriptSite(
|
||||
axdebug.IID_IActiveScriptSiteDebug
|
||||
)
|
||||
except pythoncom.com_error:
|
||||
# No debugger interface (ie, dumb host). Do the extra work.
|
||||
trace("Scripting site has no debugger interface")
|
||||
self.scriptSiteDebug = None
|
||||
# Get the debug application object.
|
||||
self.debugApplication = None
|
||||
if self.scriptSiteDebug is not None:
|
||||
# Spec says that we should test for this, and if it fails revert to
|
||||
# PDM application.
|
||||
try:
|
||||
self.debugApplication = self.scriptSiteDebug.GetApplication()
|
||||
self.rootNode = self.scriptSiteDebug.GetRootApplicationNode()
|
||||
except pythoncom.com_error:
|
||||
self.debugApplication = None
|
||||
|
||||
if self.debugApplication is None:
|
||||
# Try to get/create the default one
|
||||
# NOTE - Dont catch exceptions here - let the parent do it,
|
||||
# so it knows debug support is available.
|
||||
pdm = pythoncom.CoCreateInstance(
|
||||
axdebug.CLSID_ProcessDebugManager,
|
||||
None,
|
||||
pythoncom.CLSCTX_ALL,
|
||||
axdebug.IID_IProcessDebugManager,
|
||||
)
|
||||
self.debugApplication = pdm.GetDefaultApplication()
|
||||
self.rootNode = self.debugApplication.GetRootNode()
|
||||
|
||||
assert (
|
||||
self.debugApplication is not None
|
||||
), "Need to have a DebugApplication object by now!"
|
||||
self.activeScriptDebug = None
|
||||
|
||||
if self.debugApplication is not None:
|
||||
self.adb.AttachApp(self.debugApplication, self.ccProvider)
|
||||
self.codeContainers = {}
|
||||
self.activeScriptDebug = _wrap(
|
||||
ActiveScriptDebug(self, self.codeContainers), axdebug.IID_IActiveScriptDebug
|
||||
)
|
||||
|
||||
def Close(self):
|
||||
# Called by the language engine when it receives a close request
|
||||
if self.activeScriptDebug is not None:
|
||||
_wrap_remove(self.activeScriptDebug)
|
||||
self.activeScriptDebug = None
|
||||
self.scriptEngine = None
|
||||
self.rootNode = None
|
||||
self.debugApplication = None
|
||||
self.scriptSiteDebug = None
|
||||
if self.ccProvider is not None:
|
||||
self.ccProvider.Close()
|
||||
self.ccProvider = None
|
||||
self.codeContainers = {}
|
||||
if self.adb:
|
||||
self.adb.CloseApp()
|
||||
self.adb = None
|
||||
|
||||
# print "Close complete"
|
||||
|
||||
def IsAnyHost(self):
|
||||
"Do we have _any_ debugging interfaces installed?"
|
||||
return self.debugApplication is not None
|
||||
|
||||
def IsSimpleHost(self):
|
||||
return self.scriptSiteDebug is None
|
||||
|
||||
def HandleRuntimeError(self):
|
||||
"""Called by the engine when a runtime error occurs. If we have a debugger,
|
||||
we let it know.
|
||||
|
||||
The result is a boolean which indicates if the error handler should call
|
||||
IActiveScriptSite::OnScriptError()
|
||||
"""
|
||||
# if self.IsAnyHost:
|
||||
# site = _wrap(self, axdebug.IID_IActiveScriptSite)
|
||||
# breakResume, errorResume, fCallOnError = self.debugApplication(activeScriptErrorDebug, site)
|
||||
# Do something with these!
|
||||
# else:
|
||||
trace("HandleRuntimeError")
|
||||
fCallOnError = 1
|
||||
return fCallOnError
|
||||
|
||||
def _query_interface_for_debugger_(self, iid):
|
||||
if iid in self._debugger_interfaces_:
|
||||
return self.activeScriptDebug
|
||||
trace("DebugManager QI - unknown IID", iid)
|
||||
return 0
|
||||
|
||||
def OnEnterScript(self):
|
||||
trace("OnEnterScript")
|
||||
try:
|
||||
1 / 0
|
||||
except:
|
||||
# Bit of a hack - reach into engine.
|
||||
baseFrame = sys.exc_info()[2].tb_frame.f_back
|
||||
self.adb.SetupAXDebugging(baseFrame)
|
||||
|
||||
def OnLeaveScript(self):
|
||||
trace("OnLeaveScript")
|
||||
self.adb.ResetAXDebugging()
|
||||
|
||||
def AddScriptBlock(self, codeBlock):
|
||||
# If we dont have debugging support, dont bother.
|
||||
cc = DebugCodeBlockContainer(codeBlock, self.scriptSiteDebug)
|
||||
if self.IsSimpleHost():
|
||||
document = documents.DebugDocumentText(cc)
|
||||
document = _wrap(document, axdebug.IID_IDebugDocument)
|
||||
provider = documents.DebugDocumentProvider(document)
|
||||
provider = _wrap(provider, axdebug.IID_IDebugDocumentProvider)
|
||||
cc.debugDocument = document
|
||||
newNode = self.debugApplication.CreateApplicationNode()
|
||||
newNode.SetDocumentProvider(provider)
|
||||
newNode.Attach(self.rootNode)
|
||||
else:
|
||||
newNode = None # Managed by smart host.
|
||||
self.codeContainers[cc.sourceContext] = cc
|
||||
self.ccProvider.AddCodeContainer(cc, newNode)
|
||||
|
||||
|
||||
class DebugCodeBlockContainer(SourceCodeContainer):
|
||||
def __init__(self, codeBlock, site):
|
||||
self.codeBlock = codeBlock
|
||||
SourceCodeContainer.__init__(
|
||||
self,
|
||||
codeBlock.codeText,
|
||||
codeBlock.GetFileName(),
|
||||
codeBlock.sourceContextCookie,
|
||||
codeBlock.startLineNumber,
|
||||
site,
|
||||
)
|
||||
|
||||
def GetName(self, dnt):
|
||||
if dnt == axdebug.DOCUMENTNAMETYPE_APPNODE:
|
||||
return self.codeBlock.GetDisplayName()
|
||||
elif dnt == axdebug.DOCUMENTNAMETYPE_TITLE:
|
||||
return self.codeBlock.GetDisplayName()
|
||||
# elif dnt==axdebug.DOCUMENTNAMETYPE_FILE_TAIL:
|
||||
# elif dnt==axdebug.DOCUMENTNAMETYPE_URL:
|
||||
else:
|
||||
raise COMException(scode=winerror.S_FALSE)
|
||||
|
||||
|
||||
class EnumDebugCodeContexts(gateways.EnumDebugCodeContexts):
|
||||
def _wrap(self, ob):
|
||||
return ob
|
||||
|
||||
|
||||
class ActiveScriptDebug:
|
||||
"""The class which implements the IActiveScriptDebug interface for the Active Script engine.
|
||||
|
||||
Only ever used by smart hosts.
|
||||
"""
|
||||
|
||||
_public_methods_ = [
|
||||
"GetScriptTextAttributes",
|
||||
"GetScriptletTextAttributes",
|
||||
"EnumCodeContextsOfPosition",
|
||||
]
|
||||
_com_interfaces_ = [axdebug.IID_IActiveScriptDebug]
|
||||
|
||||
def __init__(self, debugMgr, codeContainers):
|
||||
self.debugMgr = debugMgr
|
||||
self.scriptSiteDebug = debugMgr.scriptSiteDebug
|
||||
self.codeContainers = codeContainers
|
||||
|
||||
def _Close(self):
|
||||
self.debugMgr = None
|
||||
self.scriptSiteDebug = None
|
||||
self.codeContainers = {}
|
||||
|
||||
def _query_interface_(self, iid):
|
||||
trace("DebuggerQI with", iid)
|
||||
return _wrap(self.debugMgr.scriptEngine, iid)
|
||||
|
||||
def GetScriptTextAttributes(self, code, delim, flags):
|
||||
container = SourceCodeContainer(code, "<Temp Code Block>")
|
||||
return container.GetSyntaxColorAttributes()
|
||||
|
||||
def GetScriptletTextAttributes(self, code, delim, flags):
|
||||
trace("GetScriptletTextAttributes", code, delim, flags)
|
||||
container = SourceCodeContainer(code, "<Temp Code Block>")
|
||||
return container.GetSyntaxColorAttributes()
|
||||
|
||||
def EnumCodeContextsOfPosition(self, context, charOffset, numChars):
|
||||
trace("EnumCodeContextsOfPosition", context, charOffset, numChars)
|
||||
try:
|
||||
context = self.codeContainers[context].GetCodeContextAtPosition(charOffset)
|
||||
except KeyError:
|
||||
raise COMException(scode=winerror.E_UNEXPECTED)
|
||||
enum = EnumDebugCodeContexts([context])
|
||||
return _wrap(enum, axdebug.IID_IEnumDebugCodeContexts)
|
271
.venv/Lib/site-packages/win32comext/axscript/client/error.py
Normal file
271
.venv/Lib/site-packages/win32comext/axscript/client/error.py
Normal file
@ -0,0 +1,271 @@
|
||||
"""Exception and error handling.
|
||||
|
||||
This contains the core exceptions that the implementations should raise
|
||||
as well as the IActiveScriptError interface code.
|
||||
|
||||
"""
|
||||
|
||||
import sys, traceback
|
||||
from win32com.axscript import axscript
|
||||
import winerror
|
||||
import win32com.server.exception
|
||||
import win32com.server.util
|
||||
import pythoncom
|
||||
import re
|
||||
|
||||
debugging = 0
|
||||
|
||||
|
||||
def FormatForAX(text):
|
||||
"""Format a string suitable for an AX Host"""
|
||||
# Replace all " with ', so it works OK in HTML (ie, ASP)
|
||||
return ExpandTabs(AddCR(text))
|
||||
|
||||
|
||||
def ExpandTabs(text):
|
||||
return re.sub("\t", " ", text)
|
||||
|
||||
|
||||
def AddCR(text):
|
||||
return re.sub("\n", "\r\n", text)
|
||||
|
||||
|
||||
class IActiveScriptError:
|
||||
"""An implementation of IActiveScriptError
|
||||
|
||||
The ActiveX Scripting host calls this client whenever we report
|
||||
an exception to it. This interface provides the exception details
|
||||
for the host to report to the user.
|
||||
"""
|
||||
|
||||
_com_interfaces_ = [axscript.IID_IActiveScriptError]
|
||||
_public_methods_ = ["GetSourceLineText", "GetSourcePosition", "GetExceptionInfo"]
|
||||
|
||||
def _query_interface_(self, iid):
|
||||
print("IActiveScriptError QI - unknown IID", iid)
|
||||
return 0
|
||||
|
||||
def _SetExceptionInfo(self, exc):
|
||||
self.exception = exc
|
||||
|
||||
def GetSourceLineText(self):
|
||||
return self.exception.linetext
|
||||
|
||||
def GetSourcePosition(self):
|
||||
ctx = self.exception.sourceContext
|
||||
# Zero based in the debugger (but our columns are too!)
|
||||
return (
|
||||
ctx,
|
||||
self.exception.lineno + self.exception.startLineNo - 1,
|
||||
self.exception.colno,
|
||||
)
|
||||
|
||||
def GetExceptionInfo(self):
|
||||
return self.exception
|
||||
|
||||
|
||||
class AXScriptException(win32com.server.exception.COMException):
|
||||
"""A class used as a COM exception.
|
||||
|
||||
Note this has attributes which conform to the standard attributes
|
||||
for COM exceptions, plus a few others specific to our IActiveScriptError
|
||||
object.
|
||||
"""
|
||||
|
||||
def __init__(self, site, codeBlock, exc_type, exc_value, exc_traceback):
|
||||
# set properties base class shares via base ctor...
|
||||
win32com.server.exception.COMException.__init__(
|
||||
self,
|
||||
description="Unknown Exception",
|
||||
scode=winerror.DISP_E_EXCEPTION,
|
||||
source="Python ActiveX Scripting Engine",
|
||||
)
|
||||
|
||||
# And my other values...
|
||||
if codeBlock is None:
|
||||
self.sourceContext = 0
|
||||
self.startLineNo = 0
|
||||
else:
|
||||
self.sourceContext = codeBlock.sourceContextCookie
|
||||
self.startLineNo = codeBlock.startLineNumber
|
||||
self.linetext = ""
|
||||
|
||||
self.__BuildFromException(site, exc_type, exc_value, exc_traceback)
|
||||
|
||||
def __BuildFromException(self, site, type, value, tb):
|
||||
if debugging:
|
||||
import linecache
|
||||
|
||||
linecache.clearcache()
|
||||
try:
|
||||
if issubclass(type, SyntaxError):
|
||||
self._BuildFromSyntaxError(site, value, tb)
|
||||
else:
|
||||
self._BuildFromOther(site, type, value, tb)
|
||||
except: # Error extracting traceback info!!!
|
||||
traceback.print_exc()
|
||||
# re-raise.
|
||||
raise
|
||||
|
||||
def _BuildFromSyntaxError(self, site, exc, tb):
|
||||
value = exc.args
|
||||
# All syntax errors should have a message as element 0
|
||||
try:
|
||||
msg = value[0]
|
||||
except:
|
||||
msg = "Unknown Error (%s)" % (value,)
|
||||
try:
|
||||
(filename, lineno, offset, line) = value[1]
|
||||
# Some of these may be None, which upsets us!
|
||||
if offset is None:
|
||||
offset = 0
|
||||
if line is None:
|
||||
line = ""
|
||||
except:
|
||||
msg = "Unknown"
|
||||
lineno = 0
|
||||
offset = 0
|
||||
line = "Unknown"
|
||||
self.description = FormatForAX(msg)
|
||||
self.lineno = lineno
|
||||
self.colno = offset - 1
|
||||
self.linetext = ExpandTabs(line.rstrip())
|
||||
|
||||
def _BuildFromOther(self, site, exc_type, value, tb):
|
||||
self.colno = -1
|
||||
self.lineno = 0
|
||||
if debugging: # Full traceback if debugging.
|
||||
list = traceback.format_exception(exc_type, value, tb)
|
||||
self.description = ExpandTabs("".join(list))
|
||||
return
|
||||
# Run down the traceback list, looking for the first "<Script..>"
|
||||
# Hide traceback above this. In addition, keep going down
|
||||
# looking for a "_*_" attribute, and below hide these also.
|
||||
hide_names = [
|
||||
"r_import",
|
||||
"r_reload",
|
||||
"r_open",
|
||||
] # hide from these functions down in the traceback.
|
||||
depth = None
|
||||
tb_top = tb
|
||||
while tb_top:
|
||||
filename, lineno, name, line = self.ExtractTracebackInfo(tb_top, site)
|
||||
if filename[:7] == "<Script":
|
||||
break
|
||||
tb_top = tb_top.tb_next
|
||||
format_items = []
|
||||
if tb_top: # found one.
|
||||
depth = 0
|
||||
tb_look = tb_top
|
||||
# Look down for our bottom
|
||||
while tb_look:
|
||||
filename, lineno, name, line = self.ExtractTracebackInfo(tb_look, site)
|
||||
if name in hide_names:
|
||||
break
|
||||
# We can report a line-number, but not a filename. Therefore,
|
||||
# we return the last line-number we find in one of our script
|
||||
# blocks.
|
||||
if filename.startswith("<Script"):
|
||||
self.lineno = lineno
|
||||
self.linetext = line
|
||||
format_items.append((filename, lineno, name, line))
|
||||
depth = depth + 1
|
||||
tb_look = tb_look.tb_next
|
||||
else:
|
||||
depth = None
|
||||
tb_top = tb
|
||||
|
||||
bits = ["Traceback (most recent call last):\n"]
|
||||
bits.extend(traceback.format_list(format_items))
|
||||
if exc_type == pythoncom.com_error:
|
||||
desc = "%s (0x%x)" % (value.strerror, value.hresult)
|
||||
if (
|
||||
value.hresult == winerror.DISP_E_EXCEPTION
|
||||
and value.excepinfo
|
||||
and value.excepinfo[2]
|
||||
):
|
||||
desc = value.excepinfo[2]
|
||||
bits.append("COM Error: " + desc)
|
||||
else:
|
||||
bits.extend(traceback.format_exception_only(exc_type, value))
|
||||
|
||||
# XXX - this utf8 encoding seems bogus. From well before py3k,
|
||||
# we had the comment:
|
||||
# > all items in the list are utf8 courtesy of Python magically
|
||||
# > converting unicode to utf8 before compilation.
|
||||
# but that is likely just confusion from early unicode days;
|
||||
# Python isn't doing it, pywin32 probably was, so 'mbcs' would
|
||||
# be the default encoding. We should never hit this these days
|
||||
# anyway, but on py3k, we *never* will, and str objects there
|
||||
# don't have a decode method...
|
||||
if sys.version_info < (3,):
|
||||
for i in range(len(bits)):
|
||||
if type(bits[i]) is str:
|
||||
# assert type(bits[i]) is str, type(bits[i])
|
||||
bits[i] = bits[i].decode("utf8")
|
||||
|
||||
self.description = ExpandTabs("".join(bits))
|
||||
# Clear tracebacks etc.
|
||||
tb = tb_top = tb_look = None
|
||||
|
||||
def ExtractTracebackInfo(self, tb, site):
|
||||
import linecache
|
||||
|
||||
f = tb.tb_frame
|
||||
lineno = tb.tb_lineno
|
||||
co = f.f_code
|
||||
filename = co.co_filename
|
||||
name = co.co_name
|
||||
line = linecache.getline(filename, lineno)
|
||||
if not line:
|
||||
try:
|
||||
codeBlock = site.scriptCodeBlocks[filename]
|
||||
except KeyError:
|
||||
codeBlock = None
|
||||
if codeBlock:
|
||||
# Note: 'line' will now be unicode.
|
||||
line = codeBlock.GetLineNo(lineno)
|
||||
if line:
|
||||
line = line.strip()
|
||||
else:
|
||||
line = None
|
||||
return filename, lineno, name, line
|
||||
|
||||
def __repr__(self):
|
||||
return "AXScriptException Object with description:" + self.description
|
||||
|
||||
|
||||
def ProcessAXScriptException(scriptingSite, debugManager, exceptionInstance):
|
||||
"""General function to handle any exception in AX code
|
||||
|
||||
This function creates an instance of our IActiveScriptError interface, and
|
||||
gives it to the host, along with out exception class. The host will
|
||||
likely call back on the IActiveScriptError interface to get the source text
|
||||
and other information not normally in COM exceptions.
|
||||
"""
|
||||
# traceback.print_exc()
|
||||
instance = IActiveScriptError()
|
||||
instance._SetExceptionInfo(exceptionInstance)
|
||||
gateway = win32com.server.util.wrap(instance, axscript.IID_IActiveScriptError)
|
||||
if debugManager:
|
||||
fCallOnError = debugManager.HandleRuntimeError()
|
||||
if not fCallOnError:
|
||||
return None
|
||||
|
||||
try:
|
||||
result = scriptingSite.OnScriptError(gateway)
|
||||
except pythoncom.com_error as details:
|
||||
print("**OnScriptError failed:", details)
|
||||
print("Exception description:'%s'" % (repr(exceptionInstance.description)))
|
||||
print("Exception text:'%s'" % (repr(exceptionInstance.linetext)))
|
||||
result = winerror.S_FALSE
|
||||
|
||||
if result == winerror.S_OK:
|
||||
# If the above returns NOERROR, it is assumed the error has been
|
||||
# correctly registered and the value SCRIPT_E_REPORTED is returned.
|
||||
ret = win32com.server.exception.COMException(scode=axscript.SCRIPT_E_REPORTED)
|
||||
return ret
|
||||
else:
|
||||
# The error is taken to be unreported and is propagated up the call stack
|
||||
# via the IDispatch::Invoke's EXCEPINFO parameter (hr returned is DISP_E_EXCEPTION.
|
||||
return exceptionInstance
|
1269
.venv/Lib/site-packages/win32comext/axscript/client/framework.py
Normal file
1269
.venv/Lib/site-packages/win32comext/axscript/client/framework.py
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,77 @@
|
||||
# pydumper.py
|
||||
#
|
||||
# This is being worked on - it does not yet work at all, in ay way
|
||||
# shape or form :-)
|
||||
#
|
||||
# A new script engine, derived from the standard scripting engine,
|
||||
# which dumps information.
|
||||
|
||||
# This generally can be used to grab all sorts of useful details about
|
||||
# an engine - expose bugs in it or Python, dump the object model, etc.
|
||||
|
||||
# As it is derived from the standard engine, it fully supports Python
|
||||
# as a scripting language - meaning the dumps produced can be quite dynamic,
|
||||
# and based on the script code you execute.
|
||||
|
||||
from . import pyscript
|
||||
from win32com.axscript import axscript
|
||||
|
||||
from .pyscript import RaiseAssert, trace, Exception, SCRIPTTEXT_FORCEEXECUTION
|
||||
|
||||
PyDump_CLSID = "{ac527e60-c693-11d0-9c25-00aa00125a98}"
|
||||
|
||||
|
||||
class AXScriptAttribute(pyscript.AXScriptAttribute):
|
||||
pass
|
||||
|
||||
|
||||
class NamedScriptAttribute(pyscript.NamedScriptAttribute):
|
||||
pass
|
||||
|
||||
|
||||
class PyScript(pyscript.PyScript):
|
||||
pass
|
||||
|
||||
|
||||
def Register():
|
||||
import sys
|
||||
|
||||
if "-d" in sys.argv:
|
||||
dispatcher = "DispatcherWin32trace"
|
||||
debug_desc = " (" + dispatcher + ")"
|
||||
debug_option = "Yes"
|
||||
else:
|
||||
dispatcher = None
|
||||
debug_desc = ""
|
||||
debug_option = ""
|
||||
|
||||
categories = [axscript.CATID_ActiveScript, axscript.CATID_ActiveScriptParse]
|
||||
clsid = PyDump_CLSID
|
||||
lcid = 0x0409 # // english
|
||||
policy = None # "win32com.axscript.client.axspolicy.AXScriptPolicy"
|
||||
|
||||
print("Registering COM server%s..." % debug_desc)
|
||||
from win32com.server.register import RegisterServer
|
||||
|
||||
languageName = "PyDump"
|
||||
verProgId = "Python.Dumper.1"
|
||||
RegisterServer(
|
||||
clsid=clsid,
|
||||
pythonInstString="win32com.axscript.client.pyscript.PyDumper",
|
||||
className="Python Debugging/Dumping ActiveX Scripting Engine",
|
||||
progID=languageName,
|
||||
verProgID=verProgId,
|
||||
catids=categories,
|
||||
policy=policy,
|
||||
dispatcher=dispatcher,
|
||||
)
|
||||
|
||||
CreateRegKey(languageName + "\\OLEScript")
|
||||
# Basic Registration for wsh.
|
||||
win32com.server.register._set_string(".pysDump", "pysDumpFile")
|
||||
win32com.server.register._set_string("pysDumpFile\\ScriptEngine", languageName)
|
||||
print("Dumping Server registered.")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
Register()
|
446
.venv/Lib/site-packages/win32comext/axscript/client/pyscript.py
Normal file
446
.venv/Lib/site-packages/win32comext/axscript/client/pyscript.py
Normal file
@ -0,0 +1,446 @@
|
||||
"""Python ActiveX Scripting Implementation
|
||||
|
||||
This module implements the Python ActiveX Scripting client.
|
||||
|
||||
To register the implementation, simply "run" this Python program - ie
|
||||
either double-click on it, or run "python.exe pyscript.py" from the
|
||||
command line.
|
||||
"""
|
||||
|
||||
import winerror
|
||||
import win32com
|
||||
import win32api
|
||||
import pythoncom
|
||||
import sys
|
||||
import traceback
|
||||
import re
|
||||
import win32com.client.dynamic
|
||||
from win32com.axscript.client import framework, scriptdispatch
|
||||
from win32com.axscript import axscript
|
||||
import win32com.server.register
|
||||
|
||||
from win32com.axscript.client.framework import (
|
||||
RaiseAssert,
|
||||
trace,
|
||||
Exception,
|
||||
SCRIPTTEXT_FORCEEXECUTION,
|
||||
SCRIPTTEXT_ISEXPRESSION,
|
||||
SCRIPTTEXT_ISPERSISTENT,
|
||||
)
|
||||
|
||||
PyScript_CLSID = "{DF630910-1C1D-11d0-AE36-8C0F5E000000}"
|
||||
|
||||
debugging_attr = 0
|
||||
|
||||
|
||||
def debug_attr_print(*args):
|
||||
if debugging_attr:
|
||||
trace(*args)
|
||||
|
||||
|
||||
def ExpandTabs(text):
|
||||
return re.sub("\t", " ", text)
|
||||
|
||||
|
||||
def AddCR(text):
|
||||
return re.sub("\n", "\r\n", text)
|
||||
|
||||
|
||||
class AXScriptCodeBlock(framework.AXScriptCodeBlock):
|
||||
def GetDisplayName(self):
|
||||
return "PyScript - " + framework.AXScriptCodeBlock.GetDisplayName(self)
|
||||
|
||||
|
||||
# There is only ever _one_ ax object - it exists in the global namespace
|
||||
# for all script items.
|
||||
# It performs a search from all global/visible objects
|
||||
# down.
|
||||
# This means that if 2 sub-objects of the same name are used
|
||||
# then only one is ever reachable using the ax shortcut.
|
||||
class AXScriptAttribute:
|
||||
"An attribute in a scripts namespace."
|
||||
|
||||
def __init__(self, engine):
|
||||
self.__dict__["_scriptEngine_"] = engine
|
||||
|
||||
def __getattr__(self, attr):
|
||||
if attr[1] == "_" and attr[:-1] == "_":
|
||||
raise AttributeError(attr)
|
||||
rc = self._FindAttribute_(attr)
|
||||
if rc is None:
|
||||
raise AttributeError(attr)
|
||||
return rc
|
||||
|
||||
def _Close_(self):
|
||||
self.__dict__["_scriptEngine_"] = None
|
||||
|
||||
def _DoFindAttribute_(self, obj, attr):
|
||||
try:
|
||||
return obj.subItems[attr.lower()].attributeObject
|
||||
except KeyError:
|
||||
pass
|
||||
# Check out the sub-items
|
||||
for item in obj.subItems.values():
|
||||
try:
|
||||
return self._DoFindAttribute_(item, attr)
|
||||
except AttributeError:
|
||||
pass
|
||||
raise AttributeError(attr)
|
||||
|
||||
def _FindAttribute_(self, attr):
|
||||
for item in self._scriptEngine_.subItems.values():
|
||||
try:
|
||||
return self._DoFindAttribute_(item, attr)
|
||||
except AttributeError:
|
||||
pass
|
||||
# All else fails, see if it is a global
|
||||
# (mainly b/w compat)
|
||||
return getattr(self._scriptEngine_.globalNameSpaceModule, attr)
|
||||
|
||||
|
||||
# raise AttributeError(attr)
|
||||
|
||||
|
||||
class NamedScriptAttribute:
|
||||
"An explicitely named object in an objects namespace"
|
||||
# Each named object holds a reference to one of these.
|
||||
# Whenever a sub-item appears in a namespace, it is really one of these
|
||||
# objects. Has a circular reference back to the item itself, which is
|
||||
# closed via _Close_()
|
||||
def __init__(self, scriptItem):
|
||||
self.__dict__["_scriptItem_"] = scriptItem
|
||||
|
||||
def __repr__(self):
|
||||
return "<NamedItemAttribute" + repr(self._scriptItem_) + ">"
|
||||
|
||||
def __getattr__(self, attr):
|
||||
# If a known subitem, return it.
|
||||
try:
|
||||
return self._scriptItem_.subItems[attr.lower()].attributeObject
|
||||
except KeyError:
|
||||
# Otherwise see if the dispatch can give it to us
|
||||
if self._scriptItem_.dispatchContainer:
|
||||
return getattr(self._scriptItem_.dispatchContainer, attr)
|
||||
raise AttributeError(attr)
|
||||
|
||||
def __setattr__(self, attr, value):
|
||||
# XXX - todo - if a known item, then should call its default
|
||||
# dispatch method.
|
||||
attr = attr.lower()
|
||||
if self._scriptItem_.dispatchContainer:
|
||||
try:
|
||||
return setattr(self._scriptItem_.dispatchContainer, attr, value)
|
||||
except AttributeError:
|
||||
pass
|
||||
raise AttributeError(attr)
|
||||
|
||||
def _Close_(self):
|
||||
self.__dict__["_scriptItem_"] = None
|
||||
|
||||
|
||||
class ScriptItem(framework.ScriptItem):
|
||||
def __init__(self, parentItem, name, dispatch, flags):
|
||||
framework.ScriptItem.__init__(self, parentItem, name, dispatch, flags)
|
||||
self.scriptlets = {}
|
||||
self.attributeObject = None
|
||||
|
||||
def Reset(self):
|
||||
framework.ScriptItem.Reset(self)
|
||||
if self.attributeObject:
|
||||
self.attributeObject._Close_()
|
||||
self.attributeObject = None
|
||||
|
||||
def Close(self):
|
||||
framework.ScriptItem.Close(self) # calls reset.
|
||||
self.dispatchContainer = None
|
||||
self.scriptlets = {}
|
||||
|
||||
def Register(self):
|
||||
framework.ScriptItem.Register(self)
|
||||
self.attributeObject = NamedScriptAttribute(self)
|
||||
if self.dispatch:
|
||||
# Need to avoid the new Python "lazy" dispatch behaviour.
|
||||
try:
|
||||
engine = self.GetEngine()
|
||||
olerepr = clsid = None
|
||||
typeinfo = self.dispatch.GetTypeInfo()
|
||||
clsid = typeinfo.GetTypeAttr()[0]
|
||||
try:
|
||||
olerepr = engine.mapKnownCOMTypes[clsid]
|
||||
except KeyError:
|
||||
pass
|
||||
except pythoncom.com_error:
|
||||
typeinfo = None
|
||||
if olerepr is None:
|
||||
olerepr = win32com.client.dynamic.MakeOleRepr(
|
||||
self.dispatch, typeinfo, None
|
||||
)
|
||||
if clsid is not None:
|
||||
engine.mapKnownCOMTypes[clsid] = olerepr
|
||||
self.dispatchContainer = win32com.client.dynamic.CDispatch(
|
||||
self.dispatch, olerepr, self.name
|
||||
)
|
||||
|
||||
|
||||
# self.dispatchContainer = win32com.client.dynamic.Dispatch(self.dispatch, userName = self.name)
|
||||
# self.dispatchContainer = win32com.client.dynamic.DumbDispatch(self.dispatch, userName = self.name)
|
||||
|
||||
# def Connect(self):
|
||||
# framework.ScriptItem.Connect(self)
|
||||
# def Disconnect(self):
|
||||
# framework.ScriptItem.Disconnect(self)
|
||||
|
||||
|
||||
class PyScript(framework.COMScript):
|
||||
# Setup the auto-registration stuff...
|
||||
_reg_verprogid_ = "Python.AXScript.2"
|
||||
_reg_progid_ = "Python"
|
||||
# _reg_policy_spec_ = default
|
||||
_reg_catids_ = [axscript.CATID_ActiveScript, axscript.CATID_ActiveScriptParse]
|
||||
_reg_desc_ = "Python ActiveX Scripting Engine"
|
||||
_reg_clsid_ = PyScript_CLSID
|
||||
_reg_class_spec_ = "win32com.axscript.client.pyscript.PyScript"
|
||||
_reg_remove_keys_ = [(".pys",), ("pysFile",)]
|
||||
_reg_threading_ = "both"
|
||||
|
||||
def __init__(self):
|
||||
framework.COMScript.__init__(self)
|
||||
self.globalNameSpaceModule = None
|
||||
self.codeBlocks = []
|
||||
self.scriptDispatch = None
|
||||
|
||||
def InitNew(self):
|
||||
framework.COMScript.InitNew(self)
|
||||
import imp
|
||||
|
||||
self.scriptDispatch = None
|
||||
self.globalNameSpaceModule = imp.new_module("__ax_main__")
|
||||
self.globalNameSpaceModule.__dict__["ax"] = AXScriptAttribute(self)
|
||||
|
||||
self.codeBlocks = []
|
||||
self.persistedCodeBlocks = []
|
||||
self.mapKnownCOMTypes = {} # Map of known CLSID to typereprs
|
||||
self.codeBlockCounter = 0
|
||||
|
||||
def Stop(self):
|
||||
# Flag every pending script as already done
|
||||
for b in self.codeBlocks:
|
||||
b.beenExecuted = 1
|
||||
return framework.COMScript.Stop(self)
|
||||
|
||||
def Reset(self):
|
||||
# Reset all code-blocks that are persistent, and discard the rest
|
||||
oldCodeBlocks = self.codeBlocks[:]
|
||||
self.codeBlocks = []
|
||||
for b in oldCodeBlocks:
|
||||
if b.flags & SCRIPTTEXT_ISPERSISTENT:
|
||||
b.beenExecuted = 0
|
||||
self.codeBlocks.append(b)
|
||||
return framework.COMScript.Reset(self)
|
||||
|
||||
def _GetNextCodeBlockNumber(self):
|
||||
self.codeBlockCounter = self.codeBlockCounter + 1
|
||||
return self.codeBlockCounter
|
||||
|
||||
def RegisterNamedItem(self, item):
|
||||
wasReg = item.isRegistered
|
||||
framework.COMScript.RegisterNamedItem(self, item)
|
||||
if not wasReg:
|
||||
# Insert into our namespace.
|
||||
# Add every item by name
|
||||
if item.IsVisible():
|
||||
self.globalNameSpaceModule.__dict__[item.name] = item.attributeObject
|
||||
if item.IsGlobal():
|
||||
# Global items means sub-items are also added...
|
||||
for subitem in item.subItems.values():
|
||||
self.globalNameSpaceModule.__dict__[
|
||||
subitem.name
|
||||
] = subitem.attributeObject
|
||||
# Also add all methods
|
||||
for name, entry in item.dispatchContainer._olerepr_.mapFuncs.items():
|
||||
if not entry.hidden:
|
||||
self.globalNameSpaceModule.__dict__[name] = getattr(
|
||||
item.dispatchContainer, name
|
||||
)
|
||||
|
||||
def DoExecutePendingScripts(self):
|
||||
try:
|
||||
globs = self.globalNameSpaceModule.__dict__
|
||||
for codeBlock in self.codeBlocks:
|
||||
if not codeBlock.beenExecuted:
|
||||
if self.CompileInScriptedSection(codeBlock, "exec"):
|
||||
self.ExecInScriptedSection(codeBlock, globs)
|
||||
finally:
|
||||
pass
|
||||
|
||||
def DoRun(self):
|
||||
pass
|
||||
|
||||
def Close(self):
|
||||
self.ResetNamespace()
|
||||
self.globalNameSpaceModule = None
|
||||
self.codeBlocks = []
|
||||
self.scriptDispatch = None
|
||||
framework.COMScript.Close(self)
|
||||
|
||||
def GetScriptDispatch(self, name):
|
||||
# trace("GetScriptDispatch with", name)
|
||||
# if name is not None: return None
|
||||
if self.scriptDispatch is None:
|
||||
self.scriptDispatch = scriptdispatch.MakeScriptDispatch(
|
||||
self, self.globalNameSpaceModule
|
||||
)
|
||||
return self.scriptDispatch
|
||||
|
||||
def MakeEventMethodName(self, subItemName, eventName):
|
||||
return (
|
||||
subItemName[0].upper()
|
||||
+ subItemName[1:]
|
||||
+ "_"
|
||||
+ eventName[0].upper()
|
||||
+ eventName[1:]
|
||||
)
|
||||
|
||||
def DoAddScriptlet(
|
||||
self,
|
||||
defaultName,
|
||||
code,
|
||||
itemName,
|
||||
subItemName,
|
||||
eventName,
|
||||
delimiter,
|
||||
sourceContextCookie,
|
||||
startLineNumber,
|
||||
):
|
||||
# Just store the code away - compile when called. (JIT :-)
|
||||
item = self.GetNamedItem(itemName)
|
||||
if (
|
||||
itemName == subItemName
|
||||
): # Explicit handlers - eg <SCRIPT LANGUAGE="Python" for="TestForm" Event="onSubmit">
|
||||
subItem = item
|
||||
else:
|
||||
subItem = item.GetCreateSubItem(item, subItemName, None, None)
|
||||
funcName = self.MakeEventMethodName(subItemName, eventName)
|
||||
|
||||
codeBlock = AXScriptCodeBlock(
|
||||
"Script Event %s" % funcName, code, sourceContextCookie, startLineNumber, 0
|
||||
)
|
||||
self._AddScriptCodeBlock(codeBlock)
|
||||
subItem.scriptlets[funcName] = codeBlock
|
||||
|
||||
def DoProcessScriptItemEvent(self, item, event, lcid, wFlags, args):
|
||||
# trace("ScriptItemEvent", self, item, event, event.name, lcid, wFlags, args)
|
||||
funcName = self.MakeEventMethodName(item.name, event.name)
|
||||
codeBlock = function = None
|
||||
try:
|
||||
function = item.scriptlets[funcName]
|
||||
if type(function) == type(self): # ie, is a CodeBlock instance
|
||||
codeBlock = function
|
||||
function = None
|
||||
except KeyError:
|
||||
pass
|
||||
if codeBlock is not None:
|
||||
realCode = "def %s():\n" % funcName
|
||||
for line in framework.RemoveCR(codeBlock.codeText).split("\n"):
|
||||
realCode = realCode + "\t" + line + "\n"
|
||||
realCode = realCode + "\n"
|
||||
if not self.CompileInScriptedSection(codeBlock, "exec", realCode):
|
||||
return
|
||||
dict = {}
|
||||
self.ExecInScriptedSection(
|
||||
codeBlock, self.globalNameSpaceModule.__dict__, dict
|
||||
)
|
||||
function = dict[funcName]
|
||||
# cache back in scriptlets as a function.
|
||||
item.scriptlets[funcName] = function
|
||||
if function is None:
|
||||
# still no function - see if in the global namespace.
|
||||
try:
|
||||
function = self.globalNameSpaceModule.__dict__[funcName]
|
||||
except KeyError:
|
||||
# Not there _exactly_ - do case ins search.
|
||||
funcNameLook = funcName.lower()
|
||||
for attr in self.globalNameSpaceModule.__dict__.keys():
|
||||
if funcNameLook == attr.lower():
|
||||
function = self.globalNameSpaceModule.__dict__[attr]
|
||||
# cache back in scriptlets, to avoid this overhead next time
|
||||
item.scriptlets[funcName] = function
|
||||
|
||||
if function is None:
|
||||
raise Exception(scode=winerror.DISP_E_MEMBERNOTFOUND)
|
||||
return self.ApplyInScriptedSection(codeBlock, function, args)
|
||||
|
||||
def DoParseScriptText(
|
||||
self, code, sourceContextCookie, startLineNumber, bWantResult, flags
|
||||
):
|
||||
code = framework.RemoveCR(code) + "\n"
|
||||
if flags & SCRIPTTEXT_ISEXPRESSION:
|
||||
name = "Script Expression"
|
||||
exec_type = "eval"
|
||||
else:
|
||||
name = "Script Block"
|
||||
exec_type = "exec"
|
||||
num = self._GetNextCodeBlockNumber()
|
||||
if num == 1:
|
||||
num = ""
|
||||
name = "%s %s" % (name, num)
|
||||
codeBlock = AXScriptCodeBlock(
|
||||
name, code, sourceContextCookie, startLineNumber, flags
|
||||
)
|
||||
self._AddScriptCodeBlock(codeBlock)
|
||||
globs = self.globalNameSpaceModule.__dict__
|
||||
if bWantResult: # always immediate.
|
||||
if self.CompileInScriptedSection(codeBlock, exec_type):
|
||||
if flags & SCRIPTTEXT_ISEXPRESSION:
|
||||
return self.EvalInScriptedSection(codeBlock, globs)
|
||||
else:
|
||||
return self.ExecInScriptedSection(codeBlock, globs)
|
||||
|
||||
# else compile failed, but user chose to keep running...
|
||||
else:
|
||||
if flags & SCRIPTTEXT_FORCEEXECUTION:
|
||||
if self.CompileInScriptedSection(codeBlock, exec_type):
|
||||
self.ExecInScriptedSection(codeBlock, globs)
|
||||
else:
|
||||
self.codeBlocks.append(codeBlock)
|
||||
|
||||
def GetNamedItemClass(self):
|
||||
return ScriptItem
|
||||
|
||||
def ResetNamespace(self):
|
||||
if self.globalNameSpaceModule is not None:
|
||||
try:
|
||||
self.globalNameSpaceModule.ax._Reset_()
|
||||
except AttributeError:
|
||||
pass # ???
|
||||
globalNameSpaceModule = None
|
||||
|
||||
|
||||
def DllRegisterServer():
|
||||
klass = PyScript
|
||||
win32com.server.register._set_subkeys(
|
||||
klass._reg_progid_ + "\\OLEScript", {}
|
||||
) # Just a CreateKey
|
||||
# Basic Registration for wsh.
|
||||
win32com.server.register._set_string(".pys", "pysFile")
|
||||
win32com.server.register._set_string("pysFile\\ScriptEngine", klass._reg_progid_)
|
||||
guid_wsh_shellex = "{60254CA5-953B-11CF-8C96-00AA00B8708C}"
|
||||
win32com.server.register._set_string(
|
||||
"pysFile\\ShellEx\\DropHandler", guid_wsh_shellex
|
||||
)
|
||||
win32com.server.register._set_string(
|
||||
"pysFile\\ShellEx\\PropertySheetHandlers\\WSHProps", guid_wsh_shellex
|
||||
)
|
||||
|
||||
|
||||
def Register(klass=PyScript):
|
||||
import sys
|
||||
|
||||
ret = win32com.server.register.UseCommandLine(
|
||||
klass, finalize_register=DllRegisterServer
|
||||
)
|
||||
return ret
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
Register()
|
@ -0,0 +1,49 @@
|
||||
# A version of the ActiveScripting engine that enables rexec support
|
||||
# This version supports hosting by IE - however, due to Python's
|
||||
# rexec module being neither completely trusted nor private, it is
|
||||
# *not* enabled by default.
|
||||
# As of Python 2.2, rexec is simply not available - thus, if you use this,
|
||||
# a HTML page can do almost *anything* at all on your machine.
|
||||
|
||||
# You almost certainly do NOT want to use thus!
|
||||
|
||||
import pythoncom
|
||||
from win32com.axscript import axscript
|
||||
import winerror
|
||||
from . import pyscript
|
||||
|
||||
INTERFACE_USES_DISPEX = 0x00000004 # Object knows to use IDispatchEx
|
||||
INTERFACE_USES_SECURITY_MANAGER = (
|
||||
0x00000008 # Object knows to use IInternetHostSecurityManager
|
||||
)
|
||||
|
||||
|
||||
class PyScriptRExec(pyscript.PyScript):
|
||||
# Setup the auto-registration stuff...
|
||||
_reg_verprogid_ = "Python.AXScript-rexec.2"
|
||||
_reg_progid_ = "Python" # Same ProgID as the standard engine.
|
||||
# _reg_policy_spec_ = default
|
||||
_reg_catids_ = [axscript.CATID_ActiveScript, axscript.CATID_ActiveScriptParse]
|
||||
_reg_desc_ = "Python ActiveX Scripting Engine (with rexec support)"
|
||||
_reg_clsid_ = "{69c2454b-efa2-455b-988c-c3651c4a2f69}"
|
||||
_reg_class_spec_ = "win32com.axscript.client.pyscript_rexec.PyScriptRExec"
|
||||
_reg_remove_keys_ = [(".pys",), ("pysFile",)]
|
||||
_reg_threading_ = "Apartment"
|
||||
|
||||
def _GetSupportedInterfaceSafetyOptions(self):
|
||||
# print "**** calling", pyscript.PyScript._GetSupportedInterfaceSafetyOptions, "**->", pyscript.PyScript._GetSupportedInterfaceSafetyOptions(self)
|
||||
return (
|
||||
INTERFACE_USES_DISPEX
|
||||
| INTERFACE_USES_SECURITY_MANAGER
|
||||
| axscript.INTERFACESAFE_FOR_UNTRUSTED_DATA
|
||||
| axscript.INTERFACESAFE_FOR_UNTRUSTED_CALLER
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("WARNING: By registering this engine, you are giving remote HTML code")
|
||||
print("the ability to execute *any* code on your system.")
|
||||
print()
|
||||
print("You almost certainly do NOT want to do this.")
|
||||
print("You have been warned, and are doing this at your own (significant) risk")
|
||||
pyscript.Register(PyScriptRExec)
|
@ -0,0 +1,114 @@
|
||||
"""dynamic dispatch objects for AX Script.
|
||||
|
||||
This is an IDispatch object that a scripting host may use to
|
||||
query and invoke methods on the main script. Not may hosts use
|
||||
this yet, so it is not well tested!
|
||||
"""
|
||||
|
||||
import winerror
|
||||
import types
|
||||
from win32com.server.exception import COMException
|
||||
import win32com.server.policy
|
||||
import win32com.server.util
|
||||
from win32com.client import Dispatch
|
||||
import pythoncom
|
||||
from win32com.axscript import axscript
|
||||
|
||||
debugging = 0
|
||||
|
||||
PyIDispatchType = pythoncom.TypeIIDs[pythoncom.IID_IDispatch]
|
||||
|
||||
|
||||
def _is_callable(obj):
|
||||
return type(obj) in [types.FunctionType, types.MethodType]
|
||||
# ignore hasattr(obj, "__call__") as this means all COM objects!
|
||||
|
||||
|
||||
class ScriptDispatch:
|
||||
_public_methods_ = []
|
||||
|
||||
def __init__(self, engine, scriptNamespace):
|
||||
self.engine = engine
|
||||
self.scriptNamespace = scriptNamespace
|
||||
|
||||
def _dynamic_(self, name, lcid, wFlags, args):
|
||||
# Ensure any newly added items are available.
|
||||
self.engine.RegisterNewNamedItems()
|
||||
self.engine.ProcessNewNamedItemsConnections()
|
||||
if wFlags & pythoncom.INVOKE_FUNC:
|
||||
# attempt to call a function
|
||||
try:
|
||||
func = getattr(self.scriptNamespace, name)
|
||||
if not _is_callable(func):
|
||||
raise AttributeError(name) # Not a function.
|
||||
realArgs = []
|
||||
for arg in args:
|
||||
if type(arg) == PyIDispatchType:
|
||||
realArgs.append(Dispatch(arg))
|
||||
else:
|
||||
realArgs.append(arg)
|
||||
# xxx - todo - work out what code block to pass???
|
||||
return self.engine.ApplyInScriptedSection(None, func, tuple(realArgs))
|
||||
|
||||
except AttributeError:
|
||||
if not wFlags & pythoncom.DISPATCH_PROPERTYGET:
|
||||
raise COMException(scode=winerror.DISP_E_MEMBERNOTFOUND)
|
||||
if wFlags & pythoncom.DISPATCH_PROPERTYGET:
|
||||
# attempt to get a property
|
||||
try:
|
||||
ret = getattr(self.scriptNamespace, name)
|
||||
if _is_callable(ret):
|
||||
raise AttributeError(name) # Not a property.
|
||||
except AttributeError:
|
||||
raise COMException(scode=winerror.DISP_E_MEMBERNOTFOUND)
|
||||
except COMException as instance:
|
||||
raise
|
||||
except:
|
||||
ret = self.engine.HandleException()
|
||||
return ret
|
||||
|
||||
raise COMException(scode=winerror.DISP_E_MEMBERNOTFOUND)
|
||||
|
||||
|
||||
class StrictDynamicPolicy(win32com.server.policy.DynamicPolicy):
|
||||
def _wrap_(self, object):
|
||||
win32com.server.policy.DynamicPolicy._wrap_(self, object)
|
||||
if hasattr(self._obj_, "scriptNamespace"):
|
||||
for name in dir(self._obj_.scriptNamespace):
|
||||
self._dyn_dispid_to_name_[self._getdispid_(name, 0)] = name
|
||||
|
||||
def _getmembername_(self, dispid):
|
||||
try:
|
||||
return str(self._dyn_dispid_to_name_[dispid])
|
||||
except KeyError:
|
||||
raise COMException(scode=winerror.DISP_E_UNKNOWNNAME, desc="Name not found")
|
||||
|
||||
def _getdispid_(self, name, fdex):
|
||||
try:
|
||||
func = getattr(self._obj_.scriptNamespace, str(name))
|
||||
except AttributeError:
|
||||
raise COMException(scode=winerror.DISP_E_MEMBERNOTFOUND)
|
||||
# if not _is_callable(func):
|
||||
return win32com.server.policy.DynamicPolicy._getdispid_(self, name, fdex)
|
||||
|
||||
|
||||
def _wrap_debug(obj):
|
||||
return win32com.server.util.wrap(
|
||||
obj,
|
||||
usePolicy=StrictDynamicPolicy,
|
||||
useDispatcher=win32com.server.policy.DispatcherWin32trace,
|
||||
)
|
||||
|
||||
|
||||
def _wrap_nodebug(obj):
|
||||
return win32com.server.util.wrap(obj, usePolicy=StrictDynamicPolicy)
|
||||
|
||||
|
||||
if debugging:
|
||||
_wrap = _wrap_debug
|
||||
else:
|
||||
_wrap = _wrap_nodebug
|
||||
|
||||
|
||||
def MakeScriptDispatch(engine, namespace):
|
||||
return _wrap(ScriptDispatch(engine, namespace))
|
Reference in New Issue
Block a user