From va at zaptest.com Thu Aug 1 09:19:35 2024 From: va at zaptest.com (Valentin Abrutski) Date: Thu, 1 Aug 2024 16:19:35 +0300 Subject: [python-win32] Python Windows Scripting Engine In-Reply-To: References: <8e658085-c118-4ccb-a667-3772b1eeb1a1@skippinet.com.au> <3aa8c2a7-ae04-407c-9a84-9927a3b5fcf1@skippinet.com.au> Message-ID: Hi Mark, just to let you know. I found the root cause. I was trying to get 32bit version of interface and pywin32 export 64bit version(different GUID and slightly different function signature) Thank you for your help. On Wed, Jul 31, 2024 at 5:08?PM Valentin Abrutski wrote: > Thank you Mark. I will try that. Appreciate > > ??, 31 ???. 2024??., 17:01 Mark Hammond : > >> Sorry, I can't explain that - running pyscript.py should register things >> and support for IActiveScriptParse is unconditional. You could try running >> `pyscript.py --debug` which might print some debug stuff, or even add print >> statements to client.py's QueryInterface function to make sure it's >> actually being called. Also, executing >> win32comext/axscript/test/testHost.py should try and exercise the engine. >> >> HTH, >> >> Mark >> On 2024-07-31 9:14 a.m., Valentin Abrutski wrote: >> >> Hi Mark. Thank you for the idea. And appreciate your help. >> >> I tried it. And to be sure that I'm doing it right. I've tried to use >> this approach to get not only IActiveScriptParse, but also IActiveScript >> Still the same issue. I can get IActiveScript. But when try to get >> IActiveScriptParse I get error code: 0x80004002 (E_NOINTERFACE) >> >> I've double checked GUID of IActiveScriptParse which is used in >> QuearyInterface and it looks correct: BB1A2AE2-A4F9-11cf-8F20-00805F2CD064 >> >> I'm thinking about is it possible that the way I registered Python Script >> Engine is not correct? Is it possible that there are different way to do >> that? >> Just to remind you, I just run python pyscript.py >> >> >> On Wed, Jul 31, 2024 at 12:58?AM Mark Hammond >> wrote: >> >>> >>> On 2024-07-30 4:29 p.m., Valentin Abrutski wrote: >>> >>> Hi Mark. >>> >>> I double checked what I did with my previous attempt. And still can't >>> get success. Probably you can give me an idea of what I'm doing wrong. >>> >>> I am working on an application(.Net) which provides scripting >>> capabilities via AcriveScript Engine. With the ability to debug script step >>> by step and etc. And we provide a standard set of languages VBScript and >>> JScript. And now we want to provide Python support. >>> >>> Obviously I need to add a new ActiveScript Engine for Python. to system >>> >>> What I did. I installed python and installed the pywin32 package. >>> Then I found this script >>> Python311\Lib\site-packages\win32comext\axscript\client\pyscript.py and run >>> it : >>> python pyscript.py >>> >>> Requesting elevation and retrying... >>> Registered: Python >>> >>> After that, I go to my application code and do the same we already do >>> for Standard JScript or VBScript engines. >>> For example, import of COM JScript class is defined >>> [ComImport, Guid("F414C260-6AC0-11CF-B6D1-00AA00BBBB58")] >>> public class JScript >>> { >>> } >>> >>> So I defined import class for Python using GUID from python class >>> implementation >>> [ComImport, Guid("DF630910-1C1D-11d0-AE36-8C0F5E000000")] >>> public class PythonScript >>> { >>> } >>> >>> Then my expectation is that I can cast it to IAcriveScript and >>> IActiveScripParse (like I do with standard languages) >>> _engine = new PythonScript(); >>> _iap = _engine as IActiveScriptParse; >>> _ias = _engine as IActiveScript; >>> >>> But IActiveScriptParse still is null, IActiveScript - is good. >>> I suppose that probably I did initialization in wrong way? or something >>> like that? >>> >>> My best guess is that the "as" isn't working due to a lack of a typelib >>> for the engine - but a QueryInterface(IID_IActiveScriptParse) on the >>> IActiveScript interface should work. >>> >>> HTH, >>> >>> Mark >>> >>> >>> >>> >>> >>> On Tue, Jul 30, 2024 at 10:54?PM Valentin Abrutski >>> wrote: >>> >>>> Hi Mark >>>> >>>> Appreciate for fast response. I will look into it. Thank you. >>>> >>>> >>>> On Tue, Jul 30, 2024 at 5:56?PM Mark Hammond >>>> wrote: >>>> >>>>> IActiveScriptParse is supported - check out the >>>>> com/win32comext/axscript directory. >>>>> >>>>> Cheers, >>>>> >>>>> Mark >>>>> On 2024-07-30 10:14 a.m., Valentin Abrutski wrote: >>>>> >>>>> Hello all, >>>>> >>>>> Hopefully somebody can help me. >>>>> >>>>> Microsoft provides implementations for Microsoft Scripting Engine - >>>>> VbScript and JScript. >>>>> I need to add Python Script Engine support. I see that pywin32 already >>>>> has a component for that(COM object). But it exposes only the IActiveScript >>>>> interface. For my needs I also need IActiveScriptParse interface. >>>>> >>>>> please advise me if pywin32 implements it also and I just missed >>>>> something? or if you have an idea what to do to get.. I will appreciate for >>>>> your help. >>>>> >>>>> _______________________________________________ >>>>> python-win32 mailing listpython-win32 at python.orghttps://mail.python.org/mailman/listinfo/python-win32 >>>>> >>>>> >> _______________________________________________ >> python-win32 mailing listpython-win32 at python.orghttps://mail.python.org/mailman/listinfo/python-win32 >> >> -------------- next part -------------- An HTML attachment was scrubbed... URL: From va at zaptest.com Thu Aug 1 16:37:46 2024 From: va at zaptest.com (Valentin Abrutski) Date: Thu, 1 Aug 2024 23:37:46 +0300 Subject: [python-win32] Python Windows Scripting Engine In-Reply-To: References: <8e658085-c118-4ccb-a667-3772b1eeb1a1@skippinet.com.au> <3aa8c2a7-ae04-407c-9a84-9927a3b5fcf1@skippinet.com.au> Message-ID: Hello Mark. Sorry for bothering you again. I got another issue. When I call IActiveScript method: SetScriptSite(IActiveScriptSite site) I got invalid cast exception. Mostprobably it means that IActiveScriptSite can't be properly passed as argument to SetScriptSite. My assumption that my definition of IActiveScriptSite is different from one is used in py2in32 library. I could find usages of IActiveScriptSite interface in the source code of the library. But I can't find definition of this interface. Can you advise me where I can find it? On Thu, Aug 1, 2024 at 4:19?PM Valentin Abrutski wrote: > Hi Mark, just to let you know. I found the root cause. I was trying to get > 32bit version of interface and pywin32 export 64bit version(different GUID > and slightly different function signature) > > Thank you for your help. > > On Wed, Jul 31, 2024 at 5:08?PM Valentin Abrutski wrote: > >> Thank you Mark. I will try that. Appreciate >> >> ??, 31 ???. 2024??., 17:01 Mark Hammond : >> >>> Sorry, I can't explain that - running pyscript.py should register things >>> and support for IActiveScriptParse is unconditional. You could try running >>> `pyscript.py --debug` which might print some debug stuff, or even add print >>> statements to client.py's QueryInterface function to make sure it's >>> actually being called. Also, executing >>> win32comext/axscript/test/testHost.py should try and exercise the engine. >>> >>> HTH, >>> >>> Mark >>> On 2024-07-31 9:14 a.m., Valentin Abrutski wrote: >>> >>> Hi Mark. Thank you for the idea. And appreciate your help. >>> >>> I tried it. And to be sure that I'm doing it right. I've tried to use >>> this approach to get not only IActiveScriptParse, but also IActiveScript >>> Still the same issue. I can get IActiveScript. But when try to get >>> IActiveScriptParse I get error code: 0x80004002 (E_NOINTERFACE) >>> >>> I've double checked GUID of IActiveScriptParse which is used in >>> QuearyInterface and it looks correct: BB1A2AE2-A4F9-11cf-8F20-00805F2CD064 >>> >>> I'm thinking about is it possible that the way I registered Python >>> Script Engine is not correct? Is it possible that there are different way >>> to do that? >>> Just to remind you, I just run python pyscript.py >>> >>> >>> On Wed, Jul 31, 2024 at 12:58?AM Mark Hammond >>> wrote: >>> >>>> >>>> On 2024-07-30 4:29 p.m., Valentin Abrutski wrote: >>>> >>>> Hi Mark. >>>> >>>> I double checked what I did with my previous attempt. And still can't >>>> get success. Probably you can give me an idea of what I'm doing wrong. >>>> >>>> I am working on an application(.Net) which provides scripting >>>> capabilities via AcriveScript Engine. With the ability to debug script step >>>> by step and etc. And we provide a standard set of languages VBScript and >>>> JScript. And now we want to provide Python support. >>>> >>>> Obviously I need to add a new ActiveScript Engine for Python. to system >>>> >>>> What I did. I installed python and installed the pywin32 package. >>>> Then I found this script >>>> Python311\Lib\site-packages\win32comext\axscript\client\pyscript.py and run >>>> it : >>>> python pyscript.py >>>> >>>> Requesting elevation and retrying... >>>> Registered: Python >>>> >>>> After that, I go to my application code and do the same we already do >>>> for Standard JScript or VBScript engines. >>>> For example, import of COM JScript class is defined >>>> [ComImport, Guid("F414C260-6AC0-11CF-B6D1-00AA00BBBB58")] >>>> public class JScript >>>> { >>>> } >>>> >>>> So I defined import class for Python using GUID from python class >>>> implementation >>>> [ComImport, Guid("DF630910-1C1D-11d0-AE36-8C0F5E000000")] >>>> public class PythonScript >>>> { >>>> } >>>> >>>> Then my expectation is that I can cast it to IAcriveScript and >>>> IActiveScripParse (like I do with standard languages) >>>> _engine = new PythonScript(); >>>> _iap = _engine as IActiveScriptParse; >>>> _ias = _engine as IActiveScript; >>>> >>>> But IActiveScriptParse still is null, IActiveScript - is good. >>>> I suppose that probably I did initialization in wrong way? or something >>>> like that? >>>> >>>> My best guess is that the "as" isn't working due to a lack of a typelib >>>> for the engine - but a QueryInterface(IID_IActiveScriptParse) on the >>>> IActiveScript interface should work. >>>> >>>> HTH, >>>> >>>> Mark >>>> >>>> >>>> >>>> >>>> >>>> On Tue, Jul 30, 2024 at 10:54?PM Valentin Abrutski >>>> wrote: >>>> >>>>> Hi Mark >>>>> >>>>> Appreciate for fast response. I will look into it. Thank you. >>>>> >>>>> >>>>> On Tue, Jul 30, 2024 at 5:56?PM Mark Hammond < >>>>> mhammond at skippinet.com.au> wrote: >>>>> >>>>>> IActiveScriptParse is supported - check out the >>>>>> com/win32comext/axscript directory. >>>>>> >>>>>> Cheers, >>>>>> >>>>>> Mark >>>>>> On 2024-07-30 10:14 a.m., Valentin Abrutski wrote: >>>>>> >>>>>> Hello all, >>>>>> >>>>>> Hopefully somebody can help me. >>>>>> >>>>>> Microsoft provides implementations for Microsoft Scripting Engine - >>>>>> VbScript and JScript. >>>>>> I need to add Python Script Engine support. I see that pywin32 >>>>>> already has a component for that(COM object). But it exposes only the >>>>>> IActiveScript interface. For my needs I also need IActiveScriptParse >>>>>> interface. >>>>>> >>>>>> please advise me if pywin32 implements it also and I just missed >>>>>> something? or if you have an idea what to do to get.. I will appreciate for >>>>>> your help. >>>>>> >>>>>> _______________________________________________ >>>>>> python-win32 mailing listpython-win32 at python.orghttps://mail.python.org/mailman/listinfo/python-win32 >>>>>> >>>>>> >>> _______________________________________________ >>> python-win32 mailing listpython-win32 at python.orghttps://mail.python.org/mailman/listinfo/python-win32 >>> >>> -------------- next part -------------- An HTML attachment was scrubbed... URL: From mhammond at skippinet.com.au Thu Aug 1 17:21:10 2024 From: mhammond at skippinet.com.au (Mark Hammond) Date: Thu, 1 Aug 2024 17:21:10 -0400 Subject: [python-win32] Python Windows Scripting Engine In-Reply-To: References: <8e658085-c118-4ccb-a667-3772b1eeb1a1@skippinet.com.au> <3aa8c2a7-ae04-407c-9a84-9927a3b5fcf1@skippinet.com.au> Message-ID: On 2024-08-01 4:37 p.m., Valentin Abrutski wrote: > Hello Mark. > > Sorry for bothering you again. I got another issue. When I call > IActiveScript method: SetScriptSite(IActiveScriptSite site) > I got invalid cast exception. Mostprobably it means that > IActiveScriptSite? can't be properly passed as argument to > SetScriptSite.? ?My assumption that? my definition of > IActiveScriptSite? is different from one is used in py2in32 library. > I could find usages of? ?IActiveScriptSite? ?interface in the source > code of the library. But I can't find definition?of this interface. I'm not sure what you are asking. IActiveScriptSite is documented at https://learn.microsoft.com/en-us/dotnet/api/microsoft.visualstudio.debugger.interop.iactivescriptsite?view=visualstudiosdk-2019 and IActiveScript at https://learn.microsoft.com/en-us/dotnet/api/microsoft.visualstudio.debugger.interop.iactivescript?view=visualstudiosdk-2019. The c++ "receiver" of this call for pywin32 is at https://github.com/mhammond/pywin32/blob/main/com/win32comext/axscript/src/PyGActiveScript.cpp#L5 Mark > Can you advise me where I can find it? > > On Thu, Aug 1, 2024 at 4:19?PM Valentin Abrutski wrote: > > Hi Mark, just to let you know. I found the root cause. I was > trying to get 32bit version of interface and pywin32 export 64bit > version(different GUID and slightly different function signature) > > Thank you for your help. > > On Wed, Jul 31, 2024 at 5:08?PM Valentin Abrutski > wrote: > > Thank you Mark. I will try that. Appreciate > > ??, 31 ???. 2024??., 17:01 Mark Hammond > : > > Sorry, I can't explain that - running pyscript.py should > register things and support for IActiveScriptParse is > unconditional. You could try running `pyscript.py --debug` > which might print some debug stuff, or even add print > statements to client.py's QueryInterface function to make > sure it's actually being called. Also, executing > win32comext/axscript/test/testHost.py should try and > exercise the engine. > > HTH, > > Mark > > On 2024-07-31 9:14 a.m., Valentin Abrutski wrote: >> Hi Mark. Thank you for the idea. And appreciate?your help. >> >> I tried it. And to be sure that I'm doing it right. I've >> tried to use this approach to get not only >> IActiveScriptParse, but also IActiveScript >> Still the same issue. I can get IActiveScript. But when >> try to get IActiveScriptParse I get error?code: >> |0x80004002|?(|E_NOINTERFACE|) >> >> I've double checked GUID of IActiveScriptParse which is >> used in QuearyInterface?and it looks >> correct:??BB1A2AE2-A4F9-11cf-8F20-00805F2CD064 >> >> I'm thinking about is it possible that the way I >> registered Python Script Engine is not correct? Is it >> possible?that there are different way to do that? >> Just to remind you, I just run python pyscript.py >> >> >> On Wed, Jul 31, 2024 at 12:58?AM Mark Hammond >> wrote: >> >> >> On 2024-07-30 4:29 p.m., Valentin Abrutski wrote: >>> Hi Mark. >>> >>> I double checked what I did with my previous >>> attempt. And still can't get success. Probably?you >>> can give me an idea of what I'm doing wrong. >>> >>> I am working on an application(.Net) which provides >>> scripting capabilities via AcriveScript Engine. With >>> the ability to debug script step by step and etc. >>> And we provide a standard set of languages VBScript >>> and JScript. And now we want to provide Python support. >>> >>> Obviously I need to add a new ActiveScript Engine >>> for Python. to system >>> >>> What I did. I installed python?and installed the >>> pywin32 package. >>> Then I found this script >>> Python311\Lib\site-packages\win32comext\axscript\client\pyscript.py >>> and run it : >>> python pyscript.py >>> Requesting elevation and retrying... >>> Registered: Python >>> >>> After that,?I go to my application code and do the >>> same we already do for Standard JScript or VBScript >>> engines. >>> For example, import of COM JScript class? is defined >>> [ComImport, >>> Guid("F414C260-6AC0-11CF-B6D1-00AA00BBBB58")] >>> ? ? public class JScript >>> ? ? { >>> ? ? } >>> >>> So I defined import class for Python using GUID from >>> python class implementation >>> [ComImport, >>> Guid("DF630910-1C1D-11d0-AE36-8C0F5E000000")] >>> ? ? public class PythonScript >>> ? ? { >>> ? ? } >>> >>> Then my expectation is that I can cast it to >>> IAcriveScript and IActiveScripParse (like I do with >>> standard languages) >>> ? ? _engine = new PythonScript(); >>> ? ? _iap = _engine as IActiveScriptParse; >>> ? ? _ias = _engine as IActiveScript; >>> >>> But?IActiveScriptParse still is null,?IActiveScript >>> - is good. >>> I suppose that probably I did initialization in >>> wrong way? or something like that? >> >> My best guess is that the "as" isn't working due to a >> lack of a typelib for the engine - but a >> QueryInterface(IID_IActiveScriptParse) on the >> IActiveScript interface should work. >> >> HTH, >> >> Mark >> >> >>> >>> >>> >>> On Tue, Jul 30, 2024 at 10:54?PM Valentin Abrutski >>> wrote: >>> >>> Hi Mark >>> >>> Appreciate for fast response. I will look into >>> it. Thank you. >>> >>> >>> On Tue, Jul 30, 2024 at 5:56?PM Mark Hammond >>> wrote: >>> >>> IActiveScriptParse is supported - check out >>> the com/win32comext/axscript directory. >>> >>> Cheers, >>> >>> Mark >>> >>> On 2024-07-30 10:14 a.m., Valentin Abrutski >>> wrote: >>>> Hello all, >>>> >>>> Hopefully somebody can help me. >>>> >>>> Microsoft provides implementations for >>>> Microsoft Scripting Engine - VbScript and >>>> JScript. >>>> I need to add Python Script Engine support. >>>> I see that pywin32 already has a component >>>> for that(COM object). But it exposes only >>>> the IActiveScript interface. For my needs I >>>> also need IActiveScriptParse interface. >>>> >>>> please advise me if pywin32 implements it >>>> also and I just missed something? or if you >>>> have an idea what to do to get.. I will >>>> appreciate for your help. >>>> >>>> _______________________________________________ >>>> python-win32 mailing list >>>> python-win32 at python.org >>>> https://mail.python.org/mailman/listinfo/python-win32 >>> >> >> _______________________________________________ >> python-win32 mailing list >> python-win32 at python.org >> https://mail.python.org/mailman/listinfo/python-win32 > -------------- next part -------------- An HTML attachment was scrubbed... URL: From mhammond at skippinet.com.au Mon Aug 26 16:20:06 2024 From: mhammond at skippinet.com.au (Mark Hammond) Date: Mon, 26 Aug 2024 16:20:06 -0400 Subject: [python-win32] Dispatch vs EnsureDispatch performance In-Reply-To: References: Message-ID: On 2024-07-17 10:30 a.m., Sven Bardos via python-win32 wrote: > Hi Mark, > > I found some time to debug and profile my issue a little bit more. > In my scenario I call a COM method which returns a list of 14195 > integers plus the amount of the found objects. > > If I profile that call I get the following: > > ncalls ?tottime ?percall ?cumtime ?percall filename:lineno(function) > ... > 1 ? ?0.000 ? ?0.000 ? ?0.025 ? ?0.025 __init__.py:572(_ApplyTypes_) > 1 ? ?0.000 ? ?0.000 ? ?0.007 ? ?0.007 __init__.py:603(_get_good_object_) > 14195 ? ?0.001 ? ?0.000 ? ?0.001 ? ?0.000 > __init__.py:608(_get_good_single_object_) > 14198/1 ? ?0.005 ? ?0.000 ? ?0.007 ? ?0.007 > __init__.py:614(_get_good_object_) > ... > > So _get_good_object_ is called ~14200 times. > If I do that in a loop 100x, I get an execution time of ~3.3s > > If I change the code in the _ApplyTypes_ function to: > > def _ApplyTypes_(self, dispid, wFlags, retType, argTypes, user, > resultCLSID, *args): > return self._oleobj_.InvokeTypes(dispid, 0, wFlags, retType, argTypes, > *args) > # return self._get_good_object_( > # ? ? self._oleobj_.InvokeTypes(dispid, 0, wFlags, retType, argTypes, > *args), > # ? ? user, > # ? ? resultCLSID, > # ) > > that is, avoiding the _get_good_object_() calls, the execution time is > ~1.6s for 100 iterations. Which is ~50% of the original time. The > result is the same, in this case. I'm certainly up for looking at optimizations to how this works, but I don't think it's as simple as not calling the function - there are cases where it would return different objects. I don't think an instance method is needed (ie, maybe we could just call the final implementation and maybe even inline some of those calls, but if you say the result is identical, it looks a little like there are just 2 isinstance() calls which return False in this scenario, so maybe this might also offer optimization ideas (eg, if the type in question for your examples are builtin types like int/string/etc, maybe these could be checked before making any other calls?). HTH, Mark > > Do you have any thoughts on this? > > Best regards, > Sven > > Am Mi., 17. Apr. 2024 um 17:19?Uhr schrieb Mark Hammond > : > > I'm mildly surprised by that - a profiler might show some > low-hanging fruit, and/or might show different characteristics > when many more functions are used. However, the primary reason for > EnsureDispatch is for better support of the object model - there's > far more context available and this less chance of upsetting some > COM objects - eg, when `foo.bar` is seen, EnsureDispatch knows for > sure that `bar` is a method, but dynamic dispatch doesn't know if > the resulting object is going to be called or not. > > HTH, > > Mark > > On 2024-04-17 2:07 a.m., Sven Bardos via python-win32 wrote: >> Hi, >> >> shouldn't be EnsureDispatch be faster than Dispatch once the code >> generation is done? >> >> I've measured it by calling 6000 COM calls like this: >> >> dirpath = Path('C:/Users/sbardos/AppData/Local/Temp/gen_py/3.10/') >> if dirpath.exists() and dirpath.is_dir(): >> shutil.rmtree(dirpath) >> >> app = Dispatch("CT.Application") >> job = app.CreateJobObject() >> >> start = timer() >> >> for i in range(2000): >> cnt, devIds = job.GetAllDeviceIds() >> cnt, sheetIds = job.GetSheetIds() >> dev = job.CreateDeviceObject() >> >> end = timer() >> print(f"Time ellapsed (late): {end - start}s") >> and the ensure Dispatch version: >> app = EnsureDispatch("CT.Application") >> job = app.CreateJobObject() >> start = timer() >> for i in range(2000): >> cnt, devIds = job.GetAllDeviceIds(None) >> cnt, sheetIds = job.GetSheetIds(None) >> dev = job.CreateDeviceObject() >> end = timer() >> print(f"Time ellapsed (early): {end - start}s") >> EnsureDispatch is a little bit slower ~4.2s compared to ~4.0s. >> If I don't get a performance boost with EnsureDispatch, is there >> even a point using it? >> >> Thanks, >> Sven >> >> _______________________________________________ >> python-win32 mailing list >> python-win32 at python.org >> https://mail.python.org/mailman/listinfo/python-win32 > > > _______________________________________________ > python-win32 mailing list > python-win32 at python.org > https://mail.python.org/mailman/listinfo/python-win32 -------------- next part -------------- An HTML attachment was scrubbed... URL: