From fpallanti at develer.com Thu Mar 1 15:11:20 2012 From: fpallanti at develer.com (Francesco Pallanti) Date: Thu, 01 Mar 2012 15:11:20 +0100 Subject: [python-win32] EuroPython 2012: Call for Proposal is Open! [Please spread the word] Message-ID: <1330611080.15056.19.camel@bmlab-palla> Hi guys, I'm Francesco and I am writing on behalf of EuroPython Staff (www.europython.eu). We are happy to announce that the Call for Proposals is now officially open! DEADLINE FOR PROPOSALS: MARCH 18TH, 23:59:59 CET For those who have never been at EuroPython (or similar conferences) before, the Call for Proposals is the period in which the organizers ask the community to submit proposals for talks to be held at the conference. Further details about Call for Proposal are online here: http://ep2012.europython.eu/call-for-proposals/ EuroPython is a conference run by the community for the community: the vast majority of talks that are presented at the conference will be proposed, prepared and given by members of the Python community itself. And not only that: the process that selects the best talks among all the proposals will also be public and fully driven by the community: it's called Community Voting, and will begin right after the Call for Proposals ends. CFP: Talks, Hands-On Trainings and Posters ------------------------------------------ We're looking for proposals on every aspect of Python: programming from novice to advanced levels, applications and frameworks, or how you have been involved in introducing Python into your organisation. There are three different kind of contribution that you can present at EuroPython: - Regular talk. These are standard "talk with slides", allocated in slots of 45, 60 or 90 minutes, depending on your preference and scheduling constraints. A Q&A session is held at the end of the talk. - Hands-on training. These are advanced training sessions for a smaller audience (10-20 people), to dive into the subject with all details. These sessions are 4-hours long, and the audience will be strongly encouraged to bring a laptop to experiment. They should be prepared with less slides and more source code. - Posters. Posters are a graphical way to describe a project or a technology, printed in large format; posters are exhibited at the conference, can be read at any time by participants, and can be discussed face to face with their authors during the poster session. We will take care of printing the posters too, so don't worry about logistics. More details about Call for Proposal are online here: http://ep2012.europython.eu/call-for-proposals/ Don't wait for the last day --------------------------- If possible, please avoid submitting your proposals on the last day. It might sound a strange request, but last year about 80% of the proposals were submitted in the last 72 hours. This creates a few problems for organizers because we can't have a good picture of the size of the conference until that day. Remember that proposals are fully editable at any time, even after the Call for Proposals ends. You just need to login on the website, go to the proposal page (linked from your profile page), and click the Edit button. First-time speakers are especially welcome; EuroPython is a community conference and we are eager to hear about your experience. If you have friends or colleagues who have something valuable to contribute, twist their arms to tell us about it! We are a conference run by the community for the community. Please help to spread the word by distributing this announcement to colleagues, mailing lists, your blog, Web site, and through your social networking connections. All the best, -- Francesco Pallanti - fpallanti at develer.com Develer S.r.l. - http://www.develer.com/ .software .hardware .innovation Tel.: +39 055 3984627 - ext.: 215 From le.dahut at laposte.net Fri Mar 2 11:38:27 2012 From: le.dahut at laposte.net (le dahut) Date: Fri, 02 Mar 2012 11:38:27 +0100 Subject: [python-win32] Seven 64bits and system32/syswow64 paths Message-ID: <4F50A323.8060304@laposte.net> Hi. On a Windows Seven 64bits host with 32bits version of python installed. In a MSDOS prompt I run : nbtstat -R command runs well. In a python prompt I run : import os os.system('nbtstat -R') I get : "nbtstat is not recognized as an internal or external command" Using explorer I've found "nbtstat.exe" in C:\Windows\System32. In a MSDOS prompt : dir C:\Windows\System32\nbtstat.exe finds the file. In a python prompt : os.system('dir C:\\Windows\\System32\\nbtstat.exe') returns "File not found". It seems that : * in MSDOS prompt C:\?indows\System32 and C:\?indows\SysWOW64 are two separate dirs with different content * in a python prompt C:\?indows\System32 = C:\?indows\SysWOW64 (same content) Any idea ? I want an .exe that runs on both 32 and 64 bits systems. I don't want to build separate exes. That's why I work with 32bits version of python on a 64bits host. If someone has any comment about this, he's welcome. Regards. K. From le.dahut at laposte.net Fri Mar 2 13:42:33 2012 From: le.dahut at laposte.net (le dahut) Date: Fri, 02 Mar 2012 13:42:33 +0100 Subject: [python-win32] Seven 64bits and system32/syswow64 paths In-Reply-To: <4F50A323.8060304@laposte.net> References: <4F50A323.8060304@laposte.net> Message-ID: <4F50C039.5010608@laposte.net> Sorry, I thought it was related to python but actually not : http://msdn.microsoft.com/en-us/library/aa384187%28v=vs.85%29.aspx On 03/02/2012 11:38, le dahut wrote : > Hi. > > On a Windows Seven 64bits host with 32bits version of python installed. > > In a MSDOS prompt I run : > nbtstat -R > command runs well. > > In a python prompt I run : > import os > os.system('nbtstat -R') > I get : > "nbtstat is not recognized as an internal or external command" > > > Using explorer I've found "nbtstat.exe" in C:\Windows\System32. > > In a MSDOS prompt : > dir C:\Windows\System32\nbtstat.exe > finds the file. > > In a python prompt : > os.system('dir C:\\Windows\\System32\\nbtstat.exe') > returns "File not found". > > It seems that : > * in MSDOS prompt C:\?indows\System32 and C:\?indows\SysWOW64 are two > separate dirs with different content > * in a python prompt C:\?indows\System32 = C:\?indows\SysWOW64 (same > content) > > Any idea ? > > > I want an .exe that runs on both 32 and 64 bits systems. I don't want to > build separate exes. That's why I work with 32bits version of python on > a 64bits host. > If someone has any comment about this, he's welcome. > From timr at probo.com Fri Mar 2 18:34:12 2012 From: timr at probo.com (Tim Roberts) Date: Fri, 2 Mar 2012 09:34:12 -0800 Subject: [python-win32] Seven 64bits and system32/syswow64 paths In-Reply-To: <4F50A323.8060304@laposte.net> References: <4F50A323.8060304@laposte.net> Message-ID: <4F510494.20007@probo.com> le dahut wrote: > Using explorer I've found "nbtstat.exe" in C:\Windows\System32. > > In a MSDOS prompt : > dir C:\Windows\System32\nbtstat.exe > finds the file. > > In a python prompt : > os.system('dir C:\\Windows\\System32\\nbtstat.exe') > returns "File not found". > > It seems that : > * in MSDOS prompt C:\?indows\System32 and C:\?indows\SysWOW64 are two > separate dirs with different content > * in a python prompt C:\?indows\System32 = C:\?indows\SysWOW64 (same > content) And you are exactly right. > Any idea ? This is a very confusing point, so even though it's not directly Python-related, I think it's still valuable to discuss it again. As you discovered, Windows is helping you. For reasons that have never been adequately explained to me (and believe me, I have asked people who ought to know), on a 64-bit system, all of the 64-bit commands and DLLs live in \Windows\System32. All of the 32-bit commands and DLLs live in \Windows\SysWOW64. A 64-bit process gets to see both of those directories as they really are. But for a 32-bit process, the operating system "helpfully" rewrites your paths. When you refer to \Windows\System32, the system helpfully rewrites that reference to \Windows\SysWOW64. Microsoft calls it file system redirection". I call it "file system stupidity". Most of the time, that's OK. Most of the important commands are present in both directories. A few (like nbtstat) are not, and that's a problem. There are two solutions. One is to use 64-bit Python, which you have said is a problem for you. The other is to use an API with the tongue-twisting name Wow64DisableWow64FsRedirection. Here is my script: import ctypes k32 = ctypes.windll.kernel32 wow64 = ctypes.c_long( 0 ) k32.Wow64DisableWow64FsRedirection( ctypes.byref(wow64) ) # ... do stuff with real files ... k32.Wow64RevertWow64FsRedirection( wow64 ) -- Tim Roberts, timr at probo.com Providenza & Boekelheide, Inc. From karbonforms at gmail.com Fri Mar 2 19:03:14 2012 From: karbonforms at gmail.com (Chris Ness) Date: Fri, 02 Mar 2012 18:03:14 +0000 Subject: [python-win32] Context menu troubles Message-ID: <4F510B62.1050709@gmail.com> disclaimer: I have only the faintest idea what I'm doing! I'm trying to get a windows explorer context menu in my app. I can get the menu to show, but it does not execute any commands (e.g. 'copy') my code is based on http://bcbjournal.org/articles/vol4/0006/Using_the_shell_context_menu.htm and partly on http://netez.com/2xExplorer/shellFAQ/bas_context.html I'm new to both win32 and pywin32. Any help or advice will be readily accepted! Cheers! Chris. DesktopFolder = shell.SHGetDesktopFolder() if not DesktopFolder: raise Exception("Failed to get Desktop folder.") # Get a pidl for the folder the file # is located in. FilePath = 'J:\\' FileName = 'tree.xml' Eaten, ParentPidl, attr = DesktopFolder.ParseDisplayName(Handle, None, FilePath) # Get an IShellFolder for the folder # the file is located in. ParentFolder = DesktopFolder.BindToObject(ParentPidl, None, shell.IID_IShellFolder) CM_plus = None # Get a pidl for the file itself. Eaten, Pidl, attr = ParentFolder.ParseDisplayName(Handle, None, FileName) # Get the IContextMenu for the file. i, CM = ParentFolder.GetUIObjectOf(Handle, [Pidl], shell.IID_IContextMenu, 0) #else: # Get the IContextMenu for the folder. ???????? #i, CM = ParentFolder.GetUIObjectOf(Handle, [ParentPidl], shell.IID_IContextMenu, 0) if not CM: raise Exception("Unable to get context menu interface.") else: # try to obtain a higher level pointer, first 3 then 2 try: CM_plus = CM.QueryInterface(shell.IID_IContextMenu3, None) pcmType = 3 except Exception: try: CM_plus = CM.QueryInterface(shell.IID_IContextMenu2, None) pcmType = 2 except Exception: pass if CM_plus: CM.Release() # free initial "v1.0" interface CM = CM_plus else: # no higher version supported pcmType = 1 hMenu = win32gui.CreatePopupMenu() Flags = CMF_EXPLORE # Optionally the shell will show the extended # context menu on some operating systems when # the shift key is held down at the time the # context menu is invoked. The following is # commented out but you can uncommnent this # line to show the extended context menu. # Flags |= 0x00000080; CM.QueryContextMenu(hMenu, 0, 1, 0x7FFF, Flags) # Show the menu. x, y = win32gui.GetCursorPos() flags = ( win32gui.TPM_LEFTALIGN | win32gui.TPM_LEFTBUTTON | win32gui.TPM_RIGHTBUTTON #| win32gui.TPM_RETURNCMD, ) hr = win32gui.TrackPopupMenu(hMenu, flags, x, y, 0, Handle, None) if hr != 1: e = win32api.GetLastError() s = win32api.FormatMessage(e) From timr at probo.com Fri Mar 2 19:42:32 2012 From: timr at probo.com (Tim Roberts) Date: Fri, 2 Mar 2012 10:42:32 -0800 Subject: [python-win32] Context menu troubles In-Reply-To: <4F510B62.1050709@gmail.com> References: <4F510B62.1050709@gmail.com> Message-ID: <4F511498.60404@probo.com> Chris Ness wrote: > disclaimer: I have only the faintest idea what I'm doing! > > I'm trying to get a windows explorer context menu in my app. I can get > the menu to show, but it does not execute any commands (e.g. 'copy') Right, because you haven't told it to. You implemented the stuff form the articles pretty closely until the call to TrackPopupMenu, then you went awry. TrackPopupMenu does not actually return a boolean. It returns 0 if the call fails, but if the call succeeds, it returns the command ID of the menu item that was selected, and you have to tell the shell to go invoke that command. So, if it returns a value other than 0, you need to create a CMINVOKECOMMANDINFO structure, fill it in, and pass it to CM.InvokeCommand. That will trigger the real action. -- Tim Roberts, timr at probo.com Providenza & Boekelheide, Inc. From karbonforms at gmail.com Fri Mar 2 20:03:27 2012 From: karbonforms at gmail.com (Chris Ness) Date: Fri, 02 Mar 2012 19:03:27 +0000 Subject: [python-win32] Context menu troubles In-Reply-To: <4F511498.60404@probo.com> References: <4F510B62.1050709@gmail.com> <4F511498.60404@probo.com> Message-ID: <4F51197F.3030305@gmail.com> Thanks for reply Tim. I had decided not to use the command ID technique until I got things working, so TPM_RETURNCMD was commented out when I defines flags. From my understanding of MSDN and pywin32, this should make commands immediately execute and cause TrackPopupMenu to return an HRESULT? Also forgot to mention, using python3.2 32bit, pywon32 build 217 on windows 7 I've simplified/condensed it a bit, stripped comments and changed TrackPopupMenu return variable to something more appropriate. Chris. DesktopFolder = shell.SHGetDesktopFolder() if not DesktopFolder: raise Exception("Failed to get Desktop folder.") FilePath = 'J:\\' FileName = 'tree.xml' Eaten, ParentPidl, attr = DesktopFolder.ParseDisplayName(Handle, None, FilePath) ParentFolder = DesktopFolder.BindToObject(ParentPidl, None, shell.IID_IShellFolder) CM_plus = None Eaten, Pidl, attr = ParentFolder.ParseDisplayName(Handle, None, FileName) i, CM = ParentFolder.GetUIObjectOf(Handle, [Pidl], shell.IID_IContextMenu, 0) hMenu = win32gui.CreatePopupMenu() Flags = CMF_EXPLORE CM.QueryContextMenu(hMenu, 0, 1, 0x7FFF, Flags) x, y = win32gui.GetCursorPos() flags = win32gui.TPM_LEFTALIGN hr = win32gui.TrackPopupMenu(hMenu, flags, x, y, 0, Handle, None) if hr != 1: e = win32api.GetLastError() s = win32api.FormatMessage(e) #<-------- "command completed successfully" On 02/03/2012 18:42, Tim Roberts wrote: > Chris Ness wrote: >> disclaimer: I have only the faintest idea what I'm doing! >> >> I'm trying to get a windows explorer context menu in my app. I can get >> the menu to show, but it does not execute any commands (e.g. 'copy') > Right, because you haven't told it to. You implemented the stuff form > the articles pretty closely until the call to TrackPopupMenu, then you > went awry. TrackPopupMenu does not actually return a boolean. It > returns 0 if the call fails, but if the call succeeds, it returns the > command ID of the menu item that was selected, and you have to tell the > shell to go invoke that command. > > So, if it returns a value other than 0, you need to create a > CMINVOKECOMMANDINFO structure, fill it in, and pass it to > CM.InvokeCommand. That will trigger the real action. > From karbonforms at gmail.com Fri Mar 2 20:09:08 2012 From: karbonforms at gmail.com (Chris Ness) Date: Fri, 02 Mar 2012 19:09:08 +0000 Subject: [python-win32] Context menu troubles In-Reply-To: <4F511498.60404@probo.com> References: <4F510B62.1050709@gmail.com> <4F511498.60404@probo.com> Message-ID: <4F511AD4.2000506@gmail.com> Also, the first article mentions OleInitialise(), which I tried but pythoncom.OleInitialise() does not exist in the module (AttributeError), despite what the docs say? Chris. From timr at probo.com Fri Mar 2 21:16:41 2012 From: timr at probo.com (Tim Roberts) Date: Fri, 2 Mar 2012 12:16:41 -0800 Subject: [python-win32] Context menu troubles In-Reply-To: <4F51197F.3030305@gmail.com> References: <4F510B62.1050709@gmail.com> <4F511498.60404@probo.com> <4F51197F.3030305@gmail.com> Message-ID: <4F512AA9.5080304@probo.com> Chris Ness wrote: > I had decided not to use the command ID technique until I got things > working, so TPM_RETURNCMD was commented out when I defines flags. From > my understanding of MSDN and pywin32, this should make commands > immediately execute and cause TrackPopupMenu to return an HRESULT? Hmm, I should have read the doc more closely before I replied. My fault. I doesn't work quite that automatically. TrackPopupMenu is a general-purpose Windows API -- it doesn't have any connection to or knowledge of Windows Explorer, so it cannot force Explorer to take actions. If you don't specify TPM_RETURNCMD, then the final result of selecting a menu item will be that a WM_COMMAND message sent to your window. Your window doesn't know what to do with those command codes, so nothing useful will happen. In this particular case, I think you HAVE to use TPM_RETURNCMD. -- Tim Roberts, timr at probo.com Providenza & Boekelheide, Inc. From karbonforms at gmail.com Fri Mar 2 22:14:43 2012 From: karbonforms at gmail.com (Chris Ness) Date: Fri, 02 Mar 2012 21:14:43 +0000 Subject: [python-win32] Context menu troubles In-Reply-To: <4F512AA9.5080304@probo.com> References: <4F510B62.1050709@gmail.com> <4F511498.60404@probo.com> <4F51197F.3030305@gmail.com> <4F512AA9.5080304@probo.com> Message-ID: <4F513843.6090902@gmail.com> Aaaaaaaaaaaaaah. It makes sense now. messages and such like. my lack of knowledge of win32 shows. I'll let you know how I get on. Am I right in thinking the win32 api is awfull? Chris. On 02/03/2012 20:16, Tim Roberts wrote: > Chris Ness wrote: >> I had decided not to use the command ID technique until I got things >> working, so TPM_RETURNCMD was commented out when I defines flags. From >> my understanding of MSDN and pywin32, this should make commands >> immediately execute and cause TrackPopupMenu to return an HRESULT? > Hmm, I should have read the doc more closely before I replied. My fault. > > I doesn't work quite that automatically. TrackPopupMenu is a > general-purpose Windows API -- it doesn't have any connection to or > knowledge of Windows Explorer, so it cannot force Explorer to take > actions. If you don't specify TPM_RETURNCMD, then the final result of > selecting a menu item will be that a WM_COMMAND message sent to your > window. Your window doesn't know what to do with those command codes, > so nothing useful will happen. In this particular case, I think you > HAVE to use TPM_RETURNCMD. > From karbonforms at gmail.com Sat Mar 3 12:37:48 2012 From: karbonforms at gmail.com (Chris Ness) Date: Sat, 03 Mar 2012 11:37:48 +0000 Subject: [python-win32] Context menu troubles In-Reply-To: <4F512AA9.5080304@probo.com> References: <4F510B62.1050709@gmail.com> <4F511498.60404@probo.com> <4F51197F.3030305@gmail.com> <4F512AA9.5080304@probo.com> Message-ID: <4F52028C.6050901@gmail.com> On 02/03/2012 20:16, Tim Roberts wrote: > Chris Ness wrote: >> I had decided not to use the command ID technique until I got things >> working, so TPM_RETURNCMD was commented out when I defines flags. From >> my understanding of MSDN and pywin32, this should make commands >> immediately execute and cause TrackPopupMenu to return an HRESULT? > Hmm, I should have read the doc more closely before I replied. My fault. > > I doesn't work quite that automatically. TrackPopupMenu is a > general-purpose Windows API -- it doesn't have any connection to or > knowledge of Windows Explorer, so it cannot force Explorer to take > actions. If you don't specify TPM_RETURNCMD, then the final result of > selecting a menu item will be that a WM_COMMAND message sent to your > window. Your window doesn't know what to do with those command codes, > so nothing useful will happen. In this particular case, I think you > HAVE to use TPM_RETURNCMD. All seems to be working fine now. Thanks Tim. Learning a lot here. Having a spot of bother with the context menu for a drive though (e.g."C:"). I'm getting a very minimal menu with Open, Manage, Include in Library, Copy and Properties. Choosing proprties brings up Control Panel->System. Chris. def getContextMenu(filePath = 'J:', fileName = ''): hwnd = win32gui.GetForegroundWindow() # Get an IShellFolder for the desktop. desktopFolder = shell.SHGetDesktopFolder() if not desktopFolder: raise Exception("Failed to get Desktop folder.") # Get a pidl for the folder the file is located in. eaten, parentPidl, attr = desktopFolder.ParseDisplayName(hwnd, None, filePath) # Get an IShellFolder for the folder the file is located in. parentFolder = desktopFolder.BindToObject(parentPidl, None, shell.IID_IShellFolder) if fileName: # Get a pidl for the file itself. eaten, pidl, attr = parentFolder.ParseDisplayName(hwnd, None, fileName) # Get the IContextMenu for the file. i, contextMenu = parentFolder.GetUIObjectOf(hwnd, [pidl], shell.IID_IContextMenu, 0) else: i, contextMenu = desktopFolder.GetUIObjectOf(hwnd, [parentPidl], shell.IID_IContextMenu, 0) #<----- where i attempt to get menu for a drive. contextMenu_plus = None if contextMenu: # try to obtain a higher level pointer, first 3 then 2 try: contextMenu_plus = contextMenu.QueryInterface(shell.IID_IContextMenu3, None) pcmType = 3 except Exception: try: contextMenu_plus = contextMenu.QueryInterface(shell.IID_IContextMenu2, None) pcmType = 2 except Exception: pass else: raise Exception("Unable to get context menu interface.") if contextMenu_plus: contextMenu.Release() # free initial "v1.0" interface contextMenu = contextMenu_plus else: # no higher version supported pcmType = 1 hMenu = win32gui.CreatePopupMenu() MIN_SHELL_ID = 1 MAX_SHELL_ID = 30000 # Flags |= 0x00000080; #to show the extended context menu. contextMenu.QueryContextMenu(hMenu, 0, MIN_SHELL_ID, MAX_SHELL_ID, CMF_EXPLORE) x, y = win32gui.GetCursorPos() flags = win32gui.TPM_LEFTALIGN | win32gui.TPM_RETURNCMD #| win32gui.TPM_LEFTBUTTON | win32gui.TPM_RIGHTBUTTON cmd = win32gui.TrackPopupMenu(hMenu, flags, x, y, 0, hwnd, None) if not cmd: e = win32api.GetLastError() if e: s = win32api.FormatMessage(e) raise Exception(s) CI = ( 0, #Mask hwnd, #hwnd cmd - MIN_SHELL_ID, #Verb '', #Parameters '', #Directory SW_SHOWNORMAL, #Show 0, #HotKey None #Icon ) contextMenu.InvokeCommand(CI) From skippy.hammond at gmail.com Mon Mar 5 05:18:08 2012 From: skippy.hammond at gmail.com (Mark Hammond) Date: Mon, 05 Mar 2012 15:18:08 +1100 Subject: [python-win32] Help Needed on Handling Events from a Proprietary COM Object In-Reply-To: <1330524102.92155.YahooMailNeo@web160605.mail.bf1.yahoo.com> References: <1330464378.9394.YahooMailNeo@web160603.mail.bf1.yahoo.com> <4F4D5FF9.1080101@gmail.com> <1330524102.92155.YahooMailNeo@web160605.mail.bf1.yahoo.com> Message-ID: <4F543E80.7060708@gmail.com> Sorry for the delay - I'm afraid there isn't anything obvious I can see. However, note that all the IConnection* interfaces are fully exposed in Python - so it should be able to avoid the "WithEvents" type helpers and "port" the code below directly - ie, manually doing the QI for the IConnect* interfaces, etc. You might find win32com/client/connect.py and win32com/demos/connect.py useful as these do the low-level connection-point wrangling so may either be useful directly or as a guide to using them from Python. Cheers, Mark. On 1/03/2012 1:01 AM, Darren McElfresh wrote: > Thanks for your help on this! > > I expect an "event" to make a callback on my event handler. > > I updated my code to not utilize getevents, since I'm using > DispatchWithEvents, and removed my call to MsgWaitForMultipleObjects and > updated the call to PumpWaitingMessages in a loop, to just be > PumpMessages; however it still doesn't seem to work. > > So at this point I basically have: > class Events(): > def OnChange(self, e=defaultNamedNotOptArg): > .... > .... > event_source = view.newItemEventSource( > server.typeForName(server.TypeNames.CHANGEREQUEST) ) > event_monitor = win32com.client.DispatchWithEvents( event_source, Events ) > pythoncom.PumpMessages() > > The C++ code snippets are the following > class CMyListener : > // _StItemSink is the default source (outgoing) dspinterface for > // StItemEventSource objects. > public IDispatchImpl<_IStItemSink, &DIID__IStItemSink, &LIBID_StarTeam>, > public CComObjectRoot > { > public: > CMyListener() {} > BEGIN_COM_MAP(CMyListener) > COM_INTERFACE_ENTRY(IDispatch) > COM_INTERFACE_ENTRY(_IStItemSink) > END_COM_MAP() > .... > // _IStItemSink is a dspinterface. > // We must implement IDispatch::Invoke(). > STDMETHOD(Invoke)( DISPID dispIdMember, > REFIID riid, LCID lcid, > WORD wFlags, > DISPPARAMS FAR* pDispParams, > VARIANT FAR* pVarResult, > EXCEPINFO FAR* pExcepInfo, > unsigned int FAR* puArgErr ) > { > .... > } > .... > // Create the event source for CHANGEREQUEST items. > CComPtr source; > hr = stView->newItemEventSource(type, &source); > if (!VerifyHR(hr, IID_IStView, stView)) { > return(false); > } > > // The event source is the connection point container. > CComPtr cpc; > hr = source->QueryInterface(IID_IConnectionPointContainer, (void**)&cpc); > if (!VerifyHR(hr, IID_IStItemEventSource, source)) { > return(false); > } > > // Find the connection point for Item events. > // We save it so that we can call IConnectionPointContainer::Unadvise() > later. > hr = cpc->FindConnectionPoint(DIID__IStItemSink, &m_cp); > if (!VerifyHR(hr, IID_IConnectionPointContainer, cpc)) { > return(false); > } > > // Instantiate our listener. > CComObject* listener = NULL; > hr = CComObject::CreateInstance(&listener); > if (!VerifyHR(hr)) { > return(false); > } > > // Slip in a pointer to the parent dialog. > listener->m_dlg = this; > > // Connect the listener. > // We save the cookie so that we can call > IConnectionPointContainer::Unadvise() later. > hr = m_cp->Advise(listener, &m_cookie); > if (!VerifyHR(hr, IID_IConnectionPoint, m_cp)) { > return(false); > > Any ideas on what I'm missing? Is it that the object is an Dispatch > Interface, and so I'm not handling that correctly? > > Thanks, > Darren > > > ------------------------------------------------------------------------ > *From:* Mark Hammond > *To:* Darren McElfresh > *Cc:* "python-win32 at python.org" > *Sent:* Tuesday, February 28, 2012 5:15 PM > *Subject:* Re: [python-win32] Help Needed on Handling Events from a > Proprietary COM Object > > On 29/02/2012 8:26 AM, Darren McElfresh wrote: > > I?ve read through numerous posts on how to get this to work, but I?ve > > realized it is time to ask for help. > > In general I have a COM object that returns an event handler: > > /event_source = com_object.newEventSource( arg_data )/ > > I?ve tried establishing the connection points necessary by creating an > > event class derived on the sink co-class of this event source: > > /class Events(win32com.client.getevents(COM_LIB.CLSID)):/ > > I included all of the methods that were mentioned in the generated code > > from makepy.From there I tried to utilize DispatchWithEvents to connect > > the listener: > > /event_monitor = win32com.client.DispatchWithEvents( event_source, > Events )/ > > Using DispatchWithEvents means you shouldn't need to use getevents > manually at all - it does the getevents for you. So just defining your > Events class without a base-class should work - check out the docstring > for DispatchWithEvents. > > > Everything seems fine at this point, but when I use try to listen it > > never seems to fire: > > /rc = win32event.WaitForSingleObject( event_monitor.event, TIME )/ > > What is event_monitor.event? I guess it must be an integer event handle, > but it is worth checking it is sane. Also, that doesn't really make > sense as an event sink - presumably you have referenced the 'event' > attribute before an event has fired, so the actual firing of an event > doesn't seem to need to do anything - it just sets the handle object and > wouldn't need to make a callback into your handler. Generally the firing > of an event will explicitly call a method you supply, but that doesn't > seem to be the case here. > > Even if that was "normal" for your object, you might need > MsgWaitForMultipleObjects - a message loop way well be needed to deliver > the event calls (ie, so the event handler functions can be called). > > > I?ve even tried (even though I don?t think it is necessary for single > > threaded applications): > > /pythoncom.PumpWaitingMessages()/ > > A single threaded application will have to do *something* while it is > waiting for the events to fire, so unless you are in a UI like > pythonwin, you *will* need something like PumpMessages - otherwise your > thread will just terminate. PumpWaitingMessages only pumps what is > queued now - you need PumpMessages to pump "forever" - or until you call > PostQuitMessage to kill the pump, presumably in response to a future event) > > But I'm missing something - either you expect an "event" to set a > Windows event handle (and therefore probably need > MsgWaitForMultipleObjects) or you expect an "event" to make a callback > on your event handler (in which case you need something like > PumpMessages) - but the 2 scenarios are quite different depending on > what is expected to happen. > > > However that didn?t seem to have any impact either.No matter what I try > > ? I can?t get my handlers to fire.I have sample code on how to do this > > in C++, and I have already taken the sample Java code and have my own > > version of that working; however I?d prefer to use Python if I can get > > it to work. > > I can provide my code (or the samples), but it is somewhat lengthy so I > > was hoping someone would see what I was missing right away? > > Maybe you could just provide a summary of the relevant C++ code? > > Mark > > > > > _______________________________________________ > python-win32 mailing list > python-win32 at python.org > http://mail.python.org/mailman/listinfo/python-win32 From skippy.hammond at gmail.com Mon Mar 5 05:19:45 2012 From: skippy.hammond at gmail.com (Mark Hammond) Date: Mon, 05 Mar 2012 15:19:45 +1100 Subject: [python-win32] Context menu troubles In-Reply-To: <4F511AD4.2000506@gmail.com> References: <4F510B62.1050709@gmail.com> <4F511498.60404@probo.com> <4F511AD4.2000506@gmail.com> Message-ID: <4F543EE1.9080706@gmail.com> On 3/03/2012 6:09 AM, Chris Ness wrote: > Also, the first article mentions OleInitialise(), which I tried but > pythoncom.OleInitialise() does not exist in the module (AttributeError), > despite what the docs say? The function is spelt with a "z" rather than the "s": >>> import pythoncom >>> pythoncom.OleInitialize >>> Mark From dmcelfresh at yahoo.com Mon Mar 5 17:06:49 2012 From: dmcelfresh at yahoo.com (Darren McElfresh) Date: Mon, 5 Mar 2012 08:06:49 -0800 (PST) Subject: [python-win32] Help Needed on Handling Events from a Proprietary COM Object In-Reply-To: <4F543E80.7060708@gmail.com> References: <1330464378.9394.YahooMailNeo@web160603.mail.bf1.yahoo.com> <4F4D5FF9.1080101@gmail.com> <1330524102.92155.YahooMailNeo@web160605.mail.bf1.yahoo.com> <4F543E80.7060708@gmail.com> Message-ID: <1330963609.89418.YahooMailNeo@web160606.mail.bf1.yahoo.com> Thanks.? I actually found out the problem was enabling the events within the proprietary COM object, so once I did that everything is working.? Thanks for your help! ________________________________ From: Mark Hammond To: Darren McElfresh Cc: "python-win32 at python.org" Sent: Sunday, March 4, 2012 10:18 PM Subject: Re: [python-win32] Help Needed on Handling Events from a Proprietary COM Object Sorry for the delay - I'm afraid there isn't anything obvious I can see. ? However, note that all the IConnection* interfaces are fully exposed in Python - so it should be able to avoid the "WithEvents" type helpers and "port" the code below directly - ie, manually doing the QI for the IConnect* interfaces, etc.? You might find win32com/client/connect.py and win32com/demos/connect.py useful as these do the low-level connection-point wrangling so may either be useful directly or as a guide to using them from Python. Cheers, Mark. On 1/03/2012 1:01 AM, Darren McElfresh wrote: > Thanks for your help on this! > > I expect an "event" to make a callback on my event handler. > > I updated my code to not utilize getevents, since I'm using > DispatchWithEvents, and removed my call to MsgWaitForMultipleObjects and > updated the call to PumpWaitingMessages in a loop, to just be > PumpMessages; however it still doesn't seem to work. > > So at this point I basically have: > class Events(): > def OnChange(self, e=defaultNamedNotOptArg): > .... > .... > event_source = view.newItemEventSource( > server.typeForName(server.TypeNames.CHANGEREQUEST) ) > event_monitor = win32com.client.DispatchWithEvents( event_source, Events ) > pythoncom.PumpMessages() > > The C++ code snippets are the following > class CMyListener : > // _StItemSink is the default source (outgoing) dspinterface for > // StItemEventSource objects. > public IDispatchImpl<_IStItemSink, &DIID__IStItemSink, &LIBID_StarTeam>, > public CComObjectRoot > { > public: > CMyListener() {} > BEGIN_COM_MAP(CMyListener) > COM_INTERFACE_ENTRY(IDispatch) > COM_INTERFACE_ENTRY(_IStItemSink) > END_COM_MAP() > .... > // _IStItemSink is a dspinterface. > // We must implement IDispatch::Invoke(). > STDMETHOD(Invoke)( DISPID dispIdMember, > REFIID riid, LCID lcid, > WORD wFlags, > DISPPARAMS FAR* pDispParams, > VARIANT FAR* pVarResult, > EXCEPINFO FAR* pExcepInfo, > unsigned int FAR* puArgErr ) > { > .... > } > .... > // Create the event source for CHANGEREQUEST items. > CComPtr source; > hr = stView->newItemEventSource(type, &source); > if (!VerifyHR(hr, IID_IStView, stView)) { > return(false); > } > > // The event source is the connection point container. > CComPtr cpc; > hr = source->QueryInterface(IID_IConnectionPointContainer, (void**)&cpc); > if (!VerifyHR(hr, IID_IStItemEventSource, source)) { > return(false); > } > > // Find the connection point for Item events. > // We save it so that we can call IConnectionPointContainer::Unadvise() > later. > hr = cpc->FindConnectionPoint(DIID__IStItemSink, &m_cp); > if (!VerifyHR(hr, IID_IConnectionPointContainer, cpc)) { > return(false); > } > > // Instantiate our listener. > CComObject* listener = NULL; > hr = CComObject::CreateInstance(&listener); > if (!VerifyHR(hr)) { > return(false); > } > > // Slip in a pointer to the parent dialog. > listener->m_dlg = this; > > // Connect the listener. > // We save the cookie so that we can call > IConnectionPointContainer::Unadvise() later. > hr = m_cp->Advise(listener, &m_cookie); > if (!VerifyHR(hr, IID_IConnectionPoint, m_cp)) { > return(false); > > Any ideas on what I'm missing? Is it that the object is an Dispatch > Interface, and so I'm not handling that correctly? > > Thanks, > Darren > > > ------------------------------------------------------------------------ > *From:* Mark Hammond > *To:* Darren McElfresh > *Cc:* "python-win32 at python.org" > *Sent:* Tuesday, February 28, 2012 5:15 PM > *Subject:* Re: [python-win32] Help Needed on Handling Events from a > Proprietary COM Object > > On 29/02/2012 8:26 AM, Darren McElfresh wrote: >? > I?ve read through numerous posts on how to get this to work, but I?ve >? > realized it is time to ask for help. >? > In general I have a COM object that returns an event handler: >? > /event_source = com_object.newEventSource( arg_data )/ >? > I?ve tried establishing the connection points necessary by creating an >? > event class derived on the sink co-class of this event source: >? > /class Events(win32com.client.getevents(COM_LIB.CLSID)):/ >? > I included all of the methods that were mentioned in the generated code >? > from makepy.From there I tried to utilize DispatchWithEvents to connect >? > the listener: >? > /event_monitor = win32com.client.DispatchWithEvents( event_source, > Events )/ > > Using DispatchWithEvents means you shouldn't need to use getevents > manually at all - it does the getevents for you. So just defining your > Events class without a base-class should work - check out the docstring > for DispatchWithEvents. > >? > Everything seems fine at this point, but when I use try to listen it >? > never seems to fire: >? > /rc = win32event.WaitForSingleObject( event_monitor.event, TIME )/ > > What is event_monitor.event? I guess it must be an integer event handle, > but it is worth checking it is sane. Also, that doesn't really make > sense as an event sink - presumably you have referenced the 'event' > attribute before an event has fired, so the actual firing of an event > doesn't seem to need to do anything - it just sets the handle object and > wouldn't need to make a callback into your handler. Generally the firing > of an event will explicitly call a method you supply, but that doesn't > seem to be the case here. > > Even if that was "normal" for your object, you might need > MsgWaitForMultipleObjects - a message loop way well be needed to deliver > the event calls (ie, so the event handler functions can be called). > >? > I?ve even tried (even though I don?t think it is necessary for single >? > threaded applications): >? > /pythoncom.PumpWaitingMessages()/ > > A single threaded application will have to do *something* while it is > waiting for the events to fire, so unless you are in a UI like > pythonwin, you *will* need something like PumpMessages - otherwise your > thread will just terminate. PumpWaitingMessages only pumps what is > queued now - you need PumpMessages to pump "forever" - or until you call > PostQuitMessage to kill the pump, presumably in response to a future event) > > But I'm missing something - either you expect an "event" to set a > Windows event handle (and therefore probably need > MsgWaitForMultipleObjects) or you expect an "event" to make a callback > on your event handler (in which case you need something like > PumpMessages) - but the 2 scenarios are quite different depending on > what is expected to happen. > >? > However that didn?t seem to have any impact either.No matter what I try >? > ? I can?t get my handlers to fire.I have sample code on how to do this >? > in C++, and I have already taken the sample Java code and have my own >? > version of that working; however I?d prefer to use Python if I can get >? > it to work. >? > I can provide my code (or the samples), but it is somewhat lengthy so I >? > was hoping someone would see what I was missing right away? > > Maybe you could just provide a summary of the relevant C++ code? > > Mark > > > > > _______________________________________________ > python-win32 mailing list > python-win32 at python.org > http://mail.python.org/mailman/listinfo/python-win32 -------------- next part -------------- An HTML attachment was scrubbed... URL: From reckoner at gmail.com Mon Mar 5 18:42:09 2012 From: reckoner at gmail.com (reckoner) Date: Mon, 05 Mar 2012 09:42:09 -0800 Subject: [python-win32] When closing windows, how to handle "save changes?" dialogs? Message-ID: <4F54FAF1.9040600@gmail.com> When closing windows, I need to somehow handle the case when the window I am trying to close spawns a child dialog window that asks whether I want to "save changes" or something like that . The trouble is that the dialog could be different for every kind of window I am trying to close and I would like to catch those in each case, and then later handle them separately. I just don't want to forcefully terminate the process in question, however. Any help appreciated. From timr at probo.com Mon Mar 5 20:20:16 2012 From: timr at probo.com (Tim Roberts) Date: Mon, 5 Mar 2012 11:20:16 -0800 Subject: [python-win32] Context menu troubles In-Reply-To: <4F52028C.6050901@gmail.com> References: <4F510B62.1050709@gmail.com> <4F511498.60404@probo.com> <4F51197F.3030305@gmail.com> <4F512AA9.5080304@probo.com> <4F52028C.6050901@gmail.com> Message-ID: <4F5511F0.1020708@probo.com> Chris Ness wrote: > > All seems to be working fine now. Thanks Tim. Learning a lot here. > > Having a spot of bother with the context menu for a drive though > (e.g."C:"). I'm getting a very minimal menu with Open, Manage, Include > in Library, Copy and Properties. Choosing proprties brings up Control > Panel->System. All of that is correct. Technically, C: is a device, not a filesystem. If you want to refer to the folder at the root of C:. then you need to use "C:\". That's usually pretty easy to check: if the string is length two and the second letter is colon, then add a backslash. -- Tim Roberts, timr at probo.com Providenza & Boekelheide, Inc. From andrew.george.hammond at gmail.com Tue Mar 6 03:05:01 2012 From: andrew.george.hammond at gmail.com (Andrew Hammond) Date: Mon, 5 Mar 2012 18:05:01 -0800 Subject: [python-win32] windows firewall woes? Message-ID: We have python running on a number of devices in the field and have experienced problems where it appears that a windows update has removed a windows firewall exception, blocking our python service from operating. Has anyone else experienced something like this? Is there a way to fix it without human intervention? Andrew -------------- next part -------------- An HTML attachment was scrubbed... URL: From bill at tutts.org Tue Mar 6 17:05:14 2012 From: bill at tutts.org (Bill Tutt) Date: Tue, 6 Mar 2012 11:05:14 -0500 Subject: [python-win32] windows firewall woes? In-Reply-To: References: Message-ID: This sounds more like a problem with your approach to servicing your product, and not necessarily a python windows specific problem. I can point you in the direction to create the firewall exception, but you would still need to figure out how to arrange to have the code actually execute. Windows Firewall rule exceptions don't appear that hard to define. Windows Firewall COM interfaces docs: http://msdn.microsoft.com/en-us/library/windows/desktop/aa366449(v=vs.85).aspx Some simplistic VBScript examples of using those interfaces: http://msdn.microsoft.com/en-us/library/windows/desktop/aa366421(v=vs.85).aspx I'd use the VBScript examples as a base and determine what kind of exception is best for your needs. (i.e. as little of an exception as possible) Bill On Mon, Mar 5, 2012 at 9:05 PM, Andrew Hammond < andrew.george.hammond at gmail.com> wrote: > We have python running on a number of devices in the field and have > experienced problems where it appears that a windows update has removed a > windows firewall exception, blocking our python service from operating. > > Has anyone else experienced something like this? Is there a way to fix it > without human intervention? > > Andrew > > _______________________________________________ > python-win32 mailing list > python-win32 at python.org > http://mail.python.org/mailman/listinfo/python-win32 > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From cool_go_blue at yahoo.com Thu Mar 8 18:14:39 2012 From: cool_go_blue at yahoo.com (cool_go_blue) Date: Thu, 8 Mar 2012 09:14:39 -0800 (PST) Subject: [python-win32] a trivial question Message-ID: <1331226879.31718.YahooMailClassic@web43141.mail.sp1.yahoo.com> I try to use comprehensions when I am learning Python. After opening a word document, i try to read the 2nd column of a table for each row. I print out the words as follows: ? for row in range(1,len(self.doc.Tables(1).Rows)+1): ?? for word in str(self.doc.Tables(1).Cell(row,2)).split(): ????? if word not in stopwords: ???????? print word ? But I get a runtime error when I have the following code: ? content = [[word for word in str(self.doc.Tables(1).Cell(row,2).split()) if word not in stopwords] for row in range(1,len(self.doc.Tables(1).Rows)+1)] ? The error is as follows: ? Traceback (most recent call last): File "J:\MyProjects\Python\VectorSpaceTry\src\ReadCorpus.py", line 111, in array.setup() File "J:\MyProjects\Python\VectorSpaceTry\src\ReadCorpus.py", line 79, in setup for row in range(1,len(self.doc.Tables(1).Rows)+1) File "F:\Softwares\Working\Languages\Python27\lib\site-packages\win32com\client\__init__.py", line 465, in __getattr__ raise AttributeError("'%s' object has no attribute '%s'" % (repr(self), attr)) AttributeError: '' object has no attribute 'split' ? what is wrong with my code? Thanks. B. -------------- next part -------------- An HTML attachment was scrubbed... URL: From Paul_Koning at Dell.com Thu Mar 8 18:19:20 2012 From: Paul_Koning at Dell.com (Paul_Koning at Dell.com) Date: Thu, 8 Mar 2012 11:19:20 -0600 Subject: [python-win32] a trivial question In-Reply-To: <1331226879.31718.YahooMailClassic@web43141.mail.sp1.yahoo.com> References: <1331226879.31718.YahooMailClassic@web43141.mail.sp1.yahoo.com> Message-ID: <09787EF419216C41A903FD14EE5506DD0313991CCF@AUSX7MCPC103.AMER.DELL.COM> You have a misplaced parenthesis. The working code has str (...Cell(...) ).split() and the failing code has str (...Cell(...).split() ) -in other words, the bad code has split() applied to the argument of str() rather than the result of str(). paul From: python-win32-bounces+pkoning=equallogic.com at python.org [mailto:python-win32-bounces+pkoning=equallogic.com at python.org] On Behalf Of cool_go_blue Sent: Thursday, March 08, 2012 12:15 PM To: python-win32 at python.org Subject: [python-win32] a trivial question I try to use comprehensions when I am learning Python. After opening a word document, i try to read the 2nd column of a table for each row. I print out the words as follows: for row in range(1,len(self.doc.Tables(1).Rows)+1): for word in str(self.doc.Tables(1).Cell(row,2)).split(): if word not in stopwords: print word But I get a runtime error when I have the following code: content = [[word for word in str(self.doc.Tables(1).Cell(row,2).split()) if word not in stopwords] for row in range(1,len(self.doc.Tables(1).Rows)+1)] The error is as follows: Traceback (most recent call last): File "J:\MyProjects\Python\VectorSpaceTry\src\ReadCorpus.py", line 111, in array.setup() File "J:\MyProjects\Python\VectorSpaceTry\src\ReadCorpus.py", line 79, in setup for row in range(1,len(self.doc.Tables(1).Rows)+1) File "F:\Softwares\Working\Languages\Python27\lib\site-packages\win32com\client\__init__.py", line 465, in __getattr__ raise AttributeError("'%s' object has no attribute '%s'" % (repr(self), attr)) AttributeError: '' object has no attribute 'split' what is wrong with my code? Thanks. B. -------------- next part -------------- An HTML attachment was scrubbed... URL: From rsyring at gmail.com Thu Mar 8 18:24:58 2012 From: rsyring at gmail.com (Randy Syring) Date: Thu, 08 Mar 2012 12:24:58 -0500 Subject: [python-win32] a trivial question In-Reply-To: <1331226879.31718.YahooMailClassic@web43141.mail.sp1.yahoo.com> References: <1331226879.31718.YahooMailClassic@web43141.mail.sp1.yahoo.com> Message-ID: <4F58EB6A.20602@gmail.com> On 03/08/2012 12:14 PM, cool_go_blue wrote: > [[word forword instr(/self/.doc.Tables(1).Cell(row,2).split()) ifword > notinstopwords] You have a parenthesis in the wrong place. You are doing .split() on the column object, not the result of str(). Change it to: str(self.doc.Tables(1).Cell(row,2)*)*.split() --------------------------------------------- Randy Syring Development& Executive Director Level 12 Technologies (formerly Intelicom) Direct: 502-276-0459 Office: 502-212-9913 Intelicom is now Level 12 Technologies,learn more about our name change . Please update your address book with my new email address. Principled People, Technology that Works -------------- next part -------------- An HTML attachment was scrubbed... URL: From Hien.Pham at tekelec.com Thu Mar 8 19:03:04 2012 From: Hien.Pham at tekelec.com (Pham, Hien) Date: Thu, 8 Mar 2012 13:03:04 -0500 Subject: [python-win32] a trivial question In-Reply-To: <1331226879.31718.YahooMailClassic@web43141.mail.sp1.yahoo.com> References: <1331226879.31718.YahooMailClassic@web43141.mail.sp1.yahoo.com> Message-ID: <4D86D4BDF19D8D468A21AEFF9C056D590CB26C553F@MAIL2.tekelec.com> Try this: tableSize = self.doc.getTableSize(tbl) for row in range(tableSize[1]): for col in range(tableSize[0]): print procTbl.Cell(row+1, col+1).Range).Text From: python-win32-bounces+hien.pham=tekelec.com at python.org [mailto:python-win32-bounces+hien.pham=tekelec.com at python.org] On Behalf Of cool_go_blue Sent: Thursday, March 08, 2012 12:15 PM To: python-win32 at python.org Subject: [python-win32] a trivial question I try to use comprehensions when I am learning Python. After opening a word document, i try to read the 2nd column of a table for each row. I print out the words as follows: for row in range(1,len(self.doc.Tables(1).Rows)+1): for word in str(self.doc.Tables(1).Cell(row,2)).split(): if word not in stopwords: print word But I get a runtime error when I have the following code: content = [[word for word in str(self.doc.Tables(1).Cell(row,2).split()) if word not in stopwords] for row in range(1,len(self.doc.Tables(1).Rows)+1)] The error is as follows: Traceback (most recent call last): File "J:\MyProjects\Python\VectorSpaceTry\src\ReadCorpus.py", line 111, in array.setup() File "J:\MyProjects\Python\VectorSpaceTry\src\ReadCorpus.py", line 79, in setup for row in range(1,len(self.doc.Tables(1).Rows)+1) File "F:\Softwares\Working\Languages\Python27\lib\site-packages\win32com\client\__init__.py", line 465, in __getattr__ raise AttributeError("'%s' object has no attribute '%s'" % (repr(self), attr)) AttributeError: '' object has no attribute 'split' what is wrong with my code? Thanks. B. -------------- next part -------------- An HTML attachment was scrubbed... URL: From vernondcole at gmail.com Thu Mar 8 20:48:14 2012 From: vernondcole at gmail.com (Vernon Cole) Date: Thu, 8 Mar 2012 12:48:14 -0700 Subject: [python-win32] a trivial question In-Reply-To: <1331226879.31718.YahooMailClassic@web43141.mail.sp1.yahoo.com> References: <1331226879.31718.YahooMailClassic@web43141.mail.sp1.yahoo.com> Message-ID: *self*.doc.Tables(1).Cell(row,2) is not a string, and therefore has no .split() method. str(*self*.doc.Tables(1).Cell(row,2)) returns a string, so it does have a split() method and therefore str(*self*.doc.Tables(1).Cell(row,2)).split() is correct, but str(*self*.doc.Tables(1).Cell(row,2).split()) is not. Note the different position on the double parens )) -- Vernon On Thu, Mar 8, 2012 at 10:14 AM, cool_go_blue wrote: > I try to use comprehensions when I am learning Python. After opening a > word document, i try to read the 2nd column of a table for each row. I > print out the words as follows: > > > for row in range(1,len(*self*.doc.Tables(1).Rows)+1): > > for word in str(*self*.doc.Tables(1).Cell(row,2)).split(): > > if word not in stopwords: > print word > > But I get a runtime error when I have the following code: > > > content = [[word > for word in str(*self*.doc.Tables(1).Cell(row,2).split()) if word not instopwords] > > for row in range(1,len(*self*.doc.Tables(1).Rows)+1)] > > > > The error is as follows: > > > > Traceback (most recent call last): > > *File "J:\MyProjects\Python\VectorSpaceTry\src\ReadCorpus.py", line 111, > in * > > array.setup() > > *File "J:\MyProjects\Python\VectorSpaceTry\src\ReadCorpus.py", line 79, > in setup* > > for row in range(1,len(self.doc.Tables(1).Rows)+1) > > *File > "F:\Softwares\Working\Languages\Python27\lib\site-packages\win32com\client\__init__.py", > line 465, in __getattr__* > > raise AttributeError("'%s' object has no attribute '%s'" % (repr(self), > attr)) > > AttributeError: ' instance at 0x51383312>' object has no attribute 'split' > > > > what is wrong with my code? Thanks. > > B. > > > _______________________________________________ > python-win32 mailing list > python-win32 at python.org > http://mail.python.org/mailman/listinfo/python-win32 > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From cool_go_blue at yahoo.com Thu Mar 8 23:01:38 2012 From: cool_go_blue at yahoo.com (cool_go_blue) Date: Thu, 8 Mar 2012 14:01:38 -0800 (PST) Subject: [python-win32] a trivial question In-Reply-To: Message-ID: <1331244098.32212.YahooMailClassic@web43140.mail.sp1.yahoo.com> Thanks for all resonses. I just concentrated on the "for row in ..." statement. Now I have another question. I would like to read a document with various structures such as title, subtitle, paragraph, table (as I did previously) and bullet etc. How can I get these contents for further analysis? Thanks. B. --- On Thu, 3/8/12, Vernon Cole wrote: From: Vernon Cole Subject: Re: [python-win32] a trivial question To: "cool_go_blue" Cc: python-win32 at python.org Date: Thursday, March 8, 2012, 2:48 PM self.doc.Tables(1).Cell(row,2) is not a string, and therefore has no .split() method. str(self.doc.Tables(1).Cell(row,2)) returns a string, so it does have a split() method and therefore str(self.doc.Tables(1).Cell(row,2)).split() is correct, but str(self.doc.Tables(1).Cell(row,2).split()) is not.? Note the different position on the double parens )) -- Vernon On Thu, Mar 8, 2012 at 10:14 AM, cool_go_blue wrote: I try to use comprehensions when I am learning Python. After opening a word document, i try to read the 2nd column of a table for each row. I print out the words as follows: ? for row in range(1,len(self.doc.Tables(1).Rows)+1): ?? for word in str(self.doc.Tables(1).Cell(row,2)).split(): ????? if word not in stopwords: ???????? print word ? But I get a runtime error when I have the following code: ? content = [[word for word in str(self.doc.Tables(1).Cell(row,2).split()) if word not in stopwords] for row in range(1,len(self.doc.Tables(1).Rows)+1)] ? The error is as follows: ? Traceback (most recent call last): File "J:\MyProjects\Python\VectorSpaceTry\src\ReadCorpus.py", line 111, in array.setup() File "J:\MyProjects\Python\VectorSpaceTry\src\ReadCorpus.py", line 79, in setup for row in range(1,len(self.doc.Tables(1).Rows)+1) File "F:\Softwares\Working\Languages\Python27\lib\site-packages\win32com\client\__init__.py", line 465, in __getattr__ raise AttributeError("'%s' object has no attribute '%s'" % (repr(self), attr)) AttributeError: '' object has no attribute 'split' ? what is wrong with my code? Thanks. B. _______________________________________________ python-win32 mailing list python-win32 at python.org http://mail.python.org/mailman/listinfo/python-win32 -------------- next part -------------- An HTML attachment was scrubbed... URL: From andrew.george.hammond at gmail.com Fri Mar 9 01:16:48 2012 From: andrew.george.hammond at gmail.com (Andrew Hammond) Date: Thu, 8 Mar 2012 16:16:48 -0800 Subject: [python-win32] windows firewall woes? In-Reply-To: References: Message-ID: With the following code, def add_firewall_exception(): app = win32com.client.gencache.EnsureDispatch('HNetCfg.FwAuthorizedApplication', 0) app.ProcessImageFileName = r'\Python26\python.exe' app.Scope = NET_FW_SCOPE_ALL app.IpVersion = NET_FW_IP_VERSION_ANY app.Enabled = True firewall_manager = win32com.client.gencache.EnsureDispatch('HNetCfg.FwMgr',0) profile = firewall_manager.LocalPolicy.CurrentProfile profile.AuthorizedApplications.Add(app) I get the following error message: E:\Documents and Settings\stubby\Desktop>python -OO -i firewall.py >>> add_firewall_exception() Traceback (most recent call last): File "", line 1, in File "firewall.py", line 41, in add_firewall_exception profile.AuthorizedApplications.Add(app) File "E:\python26\lib\site-packages\win32com\gen_py\58FBCF7C-E7A9-467C-80B3-FC65E8FCCA08x0x1x0.py", line 75, in Add return self._oleobj_.InvokeTypes(2, LCID, 1, (24, 0), ((9, 1),),app pywintypes.com_error: (-2147352567, 'Exception occurred.', (0, None, None, None, 0, -2147467261), None) >>> ^Z I'm not at all versed in win32com programming... any help please? On Tue, Mar 6, 2012 at 8:05 AM, Bill Tutt wrote: > This sounds more like a problem with your approach to servicing your > product, and not necessarily a python windows specific problem. > > I can point you in the direction to create the firewall exception, but you > would still need to figure out how to arrange to have the code actually > execute. > > Windows Firewall rule exceptions don't appear that hard to define. > > Windows Firewall COM interfaces docs: > > http://msdn.microsoft.com/en-us/library/windows/desktop/aa366449(v=vs.85).aspx > > Some simplistic VBScript examples of using those interfaces: > > http://msdn.microsoft.com/en-us/library/windows/desktop/aa366421(v=vs.85).aspx > > I'd use the VBScript examples as a base and determine what kind of > exception is best for your needs. (i.e. as little of an exception as > possible) > > Bill > > On Mon, Mar 5, 2012 at 9:05 PM, Andrew Hammond < > andrew.george.hammond at gmail.com> wrote: > >> We have python running on a number of devices in the field and have >> experienced problems where it appears that a windows update has removed a >> windows firewall exception, blocking our python service from operating. >> >> Has anyone else experienced something like this? Is there a way to fix it >> without human intervention? >> >> Andrew >> >> _______________________________________________ >> python-win32 mailing list >> python-win32 at python.org >> http://mail.python.org/mailman/listinfo/python-win32 >> >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: From skippy.hammond at gmail.com Fri Mar 9 06:22:48 2012 From: skippy.hammond at gmail.com (Mark Hammond) Date: Fri, 09 Mar 2012 16:22:48 +1100 Subject: [python-win32] windows firewall woes? In-Reply-To: References: Message-ID: <4F5993A8.6080908@gmail.com> As a couple of guesses, I'd ensure you do this from an elevated process (ie, "run as administrator") and also be sure to use fully-qualified paths. (The error code shown appears to be ERROR_INVALID_POINTER, but that might be a red herring) Mark On 9/03/2012 11:16 AM, Andrew Hammond wrote: > With the following code, > > def add_firewall_exception(): > app = > win32com.client.gencache.EnsureDispatch('HNetCfg.FwAuthorizedApplication', > 0) > app.ProcessImageFileName = r'\Python26\python.exe' > app.Scope = NET_FW_SCOPE_ALL > app.IpVersion = NET_FW_IP_VERSION_ANY > app.Enabled = True > > firewall_manager = > win32com.client.gencache.EnsureDispatch('HNetCfg.FwMgr',0) > profile = firewall_manager.LocalPolicy.CurrentProfile > profile.AuthorizedApplications.Add(app) > > I get the following error message: > > E:\Documents and Settings\stubby\Desktop>python -OO -i firewall.py > >>> add_firewall_exception() > Traceback (most recent call last): > File "", line 1, in > File "firewall.py", line 41, in add_firewall_exception > profile.AuthorizedApplications.Add(app) > File > "E:\python26\lib\site-packages\win32com\gen_py\58FBCF7C-E7A9-467C-80B3-FC65E8FCCA08x0x1x0.py", > line 75, in Add > return self._oleobj_.InvokeTypes(2, LCID, 1, (24, 0), ((9, 1),),app > pywintypes.com_error: (-2147352567, 'Exception occurred.', (0, None, > None, None, 0, -2147467261), None) > >>> ^Z > > I'm not at all versed in win32com programming... any help please? > > On Tue, Mar 6, 2012 at 8:05 AM, Bill Tutt > wrote: > > This sounds more like a problem with your approach to servicing your > product, and not necessarily a python windows specific problem. > > I can point you in the direction to create the firewall exception, > but you would still need to figure out how to arrange to have the > code actually execute. > > Windows Firewall rule exceptions don't appear that hard to define. > > Windows Firewall COM interfaces docs: > http://msdn.microsoft.com/en-us/library/windows/desktop/aa366449(v=vs.85).aspx > > Some simplistic VBScript examples of using those interfaces: > http://msdn.microsoft.com/en-us/library/windows/desktop/aa366421(v=vs.85).aspx > > I'd use the VBScript examples as a base and determine what kind of > exception is best for your needs. (i.e. as little of an exception as > possible) > > Bill > > On Mon, Mar 5, 2012 at 9:05 PM, Andrew Hammond > > wrote: > > We have python running on a number of devices in the field and > have experienced problems where it appears that a windows update > has removed a windows firewall exception, blocking our python > service from operating. > > Has anyone else experienced something like this? Is there a way > to fix it without human intervention? > > Andrew > > _______________________________________________ > python-win32 mailing list > python-win32 at python.org > http://mail.python.org/mailman/listinfo/python-win32 > > > > > > _______________________________________________ > python-win32 mailing list > python-win32 at python.org > http://mail.python.org/mailman/listinfo/python-win32 From dave6502 at gmail.com Fri Mar 9 14:17:52 2012 From: dave6502 at gmail.com (dave selby) Date: Fri, 9 Mar 2012 13:17:52 +0000 Subject: [python-win32] win32com can't find file but I can see it, confused Message-ID: OK I am a little confused, I have the following shell = win32com.client.Dispatch('WScript.Shell') print os.path.isfile(self.exe) print self.exe shell.Run(self.exe) The file self.exe exists, I get a 'true' from os.path.isfile, I can execute it on the command line AOK, its path is as I would expect but when I attempt to execute it I get ... True C:\Documents and Settings\dave\Desktop\My Mobile\MyMobiler\MyMobiler.exe Traceback (most recent call last): File "C:\Program Files\FX Hammer\core\diag.py", line 64, in my_mobiler_.startExe() File "C:\Program Files\FX Hammer\core\my_mobiler.py", line 93, in startExe shell.Run('C:\Documents and Settings\dave\Desktop\My Mobile\MyMobiler\MyMobiler.exe') File "", line 2, in Run pywintypes.com_error: (-2147352567, 'Exception occurred.', (0, None, None, None, 0, -2147024894), None) Now using win32api.FormatMessage() I get ... Exception occurred. The system cannot find the file specified. Am I missing anything ? Cheers Dave -- Please avoid sending me Word or PowerPoint attachments. See http://www.gnu.org/philosophy/no-word-attachments.html -- Please avoid sending me Word or PowerPoint attachments. See http://www.gnu.org/philosophy/no-word-attachments.html From rsyring at gmail.com Fri Mar 9 18:44:11 2012 From: rsyring at gmail.com (Randy Syring) Date: Fri, 09 Mar 2012 12:44:11 -0500 Subject: [python-win32] win32com can't find file but I can see it, confused In-Reply-To: References: Message-ID: <4F5A416B.9040309@gmail.com> Do you need to quote the value sent to shell.run() since there is a space in it? shell.Run('"C:\Documents and Settings\dave\Desktop\MyMobile\MyMobiler\MyMobiler.exe"') ? --------------------------------------------- Randy Syring Development& Executive Director Level 12 Technologies (formerly Intelicom) Direct: 502-276-0459 Office: 502-212-9913 Intelicom is now Level 12 Technologies,learn more about our name change . Please update your address book with my new email address. Principled People, Technology that Works On 03/09/2012 08:17 AM, dave selby wrote: > OK I am a little confused, I have the following > > shell = win32com.client.Dispatch('WScript.Shell') > print os.path.isfile(self.exe) > print self.exe > shell.Run(self.exe) > > The file self.exe exists, I get a 'true' from os.path.isfile, I can > execute it on the command line AOK, its path is as I would expect but > when I attempt to execute it I get ... > > True > C:\Documents and Settings\dave\Desktop\My Mobile\MyMobiler\MyMobiler.exe > Traceback (most recent call last): > File "C:\Program Files\FX Hammer\core\diag.py", line 64, in > my_mobiler_.startExe() > File "C:\Program Files\FX Hammer\core\my_mobiler.py", line 93, in startExe > shell.Run('C:\Documents and Settings\dave\Desktop\My > Mobile\MyMobiler\MyMobiler.exe') > File "", line 2, in Run > pywintypes.com_error: (-2147352567, 'Exception occurred.', (0, None, > None, None, 0, -2147024894), None) > > Now using win32api.FormatMessage() I get ... > > Exception occurred. > > The system cannot find the file specified. > > Am I missing anything ? > > Cheers > > Dave > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From timr at probo.com Fri Mar 9 21:00:04 2012 From: timr at probo.com (Tim Roberts) Date: Fri, 9 Mar 2012 12:00:04 -0800 Subject: [python-win32] win32com can't find file but I can see it, confused In-Reply-To: <4F5A416B.9040309@gmail.com> References: <4F5A416B.9040309@gmail.com> Message-ID: <4F5A6144.8050707@probo.com> Randy Syring wrote: > Do you need to quote the value sent to shell.run() since there is a > space in it? > > shell.Run('"C:\Documents and > Settings\dave\Desktop\MyMobile\MyMobiler\MyMobiler.exe"') Right. More than that, he needs to escape the backslashes or use a raw string, as in: shell.Run(r'"C:\Documents and Settings..."') -- Tim Roberts, timr at probo.com Providenza & Boekelheide, Inc. From andrew.george.hammond at gmail.com Fri Mar 9 21:24:55 2012 From: andrew.george.hammond at gmail.com (Andrew Hammond) Date: Fri, 9 Mar 2012 12:24:55 -0800 Subject: [python-win32] windows firewall woes? In-Reply-To: <4F5993A8.6080908@gmail.com> References: <4F5993A8.6080908@gmail.com> Message-ID: Turns out that I needed to add app.Name = 'Python' to the code. Ugh. Andrew On Thu, Mar 8, 2012 at 9:22 PM, Mark Hammond wrote: > As a couple of guesses, I'd ensure you do this from an elevated process > (ie, "run as administrator") and also be sure to use fully-qualified paths. > > (The error code shown appears to be ERROR_INVALID_POINTER, but that might > be a red herring) > > Mark > > > On 9/03/2012 11:16 AM, Andrew Hammond wrote: > >> With the following code, >> >> def add_firewall_exception(): >> app = >> win32com.client.gencache.**EnsureDispatch('HNetCfg.** >> FwAuthorizedApplication', >> 0) >> app.ProcessImageFileName = r'\Python26\python.exe' >> app.Scope = NET_FW_SCOPE_ALL >> app.IpVersion = NET_FW_IP_VERSION_ANY >> app.Enabled = True >> >> firewall_manager = >> win32com.client.gencache.**EnsureDispatch('HNetCfg.FwMgr'**,0) >> profile = firewall_manager.LocalPolicy.**CurrentProfile >> profile.**AuthorizedApplications.Add(**app) >> >> I get the following error message: >> >> E:\Documents and Settings\stubby\Desktop>python -OO -i firewall.py >> >>> add_firewall_exception() >> Traceback (most recent call last): >> File "", line 1, in >> File "firewall.py", line 41, in add_firewall_exception >> profile.**AuthorizedApplications.Add(**app) >> File >> "E:\python26\lib\site-**packages\win32com\gen_py\** >> 58FBCF7C-E7A9-467C-80B3-**FC65E8FCCA08x0x1x0.py", >> line 75, in Add >> return self._oleobj_.InvokeTypes(2, LCID, 1, (24, 0), ((9, 1),),app >> pywintypes.com_error: (-2147352567, 'Exception occurred.', (0, None, >> None, None, 0, -2147467261), None) >> >>> ^Z >> >> I'm not at all versed in win32com programming... any help please? >> >> On Tue, Mar 6, 2012 at 8:05 AM, Bill Tutt > > wrote: >> >> This sounds more like a problem with your approach to servicing your >> product, and not necessarily a python windows specific problem. >> >> I can point you in the direction to create the firewall exception, >> but you would still need to figure out how to arrange to have the >> code actually execute. >> >> Windows Firewall rule exceptions don't appear that hard to define. >> >> Windows Firewall COM interfaces docs: >> http://msdn.microsoft.com/en-**us/library/windows/desktop/** >> aa366449(v=vs.85).aspx >> >> Some simplistic VBScript examples of using those interfaces: >> http://msdn.microsoft.com/en-**us/library/windows/desktop/** >> aa366421(v=vs.85).aspx >> >> I'd use the VBScript examples as a base and determine what kind of >> exception is best for your needs. (i.e. as little of an exception as >> possible) >> >> Bill >> >> On Mon, Mar 5, 2012 at 9:05 PM, Andrew Hammond >> >> >> >> wrote: >> >> We have python running on a number of devices in the field and >> have experienced problems where it appears that a windows update >> has removed a windows firewall exception, blocking our python >> service from operating. >> >> Has anyone else experienced something like this? Is there a way >> to fix it without human intervention? >> >> Andrew >> >> ______________________________**_________________ >> python-win32 mailing list >> python-win32 at python.org >> > >> http://mail.python.org/**mailman/listinfo/python-win32 >> >> >> >> >> >> >> ______________________________**_________________ >> python-win32 mailing list >> python-win32 at python.org >> http://mail.python.org/**mailman/listinfo/python-win32 >> > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From sagarnikam123 at gmail.com Sat Mar 10 12:04:04 2012 From: sagarnikam123 at gmail.com (sagarnikam123) Date: Sat, 10 Mar 2012 03:04:04 -0800 (PST) Subject: [python-win32] how to see what content have by object? & write its content to separe file? Message-ID: <1331377444806-4564931.post@n6.nabble.com> want to see what is inside cn object & write its content line by line in .txt file >>> cn >>>for x in cn: print(x) gives output (, 38) (, 32) (, 36) (, 42) -- View this message in context: http://python.6.n6.nabble.com/how-to-see-what-content-have-by-object-write-its-content-to-separe-file-tp4564931p4564931.html Sent from the Python - python-win32 mailing list archive at Nabble.com. From timr at probo.com Mon Mar 12 19:18:19 2012 From: timr at probo.com (Tim Roberts) Date: Mon, 12 Mar 2012 11:18:19 -0700 Subject: [python-win32] how to see what content have by object? & write its content to separe file? In-Reply-To: <1331377444806-4564931.post@n6.nabble.com> References: <1331377444806-4564931.post@n6.nabble.com> Message-ID: <4F5E3DEB.6020801@probo.com> sagarnikam123 wrote: > want to see what is inside cn object & write its content line by line in .txt > file Well, that's basically what your code is currently doing. The "cn" object appears to be an iterator, returning a list of tuples one by one. If you want the results formatted in a pretty way, then you need to know more about the "Residue" object in the tuples it is returning. We don't know anything about those objects -- you'll have to find that in the code or its documentation. -- Tim Roberts, timr at probo.com Providenza & Boekelheide, Inc. From cappy2112 at gmail.com Wed Mar 14 19:53:55 2012 From: cappy2112 at gmail.com (Tony Cappellini) Date: Wed, 14 Mar 2012 11:53:55 -0700 Subject: [python-win32] Passing an object to a process Message-ID: On Windows XP - I've got a program running which has spawned a process using os.spawnv(). My program has a logger object instantiated that I want to pass to the process that was spawned. I need to log errors seen by the process, to the same logfile that the program uses for logging. I have the handle, thread ID, and process id of the process, but I see no way to share the logger object using these values. How can I pass a logger instance to the process, from the program which spawned the process? For legacy compatibility reasons, I'm stuck with an older version of Python that doesn't have the subprocess module and other features that are available with more modern releases of Python. -------------- next part -------------- An HTML attachment was scrubbed... URL: From planders at gmail.com Wed Mar 14 20:20:07 2012 From: planders at gmail.com (Preston Landers) Date: Wed, 14 Mar 2012 14:20:07 -0500 Subject: [python-win32] Passing an object to a process In-Reply-To: References: Message-ID: Without getting into too philosophical of a discussion, the only sense in which objects can truly move from one process to another is recreating them in the other process. Even fork() makes copies of everything. Have you tried pickle or other techniques of serialization? Not sure offhand if the logger module supports pickle but it might. You can always just create a new logger object using the same parameters as the original (filename, etc), right? Or am I missing something? There IS a way to get filehandles to be shared by a child process. But do you even need to do that if you can just recreate a new logger object? regards, Preston On Wed, Mar 14, 2012 at 1:53 PM, Tony Cappellini wrote: > > On Windows XP - I've got a program running which has spawned a process using > os.spawnv(). > > My program has a logger object instantiated that I want to pass to the > process that was spawned. > I need to log errors seen by the process, to the same logfile that the > program uses for logging. > > I have the handle, thread ID, and process id of the process, but I see no > way to share the logger object using these values. > > How can I pass a logger instance to the process, from the program which > spawned the process? > > For legacy compatibility reasons, I'm stuck with an older version of Python > that doesn't have the subprocess module and other features that are > available with more modern releases of Python. > > > _______________________________________________ > python-win32 mailing list > python-win32 at python.org > http://mail.python.org/mailman/listinfo/python-win32 > From timr at probo.com Wed Mar 14 20:41:58 2012 From: timr at probo.com (Tim Roberts) Date: Wed, 14 Mar 2012 12:41:58 -0700 Subject: [python-win32] Passing an object to a process In-Reply-To: References: Message-ID: <4F60F486.7010108@probo.com> Tony Cappellini wrote: > > On Windows XP - I've got a program running which has spawned a process > using os.spawnv(). > > My program has a logger object instantiated that I want to pass to the > process that was spawned. That's impossible. Objects are just memory, and memory cannot be shared between processes. > I need to log errors seen by the process, to the same logfile that the > program uses for logging. You can certainly create a new logger instance in your spawned process and have it write to the same file. As long as the logging module flushes after each write, that should work. > For legacy compatibility reasons, I'm stuck with an older version of > Python that doesn't have the subprocess module and other features that > are available with more modern releases of Python. Another alternative is to use popen instead of spawn, and have your spawned process write its messages to stdout. You could then echo them on to the logfile in your original process. That has its own buffering problems. -- Tim Roberts, timr at probo.com Providenza & Boekelheide, Inc. From max at slimmersoft.com Wed Mar 14 20:44:48 2012 From: max at slimmersoft.com (Max Slimmer) Date: Wed, 14 Mar 2012 12:44:48 -0700 Subject: [python-win32] Passing an object to a process In-Reply-To: References: Message-ID: depends what you mean by share logger object, you might be able to have logger on both apps share a common log file. OTH if you want realtime events, I pass a socket from one app to another and have implemented a proxy dialog so one app writes to the progress dialog proxy and it in turn sends data to a handler on the other system via the socket where the actual progress dialog shows progress. max On Wed, Mar 14, 2012 at 11:53 AM, Tony Cappellini wrote: > > On Windows XP - I've got a program running which has spawned a process using > os.spawnv(). > > My program has a logger object instantiated that I want to pass to the > process that was spawned. > I need to log errors seen by the process, to the same logfile that the > program uses for logging. > > I have the handle, thread ID, and process id of the process, but I see no > way to share the logger object using these values. > > How can I pass a logger instance to the process, from the program which > spawned the process? > > For legacy compatibility reasons, I'm stuck with an older version of Python > that doesn't have the subprocess module and other features that are > available with more modern releases of Python. > > > _______________________________________________ > python-win32 mailing list > python-win32 at python.org > http://mail.python.org/mailman/listinfo/python-win32 > From cappy2112 at gmail.com Wed Mar 14 20:55:21 2012 From: cappy2112 at gmail.com (Tony Cappellini) Date: Wed, 14 Mar 2012 12:55:21 -0700 Subject: [python-win32] Passing an object to a process In-Reply-To: References: Message-ID: > >>in which objects can truly move from one process to another is > >>recreating them in the other process. Even fork() makes copies of > everything. > Recreating an object in another process means it's a different object, not a shared one. > > >>Have you tried pickle or other techniques of serialization? Not sure > >>offhand if the logger module supports pickle but it might. > Yes. I've just tried this, even though I expected it not to work. If process A pickles a logger object, and process B unpickles it, referencing of an object in a different process is meaningless. In my case, when the process attempted to write to the logger, no entries were seen in the logfile. Surprisingly, no exceptions occurred- but this could just be a coincidence. >>You can always just create a new logger object using the same > >>parameters as the original (filename, etc), right? >>Or am I missing something? > That may work, and with less effort than my original idea. But if two processes write to the logfile at the same time (especially on a multicore machine), hard-to-read logfiles may result. it's worth a try. It would be great if the process could pass the info to be written to the logfile, back to its creator and let the creator do all the writing. -------------- next part -------------- An HTML attachment was scrubbed... URL: From rsyring at gmail.com Wed Mar 14 21:07:26 2012 From: rsyring at gmail.com (Randy Syring) Date: Wed, 14 Mar 2012 16:07:26 -0400 Subject: [python-win32] Passing an object to a process In-Reply-To: References: Message-ID: <4F60FA7E.5080500@gmail.com> I've used the multiprocessing module to send data between processes: http://docs.python.org/library/multiprocessing.html But, its only in 2.6 and newer. Since they are all separate processes, you could spawn a logging process and your worker processes as processes that use a newer python and then use multiprocessing. Another option might be to send the log messages to a database and then have some process be responsible for pulling those messages out and writing to a file (if needed). Just some thoughts. --------------------------------------------- Randy Syring Development& Executive Director Level 12 Technologies (formerly Intelicom) Direct: 502-276-0459 Office: 502-212-9913 Intelicom is now Level 12 Technologies,learn more about our name change . Please update your address book with my new email address. Principled People, Technology that Works On 03/14/2012 02:53 PM, Tony Cappellini wrote: > > On Windows XP - I've got a program running which has spawned a process > using os.spawnv(). > > My program has a logger object instantiated that I want to pass to the > process that was spawned. > I need to log errors seen by the process, to the same logfile that the > program uses for logging. > > I have the handle, thread ID, and process id of the process, but I see > no way to share the logger object using these values. > > How can I pass a logger instance to the process, from the program > which spawned the process? > > For legacy compatibility reasons, I'm stuck with an older version of > Python that doesn't have the subprocess module and other features that > are available with more modern releases of Python. > > > > _______________________________________________ > python-win32 mailing list > python-win32 at python.org > http://mail.python.org/mailman/listinfo/python-win32 -------------- next part -------------- An HTML attachment was scrubbed... URL: From planders at gmail.com Wed Mar 14 21:29:08 2012 From: planders at gmail.com (Preston Landers) Date: Wed, 14 Mar 2012 15:29:08 -0500 Subject: [python-win32] Passing an object to a process In-Reply-To: References: Message-ID: On Wed, Mar 14, 2012 at 2:55 PM, Tony Cappellini wrote: > >> >>in which objects can truly move from one process to another is >> >>recreating them in the other process. ?Even fork() makes copies of >> >> everything. > > Recreating an object in another process means it's a different object, not a > shared one. Yeah, I know. I was trying to make that point. There's no real way for the same object to exist in multiple processes other than SYSV shared mem. Truly shared memory (i.e, SYSV style) is tricky, not very portable, and usually the wrong answer in my experience. As fas as I know stock Python doesn't support that, and definitely never will on Windows. The point is that you need to figure out what problem you're really trying to solve (logging to one file from multiple processes, it sounds like) and then find the best / simplest approach, which I can tell you definitely doesn't involve SYSV shared memory. It's probably just creating separate logging objects in each process, pointing to the same file, and protected by file locking if necessary. >> >>Have you tried pickle or other techniques of serialization? Not sure >> >>offhand if the logger module supports pickle but it might. > > Yes. I've just tried this, even though I expected it not to work. > > If process A pickles a logger object, and process B unpickles it, > referencing of an object in a different process is meaningless. > > In my case, when the process attempted to write to the logger, no entries > were seen in the logfile. Surprisingly, no exceptions occurred- but this > could just be a coincidence. Probably because the logger object, when serialized, saves a reference to an open filehandle, which won't be automatically transfered to the other process. (There might ultimately be a way to make that work by inheriting filehandles, but again, if you can find something simpler...) > > That may work, and with less effort than my original idea. > > But if two processes write to the logfile at the same time (especially on a > multicore machine), > hard-to-read logfiles may result. > it's worth a try. Yes, that type of thing can occur, but you can also get around that with simple file locking. By the way, that same problem certainly exists even if you somehow shared the object between two processes - what if the two processes made a log call at the same time? File locking may introduce some performance issues if the logging is very frequent, but usually you can find ways to mitigate that. The main app I work on uses log files extensively, and the same file is appended to by unrelated processes without a locking mechanism. Occasionally you do see some interleaving of log entries but in my experience it's fairly rare and in my particular case we don't care much about that anyway. regards, Preston From max at slimmersoft.com Wed Mar 14 21:49:15 2012 From: max at slimmersoft.com (Max Slimmer) Date: Wed, 14 Mar 2012 13:49:15 -0700 Subject: [python-win32] Passing an object to a process In-Reply-To: References: Message-ID: If you are really just logging, use separate loggers/files, sync the clocks, and timestamp records, then merge when you are ready to process if you need timeline related results. On Wed, Mar 14, 2012 at 1:29 PM, Preston Landers wrote: > On Wed, Mar 14, 2012 at 2:55 PM, Tony Cappellini wrote: >> >>> >>in which objects can truly move from one process to another is >>> >>recreating them in the other process. ?Even fork() makes copies of >>> >> everything. >> >> Recreating an object in another process means it's a different object, not a >> shared one. > > Yeah, I know. ?I was trying to make that point. ?There's no real way > for the same object to exist in multiple processes other than SYSV > shared mem. > > Truly shared memory (i.e, SYSV style) is tricky, not very portable, > and usually the wrong answer in my experience. As fas as I know stock > Python doesn't support that, and definitely never will on Windows. > > The point is that you need to figure out what problem you're really > trying to solve (logging to one file from multiple processes, it > sounds like) and then find the best / simplest approach, which I can > tell you definitely doesn't involve SYSV shared memory. ? It's > probably just creating separate logging objects in each process, > pointing to the same file, and protected by file locking if necessary. > > >>> >>Have you tried pickle or other techniques of serialization? Not sure >>> >>offhand if the logger module supports pickle but it might. >> >> Yes. I've just tried this, even though I expected it not to work. >> >> If process A pickles a logger object, and process B unpickles it, >> referencing of an object in a different process is meaningless. >> >> In my case, when the process attempted to write to the logger, no entries >> were seen in the logfile. Surprisingly, no exceptions occurred- but this >> could just be a coincidence. > > Probably because the logger object, when serialized, saves a reference > to an open filehandle, which won't be automatically transfered to the > other process. > > (There might ultimately be a way to make that work by inheriting > filehandles, but again, if you can find something simpler...) > > >> >> That may work, and with less effort than my original idea. >> >> But if two processes write to the logfile at the same time (especially on a >> multicore machine), >> hard-to-read logfiles may result. >> it's worth a try. > > Yes, that type of thing can occur, but you can also get around that > with simple file locking. ?By the way, that same problem certainly > exists even if you somehow shared the object between two processes - > what if the two processes made a log call at the same time? > > File locking may introduce some performance issues if the logging is > very frequent, but usually you can find ways to mitigate that. > > The main app I work on uses log files extensively, and the same file > is appended to by unrelated processes without a locking mechanism. > Occasionally you do see some interleaving of log entries but in my > experience it's fairly rare and in my particular case we don't care > much about that anyway. > > regards, > Preston > _______________________________________________ > python-win32 mailing list > python-win32 at python.org > http://mail.python.org/mailman/listinfo/python-win32 From cappy2112 at gmail.com Wed Mar 14 22:23:54 2012 From: cappy2112 at gmail.com (Tony Cappellini) Date: Wed, 14 Mar 2012 14:23:54 -0700 Subject: [python-win32] Passing an object to a process In-Reply-To: References: Message-ID: Thanks for all the advice. The solution is simple, but neither elegant nor Pythonic. It's a kludge, but will suffice. The process simply opens & writes a 1 line log file, then closes it. The process also increments a counter each time the log file is written, and writes the counter value to the process log file. The program checks to see if the file exists, reads it, then writes the process log file content to the program log file. The program then deletes the process log file. (probably unnecessary, but prevents the possibility of the same line in the process log file from being written to the program log file more than once.) Performance isn't a concern, and this code won't be going to production. It's just for debugging. On Wed, Mar 14, 2012 at 1:49 PM, Max Slimmer wrote: > If you are really just logging, use separate loggers/files, sync the > clocks, and timestamp records, then merge when you are ready to > process if you need timeline related results. > > > On Wed, Mar 14, 2012 at 1:29 PM, Preston Landers > wrote: > > On Wed, Mar 14, 2012 at 2:55 PM, Tony Cappellini > wrote: > >> > >>> >>in which objects can truly move from one process to another is > >>> >>recreating them in the other process. Even fork() makes copies of > >>> >> everything. > >> > >> Recreating an object in another process means it's a different object, > not a > >> shared one. > > > > Yeah, I know. I was trying to make that point. There's no real way > > for the same object to exist in multiple processes other than SYSV > > shared mem. > > > > Truly shared memory (i.e, SYSV style) is tricky, not very portable, > > and usually the wrong answer in my experience. As fas as I know stock > > Python doesn't support that, and definitely never will on Windows. > > > > The point is that you need to figure out what problem you're really > > trying to solve (logging to one file from multiple processes, it > > sounds like) and then find the best / simplest approach, which I can > > tell you definitely doesn't involve SYSV shared memory. It's > > probably just creating separate logging objects in each process, > > pointing to the same file, and protected by file locking if necessary. > > > > > >>> >>Have you tried pickle or other techniques of serialization? Not sure > >>> >>offhand if the logger module supports pickle but it might. > >> > >> Yes. I've just tried this, even though I expected it not to work. > >> > >> If process A pickles a logger object, and process B unpickles it, > >> referencing of an object in a different process is meaningless. > >> > >> In my case, when the process attempted to write to the logger, no > entries > >> were seen in the logfile. Surprisingly, no exceptions occurred- but this > >> could just be a coincidence. > > > > Probably because the logger object, when serialized, saves a reference > > to an open filehandle, which won't be automatically transfered to the > > other process. > > > > (There might ultimately be a way to make that work by inheriting > > filehandles, but again, if you can find something simpler...) > > > > > >> > >> That may work, and with less effort than my original idea. > >> > >> But if two processes write to the logfile at the same time (especially > on a > >> multicore machine), > >> hard-to-read logfiles may result. > >> it's worth a try. > > > > Yes, that type of thing can occur, but you can also get around that > > with simple file locking. By the way, that same problem certainly > > exists even if you somehow shared the object between two processes - > > what if the two processes made a log call at the same time? > > > > File locking may introduce some performance issues if the logging is > > very frequent, but usually you can find ways to mitigate that. > > > > The main app I work on uses log files extensively, and the same file > > is appended to by unrelated processes without a locking mechanism. > > Occasionally you do see some interleaving of log entries but in my > > experience it's fairly rare and in my particular case we don't care > > much about that anyway. > > > > regards, > > Preston > > _______________________________________________ > > python-win32 mailing list > > python-win32 at python.org > > http://mail.python.org/mailman/listinfo/python-win32 > -------------- next part -------------- An HTML attachment was scrubbed... URL: From python at bdurham.com Thu Mar 15 00:52:38 2012 From: python at bdurham.com (python at bdurham.com) Date: Wed, 14 Mar 2012 19:52:38 -0400 Subject: [python-win32] Passing an object to a process In-Reply-To: References: Message-ID: <1331769158.23937.140661049335885@webmail.messagingengine.com> What about logging to a database? Malcolm -------------- next part -------------- An HTML attachment was scrubbed... URL: From karra.etc at gmail.com Tue Mar 20 02:32:32 2012 From: karra.etc at gmail.com (Sriram ET.) Date: Tue, 20 Mar 2012 07:02:32 +0530 Subject: [python-win32] Convert MAPI error code numbers into meaningful strings Message-ID: Are there any functions in pywin32 to convert, say, 0x8004010f into MAPI_E_NOT_FOUND? In general, what is the common / recommended way to deal with MAPI errors in pywin32 code? Cheers Sriram -------------- next part -------------- An HTML attachment was scrubbed... URL: From timr at probo.com Tue Mar 20 17:45:23 2012 From: timr at probo.com (Tim Roberts) Date: Tue, 20 Mar 2012 09:45:23 -0700 Subject: [python-win32] Convert MAPI error code numbers into meaningful strings In-Reply-To: References: Message-ID: <4F68B423.90407@probo.com> Sriram ET. wrote: > > Are there any functions in pywin32 to convert, say, 0x8004010f > into MAPI_E_NOT_FOUND? Do you mean, convert that number into the string MAPI_E_NOT_FOUND? In general, no. Even the C API does not do that, because in C the symbol MAPI_E_NOT_FOUND is just a compile-time alias for the number 0x8004010f. That is, the string "MAPI_E_NOT_FOUND" will not occur in any C executable. However, you can use the FormatMessage API to get a reasonable string from that: win32api.FormatMessage(0x8004010f) > In general, what is the common / recommended way to deal with MAPI > errors in pywin32 code? I'm not sure it's possible to answer that question. You need to decide that yourself. There are some errors you can recover from gracefully, and for those you can check the numeric values individually. There are other errors that you can't handle, and you shouldn't try. Either show them to the user or let the program expire. -- Tim Roberts, timr at probo.com Providenza & Boekelheide, Inc. From reckoner at gmail.com Wed Mar 21 17:47:04 2012 From: reckoner at gmail.com (reckoner) Date: Wed, 21 Mar 2012 09:47:04 -0700 Subject: [python-win32] Need workaround for error: (299, 'GetModuleFileNameEx' with win32process Message-ID: <4F6A0608.3050600@gmail.com> when using win32process, I get the following error when I try this on a Windows XP 64-bit machine: error: (299, 'GetModuleFileNameEx', 'Only part of a ReadProcessMemory or WriteProcessMemory request was completed.') I don't get this error on a Windows XP 32-bit machine. After some drilling around, I found out that this is because I am using a 32-bit version of win32process to interrogate a 64-bit running application. Now, I have to support both 32 and 64-bit Windows XP systems, so I'm looking for a workaround for this. I am running the 32-bit version of Python on a 64-bit Windows XP system. Any help appreciated. This is for Python version 2.6.2. Thanks! From Jan.Wedel at ettex.de Wed Mar 21 16:53:48 2012 From: Jan.Wedel at ettex.de (Jan Wedel) Date: Wed, 21 Mar 2012 16:53:48 +0100 Subject: [python-win32] How to write a COM Server implementing interfaces from type lib? Message-ID: <15922565.81332345228258.JavaMail.root@server1.ettex.de> Hi, I'm currently having trouble to write a COM-Server that has some special requirements: - It needs to derive from IUnknown - It needs to implement multiple interface from two different proprietary typelibs (dlls) - It needs to implement a custom category At first I started with pythoncom. I used the attribute _reg_catids_ to specify the category and _com_interfaces_ to specify the interfaces I want to implement. The client (proprietary 3rd party sw, no source) sees the server but throws some 0x80004005 error on CoCreateInstance. I was hoping that I can just tell the COM dispatcher, "yes, I have these interface implemented" and implement the methods without really having the interface classes available. I read, that pythoncom can only create components that use IDispatch so I guess the _com_interfaces_ idea won't work, will it? Then I did some further research and found comtypes. I tried to write a server stub again. I used GetModule to load the type library containing the Interfaces, importing the generated interface classes and let the main server class extend these interfaces. The first problem was, that comtypes did not support the _reg_catids_ attribute or anything similar so I had to add the Implemented Categories key manually to the registry. Then, I was able to see the server through the client, which obviously filters by categories, but it still shows the same error as before. So, what is the correct/best way to implement a server that needs to implement custom interfaces and categories? Or is it possible at all using python? Thanks! //Jan -------------- next part -------------- An HTML attachment was scrubbed... URL: From skippy.hammond at gmail.com Thu Mar 22 12:29:41 2012 From: skippy.hammond at gmail.com (Mark Hammond) Date: Thu, 22 Mar 2012 22:29:41 +1100 Subject: [python-win32] How to write a COM Server implementing interfaces from type lib? In-Reply-To: <15922565.81332345228258.JavaMail.root@server1.ettex.de> References: <15922565.81332345228258.JavaMail.root@server1.ettex.de> Message-ID: <4F6B0D25.3000208@gmail.com> On 22/03/2012 2:53 AM, Jan Wedel wrote: > Hi, > > I'm currently having trouble to write a COM-Server that has some special > requirements: > - It needs to derive from IUnknown > - It needs to implement multiple interface from two different > proprietary typelibs (dlls) > - It needs to implement a custom category > > At first I started with pythoncom. I used the attribute _reg_catids_ to > specify the category and _com_interfaces_ to specify the interfaces I > want to implement. The client (proprietary 3rd party sw, no source) sees > the server but throws some 0x80004005 error on CoCreateInstance. That's E_FAIL which is pretty generic. Doesn't sound like a simple failure to QI for the correct interface. win32com should be able to do this given there is a tlb - see the "pippo" samples. Further, using the debug facilities and win32traceutil, you should be able to see the creation of the object, the QIs on the object and any methods actually called. But as mentioned, I doubt it is a QI failure. > I was hoping that I can just tell the COM dispatcher, "yes, I have these > interface implemented" and implement the methods without really having > the interface classes available. > > I read, that pythoncom can only create components that use IDispatch so > I guess the _com_interfaces_ idea won't work, will it? As above, you should be able to fully implement them so long as makepy has been run. > Then I did some further research and found comtypes. I tried to write a > server stub again. I used GetModule to load the type library containing > the Interfaces, importing the generated interface classes and let the > main server class extend these interfaces. > > The first problem was, that comtypes did not support the _reg_catids_ > attribute or anything similar so I had to add the Implemented Categories > key manually to the registry. > Then, I was able to see the server through the client, which obviously > filters by categories, but it still shows the same error as before. > > So, what is the correct/best way to implement a server that needs to > implement custom interfaces and categories? Or is it possible at all > using python? The fact you get the same error there implies something else is going wrong, but it is impossible to guess what. Have you tried contacting the author of the object? Mark > > Thanks! > > //Jan > > > > _______________________________________________ > python-win32 mailing list > python-win32 at python.org > http://mail.python.org/mailman/listinfo/python-win32 From Jan.Wedel at ettex.de Thu Mar 22 13:51:06 2012 From: Jan.Wedel at ettex.de (Jan Wedel) Date: Thu, 22 Mar 2012 13:51:06 +0100 Subject: [python-win32] How to write a COM Server implementing interfaces from type lib? Message-ID: <31664619.191332420666526.JavaMail.root@server1.ettex.de> Hi Mark, thanks for your reply. > That's E_FAIL which is pretty generic. Doesn't sound like a simple > failure to QI for the correct interface. Yeah. The client says something like "Unknown Error" which makes it hard to tell what the problem actually is. > win32com should be able to do this given there is a tlb - see the > "pippo" samples. Further, using the debug facilities and > win32traceutil, you should be able to see the creation of the object, > the QIs on the object and any methods actually called. But as > mentioned, I doubt it is a QI failure. Yeah, there is a type library (OPC DA). Actually there are even two type libraries, each of them contains two Interface which my server needs to implement. I've had a look into policy.py and found that: def _build_typeinfos_(self): # Can only ever be one for now. (...) which means using _typelib_guid_ allows only one type lib, right? I could try to patch your code or do you think there is a general problem that would make it impossible having more than one typelib in your framework? > Have you tried contacting > the author of the object? I am the author... I only use the 3rd party typelibs. I am writing the server that must support the interfaces so that other 3rd party clients can access the server component. I can reproduce the error using python the COMView tool trying to instanciate the Server. The problem is, that I don't see why. I've enabled debugging mode when registering the server. When using one of the 3rd party clients, rhe python trace collector shows the following: Object with win32trace dispatcher created (object=None) Entering constructor in ._QueryInterface_ with unsupported IID {00000003-0000-0000-C000-000000000046} ({00000003-0000-0000-C000-000000000046}) in ._QueryInterface_ with unsupported IID {0000001B-0000-0000-C000-000000000046} ({0000001B-0000-0000-C000-000000000046}) in ._QueryInterface_ with unsupported IID {00000018-0000-0000-C000-000000000046} ({00000018-0000-0000-C000-000000000046}) in ._QueryInterface_ with unsupported IID {4C1E39E1-E3E3-4296-AA86-EC938D896E92} ({4C1E39E1-E3E3-4296-AA86-EC938D896E92}) in ._InvokeEx_-AddConnection(1, 0) [1,0,None] Connection added. Active connections: 1 in ._InvokeEx_-ReleaseConnection(1, 0, 1) [1,0,None] Connection released. Active connections: 0 The QI calls are standard COM calls, not application specific (AFAIK). You can see the "Entering constructor" message which is in my python constructor of the server. Just for fun, I implemented the IExternalConnection interface to see if the methods are called. "Connection added. ..." is my output. But I can't see an further requests that shows what the problem is. Are there any calls in pythoncom that could fail and does not give debug output? My pythoncom server starts like that: class EttexOPCServer: _reg_progid_ = "Ettex.OPC.Automation" _reg_desc_ = "ettex OPC DA Server" _reg_clsid_ = "{13B51E8D-4BC2-4DED-8D4E-4614692F88E6}" _reg_catids_ = [ '{63D5F432-CFE4-11D1-B2C8-0060083BA1FB}' ] _com_interfaces_ = [ '{00000019-0000-0000-C000-000000000046}', # IExternalConnection (Is it really mandatory?) '{39C13A4D-011E-11D0-9675-0020AFD8ADB3}', # IOPCServer '{F31DFDE2-07B6-11D2-B2D8-0060083BA1FB}', # IOPCCommon '{39C13A72-011E-11D0-9675-0020AFD8ADB3}', # IOPCItemProperties '{B196B284-BAB4-101A-B69C-00AA00341D07}' # IConnectionPointContainer ] _typelib_guid_ = "{3B540B51-0378-4551-ADCC-EA9B104302BF}" _typelib_version_ = (3, 0) _reg_clsctx_ = pythoncom.CLSCTX_LOCAL_SERVER _public_methods_ = [ 'Connect', 'Disconnect', 'GetErrorString' ] ## IExternalConnection methods _public_methods_ += [ 'AddConnection', 'ReleaseConnection' ] ################################################################# ## COM Class Attributes ################################################################# _public_attrs_ = [ 'ClientName', 'OPCGroups' ] ################################################################# ## COM Class Read-Only Attributes ################################################################# _readonly_attrs_ = [ 'OPCGroups' ] I don't have all interface methods implemented at the time but I guess that doesn't matter as long as not all type libs have been loaded, does it? If its not possible with pythoncom, is it possible with comtypes? I've tried that as well with nearly the same result ("Unknown error"): # OPC Data Access 3.00 Type Library opc_da_tl = comtypes.GUID("{3B540B51-0378-4551-ADCC-EA9B104302BF}") # OPC Common 1.10 Type Library opc_com_tl = comtypes.GUID("{B28EEDB1-AC6F-11D1-84D5-00608CB8A7E9}") GetModule((opc_da_tl, 3, 0)) GetModule((opc_com_tl, 1, 0)) import comtypes.gen.OPCDA as OpcDa import comtypes.gen.OPCCOMN as OpcCommon class EttexOPCServer2(OpcCommon.IOPCCommon, OpcCommon.IConnectionPointContainer, OpcDa.IOPCServer, OpcDa.IOPCItemProperties): _reg_progid_ = "Ettex.OPC.Automation2" _reg_desc_ = "ettex OPC DA Server 2" _reg_novers_progid_ = _reg_progid_ _reg_clsid_ = "{80A2B8F7-792E-43F4-95F8-CD6BB4B413AD}" _reg_catids_ = [ '{63D5F432-CFE4-11D1-B2C8-0060083BA1FB}' ] _reg_clsctx_ = comtypes.CLSCTX_LOCAL_SERVER _regcls_ = comtypes.server.localserver.REGCLS_MULTIPLEUSE _com_interfaces_ = [OpcCommon.IOPCCommon, OpcCommon.IConnectionPointContainer, OpcDa.IOPCServer, OpcDa.IOPCItemProperties] I don't know what to do. Is there anything more I can do to debug to find out WHAT exactly causes the error? Because as you can see, the pythoncom debug output doesn't show this error that is returned by the client. Thanks a lot! //Jan ----- Originalnachricht ----- Von: "Mark Hammond" Gesendet: Don, 3/22/2012 12:29pm An: "Jan Wedel" Cc: python-win32 at python.org Betreff: Re: [python-win32] How to write a COM Server implementing interfaces from type lib? On 22/03/2012 2:53 AM, Jan Wedel wrote: > Hi, > > I'm currently having trouble to write a COM-Server that has some special > requirements: > - It needs to derive from IUnknown > - It needs to implement multiple interface from two different > proprietary typelibs (dlls) > - It needs to implement a custom category > > At first I started with pythoncom. I used the attribute _reg_catids_ to > specify the category and _com_interfaces_ to specify the interfaces I > want to implement. The client (proprietary 3rd party sw, no source) sees > the server but throws some 0x80004005 error on CoCreateInstance. That's E_FAIL which is pretty generic. Doesn't sound like a simple failure to QI for the correct interface. win32com should be able to do this given there is a tlb - see the "pippo" samples. Further, using the debug facilities and win32traceutil, you should be able to see the creation of the object, the QIs on the object and any methods actually called. But as mentioned, I doubt it is a QI failure. > I was hoping that I can just tell the COM dispatcher, "yes, I have these > interface implemented" and implement the methods without really having > the interface classes available. > > I read, that pythoncom can only create components that use IDispatch so > I guess the _com_interfaces_ idea won't work, will it? As above, you should be able to fully implement them so long as makepy has been run. > Then I did some further research and found comtypes. I tried to write a > server stub again. I used GetModule to load the type library containing > the Interfaces, importing the generated interface classes and let the > main server class extend these interfaces. > > The first problem was, that comtypes did not support the _reg_catids_ > attribute or anything similar so I had to add the Implemented Categories > key manually to the registry. > Then, I was able to see the server through the client, which obviously > filters by categories, but it still shows the same error as before. > > So, what is the correct/best way to implement a server that needs to > implement custom interfaces and categories? Or is it possible at all > using python? The fact you get the same error there implies something else is going wrong, but it is impossible to guess what. Have you tried contacting the author of the object? Mark > > Thanks! > > //Jan > > > > _______________________________________________ > python-win32 mailing list > python-win32 at python.org > http://mail.python.org/mailman/listinfo/python-win32 From Jan.Wedel at ettex.de Thu Mar 22 17:54:41 2012 From: Jan.Wedel at ettex.de (Jan Wedel) Date: Thu, 22 Mar 2012 17:54:41 +0100 Subject: [python-win32] How to write a COM Server implementing interfaces from type lib? Message-ID: <11139111.261332435281595.JavaMail.root@server1.ettex.de> I've actually managed to patch the policy.py to allow multiple typelibraries. Instead of having a definition for interfaces, type library id, version etc i've build this into one tuple. I've created a new attribute that can have multiple of these tuples. The head of my server class now looks like this: class EttexOPCServer: _reg_progid_ = "Ettex.OPC.Automation" _reg_desc_ = "ettex OPC DA Server" _reg_clsid_ = "{13B51E8D-4BC2-4DED-8D4E-4614692F88E6}" _reg_catids_ = [ '{63D5F432-CFE4-11D1-B2C8-0060083BA1FB}' ] _typelib_interfaces_ = [ ("{3B540B51-0378-4551-ADCC-EA9B104302BF}", 3, 0, 0, [ 'IOPCServer', 'IOPCItemProperties', ] ), ("{B28EEDB1-AC6F-11D1-84D5-00608CB8A7E9}", 1, 0, 0, [ 'IOPCCommon', 'IConnectionPointContainer' ] ), ] _reg_clsctx_ = pythoncom.CLSCTX_LOCAL_SERVER I had to patch three locations in policy.py so far and I would be happy to send you my changes if you like. However it still doesn't work but I'm not sure if I have missed something in my patch or if it is a general problem in my server code or a bug in the framework. At least, the client successfully creates the object and tries to call a method of the interface but I get the following debug output: GetStatus() pythoncom error: Failed to call the universal dispatcher Traceback (most recent call last): File "C:\Program Files (x86)\Python\lib\site-packages\win32com\universal.py", line 195, in dispatch WriteFromOutTuple(retVal, meth._gw_out_args, argPtr) TypeError: The VARIANT type is unknown (0x4024). pythoncom error: Unexpected gateway error Traceback (most recent call last): File "C:\Program Files (x86)\Python\lib\site-packages\win32com\universal.py", line 195, in dispatch WriteFromOutTuple(retVal, meth._gw_out_args, argPtr) TypeError: The VARIANT type is unknown (0x4024). GetErrorString -2147467259 0 pythoncom error: Failed to call the universal dispatcher (...) I've hat a lookat the definition of GetStatus. It requires a pointer to a pointer of type "tagOPCSERVERSTATUS" which is a record definition in the type library. But when I look at what has been generated by makepy, the record map looks pretty empty to me: RecordMap = { u'tagOPCITEMVQT': '{00000000-0000-0000-0000-000000000000}', } The type lib defines 10 records! I tried to import the typelib using comtypes and get that generated (excerpt): class tagOPCSERVERSTATUS(Structure): pass # values for enumeration 'tagOPCSERVERSTATE' OPC_STATUS_RUNNING = 1 OPC_STATUS_FAILED = 2 OPC_STATUS_NOCONFIG = 3 OPC_STATUS_SUSPENDED = 4 OPC_STATUS_TEST = 5 OPC_STATUS_COMM_FAULT = 6 tagOPCSERVERSTATE = c_int # enum tagOPCSERVERSTATUS._fields_ = [ ('ftStartTime', _FILETIME), ('ftCurrentTime', _FILETIME), ('ftLastUpdateTime', _FILETIME), ('dwServerState', tagOPCSERVERSTATE), ('dwGroupCount', c_ulong), ('dwBandWidth', c_ulong), ('wMajorVersion', c_ushort), ('wMinorVersion', c_ushort), ('wBuildNumber', c_ushort), ('wReserved', c_ushort), ('szVendorInfo', WSTRING), ] Is there a bug in makepy that prevents creating these records? If yes, can I fix it or can I manually change the generated file to support the records? If not, how would I create and return such a pointer of a pointer in pythoncom? Is comtypes compatible with pythoncom so I could use the comtypes generated files? Thanks! //Jan ----- Originalnachricht ----- Von: "Jan Wedel" Gesendet: Don, 3/22/2012 1:51pm An: mhammond at skippinet.com.au Cc: python-win32 at python.org Betreff: Re: [python-win32] How to write a COM Server implementing interfaces from type lib? Hi Mark, thanks for your reply. > That's E_FAIL which is pretty generic. Doesn't sound like a simple > failure to QI for the correct interface. Yeah. The client says something like "Unknown Error" which makes it hard to tell what the problem actually is. > win32com should be able to do this given there is a tlb - see the > "pippo" samples. Further, using the debug facilities and > win32traceutil, you should be able to see the creation of the object, > the QIs on the object and any methods actually called. But as > mentioned, I doubt it is a QI failure. Yeah, there is a type library (OPC DA). Actually there are even two type libraries, each of them contains two Interface which my server needs to implement. I've had a look into policy.py and found that: def _build_typeinfos_(self): # Can only ever be one for now. (...) which means using _typelib_guid_ allows only one type lib, right? I could try to patch your code or do you think there is a general problem that would make it impossible having more than one typelib in your framework? > Have you tried contacting > the author of the object? I am the author... I only use the 3rd party typelibs. I am writing the server that must support the interfaces so that other 3rd party clients can access the server component. I can reproduce the error using python the COMView tool trying to instanciate the Server. The problem is, that I don't see why. I've enabled debugging mode when registering the server. When using one of the 3rd party clients, rhe python trace collector shows the following: Object with win32trace dispatcher created (object=None) Entering constructor in ._QueryInterface_ with unsupported IID {00000003-0000-0000-C000-000000000046} ({00000003-0000-0000-C000-000000000046}) in ._QueryInterface_ with unsupported IID {0000001B-0000-0000-C000-000000000046} ({0000001B-0000-0000-C000-000000000046}) in ._QueryInterface_ with unsupported IID {00000018-0000-0000-C000-000000000046} ({00000018-0000-0000-C000-000000000046}) in ._QueryInterface_ with unsupported IID {4C1E39E1-E3E3-4296-AA86-EC938D896E92} ({4C1E39E1-E3E3-4296-AA86-EC938D896E92}) in ._InvokeEx_-AddConnection(1, 0) [1,0,None] Connection added. Active connections: 1 in ._InvokeEx_-ReleaseConnection(1, 0, 1) [1,0,None] Connection released. Active connections: 0 The QI calls are standard COM calls, not application specific (AFAIK). You can see the "Entering constructor" message which is in my python constructor of the server. Just for fun, I implemented the IExternalConnection interface to see if the methods are called. "Connection added. ..." is my output. But I can't see an further requests that shows what the problem is. Are there any calls in pythoncom that could fail and does not give debug output? My pythoncom server starts like that: class EttexOPCServer: _reg_progid_ = "Ettex.OPC.Automation" _reg_desc_ = "ettex OPC DA Server" _reg_clsid_ = "{13B51E8D-4BC2-4DED-8D4E-4614692F88E6}" _reg_catids_ = [ '{63D5F432-CFE4-11D1-B2C8-0060083BA1FB}' ] _com_interfaces_ = [ '{00000019-0000-0000-C000-000000000046}', # IExternalConnection (Is it really mandatory?) '{39C13A4D-011E-11D0-9675-0020AFD8ADB3}', # IOPCServer '{F31DFDE2-07B6-11D2-B2D8-0060083BA1FB}', # IOPCCommon '{39C13A72-011E-11D0-9675-0020AFD8ADB3}', # IOPCItemProperties '{B196B284-BAB4-101A-B69C-00AA00341D07}' # IConnectionPointContainer ] _typelib_guid_ = "{3B540B51-0378-4551-ADCC-EA9B104302BF}" _typelib_version_ = (3, 0) _reg_clsctx_ = pythoncom.CLSCTX_LOCAL_SERVER _public_methods_ = [ 'Connect', 'Disconnect', 'GetErrorString' ] ## IExternalConnection methods _public_methods_ += [ 'AddConnection', 'ReleaseConnection' ] ################################################################# ## COM Class Attributes ################################################################# _public_attrs_ = [ 'ClientName', 'OPCGroups' ] ################################################################# ## COM Class Read-Only Attributes ################################################################# _readonly_attrs_ = [ 'OPCGroups' ] I don't have all interface methods implemented at the time but I guess that doesn't matter as long as not all type libs have been loaded, does it? If its not possible with pythoncom, is it possible with comtypes? I've tried that as well with nearly the same result ("Unknown error"): # OPC Data Access 3.00 Type Library opc_da_tl = comtypes.GUID("{3B540B51-0378-4551-ADCC-EA9B104302BF}") # OPC Common 1.10 Type Library opc_com_tl = comtypes.GUID("{B28EEDB1-AC6F-11D1-84D5-00608CB8A7E9}") GetModule((opc_da_tl, 3, 0)) GetModule((opc_com_tl, 1, 0)) import comtypes.gen.OPCDA as OpcDa import comtypes.gen.OPCCOMN as OpcCommon class EttexOPCServer2(OpcCommon.IOPCCommon, OpcCommon.IConnectionPointContainer, OpcDa.IOPCServer, OpcDa.IOPCItemProperties): _reg_progid_ = "Ettex.OPC.Automation2" _reg_desc_ = "ettex OPC DA Server 2" _reg_novers_progid_ = _reg_progid_ _reg_clsid_ = "{80A2B8F7-792E-43F4-95F8-CD6BB4B413AD}" _reg_catids_ = [ '{63D5F432-CFE4-11D1-B2C8-0060083BA1FB}' ] _reg_clsctx_ = comtypes.CLSCTX_LOCAL_SERVER _regcls_ = comtypes.server.localserver.REGCLS_MULTIPLEUSE _com_interfaces_ = [OpcCommon.IOPCCommon, OpcCommon.IConnectionPointContainer, OpcDa.IOPCServer, OpcDa.IOPCItemProperties] I don't know what to do. Is there anything more I can do to debug to find out WHAT exactly causes the error? Because as you can see, the pythoncom debug output doesn't show this error that is returned by the client. Thanks a lot! //Jan ----- Originalnachricht ----- Von: "Mark Hammond" Gesendet: Don, 3/22/2012 12:29pm An: "Jan Wedel" Cc: python-win32 at python.org Betreff: Re: [python-win32] How to write a COM Server implementing interfaces from type lib? On 22/03/2012 2:53 AM, Jan Wedel wrote: > Hi, > > I'm currently having trouble to write a COM-Server that has some special > requirements: > - It needs to derive from IUnknown > - It needs to implement multiple interface from two different > proprietary typelibs (dlls) > - It needs to implement a custom category > > At first I started with pythoncom. I used the attribute _reg_catids_ to > specify the category and _com_interfaces_ to specify the interfaces I > want to implement. The client (proprietary 3rd party sw, no source) sees > the server but throws some 0x80004005 error on CoCreateInstance. That's E_FAIL which is pretty generic. Doesn't sound like a simple failure to QI for the correct interface. win32com should be able to do this given there is a tlb - see the "pippo" samples. Further, using the debug facilities and win32traceutil, you should be able to see the creation of the object, the QIs on the object and any methods actually called. But as mentioned, I doubt it is a QI failure. > I was hoping that I can just tell the COM dispatcher, "yes, I have these > interface implemented" and implement the methods without really having > the interface classes available. > > I read, that pythoncom can only create components that use IDispatch so > I guess the _com_interfaces_ idea won't work, will it? As above, you should be able to fully implement them so long as makepy has been run. > Then I did some further research and found comtypes. I tried to write a > server stub again. I used GetModule to load the type library containing > the Interfaces, importing the generated interface classes and let the > main server class extend these interfaces. > > The first problem was, that comtypes did not support the _reg_catids_ > attribute or anything similar so I had to add the Implemented Categories > key manually to the registry. > Then, I was able to see the server through the client, which obviously > filters by categories, but it still shows the same error as before. > > So, what is the correct/best way to implement a server that needs to > implement custom interfaces and categories? Or is it possible at all > using python? The fact you get the same error there implies something else is going wrong, but it is impossible to guess what. Have you tried contacting the author of the object? Mark > > Thanks! > > //Jan > > > > _______________________________________________ > python-win32 mailing list > python-win32 at python.org > http://mail.python.org/mailman/listinfo/python-win32 _______________________________________________ python-win32 mailing list python-win32 at python.org http://mail.python.org/mailman/listinfo/python-win32 From timr at probo.com Thu Mar 22 22:36:58 2012 From: timr at probo.com (Tim Roberts) Date: Thu, 22 Mar 2012 14:36:58 -0700 Subject: [python-win32] Need workaround for error: (299, 'GetModuleFileNameEx' with win32process In-Reply-To: <4F6A0608.3050600@gmail.com> References: <4F6A0608.3050600@gmail.com> Message-ID: <4F6B9B7A.8090000@probo.com> reckoner wrote: > when using win32process, I get the following error when I try this on a > Windows XP 64-bit machine: > > error: (299, 'GetModuleFileNameEx', 'Only part of a ReadProcessMemory or > WriteProcessMemory request was completed.') > > I don't get this error on a Windows XP 32-bit machine. After some > drilling around, I found out that this is because I am using a 32-bit > version of win32process to interrogate a 64-bit running application. > Now, I have to support both 32 and 64-bit Windows XP systems, so I'm > looking for a workaround for this. I am running the 32-bit version of > Python on a 64-bit Windows XP system. I'm afraid the workaround is to install a 64-bit Python. Alternatively, you could write yourself a very short C helper utility, and compile that for 64-bit. -- Tim Roberts, timr at probo.com Providenza & Boekelheide, Inc. From mhammond at skippinet.com.au Fri Mar 23 00:22:40 2012 From: mhammond at skippinet.com.au (Mark Hammond) Date: Fri, 23 Mar 2012 10:22:40 +1100 Subject: [python-win32] How to write a COM Server implementing interfaces from type lib? In-Reply-To: <31664619.191332420666526.JavaMail.root@server1.ettex.de> References: <31664619.191332420666526.JavaMail.root@server1.ettex.de> Message-ID: <4F6BB440.3050005@skippinet.com.au> On 22/03/2012 11:51 PM, Jan Wedel wrote: > Hi Mark, > > thanks for your reply. > >> That's E_FAIL which is pretty generic. Doesn't sound like a >> simple failure to QI for the correct interface. > > Yeah. The client says something like "Unknown Error" which makes it > hard to tell what the problem actually is. > >> win32com should be able to do this given there is a tlb - see the >> "pippo" samples. Further, using the debug facilities and >> win32traceutil, you should be able to see the creation of the >> object, the QIs on the object and any methods actually called. But >> as mentioned, I doubt it is a QI failure. > > Yeah, there is a type library (OPC DA). Actually there are even two > type libraries, each of them contains two Interface which my server > needs to implement. > > I've had a look into policy.py and found that: > > def _build_typeinfos_(self): # Can only ever be one for now. (...) > > which means using _typelib_guid_ allows only one type lib, right? I > could try to patch your code or do you think there is a general > problem that would make it impossible having more than one typelib in > your framework? Just laziness on my part :) >> Have you tried contacting the author of the object? > > I am the author... I only use the 3rd party typelibs. I am writing > the server that must support the interfaces so that other 3rd party > clients can access the server component. > > I can reproduce the error using python the COMView tool trying to > instanciate the Server. The problem is, that I don't see why. I've > enabled debugging mode when registering the server. When using one of > the 3rd party clients, rhe python trace collector shows the > following: > > Object with win32trace dispatcher created (object=None) Entering > constructor in 0x0213B058>._QueryInterface_ with unsupported IID > {00000003-0000-0000-C000-000000000046} > ({00000003-0000-0000-C000-000000000046}) > in 0x0213B058>._QueryInterface_ with unsupported IID > {0000001B-0000-0000-C000-000000000046} > ({0000001B-0000-0000-C000-000000000046}) > in 0x0213B058>._QueryInterface_ with unsupported IID > {00000018-0000-0000-C000-000000000046} > ({00000018-0000-0000-C000-000000000046}) > in 0x0213B058>._QueryInterface_ with unsupported IID > {4C1E39E1-E3E3-4296-AA86-EC938D896E92} > ({4C1E39E1-E3E3-4296-AA86-EC938D896E92}) > in 0x0213B058>._InvokeEx_-AddConnection(1, 0) [1,0,None] Connection > added. Active connections: 1 in instance at 0x0213B058>._InvokeEx_-ReleaseConnection(1, 0, 1) > [1,0,None] Connection released. Active connections: 0 > > The QI calls are standard COM calls, not application specific > (AFAIK). You can see the "Entering constructor" message which is in > my python constructor of the server. Just for fun, I implemented the > IExternalConnection interface to see if the methods are called. > "Connection added. ..." is my output. But I can't see an further > requests that shows what the problem is. Are there any calls in > pythoncom that could fail and does not give debug output? Not that I'm aware of. > My pythoncom server starts like that: > > class EttexOPCServer: _reg_progid_ = "Ettex.OPC.Automation" > _reg_desc_ = "ettex OPC DA Server" _reg_clsid_ = > "{13B51E8D-4BC2-4DED-8D4E-4614692F88E6}" _reg_catids_ = [ > '{63D5F432-CFE4-11D1-B2C8-0060083BA1FB}' ] _com_interfaces_ = [ > '{00000019-0000-0000-C000-000000000046}', # IExternalConnection (Is > it really mandatory?) '{39C13A4D-011E-11D0-9675-0020AFD8ADB3}', # > IOPCServer '{F31DFDE2-07B6-11D2-B2D8-0060083BA1FB}', # IOPCCommon > '{39C13A72-011E-11D0-9675-0020AFD8ADB3}', # IOPCItemProperties > '{B196B284-BAB4-101A-B69C-00AA00341D07}' # > IConnectionPointContainer ] _typelib_guid_ = > "{3B540B51-0378-4551-ADCC-EA9B104302BF}" _typelib_version_ = (3, 0) > _reg_clsctx_ = pythoncom.CLSCTX_LOCAL_SERVER > > _public_methods_ = [ 'Connect', 'Disconnect', 'GetErrorString' ] ## > IExternalConnection methods _public_methods_ += [ 'AddConnection', > 'ReleaseConnection' ] > > ################################################################# ## > COM Class Attributes > ################################################################# > _public_attrs_ = [ 'ClientName', 'OPCGroups' ] > > ################################################################# ## > COM Class Read-Only Attributes > ################################################################# > _readonly_attrs_ = [ 'OPCGroups' ] > > I don't have all interface methods implemented at the time but I > guess that doesn't matter as long as not all type libs have been > loaded, does it? It wont matter until an attempt is made to call it, and the debug output should reflect that. > > If its not possible with pythoncom, is it possible with comtypes? > I've tried that as well with nearly the same result ("Unknown > error"): > > # OPC Data Access 3.00 Type Library opc_da_tl = > comtypes.GUID("{3B540B51-0378-4551-ADCC-EA9B104302BF}") # OPC Common > 1.10 Type Library opc_com_tl = > comtypes.GUID("{B28EEDB1-AC6F-11D1-84D5-00608CB8A7E9}") > > GetModule((opc_da_tl, 3, 0)) GetModule((opc_com_tl, 1, 0)) > > import comtypes.gen.OPCDA as OpcDa import comtypes.gen.OPCCOMN as > OpcCommon > > class EttexOPCServer2(OpcCommon.IOPCCommon, > OpcCommon.IConnectionPointContainer, OpcDa.IOPCServer, > OpcDa.IOPCItemProperties): _reg_progid_ = "Ettex.OPC.Automation2" > _reg_desc_ = "ettex OPC DA Server 2" _reg_novers_progid_ = > _reg_progid_ _reg_clsid_ = "{80A2B8F7-792E-43F4-95F8-CD6BB4B413AD}" > _reg_catids_ = [ '{63D5F432-CFE4-11D1-B2C8-0060083BA1FB}' ] > _reg_clsctx_ = comtypes.CLSCTX_LOCAL_SERVER _regcls_ = > comtypes.server.localserver.REGCLS_MULTIPLEUSE > > _com_interfaces_ = [OpcCommon.IOPCCommon, > OpcCommon.IConnectionPointContainer, OpcDa.IOPCServer, > OpcDa.IOPCItemProperties] > > I don't know what to do. Is there anything more I can do to debug to > find out WHAT exactly causes the error? Because as you can see, the > pythoncom debug output doesn't show this error that is returned by > the client. It is almost impossible to tell. It could be something quite trivial, like your method not returning exactly what is expected. Somewhere in the client there will be an "if (something_obscure) return E_FAIL;" Sorry I can't seem to be much help... Mark > > Thanks a lot! > > //Jan > > ----- Originalnachricht ----- Von: "Mark > Hammond" Gesendet: Don, 3/22/2012 12:29pm > An: "Jan Wedel" Cc: python-win32 at python.org > Betreff: Re: [python-win32] How to write a COM Server implementing > interfaces from type lib? > > On 22/03/2012 2:53 AM, Jan Wedel wrote: >> Hi, >> >> I'm currently having trouble to write a COM-Server that has some >> special requirements: - It needs to derive from IUnknown - It needs >> to implement multiple interface from two different proprietary >> typelibs (dlls) - It needs to implement a custom category >> >> At first I started with pythoncom. I used the attribute >> _reg_catids_ to specify the category and _com_interfaces_ to >> specify the interfaces I want to implement. The client (proprietary >> 3rd party sw, no source) sees the server but throws some 0x80004005 >> error on CoCreateInstance. > > That's E_FAIL which is pretty generic. Doesn't sound like a simple > failure to QI for the correct interface. > > win32com should be able to do this given there is a tlb - see the > "pippo" samples. Further, using the debug facilities and > win32traceutil, you should be able to see the creation of the > object, the QIs on the object and any methods actually called. But > as mentioned, I doubt it is a QI failure. > >> I was hoping that I can just tell the COM dispatcher, "yes, I have >> these interface implemented" and implement the methods without >> really having the interface classes available. >> >> I read, that pythoncom can only create components that use >> IDispatch so I guess the _com_interfaces_ idea won't work, will >> it? > > As above, you should be able to fully implement them so long as > makepy has been run. > >> Then I did some further research and found comtypes. I tried to >> write a server stub again. I used GetModule to load the type >> library containing the Interfaces, importing the generated >> interface classes and let the main server class extend these >> interfaces. >> >> The first problem was, that comtypes did not support the >> _reg_catids_ attribute or anything similar so I had to add the >> Implemented Categories key manually to the registry. Then, I was >> able to see the server through the client, which obviously filters >> by categories, but it still shows the same error as before. >> >> So, what is the correct/best way to implement a server that needs >> to implement custom interfaces and categories? Or is it possible at >> all using python? > > The fact you get the same error there implies something else is > going wrong, but it is impossible to guess what. Have you tried > contacting the author of the object? > > Mark > >> >> Thanks! >> >> //Jan >> >> >> >> _______________________________________________ python-win32 >> mailing list python-win32 at python.org >> http://mail.python.org/mailman/listinfo/python-win32 > From mhammond at skippinet.com.au Fri Mar 23 00:30:03 2012 From: mhammond at skippinet.com.au (Mark Hammond) Date: Fri, 23 Mar 2012 10:30:03 +1100 Subject: [python-win32] How to write a COM Server implementing interfaces from type lib? In-Reply-To: <11139111.261332435281595.JavaMail.root@server1.ettex.de> References: <11139111.261332435281595.JavaMail.root@server1.ettex.de> Message-ID: <4F6BB5FB.3000205@skippinet.com.au> On 23/03/2012 3:54 AM, Jan Wedel wrote: > I've actually managed to patch the policy.py to allow multiple > typelibraries. > > Instead of having a definition for interfaces, type library id, > version etc i've build this into one tuple. I've created a new > attribute that can have multiple of these tuples. The head of my > server class now looks like this: > > > class EttexOPCServer: _reg_progid_ = "Ettex.OPC.Automation" > _reg_desc_ = "ettex OPC DA Server" _reg_clsid_ = > "{13B51E8D-4BC2-4DED-8D4E-4614692F88E6}" _reg_catids_ = [ > '{63D5F432-CFE4-11D1-B2C8-0060083BA1FB}' ] > > _typelib_interfaces_ = [ ("{3B540B51-0378-4551-ADCC-EA9B104302BF}", > 3, 0, 0, [ 'IOPCServer', 'IOPCItemProperties', ] ), > ("{B28EEDB1-AC6F-11D1-84D5-00608CB8A7E9}", 1, 0, 0, [ 'IOPCCommon', > 'IConnectionPointContainer' ] ), ] _reg_clsctx_ = > pythoncom.CLSCTX_LOCAL_SERVER > > I had to patch three locations in policy.py so far and I would be > happy to send you my changes if you like. That would be great - a patch on sourceforge would be best. However, it might be better to wait until we are sure it is working OK :) > However it still doesn't > work but I'm not sure if I have missed something in my patch or if it > is a general problem in my server code or a bug in the framework. > > At least, the client successfully creates the object and tries to > call a method of the interface but I get the following debug output: > > GetStatus() pythoncom error: Failed to call the universal dispatcher > > Traceback (most recent call last): File "C:\Program Files > (x86)\Python\lib\site-packages\win32com\universal.py", line 195, in > dispatch WriteFromOutTuple(retVal, meth._gw_out_args, argPtr) > TypeError: The VARIANT type is unknown (0x4024). pythoncom error: > Unexpected gateway error > > Traceback (most recent call last): File "C:\Program Files > (x86)\Python\lib\site-packages\win32com\universal.py", line 195, in > dispatch WriteFromOutTuple(retVal, meth._gw_out_args, argPtr) > TypeError: The VARIANT type is unknown (0x4024). GetErrorString > -2147467259 0 pythoncom error: Failed to call the universal > dispatcher > > (...) > > I've hat a lookat the definition of GetStatus. It requires a pointer > to a pointer of type "tagOPCSERVERSTATUS" which is a record > definition in the type library. But when I look at what has been > generated by makepy, the record map looks pretty empty to me: > > RecordMap = { u'tagOPCITEMVQT': > '{00000000-0000-0000-0000-000000000000}', } > > The type lib defines 10 records! I tried to import the typelib using > comtypes and get that generated (excerpt): > > class tagOPCSERVERSTATUS(Structure): pass > > # values for enumeration 'tagOPCSERVERSTATE' OPC_STATUS_RUNNING = 1 > OPC_STATUS_FAILED = 2 OPC_STATUS_NOCONFIG = 3 OPC_STATUS_SUSPENDED = > 4 OPC_STATUS_TEST = 5 OPC_STATUS_COMM_FAULT = 6 tagOPCSERVERSTATE = > c_int # enum tagOPCSERVERSTATUS._fields_ = [ ('ftStartTime', > _FILETIME), ('ftCurrentTime', _FILETIME), ('ftLastUpdateTime', > _FILETIME), ('dwServerState', tagOPCSERVERSTATE), ('dwGroupCount', > c_ulong), ('dwBandWidth', c_ulong), ('wMajorVersion', c_ushort), > ('wMinorVersion', c_ushort), ('wBuildNumber', c_ushort), > ('wReserved', c_ushort), ('szVendorInfo', WSTRING), ] > > Is there a bug in makepy that prevents creating these records? It would seem so :) > If > yes, can I fix it or can I manually change the generated file to > support the records? I'm really not sure - you probably need to look at the existing Record tests. The "PyCOMTest" test object (which is in the source tree and needs you to build it using MSVC) has some structs for testing. > If not, how would I create and return such a > pointer of a pointer in pythoncom? Is comtypes compatible with > pythoncom so I could use the comtypes generated files? Unfortunately there isn't any compatibility between the 2. Cheers, Mark > > Thanks! > > //Jan > > ----- Originalnachricht ----- Von: "Jan Wedel" > Gesendet: Don, 3/22/2012 1:51pm An: mhammond at skippinet.com.au Cc: > python-win32 at python.org Betreff: Re: [python-win32] How to write a > COM Server implementing interfaces from type lib? > > Hi Mark, > > thanks for your reply. > >> That's E_FAIL which is pretty generic. Doesn't sound like a >> simple failure to QI for the correct interface. > > Yeah. The client says something like "Unknown Error" which makes it > hard to tell what the problem actually is. > >> win32com should be able to do this given there is a tlb - see the >> "pippo" samples. Further, using the debug facilities and >> win32traceutil, you should be able to see the creation of the >> object, the QIs on the object and any methods actually called. But >> as mentioned, I doubt it is a QI failure. > > Yeah, there is a type library (OPC DA). Actually there are even two > type libraries, each of them contains two Interface which my server > needs to implement. > > I've had a look into policy.py and found that: > > def _build_typeinfos_(self): # Can only ever be one for now. (...) > > which means using _typelib_guid_ allows only one type lib, right? I > could try to patch your code or do you think there is a general > problem that would make it impossible having more than one typelib in > your framework? > >> Have you tried contacting the author of the object? > > I am the author... I only use the 3rd party typelibs. I am writing > the server that must support the interfaces so that other 3rd party > clients can access the server component. > > I can reproduce the error using python the COMView tool trying to > instanciate the Server. The problem is, that I don't see why. I've > enabled debugging mode when registering the server. When using one of > the 3rd party clients, rhe python trace collector shows the > following: > > Object with win32trace dispatcher created (object=None) Entering > constructor in 0x0213B058>._QueryInterface_ with unsupported IID > {00000003-0000-0000-C000-000000000046} > ({00000003-0000-0000-C000-000000000046}) > in 0x0213B058>._QueryInterface_ with unsupported IID > {0000001B-0000-0000-C000-000000000046} > ({0000001B-0000-0000-C000-000000000046}) > in 0x0213B058>._QueryInterface_ with unsupported IID > {00000018-0000-0000-C000-000000000046} > ({00000018-0000-0000-C000-000000000046}) > in 0x0213B058>._QueryInterface_ with unsupported IID > {4C1E39E1-E3E3-4296-AA86-EC938D896E92} > ({4C1E39E1-E3E3-4296-AA86-EC938D896E92}) > in 0x0213B058>._InvokeEx_-AddConnection(1, 0) [1,0,None] Connection > added. Active connections: 1 in instance at 0x0213B058>._InvokeEx_-ReleaseConnection(1, 0, 1) > [1,0,None] Connection released. Active connections: 0 > > The QI calls are standard COM calls, not application specific > (AFAIK). You can see the "Entering constructor" message which is in > my python constructor of the server. Just for fun, I implemented the > IExternalConnection interface to see if the methods are called. > "Connection added. ..." is my output. But I can't see an further > requests that shows what the problem is. Are there any calls in > pythoncom that could fail and does not give debug output? > > My pythoncom server starts like that: > > class EttexOPCServer: _reg_progid_ = "Ettex.OPC.Automation" > _reg_desc_ = "ettex OPC DA Server" _reg_clsid_ = > "{13B51E8D-4BC2-4DED-8D4E-4614692F88E6}" _reg_catids_ = [ > '{63D5F432-CFE4-11D1-B2C8-0060083BA1FB}' ] _com_interfaces_ = [ > '{00000019-0000-0000-C000-000000000046}', # IExternalConnection (Is > it really mandatory?) '{39C13A4D-011E-11D0-9675-0020AFD8ADB3}', # > IOPCServer '{F31DFDE2-07B6-11D2-B2D8-0060083BA1FB}', # IOPCCommon > '{39C13A72-011E-11D0-9675-0020AFD8ADB3}', # IOPCItemProperties > '{B196B284-BAB4-101A-B69C-00AA00341D07}' # > IConnectionPointContainer ] _typelib_guid_ = > "{3B540B51-0378-4551-ADCC-EA9B104302BF}" _typelib_version_ = (3, 0) > _reg_clsctx_ = pythoncom.CLSCTX_LOCAL_SERVER > > _public_methods_ = [ 'Connect', 'Disconnect', 'GetErrorString' ] ## > IExternalConnection methods _public_methods_ += [ 'AddConnection', > 'ReleaseConnection' ] > > ################################################################# ## > COM Class Attributes > ################################################################# > _public_attrs_ = [ 'ClientName', 'OPCGroups' ] > > ################################################################# ## > COM Class Read-Only Attributes > ################################################################# > _readonly_attrs_ = [ 'OPCGroups' ] > > I don't have all interface methods implemented at the time but I > guess that doesn't matter as long as not all type libs have been > loaded, does it? > > If its not possible with pythoncom, is it possible with comtypes? > I've tried that as well with nearly the same result ("Unknown > error"): > > # OPC Data Access 3.00 Type Library opc_da_tl = > comtypes.GUID("{3B540B51-0378-4551-ADCC-EA9B104302BF}") # OPC Common > 1.10 Type Library opc_com_tl = > comtypes.GUID("{B28EEDB1-AC6F-11D1-84D5-00608CB8A7E9}") > > GetModule((opc_da_tl, 3, 0)) GetModule((opc_com_tl, 1, 0)) > > import comtypes.gen.OPCDA as OpcDa import comtypes.gen.OPCCOMN as > OpcCommon > > class EttexOPCServer2(OpcCommon.IOPCCommon, > OpcCommon.IConnectionPointContainer, OpcDa.IOPCServer, > OpcDa.IOPCItemProperties): _reg_progid_ = "Ettex.OPC.Automation2" > _reg_desc_ = "ettex OPC DA Server 2" _reg_novers_progid_ = > _reg_progid_ _reg_clsid_ = "{80A2B8F7-792E-43F4-95F8-CD6BB4B413AD}" > _reg_catids_ = [ '{63D5F432-CFE4-11D1-B2C8-0060083BA1FB}' ] > _reg_clsctx_ = comtypes.CLSCTX_LOCAL_SERVER _regcls_ = > comtypes.server.localserver.REGCLS_MULTIPLEUSE > > _com_interfaces_ = [OpcCommon.IOPCCommon, > OpcCommon.IConnectionPointContainer, OpcDa.IOPCServer, > OpcDa.IOPCItemProperties] > > I don't know what to do. Is there anything more I can do to debug to > find out WHAT exactly causes the error? Because as you can see, the > pythoncom debug output doesn't show this error that is returned by > the client. > > Thanks a lot! > > //Jan > > ----- Originalnachricht ----- Von: "Mark > Hammond" Gesendet: Don, 3/22/2012 12:29pm > An: "Jan Wedel" Cc: python-win32 at python.org > Betreff: Re: [python-win32] How to write a COM Server implementing > interfaces from type lib? > > On 22/03/2012 2:53 AM, Jan Wedel wrote: >> Hi, >> >> I'm currently having trouble to write a COM-Server that has some >> special requirements: - It needs to derive from IUnknown - It needs >> to implement multiple interface from two different proprietary >> typelibs (dlls) - It needs to implement a custom category >> >> At first I started with pythoncom. I used the attribute >> _reg_catids_ to specify the category and _com_interfaces_ to >> specify the interfaces I want to implement. The client (proprietary >> 3rd party sw, no source) sees the server but throws some 0x80004005 >> error on CoCreateInstance. > > That's E_FAIL which is pretty generic. Doesn't sound like a simple > failure to QI for the correct interface. > > win32com should be able to do this given there is a tlb - see the > "pippo" samples. Further, using the debug facilities and > win32traceutil, you should be able to see the creation of the > object, the QIs on the object and any methods actually called. But > as mentioned, I doubt it is a QI failure. > >> I was hoping that I can just tell the COM dispatcher, "yes, I have >> these interface implemented" and implement the methods without >> really having the interface classes available. >> >> I read, that pythoncom can only create components that use >> IDispatch so I guess the _com_interfaces_ idea won't work, will >> it? > > As above, you should be able to fully implement them so long as > makepy has been run. > >> Then I did some further research and found comtypes. I tried to >> write a server stub again. I used GetModule to load the type >> library containing the Interfaces, importing the generated >> interface classes and let the main server class extend these >> interfaces. >> >> The first problem was, that comtypes did not support the >> _reg_catids_ attribute or anything similar so I had to add the >> Implemented Categories key manually to the registry. Then, I was >> able to see the server through the client, which obviously filters >> by categories, but it still shows the same error as before. >> >> So, what is the correct/best way to implement a server that needs >> to implement custom interfaces and categories? Or is it possible at >> all using python? > > The fact you get the same error there implies something else is > going wrong, but it is impossible to guess what. Have you tried > contacting the author of the object? > > Mark > >> >> Thanks! >> >> //Jan >> >> >> >> _______________________________________________ python-win32 >> mailing list python-win32 at python.org >> http://mail.python.org/mailman/listinfo/python-win32 > > _______________________________________________ python-win32 mailing > list python-win32 at python.org > http://mail.python.org/mailman/listinfo/python-win32 From brad.bennett at receipt.com Fri Mar 23 22:15:48 2012 From: brad.bennett at receipt.com (Bradley Bennett) Date: Fri, 23 Mar 2012 14:15:48 -0700 Subject: [python-win32] Hiring experienced PyWin32 developer Message-ID: <4F06E35B-47DD-4009-A7AE-7D83D0D9C047@receipt.com> Dear PyWin32 developers, We are a software company in Santa Barbara looking to hire a skilled Python for Win32 developer. Information about our company SmartReceipt can be found on the web at (http://receipt.com). Specifically as the opportunity relates to PyWin32, we have a client application that runs on WindowsXP for which we need an experienced Windows and Python developer. We also have a Python/Django running on the backend and are open to finding someone that is a versatile hitter that can work in both areas if possible, but most importantly need that Windows/Python mix of skills on the team. Please contact me directly or by sending resume to careers at receipt.com. Thank you for your consideration and your help in finding us talent is greatly appreciated, Brad Bennett Bradley Bennett | VP Product Development SmartReceipt 55 Castilian Drive Santa Barbara, CA 93117 Office: (805) 617-2184 Mobile: (805) 689-3218 http://receipt.com -------------- next part -------------- An HTML attachment was scrubbed... URL: From shuwj5460 at 163.com Sat Mar 24 08:24:55 2012 From: shuwj5460 at 163.com (shuwj) Date: Sat, 24 Mar 2012 15:24:55 +0800 Subject: [python-win32] a question about word addin , IRibbonExtensibility, GetCustomUI, getImage, IPicture Message-ID: <20120324152455.DB29.AD92716B@163.com> hi, I'm writing an addin for ms word 2010. It will show a tab named JJ in which there are two buttons. one labels doo, the other labels doo2. doo2 should be displayed with customization image(edit.png) but don't show as expected. debugging with pythonwin trace collector debugging tool. there's a exception as following: -------------------------------------------- in _GetIDsOfNames_ with '(u'GetImage',)' and '2048' in _Invoke_ with 1001 2048 1 (,) 0 0 0 c_void_p(111734808) ddd pythoncom error: Python error invoking COM method. TypeError: Objects of type 'c_void_p' can not be converted to a COM VARIANT (but obtaining the buffer() of this object could) --------------------------------------------- can anybody give me some helps? Thanks. -- shuwj -------------- next part -------------- A non-text attachment was scrubbed... Name: edit.png Type: image/png Size: 707 bytes Desc: not available URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: wordaddin-example.py Type: application/octet-stream Size: 4815 bytes Desc: not available URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: gdiplus.py Type: application/octet-stream Size: 2115 bytes Desc: not available URL: From skippy.hammond at gmail.com Sun Mar 25 03:39:06 2012 From: skippy.hammond at gmail.com (Mark Hammond) Date: Sun, 25 Mar 2012 12:39:06 +1100 Subject: [python-win32] a question about word addin , IRibbonExtensibility, GetCustomUI, getImage, IPicture In-Reply-To: <20120324152455.DB29.AD92716B@163.com> References: <20120324152455.DB29.AD92716B@163.com> Message-ID: <4F6E773A.8050407@gmail.com> On 24/03/2012 6:24 PM, shuwj wrote: > hi, > > I'm writing an addin for ms word 2010. It will show a tab named JJ in > which there are two buttons. one labels doo, the other labels doo2. > doo2 should be displayed with customization image(edit.png) but don't > show as expected. > > debugging with pythonwin trace collector debugging tool. there's a > exception as following: > -------------------------------------------- > in _GetIDsOfNames_ with '(u'GetImage',)' and '2048' > > in _Invoke_ with 1001 2048 1 (,) > 0 > 0 > 0 > c_void_p(111734808) ddd > pythoncom error: Python error invoking COM method. > > TypeError: Objects of type 'c_void_p' can not be converted to a COM VARIANT (but obtaining the buffer() of this object could) > --------------------------------------------- > > can anybody give me some helps? I believe a c_void_p is a ctypes construct which aren't supported by pywin32. You need to convert it to a "normal" Python type. I'm guessing it is binary data, so in py2k, you should be able to simply use buffer(some_string_object). The error message seems to imply you may even be able to use buffer(c_void_p_object), but I don't know how they work well enough to suggest that will actually work. Mark From shuwj5460 at 163.com Sun Mar 25 13:33:22 2012 From: shuwj5460 at 163.com (shuwj) Date: Sun, 25 Mar 2012 19:33:22 +0800 Subject: [python-win32] a question about word addin , IRibbonExtensibility, GetCustomUI, getImage, IPicture In-Reply-To: References: Message-ID: <20120325193320.20AD.AD92716B@163.com> > I believe a c_void_p is a ctypes construct which aren't supported by > pywin32. You need to convert it to a "normal" Python type. I'm > guessing it is binary data, so in py2k, you should be able to simply use > buffer(some_string_object). The error message seems to imply you may > even be able to use buffer(c_void_p_object), but I don't know how they > work well enough to suggest that will actually work. > > Mark > Hi Mark, Thanks for your reply. I use buffer() in GetImage method and there's no exception now, but they don't work as expected. ----------------------------------------- class wordaddin: def GetImage(self,ctrl): from gdiplus import LoadImage i = LoadImage( 'c:/edit.png' ) i = buffer(i) print i, 'ddd' return i ----------------------------------------- gdiplus.py is as following: ----------------------------------------- #coding: gbk from ctypes import * from ctypes.wintypes import * from comtypes import GUID oleaut32 = windll.oleaut32 gdiplus = windll.gdiplus class GdiplusStartupInput(Structure): _fields_ = [ ('GdiplusVersion', c_uint32), ('DebugEventCallback', c_void_p), ('SuppressBackgroundThread', BOOL), ('SuppressExternalCodecs', BOOL) ] class GdiplusStartupOutput(Structure): _fields = [ ('NotificationHookProc', c_void_p), ('NotificationUnhookProc', c_void_p) ] class PicDesc(Structure): _fields_ = [ ('Size', UINT), ('Type', UINT), ('hPic', HBITMAP), ('hPal', HPALETTE) ] PICTYPE_BITMAP = 1 def LoadImage(filename): '''Load an image from a file. ''' #Initaialize GDI+ token = c_ulong() startup_in = GdiplusStartupInput() startup_in.GdiplusVersion = 1 startup_out = GdiplusStartupOutput() u = gdiplus.GdiplusStartup( byref(token), byref(startup_in), byref(startup_out)) fname = LPOLESTR( filename ) bitmap = c_void_p() gdiImage = c_void_p() x = LPVOID() if u == 0: print u #Load the image v = gdiplus.GdipCreateBitmapFromFile( fname, byref(gdiImage) ) if v == 0: print v #Create a bitmap handle from the GDI image gdiplus.GdipCreateHBITMAPFromBitmap( gdiImage, byref(bitmap), 0 ) #Create the IPicture object from the bitmap handle IID_IPicture = GUID('{7BF80980-BF32-101A-8BBB-00AA00300CAB}' ) picinfo = PicDesc( Type=PICTYPE_BITMAP, hPic=bitmap, hPal=0 ) picinfo.Size = picinfo.__sizeof__() print oleaut32.OleCreatePictureIndirect( byref(picinfo), byref(IID_IPicture), True, byref(x) ) gdiplus.GdipDisposeImage( gdiImage) gdiplus.GdiplusShutdown( token ) return x -- shuwj From skippy.hammond at gmail.com Sun Mar 25 14:27:39 2012 From: skippy.hammond at gmail.com (Mark Hammond) Date: Sun, 25 Mar 2012 23:27:39 +1100 Subject: [python-win32] a question about word addin , IRibbonExtensibility, GetCustomUI, getImage, IPicture In-Reply-To: <20120325193320.20AD.AD92716B@163.com> References: <20120325193320.20AD.AD92716B@163.com> Message-ID: <4F6F0F3B.4010209@gmail.com> I'm not familiar enough with ctypes to know if that makes sense, but I doubt it - nothing would seem to know the size of the buffer pointed at by 'x'. You probably need to stick with using a python string object - ensure the string contains exactly the bytes of the metafile. Mark On 25/03/2012 10:33 PM, shuwj wrote: > >> I believe a c_void_p is a ctypes construct which aren't supported by >> pywin32. You need to convert it to a "normal" Python type. I'm >> guessing it is binary data, so in py2k, you should be able to simply use >> buffer(some_string_object). The error message seems to imply you may >> even be able to use buffer(c_void_p_object), but I don't know how they >> work well enough to suggest that will actually work. >> >> Mark >> > > Hi Mark, > Thanks for your reply. I use buffer() in GetImage method and there's no > exception now, but they don't work as expected. > > > ----------------------------------------- > class wordaddin: > def GetImage(self,ctrl): > from gdiplus import LoadImage > i = LoadImage( 'c:/edit.png' ) > i = buffer(i) > print i, 'ddd' > return i > ----------------------------------------- > > > gdiplus.py is as following: > ----------------------------------------- > #coding: gbk > > from ctypes import * > from ctypes.wintypes import * > from comtypes import GUID > > oleaut32 = windll.oleaut32 > gdiplus = windll.gdiplus > > > class GdiplusStartupInput(Structure): > _fields_ = [ > ('GdiplusVersion', c_uint32), > ('DebugEventCallback', c_void_p), > ('SuppressBackgroundThread', BOOL), > ('SuppressExternalCodecs', BOOL) > ] > > class GdiplusStartupOutput(Structure): > _fields = [ > ('NotificationHookProc', c_void_p), > ('NotificationUnhookProc', c_void_p) > ] > > > class PicDesc(Structure): > _fields_ = [ > ('Size', UINT), > ('Type', UINT), > ('hPic', HBITMAP), > ('hPal', HPALETTE) > ] > > PICTYPE_BITMAP = 1 > > def LoadImage(filename): > '''Load an image from a file. > ''' > > #Initaialize GDI+ > token = c_ulong() > startup_in = GdiplusStartupInput() > startup_in.GdiplusVersion = 1 > startup_out = GdiplusStartupOutput() > u = gdiplus.GdiplusStartup( byref(token), byref(startup_in), byref(startup_out)) > > fname = LPOLESTR( filename ) > bitmap = c_void_p() > gdiImage = c_void_p() > x = LPVOID() > > if u == 0: > print u > #Load the image > v = gdiplus.GdipCreateBitmapFromFile( fname, byref(gdiImage) ) > if v == 0: > print v > > #Create a bitmap handle from the GDI image > gdiplus.GdipCreateHBITMAPFromBitmap( gdiImage, byref(bitmap), 0 ) > > #Create the IPicture object from the bitmap handle > IID_IPicture = GUID('{7BF80980-BF32-101A-8BBB-00AA00300CAB}' ) > picinfo = PicDesc( Type=PICTYPE_BITMAP, hPic=bitmap, hPal=0 ) > picinfo.Size = picinfo.__sizeof__() > > print oleaut32.OleCreatePictureIndirect( byref(picinfo), byref(IID_IPicture), True, byref(x) ) > > gdiplus.GdipDisposeImage( gdiImage) > > gdiplus.GdiplusShutdown( token ) > > > return x > > > > > > From sleerssen at gmail.com Mon Mar 26 21:08:26 2012 From: sleerssen at gmail.com (Scott Leerssen) Date: Mon, 26 Mar 2012 15:08:26 -0400 Subject: [python-win32] writing DWORD values > 0x7ffffff Message-ID: I'm trying to write a DWORD value to the registry using _winreg.SetValueEx and anything greater than 0x7fffffff yields a "ValueError: Could not convert the data to the specified type." I've seen a few posts saying that taking the complement of the large integer (basically making it a negative value) satisfies the API and fools it into storing the value, but that has the same result in my experiments. Any hints as to how to write large integers int a DWORD? Python 2.7.2 Thanks, Scott From timr at probo.com Mon Mar 26 21:20:48 2012 From: timr at probo.com (Tim Roberts) Date: Mon, 26 Mar 2012 12:20:48 -0700 Subject: [python-win32] writing DWORD values > 0x7ffffff In-Reply-To: References: Message-ID: <4F70C190.8060703@probo.com> Scott Leerssen wrote: > I'm trying to write a DWORD value to the registry using _winreg.SetValueEx and anything greater than 0x7fffffff yields a "ValueError: Could not convert the data to the specified type." I've seen a few posts saying that taking the complement of the large integer (basically making it a negative value) satisfies the API and fools it into storing the value, but that has the same result in my experiments. Any hints as to how to write large integers int a DWORD? Ugly but functional: dw = struct.unpack('l',struct.pack('L', 0x80102030))[0] -- Tim Roberts, timr at probo.com Providenza & Boekelheide, Inc. From sleerssen at gmail.com Mon Mar 26 21:35:44 2012 From: sleerssen at gmail.com (Scott Leerssen) Date: Mon, 26 Mar 2012 15:35:44 -0400 Subject: [python-win32] writing DWORD values > 0x7ffffff In-Reply-To: <4F70C190.8060703@probo.com> References: <4F70C190.8060703@probo.com> Message-ID: On Mar 26, 2012, at 3:20 PM, Tim Roberts wrote: > Scott Leerssen wrote: >> I'm trying to write a DWORD value to the registry using _winreg.SetValueEx and anything greater than 0x7fffffff yields a "ValueError: Could not convert the data to the specified type." I've seen a few posts saying that taking the complement of the large integer (basically making it a negative value) satisfies the API and fools it into storing the value, but that has the same result in my experiments. Any hints as to how to write large integers int a DWORD? > > Ugly but functional: > dw = struct.unpack('l',struct.pack('L', 0x80102030))[0] Thanks, that does the trick. Scott From sleerssen at gmail.com Mon Mar 26 21:57:53 2012 From: sleerssen at gmail.com (Scott Leerssen) Date: Mon, 26 Mar 2012 15:57:53 -0400 Subject: [python-win32] writing DWORD values > 0x7ffffff In-Reply-To: <4F70C190.8060703@probo.com> References: <4F70C190.8060703@probo.com> Message-ID: On Mar 26, 2012, at 3:20 PM, Tim Roberts wrote: > Scott Leerssen wrote: >> I'm trying to write a DWORD value to the registry using _winreg.SetValueEx and anything greater than 0x7fffffff yields a "ValueError: Could not convert the data to the specified type." I've seen a few posts saying that taking the complement of the large integer (basically making it a negative value) satisfies the API and fools it into storing the value, but that has the same result in my experiments. Any hints as to how to write large integers int a DWORD? > > Ugly but functional: > dw = struct.unpack('l',struct.pack('L', 0x80102030))[0] It looks like I need to employ the inverse of that when reading large values back out of the registry, since a simple QueryValueEx() on that value is a negative integer. From mail at timgolden.me.uk Mon Mar 26 22:03:24 2012 From: mail at timgolden.me.uk (Tim Golden) Date: Mon, 26 Mar 2012 21:03:24 +0100 Subject: [python-win32] writing DWORD values > 0x7ffffff In-Reply-To: <4F70C190.8060703@probo.com> References: <4F70C190.8060703@probo.com> Message-ID: <4F70CB8C.60302@timgolden.me.uk> On 26/03/2012 20:20, Tim Roberts wrote: > dw = struct.unpack('l',struct.pack('L', 0x80102030))[0] Seconded: I've used almost exactly this incantation for various Windows-y things for a few years now. TJG From jan.wedel at ettex.de Tue Mar 27 10:06:33 2012 From: jan.wedel at ettex.de (Jan Wedel) Date: Tue, 27 Mar 2012 10:06:33 +0200 Subject: [python-win32] How to write a COM Server implementing interfaces from type lib? In-Reply-To: <4F70ECAA.6090204@skippinet.com.au> References: <15907973.571332755494115.JavaMail.root@server1.ettex.de> Message-ID: <4F717509.8000007@ettex.de> I tried the following from the console: >>> import pythoncom Get the type lib: >>> TL_OPC_DA = pythoncom.LoadRegTypeLib('{3B540B51-0378-4551-ADCC-EA9B104302BF}', 3, 0, 0) >>> TL_OPC_DA Index 8 is the record I try to create: >>> TL_OPC_DA.GetTypeInfo(8) >>> recinfo = TL_OPC_DA.GetTypeInfo(8) Cast to ICreateTypeInfo: >>> icti = recinfo.QueryInterface(pythoncom.IID_ICreateTypeInfo) >>> icti Set random GUID: >>> icti.SetGuid(pythoncom.CreateGuid()) BAM! : >>> pythoncom.GetRecordFromTypeInfo(icti) Traceback (most recent call last): File "", line 1, in pywintypes.com_error: (-2147024809, 'Falscher Parameter.', None, None) Try another cast because I wasn't sure that GetRecordFromTypeInfo supports/checks the ICreateTypeInfo interface. >>> iti = icti.QueryInterface(pythoncom.IID_ITypeInfo) >>> iti BAM! : >>> pythoncom.GetRecordFromTypeInfo(iti) Traceback (most recent call last): File "", line 1, in pywintypes.com_error: (-2147024809, 'Falscher Parameter.', None, None) Unfortunately, as you can see, it doesn't work. Do you know if there is a way to get a more verbose error message or some COM debugging console to know what COM is actually complaining about? I mean, I'm pretty sure that it works as you assumed (Like COM tries to get the GUID from the TypeInfo and then calls GetRecordFromGuid which would explain why setting a GUID still doesnt work) but just to make sure, you know? //Jan Am 27.03.2012 00:24, schrieb Mark Hammond: > On 26/03/2012 8:51 PM, Jan Wedel wrote: >>> I'm confident the E_INVALIDARG error is coming from COM itself. It >> >>> wouldn't surprise me at all to find GetRecordInfoFromTypeInfo simply >> >>> uses the type info to fetch the GUID of the record then calls the >> >>> ...FromGuids method. >> >> >> >> Yeah, maybe. I just tried to find some explanation and found this: >> >> http://www.autohotkey.com/forum/topic84172.html >> >> >> >> This thread seems to be related and presents a solution. As far as I >> understand, COM is complaining because the UUID is missing and in this >> solution a random GUID is created and attached to the typeinfo... > > That's interesting and might well work. It could all be done from > pure Python as ICreateTypeInfo is exposed. > >>> It might be possible to write all the info needed to the generated >>> file, >> >>> but it would probably take a fair bit of work. If you look later in >> >>> PyRecord.cpp, all the "set attribute" and "get attribute" code is >> >>> implemented by way of the IRecordInfo interface - eg, GetFieldNoCopy. >> >>> It might be possible to steal the code from comtypes, but I'm not >> >>> familiar with that. >> >> >> >> The question is, is it necessaey to use the C++ part at all? Would it be >> possible to just keep the Record stuff in pure python? Why would it be >> necessary to dynamically loade the TypeInfo from a DLL that most likely >> will not change that often? > > The problem is the code that knows what "something = > aRecord.someAtribute" does. It needs to know how to move the memory > around so the right thing happens - that is what GetFieldNoCopy does. > >> The thing is, I'm currently working on a customer project and >> unfortunately I need this stuff getting to work soon. I would really >> appreciate you applying a fix to the C++ layer of pythoncom if possible >> at all. But I also understand that you can't spend all your spare time >> on that problem. > > I'd be happy to apply a fix if I knew what the fix was. From pure > Python, you might be able to: > > * load the typelib > * find the type info for the guid. > * QI the type info for ICreateTypeInfo. > * Set the GUID to some random GUID. > * Call pythoncom.GetRecordFromTypeInfo with the modified typeinfo. > * Use the result object as normal. > >> So, if it's not easy for you to fix this, could you tell me what would >> be necessary to fix or work-around this? My "vision" is to manually >> create a static definition of all relevant structs somewhere which might >> be just laborious work. > > The problem is how that static info is actually used rather than the > generation of it. Some code will need to use that static info to > support getting and setting attributes on the record. > >> My problem is that I don't know much about the >> internals of COM. Is it possible to write a pure python class that has >> the correct attributes and methods so I can return an instance of this >> class from a COM method of my server and the receiver and COM itself >> would be able to interpret it as the correct struct or does it require >> some native code? > > It would almost certainly require some native (or ctypes) code to do > it all statically without an IRecordInfo interface to perform the > heavy lifting. > > I'll try and find time to use one of the pywin32 test objects to see > if this can work by dynamically setting a GUID, but it is unlikely to > happen for a few days. > > Cheers, > > Mark >> >> >> >> //Jan >> >> ----- Originalnachricht ----- >> Von: "Mark Hammond" >> Gesendet: Sam, 24.3.2012 00:53 >> An: "Jan Wedel" >> Betreff: Re: AW: AW: AW: AW: [python-win32] How to write a COM Server >> implementing interfaces from type lib? >> >> I'm confident the E_INVALIDARG error is coming from COM itself. It >> wouldn't surprise me at all to find GetRecordInfoFromTypeInfo simply >> uses the type info to fetch the GUID of the record then calls the >> ...FromGuids method. >> >> It might be possible to write all the info needed to the generated file, >> but it would probably take a fair bit of work. If you look later in >> PyRecord.cpp, all the "set attribute" and "get attribute" code is >> implemented by way of the IRecordInfo interface - eg, GetFieldNoCopy. >> It might be possible to steal the code from comtypes, but I'm not >> familiar with that. >> >> Cheers, >> >> Mark >> >> On 24/03/2012 2:39 AM, Jan Wedel wrote: >>>> Obviously this is a "dynamic" process - other languages/tools etc are >>>> likely to use these struct definitions at compile time >>> >>> What about writing all necessary information into the generated type >>> lib files like comtypes is doing it? Or do you need to have some >>> native objects? >>> >>>> (...)it might be worth poking around the MS docs and see if they >>>> offer any way to get an IRecordInfo given just the typelib info and >>>> the >>>> struct name, as that seems the only info we have at the time we >>>> need it. >>>> If we can find something I'll try and add the support and send >>>> you a >>>> custom built pythoncomxx.dll. >>> >>> There is some modification of the Record method necessary. In my >>> server I pass an object created by GetModuleForTypelib(...) to the >>> Record() method. Inside, I check if its a nodule. If yes, I load the >>> typelib using pythoncom.LoadRegTypeLib(...) (don't know if its >>> already cached somewhere, but it was my quick and dirty attempt). >>> I've checked the MS doc and found a second method to retrieve the >>> Record object. Using the returned library object, I used >>> pythoncom.GetRecordFromTypeInfo(tlib.GetTypeInfo(8)) to retrieve the >>> Record from the type info object instead of GetRecordFromGuids. >>> >>> The "8" is hard coded for testing and is the library index of the >>> Record. If this idea could work, it's probably worth to add the >>> index to the "RecordMap" when generating the file so we have an >>> alternative look-up key instead of the GUID. >>> >>> However, it doesn't work either and gives the following result: >>> >>> Traceback (most recent call last): >>> File "C:\Program Files >>> (x86)\Python\lib\site-packages\win32com\universal.py", line 179, in >>> dispatch >>> retVal = ob._InvokeEx_(meth.dispid, 0, meth.invkind, args, >>> None, None) >>> File "C:\Program Files >>> (x86)\Python\lib\site-packages\win32com\server\policy.py", line 346, >>> in _InvokeEx_ >>> return self._invokeex_(dispid, lcid, wFlags, args, kwargs, >>> serviceProvider) >>> File "C:\Program Files >>> (x86)\Python\lib\site-packages\win32com\server\policy.py", line 650, >>> in _invokeex_ >>> return func(*args) >>> File "C:\temp\opc\PyOPCComServer.py", line 241, in GetStatus >>> status = Record("tagOPCSERVERSTATUS", GEN_TL_OPC_DA) >>> File "C:\Program Files >>> (x86)\Python\lib\site-packages\win32com\client\__init__.py", line >>> 403, in Record >>> return pythoncom.GetRecordFromTypeInfo(tlib.GetTypeInfo(8)) >>> com_error: (-2147024809, 'Falscher Parameter.', None, None) >>> >>> Which means E_INVALIDARG. I've checked the source code of >>> PyRecord.cpp and it says "This function will fail if the specified >>> type info does not have a guid defined". >>> >>> I don't know if this is a COM or PythonCom limitation... If it's the >>> latter, I would really appreciate fixing the C++ code. Otherwise, it >>> might help, having the whole definition inside the generate python >>> file as explained above. >>> >>> Thanks a lot for your help! >>> >>> //Jan >>> >>> >>> ----- Originalnachricht ----- >>> Von: "Mark Hammond" >>> Gesendet: Fre, 3/23/2012 2:43pm >>> An: "Jan Wedel" >>> Betreff: Re: AW: AW: AW: [python-win32] How to write a COM Server >>> implementing interfaces from type lib? >>> >>> So - looking at the source, the win32com.client.Record object attempts >>> to look up both the tlb guid and the record guid based on the name >>> using >>> that RecordMap dict we talked about. From there, we should wind up in >>> win32com\src\PyRecord.cpp, where we use the typelib info and the struct >>> GUID to call the COM function GetRecordInfoFromGuids(), which takes >>> those GUIDs and returns an IRecordInfo interface that tells us all the >>> struct element names and types etc. >>> >>> Obviously this is a "dynamic" process - other languages/tools etc are >>> likely to use these struct definitions at compile time, which may >>> explain why they have a NULL guid - they assume people wont need to >>> look >>> them up at runtime using GetRecordInfoFromGuids. It is late and I must >>> hit bed, but it might be worth poking around the MS docs and see if >>> they >>> offer any way to get an IRecordInfo given just the typelib info and the >>> struct name, as that seems the only info we have at the time we need >>> it. >>> If we can find something I'll try and add the support and send >>> you a >>> custom built pythoncomxx.dll. >>> >>> Cheers, >>> >>> Mark >>> >>> On 24/03/2012 12:06 AM, Jan Wedel wrote: >>>> I tried to manually add the Records to the generated file to see if >>>> patching genpy.py would solve the problem: >>>> >>>> RecordMap = { >>>> u'tagOPCITEMVQT': '{00000000-0000-0000-0000-000000000000}', >>>> u'tagOPCSERVERSTATE': '{00000000-0000-0000-0000-000000000000}', >>>> u'tagOPCSERVERSTATUS': >>>> '{00000000-0000-0000-0000-000000000000}', >>>> } >>>> >>>> The client calls the GetStatus() method of my server which is >>>> implemented as follows: >>>> >>>> def GetStatus(self): >>>> """Returns the current server status""" >>>> print "GetStatus()" >>>> >>>> # return None >>>> status = Record("tagOPCSERVERSTATUS", self) >>>> >>>> status.ftStartTime = pywintypes.Time(self.start_time) >>>> status.ftCurrentTime = pywintypes.Time(time.time()) >>>> status.ftLastUpdateTime = >>>> pywintypes.Time(self.last_update_time) >>>> status.dwServerState = ServerState.RUNNING >>>> status.dwGroupCount = len(self.groups) >>>> status.dwBandWidth = self.band_width >>>> status.wMajorVersion = MAJOR_VERSION >>>> status.wMinorVersion = MINOR_VERSION >>>> status.wBuildNumber = BUILD_NUMBER >>>> status.wReserved = 0 >>>> status.szVendorInfo = VENDOR_INFO >>>> >>>> return status >>>> >>>> with the following result: >>>> >>>> GetStatus() >>>> pythoncom error: Failed to call the universal dispatcher >>>> >>>> Traceback (most recent call last): >>>> File "C:\Program Files >>>> (x86)\Python\lib\site-packages\win32com\universal.py",line 179, in >>>> dispatch >>>> retVal = ob._InvokeEx_(meth.dispid, 0, meth.invkind, args, >>>> None, None) >>>> File "C:\Program Files >>>> (x86)\Python\lib\site-packages\win32com\server\policy.py", line >>>> 346, in _InvokeEx_ >>>> return self._invokeex_(dispid, lcid, wFlags, args, kwargs, >>>> serviceProvider) >>>> File "C:\Program Files >>>> (x86)\Python\lib\site-packages\win32com\server\policy.py", line >>>> 650, in _invokeex_ >>>> return func(*args) >>>> File "C:\temp\opc\PyOPCComServer.py", line 234, in GetStatus >>>> status = Record("tagOPCSERVERSTATUS", self) >>>> File "C:\Program Files >>>> (x86)\Python\lib\site-packages\win32com\client\__init__.py", line >>>> 399, in Record >>>> object = gencache.EnsureDispatch(object) >>>> File "C:\Program Files >>>> (x86)\Python\lib\site-packages\win32com\client\gencache.py", line >>>> 529, in EnsureDispatch >>>> disp = win32com.client.Dispatch(prog_id) >>>> File "C:\Program Files >>>> (x86)\Python\lib\site-packages\win32com\client\__init__.py", line >>>> 96, in Dispatch >>>> return __WrapDispatch(dispatch, userName, resultCLSID, >>>> typeinfo, clsctx=clsctx) >>>> File "C:\Program Files >>>> (x86)\Python\lib\site-packages\win32com\client\__init__.py", line >>>> 43, in __WrapDispatch >>>> return dynamic.Dispatch(dispatch, userName, WrapperClass, >>>> typeinfo, clsctx=clsctx) >>>> File "C:\Program Files >>>> (x86)\Python\lib\site-packages\win32com\client\dynamic.py", line >>>> 122, in Dispatch >>>> typeinfo = IDispatch.GetTypeInfo() >>>> AttributeError: EttexOPCServer instance has no attribute 'GetTypeInfo' >>>> >>>> pythoncom error: Failed to call the universal dispatcher >>>> >>>> Traceback (most recent call last): >>>> File "C:\Program Files >>>> (x86)\Python\lib\site-packages\win32com\universal.py", >>>> line 195, in dispatch >>>> WriteFromOutTuple(retVal, meth._gw_out_args, argPtr) >>>> TypeError: The VARIANT type is unknown (0x4024). >>>> >>>> If found an example of how to create a Record. However, it does use >>>> client COM and passes the object generated by Dispatch() to the >>>> Record constructor. What object should I pass on the server side? >>>> Obviously "self" doesn't work... >>>> >>>> Then I tried to return None instead which should leave the output >>>> arguments untouch, but I only get the "TypeError: The VARIANT type >>>> is unknown (0x4024)." message. The 0x4024 is 16420 and can be found >>>> in the vtable definition of the generated file: >>>> >>>> IOPCServer_vtables_ = [ >>>> (...) >>>> (( u'GetStatus' , u'ppServerStatus' , ), 1610678275, >>>> (1610678275, (), [ (16420, 2, None, None) , ], 1 , 1 , 4 , 0 , 24 , >>>> (3, 0, None, None) , 0 , )), >>>> (...) >>>> >>>> I was asking myself how does this 16420 from the vtable gets >>>> translated into a "Ptr Ptr tagOPCSERVERSTATUS"? How does the record >>>> definition know what fields it contains? Is is probably necessary >>>> to add some more information to the Record such as this number, >>>> e.g? Or does the internal COM libs uses the TypeLib information to >>>> resolve it? It tried to look into the source of this type error but >>>> the WriteFromOutTuple method is somewhere inside the pythoncom dll... >>>> >>>> I'm really stuck here... >>>> >>>> //Jan >>>> >>>> >>>> >>>> ----- Originalnachricht ----- >>>> Von: "Mark Hammond" >>>> Gesendet: Fre, 3/23/2012 12:11pm >>>> An: "Jan Wedel" >>>> Betreff: Re: AW: AW: [python-win32] How to write a COM Server >>>> implementing interfaces from type lib? >>>> >>>> I haven't got the code in front of me, but in that place it would >>>> probably be OK to use the name. I'm slightly worried about the >>>> "global" >>>> resolution though - there's probably code that can find a record given >>>> just the GUID and without regard for which tlb it was defined in >>>> (ie, so >>>> the name itself need not be unique). In that case, a tuple of >>>> (typelib_guid, name) would probably be OK. >>>> >>>> Mark >>>> >>>> On 23/03/2012 7:54 PM, Jan Wedel wrote: >>>>> After I wrote my last mail, I did some further research on the >>>>> problem. In genpy.py where the python file is generated for the >>>>> type lib, I found this code: >>>>> >>>>> print>> stream, 'RecordMap = {' >>>>> for record in recordItems.itervalues(): >>>>> if str(record.clsid) == pythoncom.IID_NULL: >>>>> print>> stream, "\t###%s: %s, # Typedef disabled >>>>> because it doesn't have a non-null GUID" % (repr(record.doc[0]), >>>>> repr(str(record.clsid))) >>>>> else: >>>>> print>> stream, "\t%s: %s," % >>>>> (repr(record.doc[0]), repr(str(record.clsid))) >>>>> print>> stream, "}" >>>>> >>>>> I've checked the typelib with COMView, and all records, modules >>>>> and enums defined have the UUID {00000-...00000} assigned. Then >>>>> I've checked some random other type libs I've found on my computer >>>>> and it seems that they are always using {0000...0000}. I don't >>>>> know much about COM but I guess this must be OK. The type lib I'm >>>>> using is made by the OPC foundation and there must be a numerous >>>>> COM clients using it so it can't be that wrong, can it? >>>>> >>>>> The question is, is it possible to create a Record object in my >>>>> server class and return it without the need of having a unique >>>>> UUID assignedand without the need of beeing defined by genyp? >>>>> >>>>> If that doesn't work, I might also try to patch the genpy.py, but >>>>> it seems as if you rely on the CLSID being unique. in the >>>>> BuildOleItemsFromType method, there is the following code: >>>>> >>>>> elif infotype == pythoncom.TKIND_RECORD or infotype == >>>>> pythoncom.TKIND_UNION: >>>>> newItem = RecordItem(info, attr, doc) >>>>> recordItems[newItem.clsid] = newItem >>>>> >>>>> Because all records have the same clsid, they get overwritten by >>>>> each other. There probably must be some other identification >>>>> mechanism. Either we use an index or the record name itself... But >>>>> then COM methods must be aware of these type in input and output >>>>> parameters... >>>>> >>>>> Do have any suggestion on how to proceed (patch/work-around)? >>>>> >>>>> Thanks! >>>>> >>>>> //Jan >>>>> >>>>> >>>>> ----- Originalnachricht ----- >>>>> Von: "Mark Hammond" >>>>> Gesendet: Fre, 3/23/2012 12:30am >>>>> An: "Jan Wedel" >>>>> Cc: python-win32 at python.org >>>>> Betreff: Re: AW: [python-win32] How to write a COM Server >>>>> implementing interfaces from type lib? >>>>> >>>>> On 23/03/2012 3:54 AM, Jan Wedel wrote: >>>>>> I've actually managed to patch the policy.py to allow multiple >>>>>> typelibraries. >>>>>> >>>>>> Instead of having a definition for interfaces, type library id, >>>>>> version etc i've build this into one tuple. I've created a new >>>>>> attribute that can have multiple of these tuples. The head of my >>>>>> server class now looks like this: >>>>>> >>>>>> >>>>>> class EttexOPCServer: _reg_progid_ = "Ettex.OPC.Automation" >>>>>> _reg_desc_ = "ettex OPC DA Server" _reg_clsid_ = >>>>>> "{13B51E8D-4BC2-4DED-8D4E-4614692F88E6}" _reg_catids_ = [ >>>>>> '{63D5F432-CFE4-11D1-B2C8-0060083BA1FB}' ] >>>>>> >>>>>> _typelib_interfaces_ = [ ("{3B540B51-0378-4551-ADCC-EA9B104302BF}", >>>>>> 3, 0, 0, [ 'IOPCServer', 'IOPCItemProperties', ] ), >>>>>> ("{B28EEDB1-AC6F-11D1-84D5-00608CB8A7E9}", 1, 0, 0, [ 'IOPCCommon', >>>>>> 'IConnectionPointContainer' ] ), ] _reg_clsctx_ = >>>>>> pythoncom.CLSCTX_LOCAL_SERVER >>>>>> >>>>>> I had to patch three locations in policy.py so far and I would be >>>>>> happy to send you my changes if you like. >>>>> >>>>> That would be great - a patch on sourceforge would be best. >>>>> However, it >>>>> might be better to wait until we are sure it is working OK :) >>>>> >>>>> >>>>>> However it still doesn't >>>>>> work but I'm not sure if I have missed something in my patch or >>>>>> if it >>>>>> is a general problem in my server code or a bug in the framework. >>>>>> >>>>>> At least, the client successfully creates the object and tries to >>>>>> call a method of the interface but I get the following debug output: >>>>>> >>>>>> GetStatus() pythoncom error: Failed to call the universal dispatcher >>>>>> >>>>>> Traceback (most recent call last): File "C:\Program Files >>>>>> (x86)\Python\lib\site-packages\win32com\universal.py", line 195, in >>>>>> dispatch WriteFromOutTuple(retVal, meth._gw_out_args, argPtr) >>>>>> TypeError: The VARIANT type is unknown (0x4024). pythoncom error: >>>>>> Unexpected gateway error >>>>>> >>>>>> Traceback (most recent call last): File "C:\Program Files >>>>>> (x86)\Python\lib\site-packages\win32com\universal.py", line 195, in >>>>>> dispatch WriteFromOutTuple(retVal, meth._gw_out_args, argPtr) >>>>>> TypeError: The VARIANT type is unknown (0x4024). GetErrorString >>>>>> -2147467259 0 pythoncom error: Failed to call the universal >>>>>> dispatcher >>>>>> >>>>>> (...) >>>>>> >>>>>> I've hat a lookat the definition of GetStatus. It requires a pointer >>>>>> to a pointer of type "tagOPCSERVERSTATUS" which is a record >>>>>> definition in the type library. But when I look at what has been >>>>>> generated by makepy, the record map looks pretty empty to me: >>>>>> >>>>>> RecordMap = { u'tagOPCITEMVQT': >>>>>> '{00000000-0000-0000-0000-000000000000}', } >>>>>> >>>>>> The type lib defines 10 records! I tried to import the typelib using >>>>>> comtypes and get that generated (excerpt): >>>>>> >>>>>> class tagOPCSERVERSTATUS(Structure): pass >>>>>> >>>>>> # values for enumeration 'tagOPCSERVERSTATE' OPC_STATUS_RUNNING = 1 >>>>>> OPC_STATUS_FAILED = 2 OPC_STATUS_NOCONFIG = 3 OPC_STATUS_SUSPENDED = >>>>>> 4 OPC_STATUS_TEST = 5 OPC_STATUS_COMM_FAULT = 6 tagOPCSERVERSTATE = >>>>>> c_int # enum tagOPCSERVERSTATUS._fields_ = [ ('ftStartTime', >>>>>> _FILETIME), ('ftCurrentTime', _FILETIME), ('ftLastUpdateTime', >>>>>> _FILETIME), ('dwServerState', tagOPCSERVERSTATE), ('dwGroupCount', >>>>>> c_ulong), ('dwBandWidth', c_ulong), ('wMajorVersion', c_ushort), >>>>>> ('wMinorVersion', c_ushort), ('wBuildNumber', c_ushort), >>>>>> ('wReserved', c_ushort), ('szVendorInfo', WSTRING), ] >>>>>> >>>>>> Is there a bug in makepy that prevents creating these records? >>>>> >>>>> It would seem so :) >>>>> >>>>>> If >>>>>> yes, can I fix it or can I manually change the generated file to >>>>>> support the records? >>>>> >>>>> I'm really not sure - you probably need to look at the existing >>>>> Record >>>>> tests. The "PyCOMTest" test object (which is in the source tree and >>>>> needs you to build it using MSVC) has some structs for testing. >>>>> >>>>> >>>>>> If not, how would I create and return such a >>>>>> pointer of a pointer in pythoncom? Is comtypes compatible with >>>>>> pythoncom so I could use the comtypes generated files? >>>>> >>>>> Unfortunately there isn't any compatibility between the 2. >>>>> >>>>> Cheers, >>>>> >>>>> Mark >>>>>> >>>>>> Thanks! >>>>>> >>>>>> //Jan >>>>>> >>>>>> ----- Originalnachricht ----- Von: "Jan Wedel" >>>>>> Gesendet: Don, 3/22/2012 1:51pm An: mhammond at skippinet.com.au Cc: >>>>>> python-win32 at python.org Betreff: Re: [python-win32] How to write a >>>>>> COM Server implementing interfaces from type lib? >>>>>> >>>>>> Hi Mark, >>>>>> >>>>>> thanks for your reply. >>>>>> >>>>>>> That's E_FAIL which is pretty generic. Doesn't sound like a >>>>>>> simple failure to QI for the correct interface. >>>>>> >>>>>> Yeah. The client says something like "Unknown Error" which makes it >>>>>> hard to tell what the problem actually is. >>>>>> >>>>>>> win32com should be able to do this given there is a tlb - see the >>>>>>> "pippo" samples. Further, using the debug facilities and >>>>>>> win32traceutil, you should be able to see the creation of the >>>>>>> object, the QIs on the object and any methods actually called. But >>>>>>> as mentioned, I doubt it is a QI failure. >>>>>> >>>>>> Yeah, there is a type library (OPC DA). Actually there are even two >>>>>> type libraries, each of them contains two Interface which my server >>>>>> needs to implement. >>>>>> >>>>>> I've had a look into policy.py and found that: >>>>>> >>>>>> def _build_typeinfos_(self): # Can only ever be one for now. (...) >>>>>> >>>>>> which means using _typelib_guid_ allows only one type lib, right? I >>>>>> could try to patch your code or do you think there is a general >>>>>> problem that would make it impossible having more than one >>>>>> typelib in >>>>>> your framework? >>>>>> >>>>>>> Have you tried contacting the author of the object? >>>>>> >>>>>> I am the author... I only use the 3rd party typelibs. I am writing >>>>>> the server that must support the interfaces so that other 3rd party >>>>>> clients can access the server component. >>>>>> >>>>>> I can reproduce the error using python the COMView tool trying to >>>>>> instanciate the Server. The problem is, that I don't see why. I've >>>>>> enabled debugging mode when registering the server. When using >>>>>> one of >>>>>> the 3rd party clients, rhe python trace collector shows the >>>>>> following: >>>>>> >>>>>> Object with win32trace dispatcher created (object=None) Entering >>>>>> constructor in>>>>> 0x0213B058>._QueryInterface_ with unsupported IID >>>>>> {00000003-0000-0000-C000-000000000046} >>>>>> ({00000003-0000-0000-C000-000000000046}) >>>>>> in>>>>> 0x0213B058>._QueryInterface_ with unsupported IID >>>>>> {0000001B-0000-0000-C000-000000000046} >>>>>> ({0000001B-0000-0000-C000-000000000046}) >>>>>> in>>>>> 0x0213B058>._QueryInterface_ with unsupported IID >>>>>> {00000018-0000-0000-C000-000000000046} >>>>>> ({00000018-0000-0000-C000-000000000046}) >>>>>> in>>>>> 0x0213B058>._QueryInterface_ with unsupported IID >>>>>> {4C1E39E1-E3E3-4296-AA86-EC938D896E92} >>>>>> ({4C1E39E1-E3E3-4296-AA86-EC938D896E92}) >>>>>> in>>>>> 0x0213B058>._InvokeEx_-AddConnection(1, 0) [1,0,None] Connection >>>>>> added. Active connections: 1 in>>>>> instance at 0x0213B058>._InvokeEx_-ReleaseConnection(1, 0, 1) >>>>>> [1,0,None] Connection released. Active connections: 0 >>>>>> >>>>>> The QI calls are standard COM calls, not application specific >>>>>> (AFAIK). You can see the "Entering constructor" message which is in >>>>>> my python constructor of the server. Just for fun, I implemented the >>>>>> IExternalConnection interface to see if the methods are called. >>>>>> "Connection added. ..." is my output. But I can't see an further >>>>>> requests that shows what the problem is. Are there any calls in >>>>>> pythoncom that could fail and does not give debug output? >>>>>> >>>>>> My pythoncom server starts like that: >>>>>> >>>>>> class EttexOPCServer: _reg_progid_ = "Ettex.OPC.Automation" >>>>>> _reg_desc_ = "ettex OPC DA Server" _reg_clsid_ = >>>>>> "{13B51E8D-4BC2-4DED-8D4E-4614692F88E6}" _reg_catids_ = [ >>>>>> '{63D5F432-CFE4-11D1-B2C8-0060083BA1FB}' ] _com_interfaces_ = [ >>>>>> '{00000019-0000-0000-C000-000000000046}', # IExternalConnection (Is >>>>>> it really mandatory?) '{39C13A4D-011E-11D0-9675-0020AFD8ADB3}', # >>>>>> IOPCServer '{F31DFDE2-07B6-11D2-B2D8-0060083BA1FB}', # IOPCCommon >>>>>> '{39C13A72-011E-11D0-9675-0020AFD8ADB3}', # IOPCItemProperties >>>>>> '{B196B284-BAB4-101A-B69C-00AA00341D07}' # >>>>>> IConnectionPointContainer ] _typelib_guid_ = >>>>>> "{3B540B51-0378-4551-ADCC-EA9B104302BF}" _typelib_version_ = (3, 0) >>>>>> _reg_clsctx_ = pythoncom.CLSCTX_LOCAL_SERVER >>>>>> >>>>>> _public_methods_ = [ 'Connect', 'Disconnect', 'GetErrorString' ] ## >>>>>> IExternalConnection methods _public_methods_ += [ 'AddConnection', >>>>>> 'ReleaseConnection' ] >>>>>> >>>>>> ################################################################# ## >>>>>> COM Class Attributes >>>>>> ################################################################# >>>>>> _public_attrs_ = [ 'ClientName', 'OPCGroups' ] >>>>>> >>>>>> ################################################################# ## >>>>>> COM Class Read-Only Attributes >>>>>> ################################################################# >>>>>> _readonly_attrs_ = [ 'OPCGroups' ] >>>>>> >>>>>> I don't have all interface methods implemented at the time but I >>>>>> guess that doesn't matter as long as not all type libs have been >>>>>> loaded, does it? >>>>>> >>>>>> If its not possible with pythoncom, is it possible with comtypes? >>>>>> I've tried that as well with nearly the same result ("Unknown >>>>>> error"): >>>>>> >>>>>> # OPC Data Access 3.00 Type Library opc_da_tl = >>>>>> comtypes.GUID("{3B540B51-0378-4551-ADCC-EA9B104302BF}") # OPC Common >>>>>> 1.10 Type Library opc_com_tl = >>>>>> comtypes.GUID("{B28EEDB1-AC6F-11D1-84D5-00608CB8A7E9}") >>>>>> >>>>>> GetModule((opc_da_tl, 3, 0)) GetModule((opc_com_tl, 1, 0)) >>>>>> >>>>>> import comtypes.gen.OPCDA as OpcDa import comtypes.gen.OPCCOMN as >>>>>> OpcCommon >>>>>> >>>>>> class EttexOPCServer2(OpcCommon.IOPCCommon, >>>>>> OpcCommon.IConnectionPointContainer, OpcDa.IOPCServer, >>>>>> OpcDa.IOPCItemProperties): _reg_progid_ = "Ettex.OPC.Automation2" >>>>>> _reg_desc_ = "ettex OPC DA Server 2" _reg_novers_progid_ = >>>>>> _reg_progid_ _reg_clsid_ = "{80A2B8F7-792E-43F4-95F8-CD6BB4B413AD}" >>>>>> _reg_catids_ = [ '{63D5F432-CFE4-11D1-B2C8-0060083BA1FB}' ] >>>>>> _reg_clsctx_ = comtypes.CLSCTX_LOCAL_SERVER _regcls_ = >>>>>> comtypes.server.localserver.REGCLS_MULTIPLEUSE >>>>>> >>>>>> _com_interfaces_ = [OpcCommon.IOPCCommon, >>>>>> OpcCommon.IConnectionPointContainer, OpcDa.IOPCServer, >>>>>> OpcDa.IOPCItemProperties] >>>>>> >>>>>> I don't know what to do. Is there anything more I can do to debug to >>>>>> find out WHAT exactly causes the error? Because as you can see, the >>>>>> pythoncom debug output doesn't show this error that is returned by >>>>>> the client. >>>>>> >>>>>> Thanks a lot! >>>>>> >>>>>> //Jan >>>>>> >>>>>> ----- Originalnachricht ----- Von: "Mark >>>>>> Hammond" Gesendet: Don, 3/22/2012 >>>>>> 12:29pm >>>>>> An: "Jan Wedel" Cc: python-win32 at python.org >>>>>> Betreff: Re: [python-win32] How to write a COM Server implementing >>>>>> interfaces from type lib? >>>>>> >>>>>> On 22/03/2012 2:53 AM, Jan Wedel wrote: >>>>>>> Hi, >>>>>>> >>>>>>> I'm currently having trouble to write a COM-Server that has some >>>>>>> special requirements: - It needs to derive from IUnknown - It needs >>>>>>> to implement multiple interface from two different proprietary >>>>>>> typelibs (dlls) - It needs to implement a custom category >>>>>>> >>>>>>> At first I started with pythoncom. I used the attribute >>>>>>> _reg_catids_ to specify the category and _com_interfaces_ to >>>>>>> specify the interfaces I want to implement. The client (proprietary >>>>>>> 3rd party sw, no source) sees the server but throws some 0x80004005 >>>>>>> error on CoCreateInstance. >>>>>> >>>>>> That's E_FAIL which is pretty generic. Doesn't sound like a simple >>>>>> failure to QI for the correct interface. >>>>>> >>>>>> win32com should be able to do this given there is a tlb - see the >>>>>> "pippo" samples. Further, using the debug facilities and >>>>>> win32traceutil, you should be able to see the creation of the >>>>>> object, the QIs on the object and any methods actually called. But >>>>>> as mentioned, I doubt it is a QI failure. >>>>>> >>>>>>> I was hoping that I can just tell the COM dispatcher, "yes, I have >>>>>>> these interface implemented" and implement the methods without >>>>>>> really having the interface classes available. >>>>>>> >>>>>>> I read, that pythoncom can only create components that use >>>>>>> IDispatch so I guess the _com_interfaces_ idea won't work, will >>>>>>> it? >>>>>> >>>>>> As above, you should be able to fully implement them so long as >>>>>> makepy has been run. >>>>>> >>>>>>> Then I did some further research and found comtypes. I tried to >>>>>>> write a server stub again. I used GetModule to load the type >>>>>>> library containing the Interfaces, importing the generated >>>>>>> interface classes and let the main server class extend these >>>>>>> interfaces. >>>>>>> >>>>>>> The first problem was, that comtypes did not support the >>>>>>> _reg_catids_ attribute or anything similar so I had to add the >>>>>>> Implemented Categories key manually to the registry. Then, I was >>>>>>> able to see the server through the client, which obviously filters >>>>>>> by categories, but it still shows the same error as before. >>>>>>> >>>>>>> So, what is the correct/best way to implement a server that needs >>>>>>> to implement custom interfaces and categories? Or is it possible at >>>>>>> all using python? >>>>>> >>>>>> The fact you get the same error there implies something else is >>>>>> going wrong, but it is impossible to guess what. Have you tried >>>>>> contacting the author of the object? >>>>>> >>>>>> Mark >>>>>> >>>>>>> >>>>>>> Thanks! >>>>>>> >>>>>>> //Jan >>>>>>> >>>>>>> >>>>>>> >>>>>>> _______________________________________________ python-win32 >>>>>>> mailing list python-win32 at python.org >>>>>>> http://mail.python.org/mailman/listinfo/python-win32 >>>>>> >>>>>> _______________________________________________ python-win32 mailing >>>>>> list python-win32 at python.org >>>>>> http://mail.python.org/mailman/listinfo/python-win32 >>>>> >>>> >>> >>> >> > > From sagarnikam123 at gmail.com Tue Mar 27 12:05:28 2012 From: sagarnikam123 at gmail.com (sagarnikam123) Date: Tue, 27 Mar 2012 03:05:28 -0700 (PDT) Subject: [python-win32] NameError: name '_DEV_MODE' is not defined Message-ID: <1332842728576-4660151.post@n6.nabble.com> while running one script i found error,what is this? if (_DEV_MODE): NameError: name '_DEV_MODE' is not defined -- View this message in context: http://python.6.n6.nabble.com/NameError-name-DEV-MODE-is-not-defined-tp4660151p4660151.html Sent from the Python - python-win32 mailing list archive at Nabble.com. From amauryfa at gmail.com Tue Mar 27 13:28:42 2012 From: amauryfa at gmail.com (Amaury Forgeot d'Arc) Date: Tue, 27 Mar 2012 13:28:42 +0200 Subject: [python-win32] NameError: name '_DEV_MODE' is not defined In-Reply-To: <1332842728576-4660151.post@n6.nabble.com> References: <1332842728576-4660151.post@n6.nabble.com> Message-ID: Hi, 2012/3/27 sagarnikam123 : > while running one script i found error,what is this? > ?if (_DEV_MODE): > NameError: name '_DEV_MODE' is not defined You need to give more context. Most probably, you modified an existing script, and removed/modified the line that defines this _DEV_MODE variable. -- Amaury Forgeot d'Arc From potterpavi at gmail.com Thu Mar 29 16:24:45 2012 From: potterpavi at gmail.com (pavi ena) Date: Thu, 29 Mar 2012 19:54:45 +0530 Subject: [python-win32] Wanted to know how we can overwrite the win32serviceutil.ServiceFramework SvcDoRun method. Message-ID: Hello, I am new to Python Window services development. I have small code below. from datetime import datetime import time import sys import os import win32service import win32serviceutil import win32api import win32con class DemoService(win32serviceutil.ServiceFramework): _svc_name_ = "DemoService" _svc_display_name_ = "DemoService" def __init__(self, args): win32serviceutil.ServiceFramework.__init__(self, args) self.isAlive = True self.args = args def SvcDoRun(self): import servicemanager while self.isAlive: start_mail_check(args[2], args[3]) self.isAlive = False def SvcStop(self): import servicemanager servicemanager.LogInfoMsg("ZetlConductorSvcs - Received stop signal") self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING) self.isAlive = False def ctrlHandler(ctrlType): return True def start_mail_check(user_id=None, passwd=None): if not user_id and not passwd: servicemanager.LogInfoMsg("DemoService - Invalid argument passed.") else: #Go ahead to download the mails from configured mail server. def main(): print ">>>", sys.argv, len(sys.argv) if __name__ == '__main__': win32api.SetConsoleCtrlHandler(ctrlHandler, True) win32serviceutil.HandleCommandLine(DemoService, argv=sys.argv) I use this script to run to download mails for different user_id and password from configured mail server. Generally i run this script as batch file which takes parameters like user_id and password python demo_svcs.py install python demo_svcs.py start %user_id% %password% At present in my code i am passing user_id and password as argv "win32serviceutil.HandleCommandLine(DemoService, argv=sys.argv)" which intern i am accessing these user_id and password in 'SvcDoRun' method with 'args', i just wanted to know is this the correct approach or do we have flexibility to overwrite 'SvcDoRun' method to get these 'user_id' and 'password' as kwd_args and use these kwd_args in 'start_mail_check' method. I want to run the same service with different user_id and password as command line args for multiple users. I gooled to find out examples with with parameters, but i am not lucky enough to find out. Could any one suggest me move forward in this regard. Thanks, Pavi -------------- next part -------------- An HTML attachment was scrubbed... URL: From timr at probo.com Thu Mar 29 19:07:35 2012 From: timr at probo.com (Tim Roberts) Date: Thu, 29 Mar 2012 10:07:35 -0700 Subject: [python-win32] Wanted to know how we can overwrite the win32serviceutil.ServiceFramework SvcDoRun method. In-Reply-To: References: Message-ID: <4F7496D7.60603@probo.com> pavi ena wrote: > > I am new to Python Window services development. I have small code below. > ... > Generally i run this script as batch file which takes parameters like > user_id > and password > > python demo_svcs.py install > python demo_svcs.py start %user_id% %password% > > At present in my code i am passing user_id and password as argv > "win32serviceutil.HandleCommandLine(DemoService, argv=sys.argv)" > which intern i am accessing these user_id and password in 'SvcDoRun' > method > with 'args', i just wanted to know is this the correct approach or do > we have flexibility > to overwrite 'SvcDoRun' method to get these 'user_id' and 'password' > as kwd_args > and use these kwd_args in 'start_mail_check' method. Remember that you have the full source code to win32serviceutil.py in your Python distribution. You can go look it up. SvcDoRun is called from win32serviceutil.py. You'll see that it is called from ServiceFramework.SvcRun with no parameters: self.SvcDoRun() SvcRun is called in response to a message from the Service Control Manager, so there's really no place to make a modification like that. I think you need to keep doing what you are doing. -- Tim Roberts, timr at probo.com Providenza & Boekelheide, Inc. From mhammond at skippinet.com.au Fri Mar 30 07:30:03 2012 From: mhammond at skippinet.com.au (Mark Hammond) Date: Fri, 30 Mar 2012 16:30:03 +1100 Subject: [python-win32] How to write a COM Server implementing interfaces from type lib? In-Reply-To: <4F717509.8000007@ettex.de> References: <15907973.571332755494115.JavaMail.root@server1.ettex.de> <4F717509.8000007@ettex.de> Message-ID: <4F7544DB.8010101@skippinet.com.au> It seems I *can* make this work with the pythoncom test object. I created a structure with no GUID in a TLB with a name StructWithoutUUID. Then, I used the code at the end of this message as a quick hack to try out the SetGuid and the output is: """ as expected, failed to create the record normally: The structure 'StructWithoutUUID' is not defined in module ' I tried the following from the console: > > >>> import pythoncom > > Get the type lib: > > >>> TL_OPC_DA = > pythoncom.LoadRegTypeLib('{3B540B51-0378-4551-ADCC-EA9B104302BF}', 3, 0, 0) > >>> TL_OPC_DA > > > Index 8 is the record I try to create: > > >>> TL_OPC_DA.GetTypeInfo(8) > > >>> recinfo = TL_OPC_DA.GetTypeInfo(8) > > Cast to ICreateTypeInfo: > > >>> icti = recinfo.QueryInterface(pythoncom.IID_ICreateTypeInfo) > >>> icti > > > Set random GUID: > > >>> icti.SetGuid(pythoncom.CreateGuid()) > > BAM! : > > >>> pythoncom.GetRecordFromTypeInfo(icti) > Traceback (most recent call last): > File "", line 1, in > pywintypes.com_error: (-2147024809, 'Falscher Parameter.', None, None) > > Try another cast because I wasn't sure that GetRecordFromTypeInfo > supports/checks the ICreateTypeInfo interface. > > >>> iti = icti.QueryInterface(pythoncom.IID_ITypeInfo) > >>> iti > > > BAM! : > > >>> pythoncom.GetRecordFromTypeInfo(iti) > Traceback (most recent call last): > File "", line 1, in > pywintypes.com_error: (-2147024809, 'Falscher Parameter.', None, None) > > Unfortunately, as you can see, it doesn't work. Do you know if there is > a way to get a more verbose error message or some COM debugging console > to know what COM is actually complaining about? I mean, I'm pretty sure > that it works as you assumed (Like COM tries to get the GUID from the > TypeInfo and then calls GetRecordFromGuid which would explain why > setting a GUID still doesnt work) but just to make sure, you know? > > //Jan > > Am 27.03.2012 00:24, schrieb Mark Hammond: >> On 26/03/2012 8:51 PM, Jan Wedel wrote: >>>> I'm confident the E_INVALIDARG error is coming from COM itself. It >>> >>>> wouldn't surprise me at all to find GetRecordInfoFromTypeInfo simply >>> >>>> uses the type info to fetch the GUID of the record then calls the >>> >>>> ...FromGuids method. >>> >>> >>> >>> Yeah, maybe. I just tried to find some explanation and found this: >>> >>> http://www.autohotkey.com/forum/topic84172.html >>> >>> >>> >>> This thread seems to be related and presents a solution. As far as I >>> understand, COM is complaining because the UUID is missing and in this >>> solution a random GUID is created and attached to the typeinfo... >> >> That's interesting and might well work. It could all be done from >> pure Python as ICreateTypeInfo is exposed. >> >>>> It might be possible to write all the info needed to the generated >>>> file, >>> >>>> but it would probably take a fair bit of work. If you look later in >>> >>>> PyRecord.cpp, all the "set attribute" and "get attribute" code is >>> >>>> implemented by way of the IRecordInfo interface - eg, GetFieldNoCopy. >>> >>>> It might be possible to steal the code from comtypes, but I'm not >>> >>>> familiar with that. >>> >>> >>> >>> The question is, is it necessaey to use the C++ part at all? Would it be >>> possible to just keep the Record stuff in pure python? Why would it be >>> necessary to dynamically loade the TypeInfo from a DLL that most likely >>> will not change that often? >> >> The problem is the code that knows what "something = >> aRecord.someAtribute" does. It needs to know how to move the memory >> around so the right thing happens - that is what GetFieldNoCopy does. >> >>> The thing is, I'm currently working on a customer project and >>> unfortunately I need this stuff getting to work soon. I would really >>> appreciate you applying a fix to the C++ layer of pythoncom if possible >>> at all. But I also understand that you can't spend all your spare time >>> on that problem. >> >> I'd be happy to apply a fix if I knew what the fix was. From pure >> Python, you might be able to: >> >> * load the typelib >> * find the type info for the guid. >> * QI the type info for ICreateTypeInfo. >> * Set the GUID to some random GUID. >> * Call pythoncom.GetRecordFromTypeInfo with the modified typeinfo. >> * Use the result object as normal. >> >>> So, if it's not easy for you to fix this, could you tell me what would >>> be necessary to fix or work-around this? My "vision" is to manually >>> create a static definition of all relevant structs somewhere which might >>> be just laborious work. >> >> The problem is how that static info is actually used rather than the >> generation of it. Some code will need to use that static info to >> support getting and setting attributes on the record. >> >>> My problem is that I don't know much about the >>> internals of COM. Is it possible to write a pure python class that has >>> the correct attributes and methods so I can return an instance of this >>> class from a COM method of my server and the receiver and COM itself >>> would be able to interpret it as the correct struct or does it require >>> some native code? >> >> It would almost certainly require some native (or ctypes) code to do >> it all statically without an IRecordInfo interface to perform the >> heavy lifting. >> >> I'll try and find time to use one of the pywin32 test objects to see >> if this can work by dynamically setting a GUID, but it is unlikely to >> happen for a few days. >> >> Cheers, >> >> Mark >>> >>> >>> >>> //Jan >>> >>> ----- Originalnachricht ----- >>> Von: "Mark Hammond" >>> Gesendet: Sam, 24.3.2012 00:53 >>> An: "Jan Wedel" >>> Betreff: Re: AW: AW: AW: AW: [python-win32] How to write a COM Server >>> implementing interfaces from type lib? >>> >>> I'm confident the E_INVALIDARG error is coming from COM itself. It >>> wouldn't surprise me at all to find GetRecordInfoFromTypeInfo simply >>> uses the type info to fetch the GUID of the record then calls the >>> ...FromGuids method. >>> >>> It might be possible to write all the info needed to the generated file, >>> but it would probably take a fair bit of work. If you look later in >>> PyRecord.cpp, all the "set attribute" and "get attribute" code is >>> implemented by way of the IRecordInfo interface - eg, GetFieldNoCopy. >>> It might be possible to steal the code from comtypes, but I'm not >>> familiar with that. >>> >>> Cheers, >>> >>> Mark >>> >>> On 24/03/2012 2:39 AM, Jan Wedel wrote: >>>>> Obviously this is a "dynamic" process - other languages/tools etc are >>>>> likely to use these struct definitions at compile time >>>> >>>> What about writing all necessary information into the generated type >>>> lib files like comtypes is doing it? Or do you need to have some >>>> native objects? >>>> >>>>> (...)it might be worth poking around the MS docs and see if they >>>>> offer any way to get an IRecordInfo given just the typelib info and >>>>> the >>>>> struct name, as that seems the only info we have at the time we >>>>> need it. >>>>> If we can find something I'll try and add the support and send >>>>> you a >>>>> custom built pythoncomxx.dll. >>>> >>>> There is some modification of the Record method necessary. In my >>>> server I pass an object created by GetModuleForTypelib(...) to the >>>> Record() method. Inside, I check if its a nodule. If yes, I load the >>>> typelib using pythoncom.LoadRegTypeLib(...) (don't know if its >>>> already cached somewhere, but it was my quick and dirty attempt). >>>> I've checked the MS doc and found a second method to retrieve the >>>> Record object. Using the returned library object, I used >>>> pythoncom.GetRecordFromTypeInfo(tlib.GetTypeInfo(8)) to retrieve the >>>> Record from the type info object instead of GetRecordFromGuids. >>>> >>>> The "8" is hard coded for testing and is the library index of the >>>> Record. If this idea could work, it's probably worth to add the >>>> index to the "RecordMap" when generating the file so we have an >>>> alternative look-up key instead of the GUID. >>>> >>>> However, it doesn't work either and gives the following result: >>>> >>>> Traceback (most recent call last): >>>> File "C:\Program Files >>>> (x86)\Python\lib\site-packages\win32com\universal.py", line 179, in >>>> dispatch >>>> retVal = ob._InvokeEx_(meth.dispid, 0, meth.invkind, args, >>>> None, None) >>>> File "C:\Program Files >>>> (x86)\Python\lib\site-packages\win32com\server\policy.py", line 346, >>>> in _InvokeEx_ >>>> return self._invokeex_(dispid, lcid, wFlags, args, kwargs, >>>> serviceProvider) >>>> File "C:\Program Files >>>> (x86)\Python\lib\site-packages\win32com\server\policy.py", line 650, >>>> in _invokeex_ >>>> return func(*args) >>>> File "C:\temp\opc\PyOPCComServer.py", line 241, in GetStatus >>>> status = Record("tagOPCSERVERSTATUS", GEN_TL_OPC_DA) >>>> File "C:\Program Files >>>> (x86)\Python\lib\site-packages\win32com\client\__init__.py", line >>>> 403, in Record >>>> return pythoncom.GetRecordFromTypeInfo(tlib.GetTypeInfo(8)) >>>> com_error: (-2147024809, 'Falscher Parameter.', None, None) >>>> >>>> Which means E_INVALIDARG. I've checked the source code of >>>> PyRecord.cpp and it says "This function will fail if the specified >>>> type info does not have a guid defined". >>>> >>>> I don't know if this is a COM or PythonCom limitation... If it's the >>>> latter, I would really appreciate fixing the C++ code. Otherwise, it >>>> might help, having the whole definition inside the generate python >>>> file as explained above. >>>> >>>> Thanks a lot for your help! >>>> >>>> //Jan >>>> >>>> >>>> ----- Originalnachricht ----- >>>> Von: "Mark Hammond" >>>> Gesendet: Fre, 3/23/2012 2:43pm >>>> An: "Jan Wedel" >>>> Betreff: Re: AW: AW: AW: [python-win32] How to write a COM Server >>>> implementing interfaces from type lib? >>>> >>>> So - looking at the source, the win32com.client.Record object attempts >>>> to look up both the tlb guid and the record guid based on the name >>>> using >>>> that RecordMap dict we talked about. From there, we should wind up in >>>> win32com\src\PyRecord.cpp, where we use the typelib info and the struct >>>> GUID to call the COM function GetRecordInfoFromGuids(), which takes >>>> those GUIDs and returns an IRecordInfo interface that tells us all the >>>> struct element names and types etc. >>>> >>>> Obviously this is a "dynamic" process - other languages/tools etc are >>>> likely to use these struct definitions at compile time, which may >>>> explain why they have a NULL guid - they assume people wont need to >>>> look >>>> them up at runtime using GetRecordInfoFromGuids. It is late and I must >>>> hit bed, but it might be worth poking around the MS docs and see if >>>> they >>>> offer any way to get an IRecordInfo given just the typelib info and the >>>> struct name, as that seems the only info we have at the time we need >>>> it. >>>> If we can find something I'll try and add the support and send >>>> you a >>>> custom built pythoncomxx.dll. >>>> >>>> Cheers, >>>> >>>> Mark >>>> >>>> On 24/03/2012 12:06 AM, Jan Wedel wrote: >>>>> I tried to manually add the Records to the generated file to see if >>>>> patching genpy.py would solve the problem: >>>>> >>>>> RecordMap = { >>>>> u'tagOPCITEMVQT': '{00000000-0000-0000-0000-000000000000}', >>>>> u'tagOPCSERVERSTATE': '{00000000-0000-0000-0000-000000000000}', >>>>> u'tagOPCSERVERSTATUS': >>>>> '{00000000-0000-0000-0000-000000000000}', >>>>> } >>>>> >>>>> The client calls the GetStatus() method of my server which is >>>>> implemented as follows: >>>>> >>>>> def GetStatus(self): >>>>> """Returns the current server status""" >>>>> print "GetStatus()" >>>>> >>>>> # return None >>>>> status = Record("tagOPCSERVERSTATUS", self) >>>>> >>>>> status.ftStartTime = pywintypes.Time(self.start_time) >>>>> status.ftCurrentTime = pywintypes.Time(time.time()) >>>>> status.ftLastUpdateTime = >>>>> pywintypes.Time(self.last_update_time) >>>>> status.dwServerState = ServerState.RUNNING >>>>> status.dwGroupCount = len(self.groups) >>>>> status.dwBandWidth = self.band_width >>>>> status.wMajorVersion = MAJOR_VERSION >>>>> status.wMinorVersion = MINOR_VERSION >>>>> status.wBuildNumber = BUILD_NUMBER >>>>> status.wReserved = 0 >>>>> status.szVendorInfo = VENDOR_INFO >>>>> >>>>> return status >>>>> >>>>> with the following result: >>>>> >>>>> GetStatus() >>>>> pythoncom error: Failed to call the universal dispatcher >>>>> >>>>> Traceback (most recent call last): >>>>> File "C:\Program Files >>>>> (x86)\Python\lib\site-packages\win32com\universal.py",line 179, in >>>>> dispatch >>>>> retVal = ob._InvokeEx_(meth.dispid, 0, meth.invkind, args, >>>>> None, None) >>>>> File "C:\Program Files >>>>> (x86)\Python\lib\site-packages\win32com\server\policy.py", line >>>>> 346, in _InvokeEx_ >>>>> return self._invokeex_(dispid, lcid, wFlags, args, kwargs, >>>>> serviceProvider) >>>>> File "C:\Program Files >>>>> (x86)\Python\lib\site-packages\win32com\server\policy.py", line >>>>> 650, in _invokeex_ >>>>> return func(*args) >>>>> File "C:\temp\opc\PyOPCComServer.py", line 234, in GetStatus >>>>> status = Record("tagOPCSERVERSTATUS", self) >>>>> File "C:\Program Files >>>>> (x86)\Python\lib\site-packages\win32com\client\__init__.py", line >>>>> 399, in Record >>>>> object = gencache.EnsureDispatch(object) >>>>> File "C:\Program Files >>>>> (x86)\Python\lib\site-packages\win32com\client\gencache.py", line >>>>> 529, in EnsureDispatch >>>>> disp = win32com.client.Dispatch(prog_id) >>>>> File "C:\Program Files >>>>> (x86)\Python\lib\site-packages\win32com\client\__init__.py", line >>>>> 96, in Dispatch >>>>> return __WrapDispatch(dispatch, userName, resultCLSID, >>>>> typeinfo, clsctx=clsctx) >>>>> File "C:\Program Files >>>>> (x86)\Python\lib\site-packages\win32com\client\__init__.py", line >>>>> 43, in __WrapDispatch >>>>> return dynamic.Dispatch(dispatch, userName, WrapperClass, >>>>> typeinfo, clsctx=clsctx) >>>>> File "C:\Program Files >>>>> (x86)\Python\lib\site-packages\win32com\client\dynamic.py", line >>>>> 122, in Dispatch >>>>> typeinfo = IDispatch.GetTypeInfo() >>>>> AttributeError: EttexOPCServer instance has no attribute 'GetTypeInfo' >>>>> >>>>> pythoncom error: Failed to call the universal dispatcher >>>>> >>>>> Traceback (most recent call last): >>>>> File "C:\Program Files >>>>> (x86)\Python\lib\site-packages\win32com\universal.py", >>>>> line 195, in dispatch >>>>> WriteFromOutTuple(retVal, meth._gw_out_args, argPtr) >>>>> TypeError: The VARIANT type is unknown (0x4024). >>>>> >>>>> If found an example of how to create a Record. However, it does use >>>>> client COM and passes the object generated by Dispatch() to the >>>>> Record constructor. What object should I pass on the server side? >>>>> Obviously "self" doesn't work... >>>>> >>>>> Then I tried to return None instead which should leave the output >>>>> arguments untouch, but I only get the "TypeError: The VARIANT type >>>>> is unknown (0x4024)." message. The 0x4024 is 16420 and can be found >>>>> in the vtable definition of the generated file: >>>>> >>>>> IOPCServer_vtables_ = [ >>>>> (...) >>>>> (( u'GetStatus' , u'ppServerStatus' , ), 1610678275, >>>>> (1610678275, (), [ (16420, 2, None, None) , ], 1 , 1 , 4 , 0 , 24 , >>>>> (3, 0, None, None) , 0 , )), >>>>> (...) >>>>> >>>>> I was asking myself how does this 16420 from the vtable gets >>>>> translated into a "Ptr Ptr tagOPCSERVERSTATUS"? How does the record >>>>> definition know what fields it contains? Is is probably necessary >>>>> to add some more information to the Record such as this number, >>>>> e.g? Or does the internal COM libs uses the TypeLib information to >>>>> resolve it? It tried to look into the source of this type error but >>>>> the WriteFromOutTuple method is somewhere inside the pythoncom dll... >>>>> >>>>> I'm really stuck here... >>>>> >>>>> //Jan >>>>> >>>>> >>>>> >>>>> ----- Originalnachricht ----- >>>>> Von: "Mark Hammond" >>>>> Gesendet: Fre, 3/23/2012 12:11pm >>>>> An: "Jan Wedel" >>>>> Betreff: Re: AW: AW: [python-win32] How to write a COM Server >>>>> implementing interfaces from type lib? >>>>> >>>>> I haven't got the code in front of me, but in that place it would >>>>> probably be OK to use the name. I'm slightly worried about the >>>>> "global" >>>>> resolution though - there's probably code that can find a record given >>>>> just the GUID and without regard for which tlb it was defined in >>>>> (ie, so >>>>> the name itself need not be unique). In that case, a tuple of >>>>> (typelib_guid, name) would probably be OK. >>>>> >>>>> Mark >>>>> >>>>> On 23/03/2012 7:54 PM, Jan Wedel wrote: >>>>>> After I wrote my last mail, I did some further research on the >>>>>> problem. In genpy.py where the python file is generated for the >>>>>> type lib, I found this code: >>>>>> >>>>>> print>> stream, 'RecordMap = {' >>>>>> for record in recordItems.itervalues(): >>>>>> if str(record.clsid) == pythoncom.IID_NULL: >>>>>> print>> stream, "\t###%s: %s, # Typedef disabled >>>>>> because it doesn't have a non-null GUID" % (repr(record.doc[0]), >>>>>> repr(str(record.clsid))) >>>>>> else: >>>>>> print>> stream, "\t%s: %s," % >>>>>> (repr(record.doc[0]), repr(str(record.clsid))) >>>>>> print>> stream, "}" >>>>>> >>>>>> I've checked the typelib with COMView, and all records, modules >>>>>> and enums defined have the UUID {00000-...00000} assigned. Then >>>>>> I've checked some random other type libs I've found on my computer >>>>>> and it seems that they are always using {0000...0000}. I don't >>>>>> know much about COM but I guess this must be OK. The type lib I'm >>>>>> using is made by the OPC foundation and there must be a numerous >>>>>> COM clients using it so it can't be that wrong, can it? >>>>>> >>>>>> The question is, is it possible to create a Record object in my >>>>>> server class and return it without the need of having a unique >>>>>> UUID assignedand without the need of beeing defined by genyp? >>>>>> >>>>>> If that doesn't work, I might also try to patch the genpy.py, but >>>>>> it seems as if you rely on the CLSID being unique. in the >>>>>> BuildOleItemsFromType method, there is the following code: >>>>>> >>>>>> elif infotype == pythoncom.TKIND_RECORD or infotype == >>>>>> pythoncom.TKIND_UNION: >>>>>> newItem = RecordItem(info, attr, doc) >>>>>> recordItems[newItem.clsid] = newItem >>>>>> >>>>>> Because all records have the same clsid, they get overwritten by >>>>>> each other. There probably must be some other identification >>>>>> mechanism. Either we use an index or the record name itself... But >>>>>> then COM methods must be aware of these type in input and output >>>>>> parameters... >>>>>> >>>>>> Do have any suggestion on how to proceed (patch/work-around)? >>>>>> >>>>>> Thanks! >>>>>> >>>>>> //Jan >>>>>> >>>>>> >>>>>> ----- Originalnachricht ----- >>>>>> Von: "Mark Hammond" >>>>>> Gesendet: Fre, 3/23/2012 12:30am >>>>>> An: "Jan Wedel" >>>>>> Cc: python-win32 at python.org >>>>>> Betreff: Re: AW: [python-win32] How to write a COM Server >>>>>> implementing interfaces from type lib? >>>>>> >>>>>> On 23/03/2012 3:54 AM, Jan Wedel wrote: >>>>>>> I've actually managed to patch the policy.py to allow multiple >>>>>>> typelibraries. >>>>>>> >>>>>>> Instead of having a definition for interfaces, type library id, >>>>>>> version etc i've build this into one tuple. I've created a new >>>>>>> attribute that can have multiple of these tuples. The head of my >>>>>>> server class now looks like this: >>>>>>> >>>>>>> >>>>>>> class EttexOPCServer: _reg_progid_ = "Ettex.OPC.Automation" >>>>>>> _reg_desc_ = "ettex OPC DA Server" _reg_clsid_ = >>>>>>> "{13B51E8D-4BC2-4DED-8D4E-4614692F88E6}" _reg_catids_ = [ >>>>>>> '{63D5F432-CFE4-11D1-B2C8-0060083BA1FB}' ] >>>>>>> >>>>>>> _typelib_interfaces_ = [ ("{3B540B51-0378-4551-ADCC-EA9B104302BF}", >>>>>>> 3, 0, 0, [ 'IOPCServer', 'IOPCItemProperties', ] ), >>>>>>> ("{B28EEDB1-AC6F-11D1-84D5-00608CB8A7E9}", 1, 0, 0, [ 'IOPCCommon', >>>>>>> 'IConnectionPointContainer' ] ), ] _reg_clsctx_ = >>>>>>> pythoncom.CLSCTX_LOCAL_SERVER >>>>>>> >>>>>>> I had to patch three locations in policy.py so far and I would be >>>>>>> happy to send you my changes if you like. >>>>>> >>>>>> That would be great - a patch on sourceforge would be best. >>>>>> However, it >>>>>> might be better to wait until we are sure it is working OK :) >>>>>> >>>>>> >>>>>>> However it still doesn't >>>>>>> work but I'm not sure if I have missed something in my patch or >>>>>>> if it >>>>>>> is a general problem in my server code or a bug in the framework. >>>>>>> >>>>>>> At least, the client successfully creates the object and tries to >>>>>>> call a method of the interface but I get the following debug output: >>>>>>> >>>>>>> GetStatus() pythoncom error: Failed to call the universal dispatcher >>>>>>> >>>>>>> Traceback (most recent call last): File "C:\Program Files >>>>>>> (x86)\Python\lib\site-packages\win32com\universal.py", line 195, in >>>>>>> dispatch WriteFromOutTuple(retVal, meth._gw_out_args, argPtr) >>>>>>> TypeError: The VARIANT type is unknown (0x4024). pythoncom error: >>>>>>> Unexpected gateway error >>>>>>> >>>>>>> Traceback (most recent call last): File "C:\Program Files >>>>>>> (x86)\Python\lib\site-packages\win32com\universal.py", line 195, in >>>>>>> dispatch WriteFromOutTuple(retVal, meth._gw_out_args, argPtr) >>>>>>> TypeError: The VARIANT type is unknown (0x4024). GetErrorString >>>>>>> -2147467259 0 pythoncom error: Failed to call the universal >>>>>>> dispatcher >>>>>>> >>>>>>> (...) >>>>>>> >>>>>>> I've hat a lookat the definition of GetStatus. It requires a pointer >>>>>>> to a pointer of type "tagOPCSERVERSTATUS" which is a record >>>>>>> definition in the type library. But when I look at what has been >>>>>>> generated by makepy, the record map looks pretty empty to me: >>>>>>> >>>>>>> RecordMap = { u'tagOPCITEMVQT': >>>>>>> '{00000000-0000-0000-0000-000000000000}', } >>>>>>> >>>>>>> The type lib defines 10 records! I tried to import the typelib using >>>>>>> comtypes and get that generated (excerpt): >>>>>>> >>>>>>> class tagOPCSERVERSTATUS(Structure): pass >>>>>>> >>>>>>> # values for enumeration 'tagOPCSERVERSTATE' OPC_STATUS_RUNNING = 1 >>>>>>> OPC_STATUS_FAILED = 2 OPC_STATUS_NOCONFIG = 3 OPC_STATUS_SUSPENDED = >>>>>>> 4 OPC_STATUS_TEST = 5 OPC_STATUS_COMM_FAULT = 6 tagOPCSERVERSTATE = >>>>>>> c_int # enum tagOPCSERVERSTATUS._fields_ = [ ('ftStartTime', >>>>>>> _FILETIME), ('ftCurrentTime', _FILETIME), ('ftLastUpdateTime', >>>>>>> _FILETIME), ('dwServerState', tagOPCSERVERSTATE), ('dwGroupCount', >>>>>>> c_ulong), ('dwBandWidth', c_ulong), ('wMajorVersion', c_ushort), >>>>>>> ('wMinorVersion', c_ushort), ('wBuildNumber', c_ushort), >>>>>>> ('wReserved', c_ushort), ('szVendorInfo', WSTRING), ] >>>>>>> >>>>>>> Is there a bug in makepy that prevents creating these records? >>>>>> >>>>>> It would seem so :) >>>>>> >>>>>>> If >>>>>>> yes, can I fix it or can I manually change the generated file to >>>>>>> support the records? >>>>>> >>>>>> I'm really not sure - you probably need to look at the existing >>>>>> Record >>>>>> tests. The "PyCOMTest" test object (which is in the source tree and >>>>>> needs you to build it using MSVC) has some structs for testing. >>>>>> >>>>>> >>>>>>> If not, how would I create and return such a >>>>>>> pointer of a pointer in pythoncom? Is comtypes compatible with >>>>>>> pythoncom so I could use the comtypes generated files? >>>>>> >>>>>> Unfortunately there isn't any compatibility between the 2. >>>>>> >>>>>> Cheers, >>>>>> >>>>>> Mark >>>>>>> >>>>>>> Thanks! >>>>>>> >>>>>>> //Jan >>>>>>> >>>>>>> ----- Originalnachricht ----- Von: "Jan Wedel" >>>>>>> Gesendet: Don, 3/22/2012 1:51pm An: mhammond at skippinet.com.au Cc: >>>>>>> python-win32 at python.org Betreff: Re: [python-win32] How to write a >>>>>>> COM Server implementing interfaces from type lib? >>>>>>> >>>>>>> Hi Mark, >>>>>>> >>>>>>> thanks for your reply. >>>>>>> >>>>>>>> That's E_FAIL which is pretty generic. Doesn't sound like a >>>>>>>> simple failure to QI for the correct interface. >>>>>>> >>>>>>> Yeah. The client says something like "Unknown Error" which makes it >>>>>>> hard to tell what the problem actually is. >>>>>>> >>>>>>>> win32com should be able to do this given there is a tlb - see the >>>>>>>> "pippo" samples. Further, using the debug facilities and >>>>>>>> win32traceutil, you should be able to see the creation of the >>>>>>>> object, the QIs on the object and any methods actually called. But >>>>>>>> as mentioned, I doubt it is a QI failure. >>>>>>> >>>>>>> Yeah, there is a type library (OPC DA). Actually there are even two >>>>>>> type libraries, each of them contains two Interface which my server >>>>>>> needs to implement. >>>>>>> >>>>>>> I've had a look into policy.py and found that: >>>>>>> >>>>>>> def _build_typeinfos_(self): # Can only ever be one for now. (...) >>>>>>> >>>>>>> which means using _typelib_guid_ allows only one type lib, right? I >>>>>>> could try to patch your code or do you think there is a general >>>>>>> problem that would make it impossible having more than one >>>>>>> typelib in >>>>>>> your framework? >>>>>>> >>>>>>>> Have you tried contacting the author of the object? >>>>>>> >>>>>>> I am the author... I only use the 3rd party typelibs. I am writing >>>>>>> the server that must support the interfaces so that other 3rd party >>>>>>> clients can access the server component. >>>>>>> >>>>>>> I can reproduce the error using python the COMView tool trying to >>>>>>> instanciate the Server. The problem is, that I don't see why. I've >>>>>>> enabled debugging mode when registering the server. When using >>>>>>> one of >>>>>>> the 3rd party clients, rhe python trace collector shows the >>>>>>> following: >>>>>>> >>>>>>> Object with win32trace dispatcher created (object=None) Entering >>>>>>> constructor in>>>>>> 0x0213B058>._QueryInterface_ with unsupported IID >>>>>>> {00000003-0000-0000-C000-000000000046} >>>>>>> ({00000003-0000-0000-C000-000000000046}) >>>>>>> in>>>>>> 0x0213B058>._QueryInterface_ with unsupported IID >>>>>>> {0000001B-0000-0000-C000-000000000046} >>>>>>> ({0000001B-0000-0000-C000-000000000046}) >>>>>>> in>>>>>> 0x0213B058>._QueryInterface_ with unsupported IID >>>>>>> {00000018-0000-0000-C000-000000000046} >>>>>>> ({00000018-0000-0000-C000-000000000046}) >>>>>>> in>>>>>> 0x0213B058>._QueryInterface_ with unsupported IID >>>>>>> {4C1E39E1-E3E3-4296-AA86-EC938D896E92} >>>>>>> ({4C1E39E1-E3E3-4296-AA86-EC938D896E92}) >>>>>>> in>>>>>> 0x0213B058>._InvokeEx_-AddConnection(1, 0) [1,0,None] Connection >>>>>>> added. Active connections: 1 in>>>>>> instance at 0x0213B058>._InvokeEx_-ReleaseConnection(1, 0, 1) >>>>>>> [1,0,None] Connection released. Active connections: 0 >>>>>>> >>>>>>> The QI calls are standard COM calls, not application specific >>>>>>> (AFAIK). You can see the "Entering constructor" message which is in >>>>>>> my python constructor of the server. Just for fun, I implemented the >>>>>>> IExternalConnection interface to see if the methods are called. >>>>>>> "Connection added. ..." is my output. But I can't see an further >>>>>>> requests that shows what the problem is. Are there any calls in >>>>>>> pythoncom that could fail and does not give debug output? >>>>>>> >>>>>>> My pythoncom server starts like that: >>>>>>> >>>>>>> class EttexOPCServer: _reg_progid_ = "Ettex.OPC.Automation" >>>>>>> _reg_desc_ = "ettex OPC DA Server" _reg_clsid_ = >>>>>>> "{13B51E8D-4BC2-4DED-8D4E-4614692F88E6}" _reg_catids_ = [ >>>>>>> '{63D5F432-CFE4-11D1-B2C8-0060083BA1FB}' ] _com_interfaces_ = [ >>>>>>> '{00000019-0000-0000-C000-000000000046}', # IExternalConnection (Is >>>>>>> it really mandatory?) '{39C13A4D-011E-11D0-9675-0020AFD8ADB3}', # >>>>>>> IOPCServer '{F31DFDE2-07B6-11D2-B2D8-0060083BA1FB}', # IOPCCommon >>>>>>> '{39C13A72-011E-11D0-9675-0020AFD8ADB3}', # IOPCItemProperties >>>>>>> '{B196B284-BAB4-101A-B69C-00AA00341D07}' # >>>>>>> IConnectionPointContainer ] _typelib_guid_ = >>>>>>> "{3B540B51-0378-4551-ADCC-EA9B104302BF}" _typelib_version_ = (3, 0) >>>>>>> _reg_clsctx_ = pythoncom.CLSCTX_LOCAL_SERVER >>>>>>> >>>>>>> _public_methods_ = [ 'Connect', 'Disconnect', 'GetErrorString' ] ## >>>>>>> IExternalConnection methods _public_methods_ += [ 'AddConnection', >>>>>>> 'ReleaseConnection' ] >>>>>>> >>>>>>> ################################################################# ## >>>>>>> COM Class Attributes >>>>>>> ################################################################# >>>>>>> _public_attrs_ = [ 'ClientName', 'OPCGroups' ] >>>>>>> >>>>>>> ################################################################# ## >>>>>>> COM Class Read-Only Attributes >>>>>>> ################################################################# >>>>>>> _readonly_attrs_ = [ 'OPCGroups' ] >>>>>>> >>>>>>> I don't have all interface methods implemented at the time but I >>>>>>> guess that doesn't matter as long as not all type libs have been >>>>>>> loaded, does it? >>>>>>> >>>>>>> If its not possible with pythoncom, is it possible with comtypes? >>>>>>> I've tried that as well with nearly the same result ("Unknown >>>>>>> error"): >>>>>>> >>>>>>> # OPC Data Access 3.00 Type Library opc_da_tl = >>>>>>> comtypes.GUID("{3B540B51-0378-4551-ADCC-EA9B104302BF}") # OPC Common >>>>>>> 1.10 Type Library opc_com_tl = >>>>>>> comtypes.GUID("{B28EEDB1-AC6F-11D1-84D5-00608CB8A7E9}") >>>>>>> >>>>>>> GetModule((opc_da_tl, 3, 0)) GetModule((opc_com_tl, 1, 0)) >>>>>>> >>>>>>> import comtypes.gen.OPCDA as OpcDa import comtypes.gen.OPCCOMN as >>>>>>> OpcCommon >>>>>>> >>>>>>> class EttexOPCServer2(OpcCommon.IOPCCommon, >>>>>>> OpcCommon.IConnectionPointContainer, OpcDa.IOPCServer, >>>>>>> OpcDa.IOPCItemProperties): _reg_progid_ = "Ettex.OPC.Automation2" >>>>>>> _reg_desc_ = "ettex OPC DA Server 2" _reg_novers_progid_ = >>>>>>> _reg_progid_ _reg_clsid_ = "{80A2B8F7-792E-43F4-95F8-CD6BB4B413AD}" >>>>>>> _reg_catids_ = [ '{63D5F432-CFE4-11D1-B2C8-0060083BA1FB}' ] >>>>>>> _reg_clsctx_ = comtypes.CLSCTX_LOCAL_SERVER _regcls_ = >>>>>>> comtypes.server.localserver.REGCLS_MULTIPLEUSE >>>>>>> >>>>>>> _com_interfaces_ = [OpcCommon.IOPCCommon, >>>>>>> OpcCommon.IConnectionPointContainer, OpcDa.IOPCServer, >>>>>>> OpcDa.IOPCItemProperties] >>>>>>> >>>>>>> I don't know what to do. Is there anything more I can do to debug to >>>>>>> find out WHAT exactly causes the error? Because as you can see, the >>>>>>> pythoncom debug output doesn't show this error that is returned by >>>>>>> the client. >>>>>>> >>>>>>> Thanks a lot! >>>>>>> >>>>>>> //Jan >>>>>>> >>>>>>> ----- Originalnachricht ----- Von: "Mark >>>>>>> Hammond" Gesendet: Don, 3/22/2012 >>>>>>> 12:29pm >>>>>>> An: "Jan Wedel" Cc: python-win32 at python.org >>>>>>> Betreff: Re: [python-win32] How to write a COM Server implementing >>>>>>> interfaces from type lib? >>>>>>> >>>>>>> On 22/03/2012 2:53 AM, Jan Wedel wrote: >>>>>>>> Hi, >>>>>>>> >>>>>>>> I'm currently having trouble to write a COM-Server that has some >>>>>>>> special requirements: - It needs to derive from IUnknown - It needs >>>>>>>> to implement multiple interface from two different proprietary >>>>>>>> typelibs (dlls) - It needs to implement a custom category >>>>>>>> >>>>>>>> At first I started with pythoncom. I used the attribute >>>>>>>> _reg_catids_ to specify the category and _com_interfaces_ to >>>>>>>> specify the interfaces I want to implement. The client (proprietary >>>>>>>> 3rd party sw, no source) sees the server but throws some 0x80004005 >>>>>>>> error on CoCreateInstance. >>>>>>> >>>>>>> That's E_FAIL which is pretty generic. Doesn't sound like a simple >>>>>>> failure to QI for the correct interface. >>>>>>> >>>>>>> win32com should be able to do this given there is a tlb - see the >>>>>>> "pippo" samples. Further, using the debug facilities and >>>>>>> win32traceutil, you should be able to see the creation of the >>>>>>> object, the QIs on the object and any methods actually called. But >>>>>>> as mentioned, I doubt it is a QI failure. >>>>>>> >>>>>>>> I was hoping that I can just tell the COM dispatcher, "yes, I have >>>>>>>> these interface implemented" and implement the methods without >>>>>>>> really having the interface classes available. >>>>>>>> >>>>>>>> I read, that pythoncom can only create components that use >>>>>>>> IDispatch so I guess the _com_interfaces_ idea won't work, will >>>>>>>> it? >>>>>>> >>>>>>> As above, you should be able to fully implement them so long as >>>>>>> makepy has been run. >>>>>>> >>>>>>>> Then I did some further research and found comtypes. I tried to >>>>>>>> write a server stub again. I used GetModule to load the type >>>>>>>> library containing the Interfaces, importing the generated >>>>>>>> interface classes and let the main server class extend these >>>>>>>> interfaces. >>>>>>>> >>>>>>>> The first problem was, that comtypes did not support the >>>>>>>> _reg_catids_ attribute or anything similar so I had to add the >>>>>>>> Implemented Categories key manually to the registry. Then, I was >>>>>>>> able to see the server through the client, which obviously filters >>>>>>>> by categories, but it still shows the same error as before. >>>>>>>> >>>>>>>> So, what is the correct/best way to implement a server that needs >>>>>>>> to implement custom interfaces and categories? Or is it possible at >>>>>>>> all using python? >>>>>>> >>>>>>> The fact you get the same error there implies something else is >>>>>>> going wrong, but it is impossible to guess what. Have you tried >>>>>>> contacting the author of the object? >>>>>>> >>>>>>> Mark >>>>>>> >>>>>>>> >>>>>>>> Thanks! >>>>>>>> >>>>>>>> //Jan >>>>>>>> >>>>>>>> >>>>>>>> >>>>>>>> _______________________________________________ python-win32 >>>>>>>> mailing list python-win32 at python.org >>>>>>>> http://mail.python.org/mailman/listinfo/python-win32 >>>>>>> >>>>>>> _______________________________________________ python-win32 mailing >>>>>>> list python-win32 at python.org >>>>>>> http://mail.python.org/mailman/listinfo/python-win32 >>>>>> >>>>> >>>> >>>> >>> >> >> > From potterpavi at gmail.com Fri Mar 30 15:34:41 2012 From: potterpavi at gmail.com (pavi ena) Date: Fri, 30 Mar 2012 19:04:41 +0530 Subject: [python-win32] Wanted to know how we can overwrite the win32serviceutil.ServiceFramework SvcDoRun method. In-Reply-To: <4F7496D7.60603@probo.com> References: <4F7496D7.60603@probo.com> Message-ID: Hello Tim Roberts, Thanks a lot. I will open up the source code and try to understand the implementation. I will continue to work with my existing code. On Thu, Mar 29, 2012 at 10:37 PM, Tim Roberts wrote: > pavi ena wrote: > > > > I am new to Python Window services development. I have small code below. > > ... > > Generally i run this script as batch file which takes parameters like > > user_id > > and password > > > > python demo_svcs.py install > > python demo_svcs.py start %user_id% %password% > > > > At present in my code i am passing user_id and password as argv > > "win32serviceutil.HandleCommandLine(DemoService, argv=sys.argv)" > > which intern i am accessing these user_id and password in 'SvcDoRun' > > method > > with 'args', i just wanted to know is this the correct approach or do > > we have flexibility > > to overwrite 'SvcDoRun' method to get these 'user_id' and 'password' > > as kwd_args > > and use these kwd_args in 'start_mail_check' method. > > Remember that you have the full source code to win32serviceutil.py in > your Python distribution. You can go look it up. SvcDoRun is called > from win32serviceutil.py. You'll see that it is called from > ServiceFramework.SvcRun with no parameters: > self.SvcDoRun() > > SvcRun is called in response to a message from the Service Control > Manager, so there's really no place to make a modification like that. I > think you need to keep doing what you are doing. > > -- > Tim Roberts, timr at probo.com > Providenza & Boekelheide, Inc. > > _______________________________________________ > python-win32 mailing list > python-win32 at python.org > http://mail.python.org/mailman/listinfo/python-win32 > -------------- next part -------------- An HTML attachment was scrubbed... URL: From reckoner at gmail.com Sat Mar 31 17:09:56 2012 From: reckoner at gmail.com (reckoner) Date: Sat, 31 Mar 2012 08:09:56 -0700 Subject: [python-win32] wait for new clipboard data? Message-ID: <4F771E44.8020701@gmail.com> I'm doing some automation using Python and I'm looking for something similar to Autohotkey's Clipwait function. see here: http://www.autohotkey.com/docs/commands/ClipWait.htm This basically waits for new clipboard data after a previous copy operation (like ctrl+c). Thanks!