Show More
The requested changes are too big and content was truncated. Show full diff
@@ -1,1 +1,2 b'' | |||||
1 | IPython/.git_commit_info.ini export-subst |
|
1 | IPython/.git_commit_info.ini export-subst | |
|
2 | * text=auto |
This diff has been collapsed as it changes many lines, (528 lines changed) Show them Hide them | |||||
@@ -1,264 +1,264 b'' | |||||
1 | # A module to expose various thread/process/job related structures and |
|
1 | # A module to expose various thread/process/job related structures and | |
2 | # methods from kernel32 |
|
2 | # methods from kernel32 | |
3 | # |
|
3 | # | |
4 | # The MIT License |
|
4 | # The MIT License | |
5 | # |
|
5 | # | |
6 | # Copyright (c) 2006 the Mozilla Foundation <http://www.mozilla.org> |
|
6 | # Copyright (c) 2006 the Mozilla Foundation <http://www.mozilla.org> | |
7 | # |
|
7 | # | |
8 | # Permission is hereby granted, free of charge, to any person obtaining a |
|
8 | # Permission is hereby granted, free of charge, to any person obtaining a | |
9 | # copy of this software and associated documentation files (the "Software"), |
|
9 | # copy of this software and associated documentation files (the "Software"), | |
10 | # to deal in the Software without restriction, including without limitation |
|
10 | # to deal in the Software without restriction, including without limitation | |
11 | # the rights to use, copy, modify, merge, publish, distribute, sublicense, |
|
11 | # the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
12 | # and/or sell copies of the Software, and to permit persons to whom the |
|
12 | # and/or sell copies of the Software, and to permit persons to whom the | |
13 | # Software is furnished to do so, subject to the following conditions: |
|
13 | # Software is furnished to do so, subject to the following conditions: | |
14 | # |
|
14 | # | |
15 | # The above copyright notice and this permission notice shall be included in |
|
15 | # The above copyright notice and this permission notice shall be included in | |
16 | # all copies or substantial portions of the Software. |
|
16 | # all copies or substantial portions of the Software. | |
17 | # |
|
17 | # | |
18 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|
18 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
19 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|
19 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
20 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
|
20 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
21 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|
21 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
22 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
|
22 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |
23 | # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
|
23 | # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |
24 | # DEALINGS IN THE SOFTWARE. |
|
24 | # DEALINGS IN THE SOFTWARE. | |
25 |
|
25 | |||
26 | from ctypes import c_void_p, POINTER, sizeof, Structure, windll, WinError, WINFUNCTYPE |
|
26 | from ctypes import c_void_p, POINTER, sizeof, Structure, windll, WinError, WINFUNCTYPE | |
27 | from ctypes.wintypes import BOOL, BYTE, DWORD, HANDLE, LPCWSTR, LPWSTR, UINT, WORD |
|
27 | from ctypes.wintypes import BOOL, BYTE, DWORD, HANDLE, LPCWSTR, LPWSTR, UINT, WORD | |
28 |
|
28 | |||
29 | LPVOID = c_void_p |
|
29 | LPVOID = c_void_p | |
30 | LPBYTE = POINTER(BYTE) |
|
30 | LPBYTE = POINTER(BYTE) | |
31 | LPDWORD = POINTER(DWORD) |
|
31 | LPDWORD = POINTER(DWORD) | |
32 |
|
32 | |||
33 | SW_HIDE = 0 |
|
33 | SW_HIDE = 0 | |
34 |
|
34 | |||
35 | def ErrCheckBool(result, func, args): |
|
35 | def ErrCheckBool(result, func, args): | |
36 | """errcheck function for Windows functions that return a BOOL True |
|
36 | """errcheck function for Windows functions that return a BOOL True | |
37 | on success""" |
|
37 | on success""" | |
38 | if not result: |
|
38 | if not result: | |
39 | raise WinError() |
|
39 | raise WinError() | |
40 | return args |
|
40 | return args | |
41 |
|
41 | |||
42 | # CloseHandle() |
|
42 | # CloseHandle() | |
43 |
|
43 | |||
44 | CloseHandleProto = WINFUNCTYPE(BOOL, HANDLE) |
|
44 | CloseHandleProto = WINFUNCTYPE(BOOL, HANDLE) | |
45 | CloseHandle = CloseHandleProto(("CloseHandle", windll.kernel32)) |
|
45 | CloseHandle = CloseHandleProto(("CloseHandle", windll.kernel32)) | |
46 | CloseHandle.errcheck = ErrCheckBool |
|
46 | CloseHandle.errcheck = ErrCheckBool | |
47 |
|
47 | |||
48 | # AutoHANDLE |
|
48 | # AutoHANDLE | |
49 |
|
49 | |||
50 | class AutoHANDLE(HANDLE): |
|
50 | class AutoHANDLE(HANDLE): | |
51 | """Subclass of HANDLE which will call CloseHandle() on deletion.""" |
|
51 | """Subclass of HANDLE which will call CloseHandle() on deletion.""" | |
52 | def Close(self): |
|
52 | def Close(self): | |
53 | if self.value: |
|
53 | if self.value: | |
54 | CloseHandle(self) |
|
54 | CloseHandle(self) | |
55 | self.value = 0 |
|
55 | self.value = 0 | |
56 |
|
56 | |||
57 | def __del__(self): |
|
57 | def __del__(self): | |
58 | self.Close() |
|
58 | self.Close() | |
59 |
|
59 | |||
60 | def __int__(self): |
|
60 | def __int__(self): | |
61 | return self.value |
|
61 | return self.value | |
62 |
|
62 | |||
63 | def ErrCheckHandle(result, func, args): |
|
63 | def ErrCheckHandle(result, func, args): | |
64 | """errcheck function for Windows functions that return a HANDLE.""" |
|
64 | """errcheck function for Windows functions that return a HANDLE.""" | |
65 | if not result: |
|
65 | if not result: | |
66 | raise WinError() |
|
66 | raise WinError() | |
67 | return AutoHANDLE(result) |
|
67 | return AutoHANDLE(result) | |
68 |
|
68 | |||
69 | # PROCESS_INFORMATION structure |
|
69 | # PROCESS_INFORMATION structure | |
70 |
|
70 | |||
71 | class PROCESS_INFORMATION(Structure): |
|
71 | class PROCESS_INFORMATION(Structure): | |
72 | _fields_ = [("hProcess", HANDLE), |
|
72 | _fields_ = [("hProcess", HANDLE), | |
73 | ("hThread", HANDLE), |
|
73 | ("hThread", HANDLE), | |
74 | ("dwProcessID", DWORD), |
|
74 | ("dwProcessID", DWORD), | |
75 | ("dwThreadID", DWORD)] |
|
75 | ("dwThreadID", DWORD)] | |
76 |
|
76 | |||
77 | def __init__(self): |
|
77 | def __init__(self): | |
78 | Structure.__init__(self) |
|
78 | Structure.__init__(self) | |
79 |
|
79 | |||
80 | self.cb = sizeof(self) |
|
80 | self.cb = sizeof(self) | |
81 |
|
81 | |||
82 | LPPROCESS_INFORMATION = POINTER(PROCESS_INFORMATION) |
|
82 | LPPROCESS_INFORMATION = POINTER(PROCESS_INFORMATION) | |
83 |
|
83 | |||
84 | # STARTUPINFO structure |
|
84 | # STARTUPINFO structure | |
85 |
|
85 | |||
86 | class STARTUPINFO(Structure): |
|
86 | class STARTUPINFO(Structure): | |
87 | _fields_ = [("cb", DWORD), |
|
87 | _fields_ = [("cb", DWORD), | |
88 | ("lpReserved", LPWSTR), |
|
88 | ("lpReserved", LPWSTR), | |
89 | ("lpDesktop", LPWSTR), |
|
89 | ("lpDesktop", LPWSTR), | |
90 | ("lpTitle", LPWSTR), |
|
90 | ("lpTitle", LPWSTR), | |
91 | ("dwX", DWORD), |
|
91 | ("dwX", DWORD), | |
92 | ("dwY", DWORD), |
|
92 | ("dwY", DWORD), | |
93 | ("dwXSize", DWORD), |
|
93 | ("dwXSize", DWORD), | |
94 | ("dwYSize", DWORD), |
|
94 | ("dwYSize", DWORD), | |
95 | ("dwXCountChars", DWORD), |
|
95 | ("dwXCountChars", DWORD), | |
96 | ("dwYCountChars", DWORD), |
|
96 | ("dwYCountChars", DWORD), | |
97 | ("dwFillAttribute", DWORD), |
|
97 | ("dwFillAttribute", DWORD), | |
98 | ("dwFlags", DWORD), |
|
98 | ("dwFlags", DWORD), | |
99 | ("wShowWindow", WORD), |
|
99 | ("wShowWindow", WORD), | |
100 | ("cbReserved2", WORD), |
|
100 | ("cbReserved2", WORD), | |
101 | ("lpReserved2", LPBYTE), |
|
101 | ("lpReserved2", LPBYTE), | |
102 | ("hStdInput", HANDLE), |
|
102 | ("hStdInput", HANDLE), | |
103 | ("hStdOutput", HANDLE), |
|
103 | ("hStdOutput", HANDLE), | |
104 | ("hStdError", HANDLE) |
|
104 | ("hStdError", HANDLE) | |
105 | ] |
|
105 | ] | |
106 | LPSTARTUPINFO = POINTER(STARTUPINFO) |
|
106 | LPSTARTUPINFO = POINTER(STARTUPINFO) | |
107 |
|
107 | |||
108 | STARTF_USESHOWWINDOW = 0x01 |
|
108 | STARTF_USESHOWWINDOW = 0x01 | |
109 | STARTF_USESIZE = 0x02 |
|
109 | STARTF_USESIZE = 0x02 | |
110 | STARTF_USEPOSITION = 0x04 |
|
110 | STARTF_USEPOSITION = 0x04 | |
111 | STARTF_USECOUNTCHARS = 0x08 |
|
111 | STARTF_USECOUNTCHARS = 0x08 | |
112 | STARTF_USEFILLATTRIBUTE = 0x10 |
|
112 | STARTF_USEFILLATTRIBUTE = 0x10 | |
113 | STARTF_RUNFULLSCREEN = 0x20 |
|
113 | STARTF_RUNFULLSCREEN = 0x20 | |
114 | STARTF_FORCEONFEEDBACK = 0x40 |
|
114 | STARTF_FORCEONFEEDBACK = 0x40 | |
115 | STARTF_FORCEOFFFEEDBACK = 0x80 |
|
115 | STARTF_FORCEOFFFEEDBACK = 0x80 | |
116 | STARTF_USESTDHANDLES = 0x100 |
|
116 | STARTF_USESTDHANDLES = 0x100 | |
117 |
|
117 | |||
118 | # EnvironmentBlock |
|
118 | # EnvironmentBlock | |
119 |
|
119 | |||
120 | class EnvironmentBlock: |
|
120 | class EnvironmentBlock: | |
121 | """An object which can be passed as the lpEnv parameter of CreateProcess. |
|
121 | """An object which can be passed as the lpEnv parameter of CreateProcess. | |
122 | It is initialized with a dictionary.""" |
|
122 | It is initialized with a dictionary.""" | |
123 |
|
123 | |||
124 | def __init__(self, dict): |
|
124 | def __init__(self, dict): | |
125 | if not dict: |
|
125 | if not dict: | |
126 | self._as_parameter_ = None |
|
126 | self._as_parameter_ = None | |
127 | else: |
|
127 | else: | |
128 | values = ["%s=%s" % (key, value) |
|
128 | values = ["%s=%s" % (key, value) | |
129 | for (key, value) in dict.iteritems()] |
|
129 | for (key, value) in dict.iteritems()] | |
130 | values.append("") |
|
130 | values.append("") | |
131 | self._as_parameter_ = LPCWSTR("\0".join(values)) |
|
131 | self._as_parameter_ = LPCWSTR("\0".join(values)) | |
132 |
|
132 | |||
133 | # CreateProcess() |
|
133 | # CreateProcess() | |
134 |
|
134 | |||
135 | CreateProcessProto = WINFUNCTYPE(BOOL, # Return type |
|
135 | CreateProcessProto = WINFUNCTYPE(BOOL, # Return type | |
136 | LPCWSTR, # lpApplicationName |
|
136 | LPCWSTR, # lpApplicationName | |
137 | LPWSTR, # lpCommandLine |
|
137 | LPWSTR, # lpCommandLine | |
138 | LPVOID, # lpProcessAttributes |
|
138 | LPVOID, # lpProcessAttributes | |
139 | LPVOID, # lpThreadAttributes |
|
139 | LPVOID, # lpThreadAttributes | |
140 | BOOL, # bInheritHandles |
|
140 | BOOL, # bInheritHandles | |
141 | DWORD, # dwCreationFlags |
|
141 | DWORD, # dwCreationFlags | |
142 | LPVOID, # lpEnvironment |
|
142 | LPVOID, # lpEnvironment | |
143 | LPCWSTR, # lpCurrentDirectory |
|
143 | LPCWSTR, # lpCurrentDirectory | |
144 | LPSTARTUPINFO, # lpStartupInfo |
|
144 | LPSTARTUPINFO, # lpStartupInfo | |
145 | LPPROCESS_INFORMATION # lpProcessInformation |
|
145 | LPPROCESS_INFORMATION # lpProcessInformation | |
146 | ) |
|
146 | ) | |
147 |
|
147 | |||
148 | CreateProcessFlags = ((1, "lpApplicationName", None), |
|
148 | CreateProcessFlags = ((1, "lpApplicationName", None), | |
149 | (1, "lpCommandLine"), |
|
149 | (1, "lpCommandLine"), | |
150 | (1, "lpProcessAttributes", None), |
|
150 | (1, "lpProcessAttributes", None), | |
151 | (1, "lpThreadAttributes", None), |
|
151 | (1, "lpThreadAttributes", None), | |
152 | (1, "bInheritHandles", True), |
|
152 | (1, "bInheritHandles", True), | |
153 | (1, "dwCreationFlags", 0), |
|
153 | (1, "dwCreationFlags", 0), | |
154 | (1, "lpEnvironment", None), |
|
154 | (1, "lpEnvironment", None), | |
155 | (1, "lpCurrentDirectory", None), |
|
155 | (1, "lpCurrentDirectory", None), | |
156 | (1, "lpStartupInfo"), |
|
156 | (1, "lpStartupInfo"), | |
157 | (2, "lpProcessInformation")) |
|
157 | (2, "lpProcessInformation")) | |
158 |
|
158 | |||
159 | def ErrCheckCreateProcess(result, func, args): |
|
159 | def ErrCheckCreateProcess(result, func, args): | |
160 | ErrCheckBool(result, func, args) |
|
160 | ErrCheckBool(result, func, args) | |
161 | # return a tuple (hProcess, hThread, dwProcessID, dwThreadID) |
|
161 | # return a tuple (hProcess, hThread, dwProcessID, dwThreadID) | |
162 | pi = args[9] |
|
162 | pi = args[9] | |
163 | return AutoHANDLE(pi.hProcess), AutoHANDLE(pi.hThread), pi.dwProcessID, pi.dwThreadID |
|
163 | return AutoHANDLE(pi.hProcess), AutoHANDLE(pi.hThread), pi.dwProcessID, pi.dwThreadID | |
164 |
|
164 | |||
165 | CreateProcess = CreateProcessProto(("CreateProcessW", windll.kernel32), |
|
165 | CreateProcess = CreateProcessProto(("CreateProcessW", windll.kernel32), | |
166 | CreateProcessFlags) |
|
166 | CreateProcessFlags) | |
167 | CreateProcess.errcheck = ErrCheckCreateProcess |
|
167 | CreateProcess.errcheck = ErrCheckCreateProcess | |
168 |
|
168 | |||
169 | CREATE_BREAKAWAY_FROM_JOB = 0x01000000 |
|
169 | CREATE_BREAKAWAY_FROM_JOB = 0x01000000 | |
170 | CREATE_DEFAULT_ERROR_MODE = 0x04000000 |
|
170 | CREATE_DEFAULT_ERROR_MODE = 0x04000000 | |
171 | CREATE_NEW_CONSOLE = 0x00000010 |
|
171 | CREATE_NEW_CONSOLE = 0x00000010 | |
172 | CREATE_NEW_PROCESS_GROUP = 0x00000200 |
|
172 | CREATE_NEW_PROCESS_GROUP = 0x00000200 | |
173 | CREATE_NO_WINDOW = 0x08000000 |
|
173 | CREATE_NO_WINDOW = 0x08000000 | |
174 | CREATE_SUSPENDED = 0x00000004 |
|
174 | CREATE_SUSPENDED = 0x00000004 | |
175 | CREATE_UNICODE_ENVIRONMENT = 0x00000400 |
|
175 | CREATE_UNICODE_ENVIRONMENT = 0x00000400 | |
176 | DEBUG_ONLY_THIS_PROCESS = 0x00000002 |
|
176 | DEBUG_ONLY_THIS_PROCESS = 0x00000002 | |
177 | DEBUG_PROCESS = 0x00000001 |
|
177 | DEBUG_PROCESS = 0x00000001 | |
178 | DETACHED_PROCESS = 0x00000008 |
|
178 | DETACHED_PROCESS = 0x00000008 | |
179 |
|
179 | |||
180 | # CreateJobObject() |
|
180 | # CreateJobObject() | |
181 |
|
181 | |||
182 | CreateJobObjectProto = WINFUNCTYPE(HANDLE, # Return type |
|
182 | CreateJobObjectProto = WINFUNCTYPE(HANDLE, # Return type | |
183 | LPVOID, # lpJobAttributes |
|
183 | LPVOID, # lpJobAttributes | |
184 | LPCWSTR # lpName |
|
184 | LPCWSTR # lpName | |
185 | ) |
|
185 | ) | |
186 |
|
186 | |||
187 | CreateJobObjectFlags = ((1, "lpJobAttributes", None), |
|
187 | CreateJobObjectFlags = ((1, "lpJobAttributes", None), | |
188 | (1, "lpName", None)) |
|
188 | (1, "lpName", None)) | |
189 |
|
189 | |||
190 | CreateJobObject = CreateJobObjectProto(("CreateJobObjectW", windll.kernel32), |
|
190 | CreateJobObject = CreateJobObjectProto(("CreateJobObjectW", windll.kernel32), | |
191 | CreateJobObjectFlags) |
|
191 | CreateJobObjectFlags) | |
192 | CreateJobObject.errcheck = ErrCheckHandle |
|
192 | CreateJobObject.errcheck = ErrCheckHandle | |
193 |
|
193 | |||
194 | # AssignProcessToJobObject() |
|
194 | # AssignProcessToJobObject() | |
195 |
|
195 | |||
196 | AssignProcessToJobObjectProto = WINFUNCTYPE(BOOL, # Return type |
|
196 | AssignProcessToJobObjectProto = WINFUNCTYPE(BOOL, # Return type | |
197 | HANDLE, # hJob |
|
197 | HANDLE, # hJob | |
198 | HANDLE # hProcess |
|
198 | HANDLE # hProcess | |
199 | ) |
|
199 | ) | |
200 | AssignProcessToJobObjectFlags = ((1, "hJob"), |
|
200 | AssignProcessToJobObjectFlags = ((1, "hJob"), | |
201 | (1, "hProcess")) |
|
201 | (1, "hProcess")) | |
202 | AssignProcessToJobObject = AssignProcessToJobObjectProto( |
|
202 | AssignProcessToJobObject = AssignProcessToJobObjectProto( | |
203 | ("AssignProcessToJobObject", windll.kernel32), |
|
203 | ("AssignProcessToJobObject", windll.kernel32), | |
204 | AssignProcessToJobObjectFlags) |
|
204 | AssignProcessToJobObjectFlags) | |
205 | AssignProcessToJobObject.errcheck = ErrCheckBool |
|
205 | AssignProcessToJobObject.errcheck = ErrCheckBool | |
206 |
|
206 | |||
207 | # ResumeThread() |
|
207 | # ResumeThread() | |
208 |
|
208 | |||
209 | def ErrCheckResumeThread(result, func, args): |
|
209 | def ErrCheckResumeThread(result, func, args): | |
210 | if result == -1: |
|
210 | if result == -1: | |
211 | raise WinError() |
|
211 | raise WinError() | |
212 |
|
212 | |||
213 | return args |
|
213 | return args | |
214 |
|
214 | |||
215 | ResumeThreadProto = WINFUNCTYPE(DWORD, # Return type |
|
215 | ResumeThreadProto = WINFUNCTYPE(DWORD, # Return type | |
216 | HANDLE # hThread |
|
216 | HANDLE # hThread | |
217 | ) |
|
217 | ) | |
218 | ResumeThreadFlags = ((1, "hThread"),) |
|
218 | ResumeThreadFlags = ((1, "hThread"),) | |
219 | ResumeThread = ResumeThreadProto(("ResumeThread", windll.kernel32), |
|
219 | ResumeThread = ResumeThreadProto(("ResumeThread", windll.kernel32), | |
220 | ResumeThreadFlags) |
|
220 | ResumeThreadFlags) | |
221 | ResumeThread.errcheck = ErrCheckResumeThread |
|
221 | ResumeThread.errcheck = ErrCheckResumeThread | |
222 |
|
222 | |||
223 | # TerminateJobObject() |
|
223 | # TerminateJobObject() | |
224 |
|
224 | |||
225 | TerminateJobObjectProto = WINFUNCTYPE(BOOL, # Return type |
|
225 | TerminateJobObjectProto = WINFUNCTYPE(BOOL, # Return type | |
226 | HANDLE, # hJob |
|
226 | HANDLE, # hJob | |
227 | UINT # uExitCode |
|
227 | UINT # uExitCode | |
228 | ) |
|
228 | ) | |
229 | TerminateJobObjectFlags = ((1, "hJob"), |
|
229 | TerminateJobObjectFlags = ((1, "hJob"), | |
230 | (1, "uExitCode", 127)) |
|
230 | (1, "uExitCode", 127)) | |
231 | TerminateJobObject = TerminateJobObjectProto( |
|
231 | TerminateJobObject = TerminateJobObjectProto( | |
232 | ("TerminateJobObject", windll.kernel32), |
|
232 | ("TerminateJobObject", windll.kernel32), | |
233 | TerminateJobObjectFlags) |
|
233 | TerminateJobObjectFlags) | |
234 | TerminateJobObject.errcheck = ErrCheckBool |
|
234 | TerminateJobObject.errcheck = ErrCheckBool | |
235 |
|
235 | |||
236 | # WaitForSingleObject() |
|
236 | # WaitForSingleObject() | |
237 |
|
237 | |||
238 | WaitForSingleObjectProto = WINFUNCTYPE(DWORD, # Return type |
|
238 | WaitForSingleObjectProto = WINFUNCTYPE(DWORD, # Return type | |
239 | HANDLE, # hHandle |
|
239 | HANDLE, # hHandle | |
240 | DWORD, # dwMilliseconds |
|
240 | DWORD, # dwMilliseconds | |
241 | ) |
|
241 | ) | |
242 | WaitForSingleObjectFlags = ((1, "hHandle"), |
|
242 | WaitForSingleObjectFlags = ((1, "hHandle"), | |
243 | (1, "dwMilliseconds", -1)) |
|
243 | (1, "dwMilliseconds", -1)) | |
244 | WaitForSingleObject = WaitForSingleObjectProto( |
|
244 | WaitForSingleObject = WaitForSingleObjectProto( | |
245 | ("WaitForSingleObject", windll.kernel32), |
|
245 | ("WaitForSingleObject", windll.kernel32), | |
246 | WaitForSingleObjectFlags) |
|
246 | WaitForSingleObjectFlags) | |
247 |
|
247 | |||
248 | INFINITE = -1 |
|
248 | INFINITE = -1 | |
249 | WAIT_TIMEOUT = 0x0102 |
|
249 | WAIT_TIMEOUT = 0x0102 | |
250 | WAIT_OBJECT_0 = 0x0 |
|
250 | WAIT_OBJECT_0 = 0x0 | |
251 | WAIT_ABANDONED = 0x0080 |
|
251 | WAIT_ABANDONED = 0x0080 | |
252 |
|
252 | |||
253 | # GetExitCodeProcess() |
|
253 | # GetExitCodeProcess() | |
254 |
|
254 | |||
255 | GetExitCodeProcessProto = WINFUNCTYPE(BOOL, # Return type |
|
255 | GetExitCodeProcessProto = WINFUNCTYPE(BOOL, # Return type | |
256 | HANDLE, # hProcess |
|
256 | HANDLE, # hProcess | |
257 | LPDWORD, # lpExitCode |
|
257 | LPDWORD, # lpExitCode | |
258 | ) |
|
258 | ) | |
259 | GetExitCodeProcessFlags = ((1, "hProcess"), |
|
259 | GetExitCodeProcessFlags = ((1, "hProcess"), | |
260 | (2, "lpExitCode")) |
|
260 | (2, "lpExitCode")) | |
261 | GetExitCodeProcess = GetExitCodeProcessProto( |
|
261 | GetExitCodeProcess = GetExitCodeProcessProto( | |
262 | ("GetExitCodeProcess", windll.kernel32), |
|
262 | ("GetExitCodeProcess", windll.kernel32), | |
263 | GetExitCodeProcessFlags) |
|
263 | GetExitCodeProcessFlags) | |
264 | GetExitCodeProcess.errcheck = ErrCheckBool |
|
264 | GetExitCodeProcess.errcheck = ErrCheckBool |
@@ -1,26 +1,26 b'' | |||||
1 | import win32api |
|
1 | import win32api | |
2 | import win32gui |
|
2 | import win32gui | |
3 | import win32con |
|
3 | import win32con | |
4 |
|
4 | |||
5 | import struct |
|
5 | import struct | |
6 | import array |
|
6 | import array | |
7 |
|
7 | |||
8 | def findWindows(): |
|
8 | def findWindows(): | |
9 | ret = [] |
|
9 | ret = [] | |
10 | sdi = win32api.RegisterWindowMessage("SciTEDirectorInterface") |
|
10 | sdi = win32api.RegisterWindowMessage("SciTEDirectorInterface") | |
11 | w = win32gui.GetWindow(win32gui.GetDesktopWindow(), win32con.GW_CHILD) |
|
11 | w = win32gui.GetWindow(win32gui.GetDesktopWindow(), win32con.GW_CHILD) | |
12 | while w: |
|
12 | while w: | |
13 | res = win32gui.SendMessage(w, sdi, 0, 0) |
|
13 | res = win32gui.SendMessage(w, sdi, 0, 0) | |
14 | if res == sdi: |
|
14 | if res == sdi: | |
15 | ret.append(w) |
|
15 | ret.append(w) | |
16 | w = win32gui.GetWindow(w, win32con.GW_HWNDNEXT) |
|
16 | w = win32gui.GetWindow(w, win32con.GW_HWNDNEXT) | |
17 |
|
17 | |||
18 | return ret |
|
18 | return ret | |
19 |
|
19 | |||
20 | def sendCommand(w, message): |
|
20 | def sendCommand(w, message): | |
21 | CopyDataStruct = "IIP" |
|
21 | CopyDataStruct = "IIP" | |
22 | char_buffer = array.array('c', message) |
|
22 | char_buffer = array.array('c', message) | |
23 | char_buffer_address = char_buffer.buffer_info()[0] |
|
23 | char_buffer_address = char_buffer.buffer_info()[0] | |
24 | char_buffer_size = char_buffer.buffer_info()[1] |
|
24 | char_buffer_size = char_buffer.buffer_info()[1] | |
25 | cds = struct.pack(CopyDataStruct, 0, char_buffer_size, char_buffer_address) |
|
25 | cds = struct.pack(CopyDataStruct, 0, char_buffer_size, char_buffer_address) | |
26 | win32gui.SendMessage(w, win32con.WM_COPYDATA, 0, cds) |
|
26 | win32gui.SendMessage(w, win32con.WM_COPYDATA, 0, cds) |
@@ -1,242 +1,242 b'' | |||||
1 | from IPython.core import ipapi |
|
1 | from IPython.core import ipapi | |
2 | ip = ipapi.get() |
|
2 | ip = ipapi.get() | |
3 |
|
3 | |||
4 | import win32api |
|
4 | import win32api | |
5 | import win32ui |
|
5 | import win32ui | |
6 | import win32console |
|
6 | import win32console | |
7 | import dde |
|
7 | import dde | |
8 | import os |
|
8 | import os | |
9 | import scitedirector |
|
9 | import scitedirector | |
10 |
|
10 | |||
11 | # test to write. |
|
11 | # test to write. | |
12 |
|
12 | |||
13 | def set_hook(synchronize_with_editor): |
|
13 | def set_hook(synchronize_with_editor): | |
14 | """Set the synchronize with editor hook with a callable object. |
|
14 | """Set the synchronize with editor hook with a callable object. | |
15 |
|
15 | |||
16 | The callable object will be called with the following arguments when |
|
16 | The callable object will be called with the following arguments when | |
17 | IPython wants to synchronize with you favorite editor: |
|
17 | IPython wants to synchronize with you favorite editor: | |
18 |
|
18 | |||
19 | - ip: a running IPython instance. |
|
19 | - ip: a running IPython instance. | |
20 |
|
20 | |||
21 | - filename: the path of the file the editor is supposed to display. |
|
21 | - filename: the path of the file the editor is supposed to display. | |
22 |
|
22 | |||
23 | - lineno : the line number of the line the editor is supposed to |
|
23 | - lineno : the line number of the line the editor is supposed to | |
24 | highlight. |
|
24 | highlight. | |
25 |
|
25 | |||
26 | - columnno : the column number of the character the editor is supposed |
|
26 | - columnno : the column number of the character the editor is supposed | |
27 | to highlight. |
|
27 | to highlight. | |
28 | """ |
|
28 | """ | |
29 | ip.set_hook("synchronize_with_editor", synchronize_with_editor) |
|
29 | ip.set_hook("synchronize_with_editor", synchronize_with_editor) | |
30 |
|
30 | |||
31 |
|
31 | |||
32 | def find_filename(filename): |
|
32 | def find_filename(filename): | |
33 | """Return the filename to synchronize with based on """ |
|
33 | """Return the filename to synchronize with based on """ | |
34 | filename = os.path.splitext(filename) |
|
34 | filename = os.path.splitext(filename) | |
35 | if filename[1] == ".pyc": |
|
35 | if filename[1] == ".pyc": | |
36 | filename = (filename[0], ".py") |
|
36 | filename = (filename[0], ".py") | |
37 | filename = "".join(filename) |
|
37 | filename = "".join(filename) | |
38 |
|
38 | |||
39 | if not os.path.isabs(filename): |
|
39 | if not os.path.isabs(filename): | |
40 | filename = os.path.join(os.getcwd(), filename) |
|
40 | filename = os.path.join(os.getcwd(), filename) | |
41 |
|
41 | |||
42 | if os.path.isfile(filename): |
|
42 | if os.path.isfile(filename): | |
43 | return filename |
|
43 | return filename | |
44 |
|
44 | |||
45 | return "" |
|
45 | return "" | |
46 |
|
46 | |||
47 |
|
47 | |||
48 | def run_command(path, command, arguments, asynchronous = True): |
|
48 | def run_command(path, command, arguments, asynchronous = True): | |
49 | """Run a shell command and return the exit code of the command""" |
|
49 | """Run a shell command and return the exit code of the command""" | |
50 | # This is a thin wrapper around os.system that: |
|
50 | # This is a thin wrapper around os.system that: | |
51 | # - Let you run command asynchronously. |
|
51 | # - Let you run command asynchronously. | |
52 | # - Accept spaces in command path. |
|
52 | # - Accept spaces in command path. | |
53 | # - Dont throw exception if the command don't exist. |
|
53 | # - Dont throw exception if the command don't exist. | |
54 | line = '' |
|
54 | line = '' | |
55 | if asynchronous: |
|
55 | if asynchronous: | |
56 | line += 'start ' |
|
56 | line += 'start ' | |
57 |
|
57 | |||
58 | try: |
|
58 | try: | |
59 | line += win32api.GetShortPathName(os.path.join(path, command) + ".exe") + " " |
|
59 | line += win32api.GetShortPathName(os.path.join(path, command) + ".exe") + " " | |
60 | except: |
|
60 | except: | |
61 | print 'could not find: "%s"' % (os.path.join(path, command) + ".exe") |
|
61 | print 'could not find: "%s"' % (os.path.join(path, command) + ".exe") | |
62 | return -1 |
|
62 | return -1 | |
63 |
|
63 | |||
64 | line += arguments |
|
64 | line += arguments | |
65 | r = os.system(line) |
|
65 | r = os.system(line) | |
66 | return r |
|
66 | return r | |
67 |
|
67 | |||
68 |
|
68 | |||
69 | def sleep(milliseconds): |
|
69 | def sleep(milliseconds): | |
70 | """Wait some milliseconds.""" |
|
70 | """Wait some milliseconds.""" | |
71 | # This is used to make sure the editor did its job before we reset the focus on the console. |
|
71 | # This is used to make sure the editor did its job before we reset the focus on the console. | |
72 | win32api.Sleep(milliseconds) |
|
72 | win32api.Sleep(milliseconds) | |
73 |
|
73 | |||
74 |
|
74 | |||
75 | def restore_console_focus(): |
|
75 | def restore_console_focus(): | |
76 | """Restore the focus to the IPython console.""" |
|
76 | """Restore the focus to the IPython console.""" | |
77 | h = win32console.GetConsoleWindow() |
|
77 | h = win32console.GetConsoleWindow() | |
78 | console_window = win32ui.CreateWindowFromHandle(h) |
|
78 | console_window = win32ui.CreateWindowFromHandle(h) | |
79 | console_window.SetForegroundWindow() |
|
79 | console_window.SetForegroundWindow() | |
80 |
|
80 | |||
81 |
|
81 | |||
82 | # This is the most simple example of hook: |
|
82 | # This is the most simple example of hook: | |
83 | class GVimHook: |
|
83 | class GVimHook: | |
84 | def __init__(self, path, wakeup_duration): |
|
84 | def __init__(self, path, wakeup_duration): | |
85 | self.path = path |
|
85 | self.path = path | |
86 | self.wakeup_duration = wakeup_duration |
|
86 | self.wakeup_duration = wakeup_duration | |
87 |
|
87 | |||
88 | def __call__(self, ip, filename, lineno, columnno): |
|
88 | def __call__(self, ip, filename, lineno, columnno): | |
89 | filename = find_filename(filename) |
|
89 | filename = find_filename(filename) | |
90 |
|
90 | |||
91 | if not filename: |
|
91 | if not filename: | |
92 | return |
|
92 | return | |
93 |
|
93 | |||
94 | run_command(self.path, 'gvim', '--remote-silent +%d "%s"' % (lineno, filename)) |
|
94 | run_command(self.path, 'gvim', '--remote-silent +%d "%s"' % (lineno, filename)) | |
95 |
|
95 | |||
96 | sleep(self.wakeup_duration) |
|
96 | sleep(self.wakeup_duration) | |
97 |
|
97 | |||
98 | restore_console_focus() |
|
98 | restore_console_focus() | |
99 |
|
99 | |||
100 |
|
100 | |||
101 | def gvim(path = r"C:\Program Files\vim\vim71", wakeup_duration = 100): |
|
101 | def gvim(path = r"C:\Program Files\vim\vim71", wakeup_duration = 100): | |
102 | synchronize_with_editor = GVimHook(path, wakeup_duration) |
|
102 | synchronize_with_editor = GVimHook(path, wakeup_duration) | |
103 | set_hook(synchronize_with_editor) |
|
103 | set_hook(synchronize_with_editor) | |
104 |
|
104 | |||
105 |
|
105 | |||
106 | class EmacsHook: |
|
106 | class EmacsHook: | |
107 | def __init__(self, path, wakeup_duration, start_duration): |
|
107 | def __init__(self, path, wakeup_duration, start_duration): | |
108 | self.path = path |
|
108 | self.path = path | |
109 | self.wakeup_duration = wakeup_duration |
|
109 | self.wakeup_duration = wakeup_duration | |
110 | self.start_duration = start_duration |
|
110 | self.start_duration = start_duration | |
111 |
|
111 | |||
112 | def __call__(self, ip, filename, lineno, columnno): |
|
112 | def __call__(self, ip, filename, lineno, columnno): | |
113 | filename = find_filename(filename) |
|
113 | filename = find_filename(filename) | |
114 |
|
114 | |||
115 | if not filename: |
|
115 | if not filename: | |
116 | return |
|
116 | return | |
117 |
|
117 | |||
118 | r = run_command(self.path, "emacsclient", '-n +%d:%d "%s" 2>nul' % (lineno, columnno, filename), False) |
|
118 | r = run_command(self.path, "emacsclient", '-n +%d:%d "%s" 2>nul' % (lineno, columnno, filename), False) | |
119 | if r != 0: |
|
119 | if r != 0: | |
120 | run_command(self.path, 'runemacs', '--quick -f server-start +%d:%d "%s"' % (lineno, columnno, filename)) |
|
120 | run_command(self.path, 'runemacs', '--quick -f server-start +%d:%d "%s"' % (lineno, columnno, filename)) | |
121 | sleep(self.start_duration) |
|
121 | sleep(self.start_duration) | |
122 | else: |
|
122 | else: | |
123 | sleep(self.wakeup_duration) |
|
123 | sleep(self.wakeup_duration) | |
124 |
|
124 | |||
125 | restore_console_focus() |
|
125 | restore_console_focus() | |
126 |
|
126 | |||
127 |
|
127 | |||
128 | def emacs(path = r"C:\Program Files\emacs\bin", wakeup_duration = 100, start_duration = 2000): |
|
128 | def emacs(path = r"C:\Program Files\emacs\bin", wakeup_duration = 100, start_duration = 2000): | |
129 | synchronize_with_editor = EmacsHook(path, wakeup_duration, start_duration) |
|
129 | synchronize_with_editor = EmacsHook(path, wakeup_duration, start_duration) | |
130 | set_hook(synchronize_with_editor) |
|
130 | set_hook(synchronize_with_editor) | |
131 |
|
131 | |||
132 |
|
132 | |||
133 | class SciteHook: |
|
133 | class SciteHook: | |
134 | def __init__(self, path, wakeup_duration, start_duration): |
|
134 | def __init__(self, path, wakeup_duration, start_duration): | |
135 | self.path = path |
|
135 | self.path = path | |
136 | self.wakeup_duration = wakeup_duration |
|
136 | self.wakeup_duration = wakeup_duration | |
137 | self.start_duration = start_duration |
|
137 | self.start_duration = start_duration | |
138 |
|
138 | |||
139 | def __call__(self, ip, filename, lineno, columnno): |
|
139 | def __call__(self, ip, filename, lineno, columnno): | |
140 | filename = find_filename(filename) |
|
140 | filename = find_filename(filename) | |
141 |
|
141 | |||
142 | if not filename: |
|
142 | if not filename: | |
143 | return |
|
143 | return | |
144 |
|
144 | |||
145 | scites = scitedirector.findWindows() |
|
145 | scites = scitedirector.findWindows() | |
146 | if not scites: |
|
146 | if not scites: | |
147 | run_command(self.path, "scite", '"-open:%s" -goto:%d' % (filename.replace("\\", "/"), lineno)) |
|
147 | run_command(self.path, "scite", '"-open:%s" -goto:%d' % (filename.replace("\\", "/"), lineno)) | |
148 |
|
148 | |||
149 | sleep(self.start_duration) |
|
149 | sleep(self.start_duration) | |
150 | restore_console_focus() |
|
150 | restore_console_focus() | |
151 | else: |
|
151 | else: | |
152 | scite = scites[0] |
|
152 | scite = scites[0] | |
153 | scitedirector.sendCommand(scite, 'open:%s' % filename.replace("\\", "/")) |
|
153 | scitedirector.sendCommand(scite, 'open:%s' % filename.replace("\\", "/")) | |
154 | scitedirector.sendCommand(scite, "goto:%d" % lineno) |
|
154 | scitedirector.sendCommand(scite, "goto:%d" % lineno) | |
155 |
|
155 | |||
156 |
|
156 | |||
157 | def scite(path = r"C:\Program Files\SciTE Source Code Editor", wakeup_duration = 100, start_duration = 500): |
|
157 | def scite(path = r"C:\Program Files\SciTE Source Code Editor", wakeup_duration = 100, start_duration = 500): | |
158 | synchronize_with_editor = SciteHook(path, wakeup_duration, start_duration) |
|
158 | synchronize_with_editor = SciteHook(path, wakeup_duration, start_duration) | |
159 | set_hook(synchronize_with_editor) |
|
159 | set_hook(synchronize_with_editor) | |
160 |
|
160 | |||
161 |
|
161 | |||
162 | class NodePadPlusPlusHook: |
|
162 | class NodePadPlusPlusHook: | |
163 | def __init__(self, path, wakeup_duration): |
|
163 | def __init__(self, path, wakeup_duration): | |
164 | self.path = path |
|
164 | self.path = path | |
165 | self.wakeup_duration = wakeup_duration |
|
165 | self.wakeup_duration = wakeup_duration | |
166 |
|
166 | |||
167 | def __call__(self, ip, filename, lineno, columnno): |
|
167 | def __call__(self, ip, filename, lineno, columnno): | |
168 | filename = find_filename(filename) |
|
168 | filename = find_filename(filename) | |
169 |
|
169 | |||
170 | if not filename: |
|
170 | if not filename: | |
171 | return |
|
171 | return | |
172 |
|
172 | |||
173 | run_command(self.path, "notepad++", '"%s" -n%d' % (filename, lineno)) |
|
173 | run_command(self.path, "notepad++", '"%s" -n%d' % (filename, lineno)) | |
174 |
|
174 | |||
175 | sleep(self.wakeup_duration) |
|
175 | sleep(self.wakeup_duration) | |
176 |
|
176 | |||
177 | restore_console_focus() |
|
177 | restore_console_focus() | |
178 |
|
178 | |||
179 |
|
179 | |||
180 | def notepadplusplus(path = r"C:\Program Files\Notepad++", wakeup_duration = 100): |
|
180 | def notepadplusplus(path = r"C:\Program Files\Notepad++", wakeup_duration = 100): | |
181 | synchronize_with_editor = NodePadPlusPlusHook(path, wakeup_duration) |
|
181 | synchronize_with_editor = NodePadPlusPlusHook(path, wakeup_duration) | |
182 | set_hook(synchronize_with_editor) |
|
182 | set_hook(synchronize_with_editor) | |
183 |
|
183 | |||
184 |
|
184 | |||
185 | class PsPadHook: |
|
185 | class PsPadHook: | |
186 | def __init__(self, path, wakeup_duration): |
|
186 | def __init__(self, path, wakeup_duration): | |
187 | self.path = path |
|
187 | self.path = path | |
188 | self.wakeup_duration = wakeup_duration |
|
188 | self.wakeup_duration = wakeup_duration | |
189 |
|
189 | |||
190 | def __call__(self, ip, filename, lineno, columnno): |
|
190 | def __call__(self, ip, filename, lineno, columnno): | |
191 | filename = find_filename(filename) |
|
191 | filename = find_filename(filename) | |
192 |
|
192 | |||
193 | if not filename: |
|
193 | if not filename: | |
194 | return |
|
194 | return | |
195 |
|
195 | |||
196 | run_command(self.path, "pspad", '"%s" -%d' % (filename, lineno)) |
|
196 | run_command(self.path, "pspad", '"%s" -%d' % (filename, lineno)) | |
197 |
|
197 | |||
198 | sleep(self.wakeup_duration) |
|
198 | sleep(self.wakeup_duration) | |
199 |
|
199 | |||
200 | restore_console_focus() |
|
200 | restore_console_focus() | |
201 |
|
201 | |||
202 |
|
202 | |||
203 | def pspad(path = r"C:\Program Files\PSPad editor", wakeup_duration = 100): |
|
203 | def pspad(path = r"C:\Program Files\PSPad editor", wakeup_duration = 100): | |
204 | synchronize_with_editor = PsPadHook(path, wakeup_duration) |
|
204 | synchronize_with_editor = PsPadHook(path, wakeup_duration) | |
205 | set_hook(synchronize_with_editor) |
|
205 | set_hook(synchronize_with_editor) | |
206 |
|
206 | |||
207 |
|
207 | |||
208 | # This is an example of DDE hook: |
|
208 | # This is an example of DDE hook: | |
209 | class UltraEditHook: |
|
209 | class UltraEditHook: | |
210 | def __init__(self, path, wakeup_duration, start_duration): |
|
210 | def __init__(self, path, wakeup_duration, start_duration): | |
211 | self.path = path |
|
211 | self.path = path | |
212 | self.wakeup_duration = wakeup_duration |
|
212 | self.wakeup_duration = wakeup_duration | |
213 | self.start_duration = start_duration |
|
213 | self.start_duration = start_duration | |
214 |
|
214 | |||
215 | def __call__(self, ip, filename, lineno, columnno): |
|
215 | def __call__(self, ip, filename, lineno, columnno): | |
216 | filename = find_filename(filename) |
|
216 | filename = find_filename(filename) | |
217 |
|
217 | |||
218 | if not filename: |
|
218 | if not filename: | |
219 | return |
|
219 | return | |
220 |
|
220 | |||
221 | server = dde.CreateServer() |
|
221 | server = dde.CreateServer() | |
222 | server.Create("myddeserver") |
|
222 | server.Create("myddeserver") | |
223 | conversation = dde.CreateConversation(server) |
|
223 | conversation = dde.CreateConversation(server) | |
224 | try: |
|
224 | try: | |
225 | conversation.ConnectTo("uedit32", "System") |
|
225 | conversation.ConnectTo("uedit32", "System") | |
226 | conversation.Exec(r'[open("%s/%d"])' % (filename, lineno)) |
|
226 | conversation.Exec(r'[open("%s/%d"])' % (filename, lineno)) | |
227 |
|
227 | |||
228 | sleep(self.wakeup_duration) |
|
228 | sleep(self.wakeup_duration) | |
229 | except: |
|
229 | except: | |
230 | run_command(self.path, 'uedit32', '"%s/%d"' % (filename, lineno)) |
|
230 | run_command(self.path, 'uedit32', '"%s/%d"' % (filename, lineno)) | |
231 |
|
231 | |||
232 | sleep(self.start_duration) |
|
232 | sleep(self.start_duration) | |
233 |
|
233 | |||
234 | server.Shutdown() |
|
234 | server.Shutdown() | |
235 |
|
235 | |||
236 | restore_console_focus() |
|
236 | restore_console_focus() | |
237 |
|
237 | |||
238 |
|
238 | |||
239 | def ultraedit(path = r"C:\Program Files\IDM Computer Solutions\UltraEdit-32", wakeup_duration = 10, start_duration = 2000): |
|
239 | def ultraedit(path = r"C:\Program Files\IDM Computer Solutions\UltraEdit-32", wakeup_duration = 10, start_duration = 2000): | |
240 | synchronize_with_editor = UltraEditHook(path, wakeup_duration, start_duration) |
|
240 | synchronize_with_editor = UltraEditHook(path, wakeup_duration, start_duration) | |
241 | set_hook(synchronize_with_editor) |
|
241 | set_hook(synchronize_with_editor) | |
242 | No newline at end of file |
|
242 |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
General Comments 0
You need to be logged in to leave comments.
Login now