From milan.kase at gmail.com Sun Jun 2 13:54:45 2013 From: milan.kase at gmail.com (=?ISO-8859-2?Q?Milan_Ka=B9e?=) Date: Sun, 2 Jun 2013 13:54:45 +0200 Subject: [python-win32] Strange order of OnEnter/LeaveScript site methods in application hosting Python active scripting engine In-Reply-To: <51A7E06D.7010600@skippinet.com.au> References: <51A6F459.9060708@gmail.com> <51A7E06D.7010600@skippinet.com.au> Message-ID: These events are (actually were) quite reliable way to determine when the actual script execution begins/ends among various (buggy) scripting engine. The application uses these events to change the state of the GUI. This does not work any more correctly with Python. IMHO Python's implementation violates the contract documented in MSDN (linked in my first post) and deviates from implementations of other engines (tested with JScript, VBScript, Ruby, PHP, Lua). -- Milan 2013/5/31 Mark Hammond > On 31/05/2013 5:33 AM, Milan Ka?e wrote: > >> I tried to take stack dumps (attached bellow) and it seems that the >> first pair of calls is coming from CompileInScriptedSection while the >> second pair is from ExecInScriptedSection. Do you have a clue what's >> going on here? >> > > Right - script blocks are compiled before they are executed. I really > can't remember why the compilation step does this - what problem is it > causing you? > > Mark > >> >> 0.00000000*** OnEnterScript *** >> >> 0.00142864 File >> "C:\Python27\lib\site-**packages\win32com\server\**policy.py", line 324, >> in >> _InvokeEx_ >> 0.00142864 return self._invokeex_(dispid, lcid, wFlags, args, kwargs, >> serviceProvider) >> 0.00142864 File >> "C:\Python27\lib\site-**packages\win32com\server\**policy.py", line 585, >> in >> _invokeex_ >> 0.00142864 return func(*args) >> 0.00142864 File >> "C:\Python27\lib\site-**packages\win32comext\axscript\**client\framework.py", >> line >> 610, in SetScriptState >> 0.00142864 self.Run() >> 0.00142864 File >> "C:\Python27\lib\site-**packages\win32comext\axscript\**client\framework.py", >> line >> 788, in Run >> 0.00142864 self.ExecutePendingScripts() >> 0.00142864 File >> "C:\Python27\lib\site-**packages\win32comext\axscript\**client\framework.py", >> line >> 736, in ExecutePendingScripts >> 0.00142864 self.DoExecutePendingScripts() >> 0.00142864 File >> "C:\Python27\lib\site-**packages\win32comext\axscript\** >> client\pyscript.py", >> line 237, in DoExecutePendingScripts >> 0.00142864 if self.CompileInScriptedSection(**codeBlock, "exec"): >> 0.00142864 File >> "C:\Python27\lib\site-**packages\win32comext\axscript\**client\framework.py", >> line >> 872, in CompileInScriptedSection >> 0.00142864 self.BeginScriptedSection() >> 0.00142864 File >> "C:\Python27\lib\site-**packages\win32comext\axscript\**client\framework.py", >> line >> 972, in BeginScriptedSection >> 0.00142864 win32api.OutputDebugString("".** >> join(traceback.format_stack())**) >> 0.00574597*** OnLeaveScript *** >> >> 0.00618566 File >> "C:\Python27\lib\site-**packages\win32com\server\**policy.py", line 324, >> in >> _InvokeEx_ >> 0.00618566 return self._invokeex_(dispid, lcid, wFlags, args, kwargs, >> serviceProvider) >> 0.00618566 File >> "C:\Python27\lib\site-**packages\win32com\server\**policy.py", line 585, >> in >> _invokeex_ >> 0.00618566 return func(*args) >> 0.00618566 File >> "C:\Python27\lib\site-**packages\win32comext\axscript\**client\framework.py", >> line >> 610, in SetScriptState >> 0.00618566 self.Run() >> 0.00618566 File >> "C:\Python27\lib\site-**packages\win32comext\axscript\**client\framework.py", >> line >> 788, in Run >> 0.00618566 self.ExecutePendingScripts() >> 0.00618566 File >> "C:\Python27\lib\site-**packages\win32comext\axscript\**client\framework.py", >> line >> 736, in ExecutePendingScripts >> 0.00618566 self.DoExecutePendingScripts() >> 0.00618566 File >> "C:\Python27\lib\site-**packages\win32comext\axscript\** >> client\pyscript.py", >> line 237, in DoExecutePendingScripts >> 0.00618566 if self.CompileInScriptedSection(**codeBlock, "exec"): >> 0.00618566 File >> "C:\Python27\lib\site-**packages\win32comext\axscript\**client\framework.py", >> line >> 880, in CompileInScriptedSection >> 0.00618566 self.EndScriptedSection() >> 0.00618566 File >> "C:\Python27\lib\site-**packages\win32comext\axscript\**client\framework.py", >> line >> 979, in EndScriptedSection >> 0.00618566 win32api.OutputDebugString("".** >> join(traceback.format_stack())**) >> 0.00675985*** OnEnterScript *** >> >> 0.00718076 File >> "C:\Python27\lib\site-**packages\win32com\server\**policy.py", line 324, >> in >> _InvokeEx_ >> 0.00718076 return self._invokeex_(dispid, lcid, wFlags, args, kwargs, >> serviceProvider) >> 0.00718076 File >> "C:\Python27\lib\site-**packages\win32com\server\**policy.py", line 585, >> in >> _invokeex_ >> 0.00718076 return func(*args) >> 0.00718076 File >> "C:\Python27\lib\site-**packages\win32comext\axscript\**client\framework.py", >> line >> 610, in SetScriptState >> 0.00718076 self.Run() >> 0.00718076 File >> "C:\Python27\lib\site-**packages\win32comext\axscript\**client\framework.py", >> line >> 788, in Run >> 0.00718076 self.ExecutePendingScripts() >> 0.00718076 File >> "C:\Python27\lib\site-**packages\win32comext\axscript\**client\framework.py", >> line >> 736, in ExecutePendingScripts >> 0.00718076 self.DoExecutePendingScripts() >> 0.00718076 File >> "C:\Python27\lib\site-**packages\win32comext\axscript\** >> client\pyscript.py", >> line 238, in DoExecutePendingScripts >> 0.00718076 self.ExecInScriptedSection(**codeBlock, globs) >> 0.00718076 File >> "C:\Python27\lib\site-**packages\win32comext\axscript\**client\framework.py", >> line >> 899, in ExecInScriptedSection >> 0.00718076 self.BeginScriptedSection() >> 0.00718076 File >> "C:\Python27\lib\site-**packages\win32comext\axscript\**client\framework.py", >> line >> 972, in BeginScriptedSection >> 0.00718076 win32api.OutputDebugString("".** >> join(traceback.format_stack())**) >> 3.00900340*** OnLeaveScript *** >> >> 3.00964451 File >> "C:\Python27\lib\site-**packages\win32com\server\**policy.py", line 324, >> in >> _InvokeEx_ >> 3.00964451 return self._invokeex_(dispid, lcid, wFlags, args, kwargs, >> serviceProvider) >> 3.00964451 File >> "C:\Python27\lib\site-**packages\win32com\server\**policy.py", line 585, >> in >> _invokeex_ >> 3.00964451 return func(*args) >> 3.00964451 File >> "C:\Python27\lib\site-**packages\win32comext\axscript\**client\framework.py", >> line >> 610, in SetScriptState >> 3.00964451 self.Run() >> 3.00964451 File >> "C:\Python27\lib\site-**packages\win32comext\axscript\**client\framework.py", >> line >> 788, in Run >> 3.00964451 self.ExecutePendingScripts() >> 3.00964451 File >> "C:\Python27\lib\site-**packages\win32comext\axscript\**client\framework.py", >> line >> 736, in ExecutePendingScripts >> 3.00964451 self.DoExecutePendingScripts() >> 3.00964451 File >> "C:\Python27\lib\site-**packages\win32comext\axscript\** >> client\pyscript.py", >> line 238, in DoExecutePendingScripts >> 3.00964451 self.ExecInScriptedSection(**codeBlock, globs) >> 3.00964451 File >> "C:\Python27\lib\site-**packages\win32comext\axscript\**client\framework.py", >> line >> 905, in ExecInScriptedSection >> 3.00964451 self.EndScriptedSection() >> 3.00964451 File >> "C:\Python27\lib\site-**packages\win32comext\axscript\**client\framework.py", >> line >> 979, in EndScriptedSection >> 3.00964451 win32api.OutputDebugString("".** >> join(traceback.format_stack())**) >> 3.01041079pythoncom error: >> 3.01048589Unexpected exception in gateway method 'SetScriptSite' >> 3.01056170 >> 3.01062036 >> 3.01094675Traceback (most recent call last): >> >> 3.01094675 File >> "C:\Python27\lib\site-**packages\win32com\server\**policy.py", line 324, >> in >> _InvokeEx_ >> 3.01094675 return self._invokeex_(dispid, lcid, wFlags, args, kwargs, >> serviceProvider) >> 3.01094675 File >> "C:\Python27\lib\site-**packages\win32com\server\**policy.py", line 585, >> in >> _invokeex_ >> 3.01094675 return func(*args) >> 3.01094675 File >> "C:\Python27\lib\site-**packages\win32comext\axscript\**client\framework.py", >> line >> 580, in SetScriptSite >> 3.01094675 self.lcid = site.GetLCID() >> 3.01094675AttributeError: 'NoneType' object has no attribute 'GetLCID' >> >> 3.01102114pythoncom error: >> 3.01107931Unexpected gateway error >> 3.01122880 >> 3.01147223 >> 3.01194453Traceback (most recent call last): >> >> 3.01194453 File >> "C:\Python27\lib\site-**packages\win32com\server\**policy.py", line 324, >> in >> _InvokeEx_ >> 3.01194453 return self._invokeex_(dispid, lcid, wFlags, args, kwargs, >> serviceProvider) >> 3.01194453 File >> "C:\Python27\lib\site-**packages\win32com\server\**policy.py", line 585, >> in >> _invokeex_ >> 3.01194453 return func(*args) >> 3.01194453 File >> "C:\Python27\lib\site-**packages\win32comext\axscript\**client\framework.py", >> line >> 580, in SetScriptSite >> 3.01194453 self.lcid = site.GetLCID() >> 3.01194453AttributeError: 'NoneType' object has no attribute 'GetLCID' >> >> >> >> 2013/5/30 Mark Hammond > >> >> >> >> Apart from the engine being called with no script to execute for >> some reason, it may be that an event handler is being added, which >> causes Python to execute things twice - once to "build" the event >> handler, and again when it is actually executed. >> >> Either way, if you check out >> win32comext/axscript/client/__**framework.py and look for >> >> ApplyInScriptedSection(), you will find where these calls originate >> from. If you can print (or otherwise arrange to see) what the code >> is, it might give us more of a clue. >> >> HTH, >> >> Mark >> >> >> On 30/05/2013 3:34 AM, Milan Ka?e wrote: >> >> Hello, >> a user of our application which can host various active scripting >> engines reported problems when using the application together with >> Python active scripting engine. I traced the problem down to the >> order >> in which the engine calls the site's OnEnterScript/OnLeaveScript >> methods. >> >> The usual scenario with other engines (including MS JScript and >> VBScript) is: >> 1. OnEnterScript >> 2. ...executing script... >> 3. OnLeaveScript >> >> However with Python engine, after calling >> IActiveScript.SetScriptState(_**_SCRIPTSTATE_CONNECTED) the >> >> scenario is >> following: >> 1. OnEnterScript >> 2. OnLeaveScript >> 3. OnEnterScript >> 4. ...executing script... >> 5. OnLeaveScript >> >> One would expect either the first scenario or in case the events >> are >> raised multiple times, then the calls should be nested (as stated >> in >> MSDN, >> http://msdn.microsoft.com/en-_**_us/library/9c1cww48(v=vs.94).** >> __aspx >> > aspx >). >> >> Is the Python's way of calling these methods intentional or is >> it a bug? >> >> Thanks, >> Milan >> >> >> ______________________________**___________________ >> 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 esj at harvee.org Mon Jun 3 19:14:55 2013 From: esj at harvee.org (Eric Johansson) Date: Mon, 03 Jun 2013 13:14:55 -0400 Subject: [python-win32] clipboard errors Message-ID: <51ACCF0F.7050102@harvee.org> I'm having a bit of trouble the Windows clipboard. I keep getting things like the trace back below.: 2013-06-03 12:56:26,667 - DEBUG - VFU TB Traceback (most recent call last): File "C:\NatLink\NatLink\Vocola\extensions\vocola_ext_togglename.py", line 180, in vc_first_unknown clipboard_string = clipboard_instance.clipboard_get() File "C:\NatLink\NatLink\Vocola\extensions\vocola_ext_togglename.py", line 88, in clipboard_get result=self.win32clipboard.GetClipboardData(self.win32con.CF_TEXT) error: (183, 'GetClipboardData', 'Cannot create a file when that file already exists.') the code is implemented as can be found at github https://github.com/togglename/togglename/blob/master/vocola/extensions/vocola_ext_togglename.py Start about line 69. Would appreciate any insight as to why I'm getting these errors. From johned9999 at comcast.net Tue Jun 4 06:51:34 2013 From: johned9999 at comcast.net (John Spitzer) Date: Mon, 03 Jun 2013 21:51:34 -0700 Subject: [python-win32] Python and Win 7 Registry VirtualStore Message-ID: <51AD7256.9040806@comcast.net> Hello, I've searched the python sites and help, library's and all the forums I could find, but haven't seen any mention of this. This help line seemed like a good place to ask this. I am on an HP laptop Intel Core 2 Duo, running Windows 7 Pro SP1 32Bit. I am using Python 2.7.3. I have an application I built that ran fine on Windows XP, but now fails on Windows 7. The place I'm encountering the problem is where I try to read a key from the registry. I believe it's because of the Virtualization of the registry on Windows 7. This key is created by another app that I'm trying to co-ordinate with. On Windows XP the Registry key was: [HKEY_LOCAL_MACHINE\SOFTWARE\Interface Software\ConnMgr] "DB Path"="C:\\Documents and Settings\\All Users\\Application Data\\" When this app is installed on Windows 7, the key is directed to the registry Virtual Store at: [HKEY_CURRENT_USER\Software\Classes\VirtualStore\MACHINE\SOFTWARE\Interface Software\ConnMgr] "DB Path"="C:\\ProgramData\\EnvisionWare\\" So far that is what I think I'd expected on Windows 7 and the virtualization of the registry. The code fragment that is reading the registry is: ----- from _winreg import * ConnKey = OpenKey(HKEY_LOCAL_MACHINE, r'SOFTWARE\Interface Software\ConnMgr', 0, KEY_READ) ConnValue = QueryValueEx(ConnKey, "DB Path") EWDataSource = os.path.split(str(ConnValue[0])) ------ The OpenKey fails with the message: WindowsError: (2, 'The system cannot find the file specified"). I believe this is because the key does not exist at the path [HKEY_LOCAL_MACHINE\SOFTWARE\Interface Software\ConnMgr]. After all this, the question is: Why isn't the OpenKey call being redirected to the VirtualStore? What can I change in the program, ACLs or other to make it be redirected? Any help would be appreciated. Thanks, John -- John Spitzer johned9999 at comcast.net 503-590-7434 From ckkart at hoc.net Tue Jun 4 13:39:33 2013 From: ckkart at hoc.net (Christian K.) Date: Tue, 04 Jun 2013 08:39:33 -0300 Subject: [python-win32] wx.Frame with windows parent Message-ID: Hi, I asked this some time ago on the wxpython list and still have no solution: I am trying to make a wx.Dialog float on a non-wxpython parent. I get the HWND of the window, call wx.Window_FromHWND(None, HWND) and open the dialog with that parent and FLOAT_ON_PARENT style. This works very well but suprisingly, it prevents the parent frame (in this case Outlook) from closing when clicking on the window's close button. Actually this happens right after calling wx.Window_FromHWND, i.e. before opening/attaching the child window. After that the close button is no working anymore. Is that to be expected? How can I possibly avoid that? This happens with wxpython 2.8.12.1 and latest pywin32 on windows 7 (32bit) Regards, Christian From timr at probo.com Tue Jun 4 18:56:08 2013 From: timr at probo.com (Tim Roberts) Date: Tue, 4 Jun 2013 09:56:08 -0700 Subject: [python-win32] clipboard errors In-Reply-To: <51ACCF0F.7050102@harvee.org> References: <51ACCF0F.7050102@harvee.org> Message-ID: <51AE1C28.8070409@probo.com> Eric Johansson wrote: > I'm having a bit of trouble the Windows clipboard. I keep getting things > like the trace back below.: > > 2013-06-03 12:56:26,667 - DEBUG - VFU TB Traceback (most recent call last): > File "C:\NatLink\NatLink\Vocola\extensions\vocola_ext_togglename.py", > line 180, in vc_first_unknown > clipboard_string = clipboard_instance.clipboard_get() > File "C:\NatLink\NatLink\Vocola\extensions\vocola_ext_togglename.py", > line 88, in clipboard_get > result=self.win32clipboard.GetClipboardData(self.win32con.CF_TEXT) > error: (183, 'GetClipboardData', 'Cannot create a file when that file > already exists.') > ... > Would appreciate any insight as to why I'm getting these errors. What is on the clipboard? This code expects only text data in the clipboard (CF_TEXT). If the clipboard contains an image, you'll get an error. It may be that a try/except is appropriate here. The text of the error is a bit misleading. Error code 183 is ERROR_ALREADY_EXISTS. That doesn't necessarily involve a file at all. -- Tim Roberts, timr at probo.com Providenza & Boekelheide, Inc. From timr at probo.com Tue Jun 4 19:10:41 2013 From: timr at probo.com (Tim Roberts) Date: Tue, 4 Jun 2013 10:10:41 -0700 Subject: [python-win32] Python and Win 7 Registry VirtualStore In-Reply-To: <51AD7256.9040806@comcast.net> References: <51AD7256.9040806@comcast.net> Message-ID: <51AE1F91.2060804@probo.com> John Spitzer wrote: > I have an application I built that ran fine on Windows XP, but now fails > on Windows 7. The place I'm encountering the problem is where I try to > read a key from the registry. I believe it's because of the > Virtualization of the registry on Windows 7. This key is created by > another app that I'm trying to co-ordinate with. ... > The code fragment that is reading the registry is: > ----- > from _winreg import * > > ConnKey = OpenKey(HKEY_LOCAL_MACHINE, r'SOFTWARE\Interface > Software\ConnMgr', 0, KEY_READ) > ConnValue = QueryValueEx(ConnKey, "DB Path") > EWDataSource = os.path.split(str(ConnValue[0])) > ------ > The OpenKey fails with the message: WindowsError: (2, 'The system cannot > find the file specified"). I believe this is because the key does not > exist at the path [HKEY_LOCAL_MACHINE\SOFTWARE\Interface Software\ConnMgr]. > > After all this, the question is: Why isn't the OpenKey call being > redirected to the VirtualStore? What can I change in the program, ACLs > or other to make it be redirected? Is your application a service? Is it running elevated? -- Tim Roberts, timr at probo.com Providenza & Boekelheide, Inc. From vernondcole at gmail.com Tue Jun 4 21:10:49 2013 From: vernondcole at gmail.com (Vernon D. Cole) Date: Tue, 4 Jun 2013 13:10:49 -0600 Subject: [python-win32] adodbapi versions and Python 2.4 -- a status report. Message-ID: I have just released an upgraded version (2.5.0) of adodbapi on its sourceforge site. http://sf.net/projects/adodbapi ( I suppose that I should say here, for the benefit on new readers, that adodbapi is a PEP 249 compliant database api module which ships as part of pywin32, as well as being available separately for IronPython users.) Version 2.5 adds several new features, the most important of which is a server module which can be used to enable a Windows computer to act as a proxy so that a Linux (or Windows) client can use it to read an ADO data source. This version is a key part of an update to django-mssql which I am now working on. There are other new features which would be handy to Windows users in general. Connection strings can be built using keyword arguments, and can be used to switch the default paramstyle and autocommit features of the connection. Because the remote and server modules use Pyro4 to communicate, and since Pyro4 requires Python 2.5 or later, I have made use of Python 2.5 features in the new version. [ Relax, everyone. The old way of connecting works just like it always has -- you only need Pyro if you import the new modules. ] This means that there is now a version mismatch between the adodbapi in pywin32 and the one on sourceforge. There is nothing dangerous about that, it only makes things a bit inconvenient for users who want the new features. I cannot upgrade the module here until the decision has been made to drop Python 2.4 support. The version in pywin32 (adodbapi v 2.4.3) has been updated with the latest support requests and patches. -- Vernon Cole -------------- next part -------------- An HTML attachment was scrubbed... URL: From AubinL at netpolarity.com Wed Jun 5 06:16:52 2013 From: AubinL at netpolarity.com (Aubin LaBrosse) Date: Tue, 4 Jun 2013 21:16:52 -0700 Subject: [python-win32] PySBinaryArray?? Message-ID: <20D91BE563145C44B22ABA9D3580BEB6B7FE3D7E7C@npex1> Hello, List, I'm new to pywin32 and have been able to use it quite sufficiently with the help of the internet and some (rather rudimentary, I admit) knowledge of the windows api. I've been able to do some quite clever things with HTML on the windows clipboard and the Extended MAPI support. However I am stumped on one thing, which I would have imagined would be rather easy to do somehow but just can't seem to figure it out. I have used Extended MAPI to open the outlook outbox, create, and send an email message. Now I want to move that message from the outbox to the sent items folder, as outlook itself would do. Without doing so, it simply sits in the outbox, or is sent and deleted if I set the PR_DELETE_AFTER_SUBMIT (apologies if that's not the exact name, doing this from memory as I write this email quickly) property flag So anyway, there exists PyIMAPIFolder.MoveMessages - I have a python reference to a PYIMessage object that I would like to move, but the first parameter to MoveMessages is what appears to be called a PySBinaryArray which, all the documentation I can find on it essentially says is a 'list of strings containing binary data' What binary data, exactly? The body of the message? Some other message identifier or property tag which must be used to indicate which message is to be moved? Something else entirely? And even if I knew, how the heck do I create the proper PySBinaryArray object with which to pass in?! This API is so obtuse sometimes (I get that that's microsoft's fault, not python's - LOL ) Any help/pointers/tips would be MOST appreciated - and thanks in advance for the time! Please CC directly on all replies, as I am not subscribed to the list. Thank you! -Aubin -------------- next part -------------- An HTML attachment was scrubbed... URL: From skippy.hammond at gmail.com Wed Jun 5 06:26:39 2013 From: skippy.hammond at gmail.com (Mark Hammond) Date: Wed, 05 Jun 2013 14:26:39 +1000 Subject: [python-win32] PySBinaryArray?? In-Reply-To: <20D91BE563145C44B22ABA9D3580BEB6B7FE3D7E7C@npex1> References: <20D91BE563145C44B22ABA9D3580BEB6B7FE3D7E7C@npex1> Message-ID: <51AEBDFF.60009@gmail.com> It's just a list/sequence of strings (in py2k) or bytes (in py3k). In this context, IIRC, it's just the entryids of the messages to move... HTH, Mark On 5/06/2013 2:16 PM, Aubin LaBrosse wrote: > Hello, List, > > I?m new to pywin32 and have been able to use it quite sufficiently with > the help of the internet and some (rather rudimentary, I admit) > knowledge of the windows api. I?ve been able to do some quite clever > things with HTML on the windows clipboard and the Extended MAPI support. > However I am stumped on one thing, which I would have imagined would > be rather easy to do somehow but just can?t seem to figure it out. I > have used Extended MAPI to open the outlook outbox, create, and send an > email message. Now I want to move that message from the outbox to the > sent items folder, as outlook itself would do. Without doing so, it > simply sits in the outbox, or is sent and deleted if I set the > PR_DELETE_AFTER_SUBMIT (apologies if that?s not the exact name, doing > this from memory as I write this email quickly) property flag > > So anyway, there exists PyIMAPIFolder.MoveMessages ? I have a python > reference to a PYIMessage object that I would like to move, but the > first parameter to MoveMessages is what appears to be called a > PySBinaryArray which, all the documentation I can find on it essentially > says is a ?list of strings containing binary data? > > What binary data, exactly? The body of the message? Some other message > identifier or property tag which must be used to indicate which message > is to be moved? Something else entirely? And even if I knew, how the > heck do I create the proper PySBinaryArray object with which to pass in?! > > This API is so obtuse sometimes (I get that that?s microsoft?s fault, > not python?s ? LOL ) > > Any help/pointers/tips would be MOST appreciated ? and thanks in advance > for the time! > > Please CC directly on all replies, as I am not subscribed to the list. > > Thank you! > > -Aubin > > > > _______________________________________________ > python-win32 mailing list > python-win32 at python.org > http://mail.python.org/mailman/listinfo/python-win32 > From timr at probo.com Wed Jun 5 18:53:40 2013 From: timr at probo.com (Tim Roberts) Date: Wed, 5 Jun 2013 09:53:40 -0700 Subject: [python-win32] PySBinaryArray?? In-Reply-To: <20D91BE563145C44B22ABA9D3580BEB6B7FE3D7E7C@npex1> References: <20D91BE563145C44B22ABA9D3580BEB6B7FE3D7E7C@npex1> Message-ID: <51AF6D14.2000401@probo.com> Aubin LaBrosse wrote: > > > I?m new to pywin32 and have been able to use it quite sufficiently > with the help of the internet and some (rather rudimentary, I admit) > knowledge of the windows api. I?ve been able to do some quite clever > things with HTML on the windows clipboard and the Extended MAPI > support. However I am stumped on one thing, which I would have > imagined would be rather easy to do somehow but just can?t seem to > figure it out. I have used Extended MAPI to open the outlook outbox, > create, and send an email message. Now I want to move that message > from the outbox to the sent items folder, as outlook itself would do. > Without doing so, it simply sits in the outbox, or is sent and deleted > if I set the PR_DELETE_AFTER_SUBMIT (apologies if that?s not the exact > name, doing this from memory as I write this email quickly) property flag > It should sit in the outbox until the next regularly scheduled Send/Receive cycle. After Outlook sends it on, Outlook will automatically move it to "Sent Items". What is the mail server here? Exchange? POP? IMAP? Is Outlook configured to work online 100% of the time? What is the last call you make to send the message on its way? > Please CC directly on all replies, as I am not subscribed to the list. > Why not? When you're getting help from a list like this, it's only polite to stick around so you can eventually help others with the same kind of problems. -- Tim Roberts, timr at probo.com Providenza & Boekelheide, Inc. -------------- next part -------------- An HTML attachment was scrubbed... URL: From AubinL at netpolarity.com Wed Jun 5 19:24:29 2013 From: AubinL at netpolarity.com (Aubin LaBrosse) Date: Wed, 5 Jun 2013 10:24:29 -0700 Subject: [python-win32] PySBinaryArray?? In-Reply-To: <51AF6D14.2000401@probo.com> References: <20D91BE563145C44B22ABA9D3580BEB6B7FE3D7E7C@npex1> <51AF6D14.2000401@probo.com> Message-ID: <20D91BE563145C44B22ABA9D3580BEB6B7FE3D8145@npex1> It should sit in the outbox until the next regularly scheduled Send/Receive cycle. After Outlook sends it on, Outlook will automatically move it to "Sent Items". What is the mail server here? Exchange? POP? IMAP? Is Outlook configured to work online 100% of the time? Mail server is exchange Last calls I made are: outboxfolder.SaveChanges(0) message.SubmitMessage(0) outlook is 100% online, yes for whatever reason when I send programmatically in this way I never see it move to sent items - it just hangs out in the outbox. So I just assumed I had to move it myself. Why not? When you're getting help from a list like this, it's only polite to stick around so you can eventually help others with the same kind of problems. I didn't intend anything unfriendly by it - I'll subscribe today - it was just a quick email to the list before I left work at 10pm last night. LOL -a ________________________________ From: Tim Roberts [mailto:timr at probo.com] Sent: Wednesday, June 05, 2013 9:54 AM To: Aubin LaBrosse Cc: python-win32 at python.org Subject: Re: [python-win32] PySBinaryArray?? Aubin LaBrosse wrote: I'm new to pywin32 and have been able to use it quite sufficiently with the help of the internet and some (rather rudimentary, I admit) knowledge of the windows api. I've been able to do some quite clever things with HTML on the windows clipboard and the Extended MAPI support. However I am stumped on one thing, which I would have imagined would be rather easy to do somehow but just can't seem to figure it out. I have used Extended MAPI to open the outlook outbox, create, and send an email message. Now I want to move that message from the outbox to the sent items folder, as outlook itself would do. Without doing so, it simply sits in the outbox, or is sent and deleted if I set the PR_DELETE_AFTER_SUBMIT (apologies if that's not the exact name, doing this from memory as I write this email quickly) property flag It should sit in the outbox until the next regularly scheduled Send/Receive cycle. After Outlook sends it on, Outlook will automatically move it to "Sent Items". What is the mail server here? Exchange? POP? IMAP? Is Outlook configured to work online 100% of the time? What is the last call you make to send the message on its way? Please CC directly on all replies, as I am not subscribed to the list. Why not? When you're getting help from a list like this, it's only polite to stick around so you can eventually help others with the same kind of problems. -- Tim Roberts, timr at probo.com Providenza & Boekelheide, Inc. -------------- next part -------------- An HTML attachment was scrubbed... URL: From timr at probo.com Wed Jun 5 19:34:58 2013 From: timr at probo.com (Tim Roberts) Date: Wed, 5 Jun 2013 10:34:58 -0700 Subject: [python-win32] PySBinaryArray?? In-Reply-To: <20D91BE563145C44B22ABA9D3580BEB6B7FE3D8145@npex1> References: <20D91BE563145C44B22ABA9D3580BEB6B7FE3D7E7C@npex1> <51AF6D14.2000401@probo.com> <20D91BE563145C44B22ABA9D3580BEB6B7FE3D8145@npex1> Message-ID: <51AF76C2.1060603@probo.com> Aubin LaBrosse wrote: > > > > Mail server is exchange > > Last calls I made are: > > > > outboxfolder.SaveChanges(0) > > message.SubmitMessage(0) > > > > outlook is 100% online, yes > > > > for whatever reason when I send programmatically in this way I never > see it move to sent items ? it just hangs out in the outbox. So I just > assumed I had to move it myself. > No, that's not the right answer. You don't really want the message in "Sent Items". What you want is for Outlook to move it to "Sent Items" because it got sent. Did you say you had tried doing this before SaveChanges: message.SetReadFlag(CLEAR_READ_FLAG) message.SetProps([(mapitags.PR_DELETE_AFTER_SUBMIT,1)]) -- Tim Roberts, timr at probo.com Providenza & Boekelheide, Inc. -------------- next part -------------- An HTML attachment was scrubbed... URL: From AubinL at netpolarity.com Wed Jun 5 19:39:29 2013 From: AubinL at netpolarity.com (Aubin LaBrosse) Date: Wed, 5 Jun 2013 10:39:29 -0700 Subject: [python-win32] PySBinaryArray?? In-Reply-To: <51AF76C2.1060603@probo.com> References: <20D91BE563145C44B22ABA9D3580BEB6B7FE3D7E7C@npex1> <51AF6D14.2000401@probo.com> <20D91BE563145C44B22ABA9D3580BEB6B7FE3D8145@npex1> <51AF76C2.1060603@probo.com> Message-ID: <20D91BE563145C44B22ABA9D3580BEB6B7FE3D81A0@npex1> Well, I did set the delete after submit flag, but I didn't clear the read flag first. I will try that and report back Thank you! ________________________________ From: Tim Roberts [mailto:timr at probo.com] Sent: Wednesday, June 05, 2013 10:35 AM To: Aubin LaBrosse; Python-Win32 List Subject: Re: [python-win32] PySBinaryArray?? Aubin LaBrosse wrote: Mail server is exchange Last calls I made are: outboxfolder.SaveChanges(0) message.SubmitMessage(0) outlook is 100% online, yes for whatever reason when I send programmatically in this way I never see it move to sent items - it just hangs out in the outbox. So I just assumed I had to move it myself. No, that's not the right answer. You don't really want the message in "Sent Items". What you want is for Outlook to move it to "Sent Items" because it got sent. Did you say you had tried doing this before SaveChanges: message.SetReadFlag(CLEAR_READ_FLAG) message.SetProps([(mapitags.PR_DELETE_AFTER_SUBMIT,1)]) -- Tim Roberts, timr at probo.com Providenza & Boekelheide, Inc. -------------- next part -------------- An HTML attachment was scrubbed... URL: From timr at probo.com Fri Jun 7 00:27:21 2013 From: timr at probo.com (Tim Roberts) Date: Thu, 6 Jun 2013 15:27:21 -0700 Subject: [python-win32] PySBinaryArray?? In-Reply-To: <20D91BE563145C44B22ABA9D3580BEB6B7FE44A14F@npex1> References: <20D91BE563145C44B22ABA9D3580BEB6B7FE3D7E7C@npex1> <51AF6D14.2000401@probo.com> <20D91BE563145C44B22ABA9D3580BEB6B7FE3D8145@npex1> <51AF76C2.1060603@probo.com> <20D91BE563145C44B22ABA9D3580BEB6B7FE44A14F@npex1> Message-ID: <51B10CC9.7030804@probo.com> Aubin LaBrosse wrote: > > > I was able to test that clearing the read flag and setting delete > after submit didn?t result in the email ending up in sent items. When > delete after submit is set it does however at least get removed from > the outbox. > Is the message actually being sent? -- Tim Roberts, timr at probo.com Providenza & Boekelheide, Inc. From AubinL at netpolarity.com Fri Jun 7 00:29:27 2013 From: AubinL at netpolarity.com (Aubin LaBrosse) Date: Thu, 6 Jun 2013 15:29:27 -0700 Subject: [python-win32] PySBinaryArray?? In-Reply-To: <51B10CC9.7030804@probo.com> References: <20D91BE563145C44B22ABA9D3580BEB6B7FE3D7E7C@npex1> <51AF6D14.2000401@probo.com> <20D91BE563145C44B22ABA9D3580BEB6B7FE3D8145@npex1> <51AF76C2.1060603@probo.com> <20D91BE563145C44B22ABA9D3580BEB6B7FE44A14F@npex1> <51B10CC9.7030804@probo.com> Message-ID: <20D91BE563145C44B22ABA9D3580BEB6B7FE44A55B@npex1> It is, indeed. Shows up in my inbox just fine.... -----Original Message----- From: python-win32 [mailto:python-win32-bounces+aubinl=netpolarity.com at python.org] On Behalf Of Tim Roberts Sent: Thursday, June 06, 2013 3:27 PM To: Python-Win32 List Subject: Re: [python-win32] PySBinaryArray?? Aubin LaBrosse wrote: > > > I was able to test that clearing the read flag and setting delete > after submit didn't result in the email ending up in sent items. When > delete after submit is set it does however at least get removed from > the outbox. > Is the message actually being sent? -- 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 From AubinL at netpolarity.com Thu Jun 6 21:35:38 2013 From: AubinL at netpolarity.com (Aubin LaBrosse) Date: Thu, 6 Jun 2013 12:35:38 -0700 Subject: [python-win32] PySBinaryArray?? In-Reply-To: <51AF76C2.1060603@probo.com> References: <20D91BE563145C44B22ABA9D3580BEB6B7FE3D7E7C@npex1> <51AF6D14.2000401@probo.com> <20D91BE563145C44B22ABA9D3580BEB6B7FE3D8145@npex1> <51AF76C2.1060603@probo.com> Message-ID: <20D91BE563145C44B22ABA9D3580BEB6B7FE44A14F@npex1> Hi Tim, I was able to test that clearing the read flag and setting delete after submit didn't result in the email ending up in sent items. When delete after submit is set it does however at least get removed from the outbox. I should probably mention I'm running this against outlook 2003 on windows xp (as high as we've upgraded here at my job...) I even tried to explicitly call moveMessages on the outbox folder and move it to sent items folder 'manually' so to speak - no errors from this, but no joy either. I've included my code below for anyone who can see issues with it or has suggestions. I don't suppose anyone has an outlook 2003 setup they could try to send an email via and see if it ends up in sent?? """module to send mail with Extended MAPI using the pywin32 mapi wrappers...""" # this was based on Jason Hattingh's C++ code at http://www.codeproject.com/internet/mapadmin.asp # written by David Fraser and Stephen Emslie # you can test this by changing the variables at the bottom and running from the command line from win32com.mapi import mapi from win32com.mapi import mapitags def SendEMAPIMail(Subject="", Message="", SendTo=None, SendCC=None, SendBCC=None, MAPIProfile=None): """Sends an email to the recipient using the extended MAPI interface Subject and Message are strings Send{To,CC,BCC} are comma-separated address lists MAPIProfile is the name of the MAPI profile""" # initialize and log on mapi.MAPIInitialize(None) session = mapi.MAPILogonEx(0, None, None, mapi.MAPI_EXTENDED | mapi.MAPI_USE_DEFAULT) messagestorestable = session.GetMsgStoresTable(0) messagestorestable.SetColumns((mapitags.PR_ENTRYID, mapitags.PR_DISPLAY_NAME_A, mapitags.PR_DEFAULT_STORE),0) foundDefStore = False while (True): foundDefStore = False rows = messagestorestable.QueryRows(1, 0) if len(rows) != 1: break row = rows[0] for x in range(len(row)): propertyid, propertyvalue = row[x] if (propertyid == mapitags.PR_DEFAULT_STORE and propertyvalue == True): foundDefStore = True break if (foundDefStore): break # unpack the row and open the message store (eid_tag, eid), (name_tag, name), (def_store_tag, def_store) = row msgstore = session.OpenMsgStore(0,eid,None,mapi.MDB_NO_DIALOG | mapi.MAPI_BEST_ACCESS) # get the outbox hr, props = msgstore.GetProps((mapitags.PR_IPM_OUTBOX_ENTRYID), 0) (tag, eid) = props[0] outboxfolder = msgstore.OpenEntry(eid,None,mapi.MAPI_BEST_ACCESS) #get the 'sent items' folder - by default. we will have to get the user's #desired folder as well, if they've changed it... hr, props = msgstore.GetProps((mapitags.PR_IPM_SENTMAIL_ENTRYID), 0) (tag, eid) = props[0] destFolder = msgstore.OpenEntry(eid, None, mapi.MAPI_BEST_ACCESS) # create the message and the addrlist message = outboxfolder.CreateMessage(None,0) # note: you can use the resolveaddress functions for this. but you may get headaches pal = [] def makeentry(recipient, recipienttype): return ((mapitags.PR_RECIPIENT_TYPE, recipienttype), (mapitags.PR_SEND_RICH_INFO, False), (mapitags.PR_DISPLAY_TYPE, 0), (mapitags.PR_OBJECT_TYPE, 6), (mapitags.PR_EMAIL_ADDRESS_A, recipient), (mapitags.PR_ADDRTYPE_A, 'SMTP'), (mapitags.PR_DISPLAY_NAME_A, recipient)) if SendTo: pal.extend([makeentry(recipient, mapi.MAPI_TO) for recipient in SendTo.split(",")]) if SendCC: pal.extend([makeentry(recipient, mapi.MAPI_CC) for recipient in SendCC.split(",")]) if SendBCC: pal.extend([makeentry(recipient, mapi.MAPI_BCC) for recipient in SendBCC.split(",")]) # add the resolved recipients to the message message.ModifyRecipients(mapi.MODRECIP_ADD,pal) message.SetProps([(mapitags.PR_BODY_HTML_A,Message), (mapitags.PR_SUBJECT_A,Subject), (mapitags.PR_DELETE_AFTER_SUBMIT, 1)]) # save changes and submit outboxfolder.SaveChanges(0) message.SubmitMessage(0) message.SetReadFlag(0) #get the message id so i can move it... hr, props = message.GetProps((mapitags.PR_ENTRYID),0) (msg_eid_tag, msg_eid) = props[0] #1 is MESSAGE_MOVE according to msdn docs but i don't feel like figuring out if it has a symbolic constant or not... outboxfolder.CopyMessages([msg_eid], None, destFolder, 0, None, 1) ________________________________ From: Tim Roberts [mailto:timr at probo.com] Sent: Wednesday, June 05, 2013 10:35 AM To: Aubin LaBrosse; Python-Win32 List Subject: Re: [python-win32] PySBinaryArray?? Aubin LaBrosse wrote: Mail server is exchange Last calls I made are: outboxfolder.SaveChanges(0) message.SubmitMessage(0) outlook is 100% online, yes for whatever reason when I send programmatically in this way I never see it move to sent items - it just hangs out in the outbox. So I just assumed I had to move it myself. No, that's not the right answer. You don't really want the message in "Sent Items". What you want is for Outlook to move it to "Sent Items" because it got sent. Did you say you had tried doing this before SaveChanges: message.SetReadFlag(CLEAR_READ_FLAG) message.SetProps([(mapitags.PR_DELETE_AFTER_SUBMIT,1)]) -- Tim Roberts, timr at probo.com Providenza & Boekelheide, Inc. -------------- next part -------------- An HTML attachment was scrubbed... URL: From johned9999 at comcast.net Sat Jun 8 19:33:40 2013 From: johned9999 at comcast.net (John Spitzer) Date: Sat, 08 Jun 2013 10:33:40 -0700 Subject: [python-win32] Python and Win 7 Registry VirtualStore In-Reply-To: <51AD7256.9040806@comcast.net> References: <51AD7256.9040806@comcast.net> Message-ID: <51B36AF4.8040302@comcast.net> Hello team. I've done some more testing on this I'm really hoping there is an answer to what I'm trying to do. Maybe there is something I'm overlooking or don't understand about the registry and permissions on Windows 7 and how the _winreg library works. As shown below, I'm trying to retrieve a value from a registry key. The app that is writing the key appears to be coded so that Windows writes the key to the VirtualStore area of the registry. Everything I've read so far says application programs, if the permissions and access is coded correctly, should not access the VS keys directly. As a test, I put the following two lines in my program: ----- # ConnKey = OpenKey(HKEY_LOCAL_MACHINE, r'SOFTWARE\Interface Software\ConnMgr', 0, KEY_READ) ConnKey = OpenKey(HKEY_CURRENT_USER, r'Software\Classes\VirtualStore\MACHINE\SOFTWARE\Interface Software\ConnMgr', 0, KEY_READ) ConnValue = QueryValueEx(ConnKey, "DB Path") ----- When I execute the program with the line that access the HKCU key, the program retrieves the key as expected. As shown, it is accessing the key explicitly from the virtual store. This shows the key is where I expect it and I can access it. To test the access of the key in HKLM, I manually created the appropriate key value in HKLM. This is where the application stored the key on Windows XP. I also ran this program both as an administrator and standard user. With KEY_READ access, I can read the key. With KEY_ALL_ACCESS I get the error: [Error 5] Access is denied. How do I code this so that the access is directed to the Virtual Store, or am I not understanding how this is suppose to work (very possible). I am certain that I'm not the first to encounter this behavior. Thanks for your help, John On 06/03/2013 9:51 PM, John Spitzer wrote: > > Hello, > > I've searched the python sites and help, library's and all the forums > I could find, but haven't seen any mention of this. This help line > seemed like a good place to ask this. > > I am on an HP laptop Intel Core 2 Duo, running Windows 7 Pro SP1 > 32Bit. I am using Python 2.7.3. > > I have an application I built that ran fine on Windows XP, but now > fails on Windows 7. The place I'm encountering the problem is where I > try to read a key from the registry. I believe it's because of the > Virtualization of the registry on Windows 7. This key is created by > another app that I'm trying to co-ordinate with. On Windows XP the > Registry key was: > > [HKEY_LOCAL_MACHINE\SOFTWARE\Interface Software\ConnMgr] > "DB Path"="C:\\Documents and Settings\\All Users\\Application > Data\\" > > When this app is installed on Windows 7, the key is directed to the > registry Virtual Store at: > [HKEY_CURRENT_USER\Software\Classes\VirtualStore\MACHINE\SOFTWARE\Interface > Software\ConnMgr] > "DB Path"="C:\\ProgramData\\EnvisionWare\\" > > So far that is what I think I'd expected on Windows 7 and the > virtualization of the registry. > > The code fragment that is reading the registry is: > ----- > from _winreg import * > > > ConnKey = OpenKey(HKEY_LOCAL_MACHINE, r'SOFTWARE\Interface > Software\ConnMgr', 0, KEY_READ) > ConnValue = QueryValueEx(ConnKey, "DB Path") > EWDataSource = os.path.split(str(ConnValue[0])) > ------ > The OpenKey fails with the message: WindowsError: (2, 'The system > cannot find the file specified"). I believe this is because the key > does not exist at the path [HKEY_LOCAL_MACHINE\SOFTWARE\Interface > Software\ConnMgr]. > > After all this, the question is: Why isn't the OpenKey call being > redirected to the VirtualStore? What can I change in the program, ACLs > or other to make it be redirected? > > Any help would be appreciated. > Thanks, > John > -- John Spitzer johned9999 at comcast.net 503-590-7434 From AubinL at netpolarity.com Sun Jun 9 03:41:37 2013 From: AubinL at netpolarity.com (Aubin LaBrosse) Date: Sat, 8 Jun 2013 18:41:37 -0700 Subject: [python-win32] PySBinaryArray?? / Making sure messages show up in 'Sent Mail' In-Reply-To: <20D91BE563145C44B22ABA9D3580BEB6B7FE44A14F@npex1> References: <20D91BE563145C44B22ABA9D3580BEB6B7FE3D7E7C@npex1> <51AF6D14.2000401@probo.com> <20D91BE563145C44B22ABA9D3580BEB6B7FE3D8145@npex1> <51AF76C2.1060603@probo.com> <20D91BE563145C44B22ABA9D3580BEB6B7FE44A14F@npex1> Message-ID: <20D91BE563145C44B22ABA9D3580BEB6B7FE4A4B1D@npex1> Tim, and list Sending this here for historical accuracy in case anyone stumbles on this thread. Maybe it should have been obvious, but to me, it certainly wasn't. In order to get a mail message to show up in 'Sent Mail' using the latest pywin32 against, at least in my case, Outlook2003 on windowsXP, be sure to do two things: 1) set mapiTags.PR_SENTMAIL_ENTRYID *on the message itself* - it was entirely nonobvious to me that this should be necessary and I only realized it by tracking back to the original C++ code that my Extended MAPI python code had been based on and reading a 7 year old comment thread. Thank god everything we put onto the internet exists in perpetuity. ;-) 2) Do NOT set the delete after submit flag. Doing this will do just as it says, delete the message entirely after submission - which removes it from the outbox but doesn't put it in sent because it goes to the bit bucket. This part was just a logical deduction on my part once I realized I still had PR_DELETE_AFTER_SUBMIT set from previous monkeying. Of course, doing number one requires the eid of the sent folder so that you can set it on the message, and although I'm sure you all know this, for new folks like me that looks like this: #get the 'sent items' folder - by default. we will have to get the user's #desired folder as well, if they've changed it... hr, props = msgstore.GetProps((mapitags.PR_IPM_SENTMAIL_ENTRYID), 0) (tag, sent_mail_eid) = props[0] And the final set of message properties (besides recipients, of course) are: message.SetProps([(mapitags.PR_BODY_HTML_A,Message), (mapitags.PR_SUBJECT_A,Subject), (mapitags.PR_SENTMAIL_ENTRYID, sent_mail_eid) ]) Thanks for all your help, everyone! Now to go off and see if Outlook will put that message wherever I want it if I set the eid of the "sent" folder to the eid of some other destination folder, or if it will be "too smart" for me and do something silly like compare the sentmail eid on the message to the PR_IPM_SENTMAIL_ENTRYID from the message store. But, in theory, the only *point* of even requiring the SENTMAIL_ENTRYID to be set on the individual message level is precisely so that you can do exactly that! So hopefully there will be no shenanigans, but, I've learned never to expect or assume anything as far as Windows is concerned. -a ________________________________ From: python-win32 [mailto:python-win32-bounces+aubinl=netpolarity.com at python.org] On Behalf Of Aubin LaBrosse Sent: Thursday, June 06, 2013 12:36 PM To: Tim Roberts; Python-Win32 List Subject: Re: [python-win32] PySBinaryArray?? Hi Tim, I was able to test that clearing the read flag and setting delete after submit didn't result in the email ending up in sent items. When delete after submit is set it does however at least get removed from the outbox. I should probably mention I'm running this against outlook 2003 on windows xp (as high as we've upgraded here at my job...) I even tried to explicitly call moveMessages on the outbox folder and move it to sent items folder 'manually' so to speak - no errors from this, but no joy either. I've included my code below for anyone who can see issues with it or has suggestions. I don't suppose anyone has an outlook 2003 setup they could try to send an email via and see if it ends up in sent?? """module to send mail with Extended MAPI using the pywin32 mapi wrappers...""" # this was based on Jason Hattingh's C++ code at http://www.codeproject.com/internet/mapadmin.asp # written by David Fraser and Stephen Emslie # you can test this by changing the variables at the bottom and running from the command line from win32com.mapi import mapi from win32com.mapi import mapitags def SendEMAPIMail(Subject="", Message="", SendTo=None, SendCC=None, SendBCC=None, MAPIProfile=None): """Sends an email to the recipient using the extended MAPI interface Subject and Message are strings Send{To,CC,BCC} are comma-separated address lists MAPIProfile is the name of the MAPI profile""" # initialize and log on mapi.MAPIInitialize(None) session = mapi.MAPILogonEx(0, None, None, mapi.MAPI_EXTENDED | mapi.MAPI_USE_DEFAULT) messagestorestable = session.GetMsgStoresTable(0) messagestorestable.SetColumns((mapitags.PR_ENTRYID, mapitags.PR_DISPLAY_NAME_A, mapitags.PR_DEFAULT_STORE),0) foundDefStore = False while (True): foundDefStore = False rows = messagestorestable.QueryRows(1, 0) if len(rows) != 1: break row = rows[0] for x in range(len(row)): propertyid, propertyvalue = row[x] if (propertyid == mapitags.PR_DEFAULT_STORE and propertyvalue == True): foundDefStore = True break if (foundDefStore): break # unpack the row and open the message store (eid_tag, eid), (name_tag, name), (def_store_tag, def_store) = row msgstore = session.OpenMsgStore(0,eid,None,mapi.MDB_NO_DIALOG | mapi.MAPI_BEST_ACCESS) # get the outbox hr, props = msgstore.GetProps((mapitags.PR_IPM_OUTBOX_ENTRYID), 0) (tag, eid) = props[0] outboxfolder = msgstore.OpenEntry(eid,None,mapi.MAPI_BEST_ACCESS) #get the 'sent items' folder - by default. we will have to get the user's #desired folder as well, if they've changed it... hr, props = msgstore.GetProps((mapitags.PR_IPM_SENTMAIL_ENTRYID), 0) (tag, eid) = props[0] destFolder = msgstore.OpenEntry(eid, None, mapi.MAPI_BEST_ACCESS) # create the message and the addrlist message = outboxfolder.CreateMessage(None,0) # note: you can use the resolveaddress functions for this. but you may get headaches pal = [] def makeentry(recipient, recipienttype): return ((mapitags.PR_RECIPIENT_TYPE, recipienttype), (mapitags.PR_SEND_RICH_INFO, False), (mapitags.PR_DISPLAY_TYPE, 0), (mapitags.PR_OBJECT_TYPE, 6), (mapitags.PR_EMAIL_ADDRESS_A, recipient), (mapitags.PR_ADDRTYPE_A, 'SMTP'), (mapitags.PR_DISPLAY_NAME_A, recipient)) if SendTo: pal.extend([makeentry(recipient, mapi.MAPI_TO) for recipient in SendTo.split(",")]) if SendCC: pal.extend([makeentry(recipient, mapi.MAPI_CC) for recipient in SendCC.split(",")]) if SendBCC: pal.extend([makeentry(recipient, mapi.MAPI_BCC) for recipient in SendBCC.split(",")]) # add the resolved recipients to the message message.ModifyRecipients(mapi.MODRECIP_ADD,pal) message.SetProps([(mapitags.PR_BODY_HTML_A,Message), (mapitags.PR_SUBJECT_A,Subject), (mapitags.PR_DELETE_AFTER_SUBMIT, 1)]) # save changes and submit outboxfolder.SaveChanges(0) message.SubmitMessage(0) message.SetReadFlag(0) #get the message id so i can move it... hr, props = message.GetProps((mapitags.PR_ENTRYID),0) (msg_eid_tag, msg_eid) = props[0] #1 is MESSAGE_MOVE according to msdn docs but i don't feel like figuring out if it has a symbolic constant or not... outboxfolder.CopyMessages([msg_eid], None, destFolder, 0, None, 1) ________________________________ From: Tim Roberts [mailto:timr at probo.com] Sent: Wednesday, June 05, 2013 10:35 AM To: Aubin LaBrosse; Python-Win32 List Subject: Re: [python-win32] PySBinaryArray?? Aubin LaBrosse wrote: Mail server is exchange Last calls I made are: outboxfolder.SaveChanges(0) message.SubmitMessage(0) outlook is 100% online, yes for whatever reason when I send programmatically in this way I never see it move to sent items - it just hangs out in the outbox. So I just assumed I had to move it myself. No, that's not the right answer. You don't really want the message in "Sent Items". What you want is for Outlook to move it to "Sent Items" because it got sent. Did you say you had tried doing this before SaveChanges: message.SetReadFlag(CLEAR_READ_FLAG) message.SetProps([(mapitags.PR_DELETE_AFTER_SUBMIT,1)]) -- Tim Roberts, timr at probo.com Providenza & Boekelheide, Inc. -------------- next part -------------- An HTML attachment was scrubbed... URL: From timr at probo.com Mon Jun 10 19:49:04 2013 From: timr at probo.com (Tim Roberts) Date: Mon, 10 Jun 2013 10:49:04 -0700 Subject: [python-win32] Python and Win 7 Registry VirtualStore In-Reply-To: <51B36AF4.8040302@comcast.net> References: <51AD7256.9040806@comcast.net> <51B36AF4.8040302@comcast.net> Message-ID: <51B61190.8070509@probo.com> John Spitzer wrote: > Everything I've read > so far says application programs, if the permissions and access is coded > correctly, should not access the VS keys directly. Sort of. This advice applies to legacy programs that don't know about the virtualization. New apps should all be using HKCU keys from the beginning, so the problem doesn't exist. But when you have a new app that has to deal with information created by an older app, sometimes you do have to poke through the virtualization directly. > To test the access of the key in HKLM, I manually created the > appropriate key value in HKLM. This is where the application stored the > key on Windows XP. I also ran this program both as an administrator and > standard user. With KEY_READ access, I can read the key. With > KEY_ALL_ACCESS I get the error: [Error 5] Access is denied. Are you using 32-bit Python or 64-bit Python? Registry virtualization is only enabled for 32-bit processes. 64-bit apps are supposed to know what's going on and use the right keys to begin with. The virtualization is complicated. When you open the HKLM key from a 32-bit app, if you ask for write access and you are not entitled to write access, it's supposed to open it with read access (unless a particular flag is set on the key -- see below). Then, when you try to write to it, it redirects to HKCU. The registry key itself has certain flags that affect the virtualization. For example, try this from a command line: reg flags "HKLM\Software\Interface Software\ConnMgr" query and see if any of the flags are set. -- Tim Roberts, timr at probo.com Providenza & Boekelheide, Inc. From vernondcole at gmail.com Thu Jun 13 20:41:40 2013 From: vernondcole at gmail.com (Vernon D. Cole) Date: Thu, 13 Jun 2013 19:41:40 +0100 Subject: [python-win32] Notice: Restriction on use of adodbapi remote server with Pyro4 version 2.20 Message-ID: Pywin 32 users: Anyone trying the new ADO remote/proxy feature of adodbapi: Pyro 2.20 (just released) uses a new serializer which does not handle decimal or datetime data types. If you update your Pyro4, you need to switch back to the old pickle serializer by defining the environment variable PYRO_SERIALIZER=pickle -- Vernon Cole -------------- next part -------------- An HTML attachment was scrubbed... URL: From vernondcole at gmail.com Fri Jun 14 11:00:35 2013 From: vernondcole at gmail.com (Vernon D. Cole) Date: Fri, 14 Jun 2013 10:00:35 +0100 Subject: [python-win32] adodbapi and .hgeol Message-ID: I found the following on [pywin32-checkins] this morning: diff -r 4ded0a838f8c -r 1594b8c27383 .hgeol > --- a/.hgeol Mon Apr 29 10:01:40 2013 -0400 > +++ b/.hgeol Thu Jun 13 18:29:09 2013 +1000 > @@ -2,4 +2,8 @@ > **.dsp = CRLF > **.dsw = CRLF > **.vbp = CRLF > +# adodbapi appears to have been checked in with windows line endings > +# and without the 'eol' extension enabled, so we say it's binary to stop > +# hg continually thinking it has changed. > +path:adodbapi = bin > ** = native > diff -r 4ded0a838f8c -r 1594b8c27383 CHANGES.txt > --- a/CHANGES.txt Mon Apr 29 10:01:40 2013 -0400 > +++ b/CHANGES.txt Thu Jun 13 18:29:09 2013 +1000 No matter how old you get (I just turned 63) you still have new things to learn. Until today, I have been completely unaware of an .hgeol file. Since adodbapi now also runs on Linux, I had better make sure the line endings stay right. Python does not care, nor does the Pythonwin IDE editor, but I have not been consistant about what editor I use, which may be the cause of this problem. My quick reading of the documentation for .hgeol leads me to believe that setting the entire adodbapi path to =bin is not the correct way to handle this. I will adapt my other mercurial repository to match this -- but I want to do it right this time. What line ending style are my Python and .txt files supposed to have? I will adapt my source. -- Vernon Cole -------------- next part -------------- An HTML attachment was scrubbed... URL: From skippy.hammond at gmail.com Mon Jun 17 08:59:09 2013 From: skippy.hammond at gmail.com (Mark Hammond) Date: Mon, 17 Jun 2013 16:59:09 +1000 Subject: [python-win32] adodbapi and .hgeol In-Reply-To: References: Message-ID: <51BEB3BD.7080408@gmail.com> On 14/06/2013 7:00 PM, Vernon D. Cole wrote: > I found the following on [pywin32-checkins] this morning: > > diff -r 4ded0a838f8c -r 1594b8c27383 .hgeol > --- a/.hgeol Mon Apr 29 10:01:40 2013 -0400 > +++ b/.hgeol Thu Jun 13 18:29:09 2013 +1000 > @@ -2,4 +2,8 @@ > **.dsp = CRLF > **.dsw = CRLF > **.vbp = CRLF > +# adodbapi appears to have been checked in with windows line endings > +# and without the 'eol' extension enabled, so we say it's binary to > stop > +# hg continually thinking it has changed. > +path:adodbapi = bin > ** = native > diff -r 4ded0a838f8c -r 1594b8c27383 CHANGES.txt > --- a/CHANGES.txt Mon Apr 29 10:01:40 2013 -0400 > +++ b/CHANGES.txt Thu Jun 13 18:29:09 2013 +1000 > > > No matter how old you get (I just turned 63) you still have new things > to learn. Until today, I have been completely unaware of an .hgeol file. > > Since adodbapi now also runs on Linux, I had better make sure the line > endings stay right. Python does not care, nor does the Pythonwin IDE > editor, but I have not been consistant about what editor I use, which > may be the cause of this problem. > > My quick reading of the documentation for .hgeol leads me to believe > that setting the entire adodbapi path to =bin is not the correct way to > handle this. I will adapt my other mercurial repository to match this > -- but I want to do it right this time. What line ending style are my > Python and .txt files supposed to have? I will adapt my source. It's all quite confusing and a PITA. What I *think* the story is... * Using the "eol" extension means that it's possible to have the repository use \n as line endings, and, depending on the platform being used, have either \n or \r\n line-endings in checkouts of the repository. This has obvious benefits for cross-platform projects - but in the case of pywin32 it's not any practical benefit (ie, for this project there would be almost no downsides to having the repo itself always have \r\n endings) But we are where we are - in pywin32, the repository has \n line endings. If the eol extension is enabled, a checkout on Windows will have \r\n line endings. A checkout on Linux etc would have \n line endings (except adodbapi - see below) Unfortunately, enabling the eol extension isn't enough to "fix" the current checkout - so you either want to have enabled eol before checking out, or clobber the existing tree ('hg up -r null'), then do a normal update. To demonstrate: # first clone the pywin32 directory, but do *not* update the working tree. % hg clone -U pywin32 pywin32-clone % cd pywin32-clone # this dir is empty, apart from .hg/ # Just in-case eol is enabled globally, we'll disable it for this clone: % echo "[extensions]" >> .hg/hgrc % echo "eol=!" >> .hg/hgrc # this disables it locally. # now update the working copy: % hg up # .. now view the EOL chars of, eg, setup.py - use some editor # like Scite or Pythonwin which can show these. # setup.py has \n line endings. # Do the same for, eg, adodbapi/is64bit.py - note it has \r\n! # [FWIW - license.txt in adpdbapi has \n...] # Now, enable EOL for this repo - edit .hg/hgrc and remove the # "eol=!" line... % hg up # hg says it did nothing - setup.py has not changed! # So - nuke the working tree % hg up -r null # verify all files gone. % hg up # Now re-check setup.py - it now has \r\n locally. adodbapi.py's files # still all have \r\n. So - it appears that adodbapi was initially (or most recently - I haven't checked the history) checked into hg *without* the eol extension being enabled and while the local tree had \r\n line endings. This means the *repository* copy of adodbapi has \r\n line endings. With the eol extension installed, hg gets very upset (even though it probably shouldn't) - it keeps thinking the adodbapi files have always changed (a diff shows every line changed). I can't find a way to avoid that - except, to tell hg that the adodbapi directory consists of "binary" files. This simply tells hg to not attempt line ending conversions on these files. So we end up with adodbapi having \r\n line endings regardless of the platform on which the repo is checked out on. The "fix" to this would, IIUC (and untested), involve: * ensuring eol is disabled for the clone * adjust all files to have \n line endings * commit the changes [and to get things sane again] * nuke the tree (ie, 'hg up -r null') * enable the eol extension * Remove the 'binary' annotation in .hgeol * 'hg up' * verify it all worked as expected. * commit .hgeol * probably mail the checkins list explaining that you just did this, and for others to be aware of hg being dumb, not realizing current checkouts need updating etc, so to consider doing, eg, "hg up -C" or similar to stop it complaining :) The other downside of this is this checkin would touch every line of every such file - so things like 'hg blame' etc would become useless for these files - it would be impossible to see what change touched a single line - this checkin would get the blame for every single line. OTOH though, the problem is purely theoretical - I doubt people are using this repo anywhere but Windows, so no one will notice any difference. So the status quo is probably fine in practice, and it avoids the 'blame' problem mentioned above. Which is exactly why I just changed .hgeol instead of coordinating a line-end-change commit with you (but I do apologize for not firing you a mail at the time anyway). However, if you have an existing hg repo which you hope people also use on Linux, you probably *do* want to take action in that repo - the files should be in the repo with \n line endings, and rely on the eol extension to get \r\n files locally on Windows. (If your current repo is the same as pywin32, I'd expect linux users which checkout your repo will end up with \r\n line endings on Linux). If you do fix that repo, then you could consider fixing pywin32 too - but that's your call and is unlikely to impact anyone using pywin32. Just to make matters worse, the 'eol' extension really isn't a panacea - I do a huge amount of work with the huge Mozilla hg repositories, and 'eol' just impacts performance too much. So I have the eol extension disabled globally (so my mozilla checkouts all have \n line endings locally), and just enable it locally for a few repos such as pywin32. I hope that makes sense (and is accurate ;) Mark From patrick.tisdale at gmail.com Tue Jun 18 23:51:46 2013 From: patrick.tisdale at gmail.com (Patrick Tisdale) Date: Tue, 18 Jun 2013 16:51:46 -0500 Subject: [python-win32] Killing a subprocess spawned by a service Message-ID: Hello list, I have written a test script to run as a service. The service starts up properly, and spawns a subprocess (called test.py) using subprocess.Popen. However, I am having no luck killing the subprocess when I stop the service. I am using os.kill() It works fine when running pythonservice.exe in debug mode. But when I start it using "net start" the subprocess.Popen.pid matches the "cmd" that it spawns (due to shell=True, I suppose). I have tried it without shell=True, but can't get the script to run without it. The test script is a simple script that periodically writes to a file. The script that I actually need to make work is a twisted twistd (.tac) file, which will have multiple TCP connections open, and I need to be able to close those connections before it exits. Any ideas on what I'm missing? Thanks, Patrick Tisdale -------------- next part -------------- An HTML attachment was scrubbed... URL: From skippy.hammond at gmail.com Wed Jun 19 06:13:37 2013 From: skippy.hammond at gmail.com (Mark Hammond) Date: Wed, 19 Jun 2013 14:13:37 +1000 Subject: [python-win32] Killing a subprocess spawned by a service In-Reply-To: References: Message-ID: <51C12FF1.1090703@gmail.com> The other solutions I can think of are likely heavier and harder than arranging to spawn the child without shell=1 - so I'd suggest tackling that. Or *maybe* - you could do something like spawning a thread in the child process to read from stdin - that's likely to block until the cmd.exe parent is killed, in which case the read would return with an error - at which point the child could terminate itself... Mark On 19/06/2013 7:51 AM, Patrick Tisdale wrote: > Hello list, > I have written a test script to run as a service. The service starts up > properly, and spawns a subprocess (called test.py) using > subprocess.Popen. However, I am having no luck killing the subprocess > when I stop the service. I am using os.kill() > > It works fine when running pythonservice.exe in debug mode. But when I > start it using "net start" the subprocess.Popen.pid matches the "cmd" > that it spawns (due to shell=True, I suppose). I have tried it without > shell=True, but can't get the script to run without it. > > > The test script is a simple script that periodically writes to a file. > The script that I actually need to make work is a twisted twistd (.tac) > file, which will have multiple TCP connections open, and I need to be > able to close those connections before it exits. > > Any ideas on what I'm missing? > > Thanks, > Patrick Tisdale > > > _______________________________________________ > python-win32 mailing list > python-win32 at python.org > http://mail.python.org/mailman/listinfo/python-win32 > From patrick.tisdale at gmail.com Wed Jun 19 16:20:41 2013 From: patrick.tisdale at gmail.com (Patrick Tisdale) Date: Wed, 19 Jun 2013 09:20:41 -0500 Subject: [python-win32] Killing a subprocess spawned by a service In-Reply-To: <51C12FF1.1090703@gmail.com> References: <51C12FF1.1090703@gmail.com> Message-ID: I can get rid of the shell=1 using subprocess.Popen(["python.exe", "C:\\Python27\\Scripts\\test.py"]). This also works fine using debug mode. I can kill it via os.kill() or Popen.send_signal(). It also runs fine via "net start". But when I stop it via "net stop", it gives me the following error: ok.kill(self.pid, signal.CTRL_BREAK_EVENT) WindowsError: (6, 'The handle is invalid') I have verified that Popen.pid matches the PID of python.exe in tasklist. The python docs say that on windows, os.kill() also takes a handle. I tried passing it Popen._handle (and int(Popen._handle)), but it still says the handle is invalid. Any idea why the handle would be invalid? Patrick On Tue, Jun 18, 2013 at 11:13 PM, Mark Hammond wrote: > The other solutions I can think of are likely heavier and harder than > arranging to spawn the child without shell=1 - so I'd suggest tackling that. > > Or *maybe* - you could do something like spawning a thread in the child > process to read from stdin - that's likely to block until the cmd.exe > parent is killed, in which case the read would return with an error - at > which point the child could terminate itself... > > Mark > > > On 19/06/2013 7:51 AM, Patrick Tisdale wrote: > >> Hello list, >> I have written a test script to run as a service. The service starts up >> properly, and spawns a subprocess (called test.py) using >> subprocess.Popen. However, I am having no luck killing the subprocess >> when I stop the service. I am using os.kill() >> >> It works fine when running pythonservice.exe in debug mode. But when I >> start it using "net start" the subprocess.Popen.pid matches the "cmd" >> that it spawns (due to shell=True, I suppose). I have tried it without >> shell=True, but can't get the script to run without it. >> >> >> The test script is a simple script that periodically writes to a file. >> The script that I actually need to make work is a twisted twistd (.tac) >> file, which will have multiple TCP connections open, and I need to be >> able to close those connections before it exits. >> >> Any ideas on what I'm missing? >> >> Thanks, >> Patrick Tisdale >> >> >> ______________________________**_________________ >> 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 tom at pentest.7safe.com Wed Jun 19 17:04:09 2013 From: tom at pentest.7safe.com (Tom) Date: Wed, 19 Jun 2013 16:04:09 +0100 Subject: [python-win32] Killing a subprocess spawned by a service In-Reply-To: References: <51C12FF1.1090703@gmail.com> Message-ID: Have you tried spawning "pythonw.exe" instead of "python.exe"? http://bugs.python.org/issue3905 might help you. A bit of googling suggests this is a recurring issue with subprocess and non-windowed applications. On Wed, Jun 19, 2013 at 3:20 PM, Patrick Tisdale wrote: > I can get rid of the shell=1 using subprocess.Popen(["python.exe", > "C:\\Python27\\Scripts\\test.py"]). This also works fine using debug > mode. I can kill it via os.kill() or Popen.send_signal(). > > It also runs fine via "net start". But when I stop it via "net stop", it > gives me the following error: > ok.kill(self.pid, signal.CTRL_BREAK_EVENT) > WindowsError: (6, 'The handle is invalid') > > I have verified that Popen.pid matches the PID of python.exe in tasklist. > > The python docs say that on windows, os.kill() also takes a handle. I > tried passing it Popen._handle (and int(Popen._handle)), but it still says > the handle is invalid. > > Any idea why the handle would be invalid? > > Patrick > > > On Tue, Jun 18, 2013 at 11:13 PM, Mark Hammond wrote: > >> The other solutions I can think of are likely heavier and harder than >> arranging to spawn the child without shell=1 - so I'd suggest tackling that. >> >> Or *maybe* - you could do something like spawning a thread in the child >> process to read from stdin - that's likely to block until the cmd.exe >> parent is killed, in which case the read would return with an error - at >> which point the child could terminate itself... >> >> Mark >> >> >> On 19/06/2013 7:51 AM, Patrick Tisdale wrote: >> >>> Hello list, >>> I have written a test script to run as a service. The service starts up >>> properly, and spawns a subprocess (called test.py) using >>> subprocess.Popen. However, I am having no luck killing the subprocess >>> when I stop the service. I am using os.kill() >>> >>> It works fine when running pythonservice.exe in debug mode. But when I >>> start it using "net start" the subprocess.Popen.pid matches the "cmd" >>> that it spawns (due to shell=True, I suppose). I have tried it without >>> shell=True, but can't get the script to run without it. >>> >>> >>> The test script is a simple script that periodically writes to a file. >>> The script that I actually need to make work is a twisted twistd (.tac) >>> file, which will have multiple TCP connections open, and I need to be >>> able to close those connections before it exits. >>> >>> Any ideas on what I'm missing? >>> >>> Thanks, >>> Patrick Tisdale >>> >>> >>> ______________________________**_________________ >>> 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 wsadkin at ParlanceCorp.com Wed Jun 19 23:51:19 2013 From: wsadkin at ParlanceCorp.com (Will Sadkin) Date: Wed, 19 Jun 2013 21:51:19 +0000 Subject: [python-win32] Building pywin32 msi installers Message-ID: <75BADF2D5A2DD345819BDC79C664DA4D20F136@Exchange2010.nameconnector.com> Hi All, I really need to be able to do a silent install of the pywin32 package for python2.7, so I started looking at the distutils bdist_msi option, to see if I could get that working for pywin32. Although I *was eventually able to do so,* I ran into several problems that I had to work around in the process: 1) I couldn't build from the latest source version (218). This is because the downloadable pywin32-218.zip file is either incomplete or inconsistent, because the win32\src\PerfMon directory no longer includes perfutil.h, but the code therein attempts to include it. (See bug https://sourceforge.net/p/pywin32/bugs/647/.) 2) I was able to successfully build the source tree for pywin32-217, but when I ran with the bdist_msi option, it complained: Executing post install script... creating dist Traceback (most recent call last): File "setup.py", line 2435, in [...] File "c:\Python27\lib\distutils\command\bdist_msi.py", line 232, in run sversion = "%d.%d.%d" % StrictVersion(version).version File "c:\Python27\lib\distutils\version.py", line 40, in init self.parse(vstring) File "c:\Python27\lib\distutils\version.py", line 107, in parse raise ValueError, "invalid version number '%s'" % vstring ValueError: invalid version number '217' (Bug https://sourceforge.net/p/pywin32/bugs/648/.) It turns out that this error is thrown because the msi installer mechanism requires the use of the 'StrictVersion' class in the distutils package, and that disallows a single integer version number. Similarly, the pywin32_version string used to compile the sources (eg. 2.7.217.0) is also illegal, because it only allows an Major.Minor[.build][abN] structure. Since the dist object specified in the setup.py just uses the build_id (eg. '217') as the version, this makes the distutils stuff choke when trying to use the bdist_msi option. To work around this, I modified the setup.py script to add a pywin32_msi_version string, which I set to: build_id_patch = build_id if not "." in build_id_patch: build_id_patch = build_id_patch + ".0" pywin32_version="%d.%d.%s" % (sys.version_info[0], sys.version_info[1], build_id_patch) + pywin32_msi_version = "%d.%d.%s" % (sys.version_info[0], sys.version_info[1], build_id) (That is, exclude the .0 from the string, so that it was just '2.7.217'. This seemed a reasonable thing to do, as I've never seen a "patch" number on any pywin32 version, and the rest seemed appropriate, but I don't know if Mark Hammond would agree, and if there ever was a patch number, this would not work.) I then also modified the dist object's setup construction, thusly: dist = setup(name="pywin32", < version=str(build_id), --- > version=str(pywin32_msi_version), description="Python for Window Extensions", With these minor changes, I was then able to successfully build the msi. However, I have no idea of the possible other consequences of this modification, vis-?-vis the other distutils bdist methods, and so am not sure if this would be an appropriate general fix. However, there was yet another problem: 3) On actually trying to use the resulting .msi, the postinstall script failed. It turns out that there is a bug in the distutils build_msi.py file; although the documentation claims that it supplies the -install and -remove arguments to any postinstall scripts for their respective invocation, it does not, in fact, currently do this. As a result, the pywin32_postinstall.py just generated a usage message because it was run without arguments, and thus didn't work properly, either for install or remove. It turns out that this distutils bug was reported back in August of 2012, and a patch has even been supplied (see http://bugs.python.org/issue15797.) When I applied the supplied patch, and rebuilt my msi, it properly ran the postinstall script, and (as far as I can tell) the resulting install works perfectly! (And there was much rejoicing... yea...) So: The reasons for my post to this forum: 1) Is the change I made to the version string used in the dist construction appropriate? If not, what would be the appropriate version to use? 2) Can this version be used for both the .exe and the .msi build methods, or, if not, is there a way to conditionally set this based on which type of build is being attempted? 3) The patch for distutils was submitted in August of 2012, but, AFAICT, has not been incorporated into the 2.7.x distutils source; is there a way to expedite that? 4) Would it be possible to take all of this into account, verify that I'm not missing anything subtle, and generate "official" .msi files for pywin32, since this is all targeted *for Microsoft systems,* after all... ;) Thanks in advance, /Will Sadkin From skippy.hammond at gmail.com Thu Jun 20 09:15:39 2013 From: skippy.hammond at gmail.com (Mark Hammond) Date: Thu, 20 Jun 2013 17:15:39 +1000 Subject: [python-win32] Building pywin32 msi installers In-Reply-To: <75BADF2D5A2DD345819BDC79C664DA4D20F136@Exchange2010.nameconnector.com> References: <75BADF2D5A2DD345819BDC79C664DA4D20F136@Exchange2010.nameconnector.com> Message-ID: <51C2AC1B.8020703@gmail.com> I've wanted bdist_msi to work for ages. There was some issue with the install scripts that always caused grief, and my memory is hazy - it *might* be that the uninstall process doesn't run the post-install script at the correct time - ie, that it runs *after* the uninstall, which means pywin32 isn't available to undo some of the stuff it did as it can't import pywin32 itself. Another problem I'd expect to find is that the post-install script tries to tell distutils about new files and registry entries created at install time - this probably fails silently now (ie, it might *appear* to work but probably leaves trash behind.) That said, if we can make it work correctly in these cases, I'm definitely up for accepting patches! As to some of your other points: On 20/06/2013 7:51 AM, Will Sadkin wrote: > > I really need to be able to do a silent install of the pywin32 > package for python2.7, The other way to approach this is simply to copy the files yourself and run the post-install script manually - ie, I assume you want to install pywin32 as part of a "larger" install, so you could just ignore the pywin32 installer completely... > 1) I couldn't build from the latest source version (218). This is > because the downloadable pywin32-218.zip file is either incomplete or > inconsistent, because the win32\src\PerfMon directory no longer > includes perfutil.h, but the code therein attempts to include it. > (See bug https://sourceforge.net/p/pywin32/bugs/647/.) Yeah, I screwed that release up in that regard. I normally unzip the source package and attempt to build it before release, but forgot that time :( > (That is, exclude the .0 from the string, so that it was just > '2.7.217'. This seemed a reasonable thing to do, as I've never seen a > "patch" number on any pywin32 version, and the rest seemed > appropriate, but I don't know if Mark Hammond would agree, and if > there ever was a patch number, this would not work.) I have used the patch version in the past - mainly when I've found one single package was uploaded incorrectly due to a build issue rather than due to a bug in the code itself. eg: https://sourceforge.net/projects/pywin32/files/pywin32/Build216/ - where is a "216.1" build for Python 3.2. The other thing I've done in the past is to upload custom pywin32 builds for people when they've reported a bug but can't rebuild the world to test it - I usually change that version string immediately after release, so any such "interim" builds can't be confused with the official builds (but such builds don't end up on sourceforge) But I'm happy to change things in this area if it blocks support for MSI. The other thing I'd want to make sure is that the Python version in that number does something sane - eg, I wouldn't want the MSI infrastructure to think that "2.7.217" was an earlier version (or even related in any way) than "3.2.216" etc. > It turns out that this distutils bug was reported back in August of > 2012, and a patch has even been supplied (see > http://bugs.python.org/issue15797.) When I applied the supplied > patch, and rebuilt my msi, it properly ran the postinstall script, > and (as far as I can tell) the resulting install works perfectly! I can probably help push that through. Although it seems unlikely for it to be accepted into the 2.x branch, which is a problem. OTOH though, if you help get this working and you only care about 3.x, I could certainly live with the fact that MSI installers are only available for 3.x... I wonder if there are heuristics the post-install script could use to work around this itself? You said the uninstall worked - did it actually leave a clean file-system afterwards? If so, it would seem the issue I mentioned before might not be a problem at all - but it's not clear to me how, even if pywin32 was fully unavailable at uninstall time, how we could determine if this invocation is for a re-install or an uninstall (ie, it's not clear to me that the absence of certain files would be a reliable guide here) > (And there was much rejoicing... yea...) Awesome :) > So: The reasons for my post to this forum: > > 1) Is the change I made to the version string used in the dist > construction appropriate? If not, what would be the appropriate > version to use? We can work something out there. > 2) Can this version be used for both the .exe and the .msi build > methods, or, if not, is there a way to conditionally set this based > on which type of build is being attempted? Not having a patch version for the .exe distros would be fine even if it means I need to change a couple of things in how I release. > 3) The patch for distutils was submitted in August of 2012, but, > AFAICT, has not been incorporated into the 2.7.x distutils source; is > there a way to expedite that? I can probably help, but as mentioned, I'm not sure it would be acceptable for 2.x. Getting it only in 3.latest would mean I can probably get things to work for all 3.* builds - but not 2.* builds. > 4) Would it be possible to take all of this into account, verify that > I'm not missing anything subtle, and generate "official" .msi files > for pywin32, since this is all targeted *for Microsoft systems,* > after all... ;) Sure - although TBH my personal motivation for this is quite small (I'm not using Python at all in my day-job) and my time is pretty tight at the moment (and I'm away for the next week or so, so will be slower than usual in replies etc) - so the reality is that you are probably going to need to drive this - with my support - to make it happen. Cheers, Mark From mmanfre at gmail.com Thu Jun 20 22:06:25 2013 From: mmanfre at gmail.com (Michael Manfre) Date: Thu, 20 Jun 2013 16:06:25 -0400 Subject: [python-win32] Passing Args through PythonService.exe Message-ID: Is it possible to pass args through PythonService.exe on to the ServiceFramework class? The only arg that I ever see come through the init is a tuple containing only the _svc_name_. I need to install many services for celery workers and having to create a separate class/file for each environment and queue combination would be painful. I started to dig in to PythonService.cpp, but have yet to find any way of controlling what argv will used with the init. Regards, Michael Manfre -------------- next part -------------- An HTML attachment was scrubbed... URL: From wsadkin at ParlanceCorp.com Fri Jun 21 19:03:53 2013 From: wsadkin at ParlanceCorp.com (Will Sadkin) Date: Fri, 21 Jun 2013 17:03:53 +0000 Subject: [python-win32] Building pywin32 msi installers In-Reply-To: <51C2AC1B.8020703@gmail.com> References: <75BADF2D5A2DD345819BDC79C664DA4D20F136@Exchange2010.nameconnector.com> <51C2AC1B.8020703@gmail.com> Message-ID: <75BADF2D5A2DD345819BDC79C664DA4D2124FF@Exchange2010.nameconnector.com> On 20/06/2013 3:16 AM , Mark Hammond wrote: > I've wanted bdist_msi to work for ages. There was some issue with the > install scripts that always caused grief, and my memory is hazy - it *might* > be that the uninstall process doesn't run the post-install script at the > correct time - ie, that it runs *after* the uninstall, which means pywin32 > isn't available to undo some of the stuff it did as it can't import pywin32 > itself. There's a comment in the pywin32_postinstall.py script that says: elif arg == "-remove": # bdist_msi calls us before uninstall, so we can undo what we # previously did. Sadly, bdist_wininst calls us *after*, so # we can't do much at all. if not is_bdist_wininst: uninstall() And I've confirmed that this comment re: bdist_msi is correct. Given this, I expect that these issues were with the bdist_wininst, and so a working msi installer might be even better than the existing installer on that score. > Another problem I'd expect to find is that the post-install script tries to tell > distutils about new files and registry entries created at install time - this probably > fails silently now (ie, it might *appear* to work but probably leaves > trash behind.) I couldn't identify the code that does this thing you mention above, but given this concern, I did some careful checking. As far as I can tell, there are 3 complaints re: trash: 1) What's left behind in the file system after an install followed by an immediate uninstall are 3 site-packages subtrees: win32\lib, win32com\{client,server,servers}, and win32comext\{axscript,shell}, and all of these only contain .pyc files. Unfortunately, as .pycs are generated post-install by the interpreter, and I'm not sure how to identify the ones associated with just the pywin32 stuff, so I don't quite know how to get rid of them so that these directories are cleanly removed. Further, if the other directories installed get invoked, I'm sure that there will be .pycs generated there too. Is there a way to have the postinstall script know (without hardcoding), which directories it should recursively clean out the .pycs from? Or is there some other mechanism I can use that I'm not aware of? 2) There is also much black magic juju-bwana re: create_shortcut that is in that script and I don't entirely understand... But running the postinstall.py -install manually on windows 7, it says: Can't install shortcuts - u'C:\\Users\\DevTest7\\AppData\\Roaming\\Microsoft\\Windows\\Start Menu\\Programs\\Python 2.7' is not a folder. I don't yet know why it's trying to use this folder, but this whole thing is part of the black magic I don't understand, and there are comments in the postinstall script that suggest that none of this stuff actually works on windows 7 anyway. Do we know if this step actually works for win7 with the current installer? 3) And on manually trying the -remove version of the script, it complained: Failed to unregister Pythonwin: [Error 5] Access is denied But I tracked this down to a bug in the uninstall code in the postinstall.py script; _winreg.DeleteKey() doesn't allow you delete a key with subkeys, but you had created two keys with (command) subkeys in the install process. Once I fixed the postinstall script to Delete the subkeys and then the root key, the script properly removed the pythonwin.exe keys and unregistered it. (I suspect this is actually currently broken in the regular installer as well if you use the bdist_wininst distutils mechanism, unless that code is circumvented in your .exe installer.) (I will supply a patch for this too.) Should I be looking for anything else while I'm at it? > > 1) I couldn't build from the latest source version (218). [...] > Yeah, I screwed that release up in that regard. I normally unzip the source package and attempt to build > it before release, but forgot that time :( Ok, well, with luck, the changes to allow construction of an official msi can become part of version 219. ;) > I have used the patch version in the past - mainly when I've found one single package was uploaded > incorrectly due to a build issue rather than due to a bug in the code itself. > eg: https://sourceforge.net/projects/pywin32/files/pywin32/Build216/ - where is a "216.1" build for Python 3.2. > > The other thing I've done in the past is to upload custom pywin32 builds for people when they've reported a > bug but can't rebuild the world to test it - I usually change that version string immediately after release, so any > such "interim" builds can't be confused with the official builds (but such builds don't end up on sourceforge) > > But I'm happy to change things in this area if it blocks support for MSI. The other thing I'd want to make sure is > that the Python version in that number does something sane - eg, I wouldn't want the MSI infrastructure to > think that "2.7.217" was an earlier version (or even related in any way) than "3.2.216" etc. Yeeeaaaahhh, the docstring on the strict version class says "the rationale for this version string numbering system will be explained in the distutils documentation," but no such rationale is provided there. Further, here's a snippet of the bdist_msi.py code: version = metadata.get_version() # ProductVersion must be strictly numeric # XXX need to deal with prerelease versions sversion = "%d.%d.%d" % StrictVersion(version).version # Prefix ProductName with Python x.y, so that # it sorts together with the other Python packages # in Add-Remove-Programs (APR) fullname = self.distribution.get_fullname() if self.target_version: product_name = "Python %s %s" % (self.target_version, fullname) else: product_name = "Python %s" % (fullname) This assumes that the StrictVersion(version).version is literally a tuple of 3 components; otherwise the string format would generate an exception; fortunately, if you don't provide the 3rd component, it appends a 0 for you (see below). Also, the above code automatically sticks "Python x.y" into the product name used, so I don't think we need to include those in the version string like I was. >From the distutils\version.py file: class StrictVersion (Version): [...] version_re = re.compile(r'^(\d+) \. (\d+) (\. (\d+))? ([ab](\d+))?$', re.VERBOSE) def parse (self, vstring): match = self.version_re.match(vstring) if not match: raise ValueError, "invalid version number '%s'" % vstring (major, minor, patch, prerelease, prerelease_num) = \ match.group(1, 2, 4, 5, 6) if patch: self.version = tuple(map(string.atoi, [major, minor, patch])) else: self.version = tuple(map(string.atoi, [major, minor]) + [0]) if prerelease: self.prerelease = (prerelease[0], string.atoi(prerelease_num)) else: self.prerelease = None Given the code in bdist_msi using the current python release major.minor release number already in the product name, this suggests that we should just specify build_id as major, and your patch number (usually .0) as minor in the version string. That way, you don't have to change a thing with respect to versioning, and instead of my previous patch, we can just use your build_id_patch variable as the dist version, eg: dist = setup(name="pywin32", ! version=str(build_id), description="Python for Window Extensions", long_description="Python extensions for Microsoft Windows\n" "Provides access to much of the Win32 API, the\n" "ability to create and use COM objects, and the\n" "Pythonwin environment.", --- 2328,2340 ---- 'build_py' : my_build_py, 'build_scripts' : my_build_scripts, } dist = setup(name="pywin32", ! # msi construction needs a major.minor version, so we use build_id_patch ! # for this instead: ! version=str(build_id_patch), description="Python for Window Extensions", long_description="Python extensions for Microsoft Windows\n" and that's the only change required in the setup file! This produces an msi named pywin32-217.0.win32-py2.7.msi, which also (mostly) avoids the repetitive redundancy there too. > > It turns out that this distutils bug was reported back in August of > > 2012, and a patch has even been supplied (see > > http://bugs.python.org/issue15797.) When I applied the supplied > > patch, and rebuilt my msi, it properly ran the postinstall script, and > > (as far as I can tell) the resulting install works perfectly! > > I can probably help push that through. Although it seems unlikely for it to be accepted into > the 2.x branch, which is a problem. OTOH though, if you help get this working and you only > care about 3.x, I could certainly live with the fact that MSI installers are only available for 3.x... Regrettably, I need them for 2.7. > I wonder if there are heuristics the post-install script could use to work around this itself? > You said the uninstall worked - did it actually leave a clean file-system afterwards? If so, it > would seem the issue I mentioned before might not be a problem at all - but it's not clear > to me how, even if pywin32 was fully unavailable at uninstall time, how we could determine > if this invocation is for a re-install or an uninstall (ie, it's not clear to me that the absence of > certain files would be a reliable guide here) Yeah, I thought about that, and struggled with the same issues: without arguments, how would it know whether it was being invoked for install or remove? But when I discovered what the real problem was, and went a-googling, I discovered that bug report and patch submission against the distutils, and so I thought that was the better choice. If I can resolve the other issues, and submit patches, is there any way I can convince you to to apply that distutils patch on your system, so that you can then use it to build the msi's? If they work and come from you, I suspect no one will care that they were built with an "unsanctioned" version of distutils... Regards, /Will From feng.xu at naen-china.com Sat Jun 22 09:59:16 2013 From: feng.xu at naen-china.com (feng.xu) Date: Sat, 22 Jun 2013 15:59:16 +0800 Subject: [python-win32] New win32com.client.VARIANT object Message-ID: <201306221559159250034@naen-china.com> Dear Mark: Where can i get this VARIANT module? it seems that i have issue you described in the email. I cannot find this module in the activate python 2.7 Thank you very much. feng.xu -------------- next part -------------- An HTML attachment was scrubbed... URL: