Kiln » TortoiseHg » TortoiseHg
Clone URL:  
Pushed to one repository · View In Graph Contained in 0.8, 0.8.1, and 0.8.2

merge with Steve

Changeset ec93aef2b071

Parents 1372217a0c1d

Parents 0ca931587f68

by Adrian Buehlmann

Changes to 15 files · Browse files at ec93aef2b071 Showing diff from parent 1372217a0c1d 0ca931587f68 Diff from another changeset...

Change 1 of 1 Show Entire File contrib/​tracelog.py Stacked
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
@@ -1,142 +0,0 @@
-# -# A PyGtk-based Python Trace Collector window -# -# Copyright (C) 2007 TK Soh <teekaysoh@gmail.com> -# - -import pygtk -pygtk.require("2.0") -import gtk -import gobject -import pango -import threading -import Queue -import win32trace -import time - -try: - from hggtk.hglib import toutf -except ImportError: - import locale - _encoding = locale.getpreferredencoding() - def toutf(s): - return s.decode(_encoding, 'replace').encode('utf-8') - -class TraceLog(): - def __init__(self): - self.window = gtk.Window(gtk.WINDOW_TOPLEVEL) - self.window.set_title("Python Trace Collector") - - # construct window - self.window.set_default_size(700, 400) - self.main_area = gtk.VBox() - self.window.add(self.main_area) - - # mimic standard dialog widgets - self.action_area = gtk.HBox() - self.main_area.pack_end(self.action_area, False, False, 5) - sep = gtk.HSeparator() - self.main_area.pack_end(sep, False, False, 0) - self.vbox = gtk.VBox() - self.main_area.pack_end(self.vbox) - - # add python trace ouput window - scrolledwindow = gtk.ScrolledWindow() - scrolledwindow.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) - self.textview = gtk.TextView(buffer=None) - self.textview.set_editable(False) - self.textview.modify_font(pango.FontDescription("Monospace")) - scrolledwindow.add(self.textview) - self.textview.set_editable(False) - self.textbuffer = self.textview.get_buffer() - self.vbox.pack_start(scrolledwindow, True, True) - self.vbox.show_all() - - # add buttons - self._button_quit = gtk.Button("Quit") - self._button_quit.connect('clicked', self._on_ok_clicked) - self.action_area.pack_end(self._button_quit, False, False, 5) - - self._button_clear = gtk.Button("Clear") - self._button_clear.connect('clicked', self._on_clear_clicked) - self.action_area.pack_end(self._button_clear, False, False, 5) - - # add assorted window event handlers - self.window.connect('map_event', self._on_window_map_event) - self.window.connect('delete_event', self._on_window_close_clicked) - - def _on_ok_clicked(self, button): - self._stop_read_thread() - gtk.main_quit() - - def _on_clear_clicked(self, button): - self.write("", False) - - def _on_window_close_clicked(self, event, param): - self._stop_read_thread() - gtk.main_quit() - - def _on_window_map_event(self, event, param): - self._begin_trace() - - def _begin_trace(self): - self.queue = Queue.Queue() - win32trace.InitRead() - self.write("Collecting Python Trace Output...\n") - gobject.timeout_add(10, self._process_queue) - self._start_read_thread() - - def _start_read_thread(self): - self._read_trace = True - self.thread1 = threading.Thread(target=self._do_read_trace) - self.thread1.start() - - def _stop_read_thread(self): - self._read_trace = False - - # wait for worker thread to to fix Unhandled exception in thread - self.thread1.join() - - def _process_queue(self): - """ - Handle all the messages currently in the queue (if any). - """ - while self.queue.qsize(): - try: - msg = self.queue.get(0) - ts = '[%s] ' % time.strftime('%c') - for line in msg.splitlines(True): - self.write(ts + line) - except Queue.Empty: - pass - - return True - - def _do_read_trace(self): - """ - print buffer collected in win32trace - """ - while self._read_trace: - msg = win32trace.read() - if msg: - self.queue.put(msg) - - def write(self, msg, append=True): - msg = toutf(msg) - if append: - enditer = self.textbuffer.get_end_iter() - self.textbuffer.insert(enditer, msg) - else: - self.textbuffer.set_text(msg) - - def main(self): - self.window.show_all() - gtk.main() - -def run(): - dlg = TraceLog() - dlg.main() - -if __name__ == "__main__": - run() -
Change 1 of 1 Show Entire File contrib/​win32/​__paths__.py Stacked
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
@@ -0,0 +1,27 @@
+""" +__paths__.py + Copyright (C) 2009 Steve Borho <steve@borho.org> + +This software may be used and distributed according to the terms +of the GNU General Public License, incorporated herein by reference. +""" + +# This version of __paths__.py is used in the binary installer +# distributions of TortoiseHg on Windows. Since we no longer need to +# worry about Python shell extensions, we can use the path of the +# current executable to find our package data. + +import os +import win32api, win32process + +proc = win32api.GetCurrentProcess() +try: + # This will fail on windows < NT + procpath = win32process.GetModuleFileNameEx(proc, 0) +except: + procpath = win32api.GetModuleFileName(0) + +bin_path = os.path.dirname(procpath) +license_path = os.path.join(bin_path, 'COPYING.txt') +locale_path = os.path.join(bin_path, 'locale') +icon_path = os.path.join(bin_path, 'icons')
 
4
5
6
7
 
8
9
10
11
 
12
13
14
15
16
17
 
18
19
20
 
36
37
38
39
 
40
41
42
43
44
45
 
46
47
48
 
49
50
51
 
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
 
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
 
202
203
204
 
212
213
214
 
 
 
4
5
6
 
7
8
9
10
 
11
12
13
14
15
16
 
17
18
19
20
 
36
37
38
 
39
40
41
42
43
44
 
45
46
47
48
49
50
51
52
 
71
72
73
 
74
75
76
77
78
 
79
80
81
 
82
83
84
 
171
172
173
 
 
174
 
175
176
177
178
179
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
180
181
182
183
 
191
192
193
194
195
@@ -4,17 +4,17 @@
 [Setup]  AppCopyright=Copyright 2005-2009 Matt Mackall and others  AppName=TortoiseHg -AppVerName=TortoiseHg-0.7 +AppVerName=TortoiseHg-0.8  InfoAfterFile=contrib/win32/postinstall.txt  LicenseFile=COPYING.txt  ShowLanguageDialog=yes -AppPublisher=TK Soh and others +AppPublisher=Steve Borho and others  AppPublisherURL=http://bitbucket.org/tortoisehg/stable/  AppSupportURL=http://bitbucket.org/tortoisehg/stable/  AppUpdatesURL=http://bitbucket.org/tortoisehg/stable/  AppID=TortoiseHg  AppContact=teekaysoh@gmail.com -OutputBaseFilename=TortoiseHg-0.7 +OutputBaseFilename=TortoiseHg-0.8  DefaultDirName={pf}\TortoiseHg  SourceDir=..\..  VersionInfoDescription=Mercurial distributed SCM @@ -36,16 +36,17 @@
   [Files]  Source: contrib\mercurial.el; DestDir: {app}/contrib -Source: contrib\vim\*.*; DestDir: {app}/contrib/Vim +Source: contrib\vim\*.*; DestDir: {app}/contrib/vim  Source: contrib\zsh_completion; DestDir: {app}/contrib  Source: contrib\hgk; DestDir: {app}/contrib  Source: contrib\win32\ReadMe.html; DestDir: {app}; Flags: isreadme  Source: {app}\Mercurial.ini; DestDir: {app}\backup; Flags: external skipifsourcedoesntexist uninsneveruninstall  Source: contrib\win32\mercurial.ini; DestDir: {app}; DestName: Mercurial.ini; AfterInstall: FileExpandString('{app}\Mercurial.ini') -Source: ..\stable.snap; DestDir: {app}; DestName: ReleaseNotes.txt +Source: ReleaseNotes.txt; DestDir: {app}; DestName: ReleaseNotes.txt  Source: ..\contrib\*.exe; DestDir: {app}; Flags: ignoreversion restartreplace uninsrestartdelete  Source: ..\contrib\TortoiseOverlays\*.*; DestDir: {app}/TortoiseOverlays;  Source: dist\*.exe; DestDir: {app}; Flags: ignoreversion restartreplace uninsrestartdelete +Source: win32\shellext\THgShell.dll; DestDir: {app}; Flags: ignoreversion restartreplace uninsrestartdelete  Source: dist\*.dll; DestDir: {app}; Flags: ignoreversion restartreplace uninsrestartdelete  Source: dist\*.pyd; DestDir: {app}; Flags: ignoreversion restartreplace uninsrestartdelete  Source: dist\library.zip; DestDir: {app} @@ -70,17 +71,14 @@
 Name: {group}\TortoiseHg Web Site; Filename: {app}\TortoiseHg.url  Name: {group}\Mercurial Web Site; Filename: {app}\Mercurial.url  Name: {group}\Mercurial Command Reference; Filename: {app}\docs\hg.1.html -Name: {group}\Python Trace Collector; Filename: {app}\tracelog.exe  Name: {group}\Uninstall TortoiseHg; Filename: {uninstallexe}    [Run]  Filename: {app}\add_path.exe; Parameters: {app}; StatusMsg: Adding the installation path to the search path...  Filename: msiexec.exe; Parameters: "/i ""{app}\TortoiseOverlays\TortoiseOverlays-1.0.4.11886-win32.msi"" /qn /norestart ALLUSERS=1"; StatusMsg: Installing TortoiseOverlays.dll ... -Filename: regsvr32.exe; Parameters: "/s ""{app}\tortoisehg.dll"""; StatusMsg: Installing shell extension...    [UninstallRun]  Filename: {app}\add_path.exe; Parameters: /del {app} -Filename: regsvr32.exe; Parameters: "/s /u ""{app}\tortoisehg.dll"""    [UninstallDelete]  Type: files; Name: {app}\Mercurial.url @@ -173,32 +171,13 @@
 function InitializeSetup(): Boolean;  var   ThgSwReg: String; - CRLF: String; - msg: String;  begin - CRLF := chr(10) + chr(13);   Result := True;     {abort installation if TortoiseHg 0.4 or earlier is installed}   if RegQueryStringValue(HKLM, 'Software\TortoiseHg', '', ThgSwReg) then   begin - IsUpgrade := True; - {gpyfm was unbundled after 0.4, so it's a good guess} - if (FileExists(ThgSwReg + '\gpyfm.exe')) then - begin - msg := 'TortoiseHg Setup Error:' + CRLF + CRLF + - 'The version of TortoiseHg installed is too old to upgrade in place.' + CRLF + - 'You must uninstall it before installing this version.' + CRLF + CRLF + - 'Please uninstall the existing version, then run the installer again ' + - 'to continue.'; - MsgBox(msg, mbError, MB_OK); - Result := False; {quit and abort installation} - end else begin - msg := 'Your current site-wide Mercurial.ini will be copied into' + CRLF + - ThgSwReg + '\backup' + CRLF + - 'After install you may merge changes back into the new Mercurial.ini' - MsgBox(msg, mbInformation, MB_OK); - end; + IsUpgrade := True;   end;  end;   @@ -212,3 +191,5 @@
  Result := False;   end;  end; + +#include "registry.iss"
Change 1 of 1 Show Entire File contrib/​win32/​registry.iss Stacked
renamed from win32/shellext/registry.iss
 
3
4
5
 
 
6
7
8
 
3
4
5
6
7
8
9
10
@@ -3,6 +3,8 @@
 ; register TortoiseHg config info  Root: HKLM; Subkey: Software\TortoiseHgShell; Flags: uninsdeletekey  Root: HKLM; Subkey: Software\TortoiseHgShell; ValueType: string; ValueName: ; ValueData: {app} +Root: HKLM; Subkey: Software\TortoiseHg; Flags: uninsdeletekey +Root: HKLM; Subkey: Software\TortoiseHg; ValueType: string; ValueName: ; ValueData: {app}    ; Icon handler COM controls  Root: HKCR; Subkey: CLSID\{{B456DBA0-7BF4-478c-937A-05130C2C212E}; Flags: uninsdeletekey
 
1
2
3
4
 
5
6
7
 
1
2
3
 
4
5
6
7
@@ -1,7 +1,7 @@
 [py2exe]  excludes=pywin, pywin.dialogs, pywin.dialogs.list, PyQt, PyQt4.QtCode, PyQt4.QtGui  includes=cairo, pango, pangocairo, atk, gobject, dbhash -packages=email, hgext, hgext.convert, encodings, hggtk, hggtk.vis, hggtk.iniparse, tortoise +packages=email, hgext, hgext.convert, encodings, hggtk, hggtk.logview, thgutil, thgutil.iniparse    # Disabled for 0.7 release  #dll_excludes=iconv.dll, intl.dll, libatk-1.0-0.dll, libgdk_pixbuf-2.0-0.dll, libgdk-win32-2.0-0.dll, libglib-2.0-0.dll, libgmodule-2.0-0.dll, libgobject-2.0-0.dll, libgthread-2.0-0.dll, libgtk-win32-2.0-0.dll, libpango-1.0-0.dll, libpangowin32-1.0-0.dll, libcairo-2.dll, libglade-2.0-0.dll, libpangocairo-1.0-0.dll, libpangoft2-1.0-0.dll
 
92
93
94
95
96
97
98
99
100
101
102
103
104
 
142
143
144
145
 
 
 
 
 
 
 
 
 
 
 
146
147
 
148
149
150
 
174
175
176
177
 
 
178
179
180
 
185
186
187
188
189
 
 
190
191
192
 
92
93
94
 
 
 
 
 
95
 
96
97
98
 
136
137
138
 
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
 
179
180
181
 
182
183
184
185
186
 
191
192
193
 
 
194
195
196
197
198
@@ -92,13 +92,7 @@
  except ImportError:   pass   - extra['windows'] = [ - {'script':'contrib/tracelog.py', - 'icon_resources':[(1, 'icons/tortoise/python.ico')]} - ] - extra['com_server'] = ['tortoisehg']   extra['console'] = ['hg', 'hgtk'] -  except ImportError:   pass   @@ -142,9 +136,20 @@
  self.mkpath(modir)   self.make_file([pofile], mofile, spawn, (cmd,))   self.distribution.data_files.append((join('mercurial', modir), - [mofile])) + [mofile])) + +class build_shellext(build): + description = "Build TortoiseHg shell extensions" + + def run(self): + cwd = os.getcwd() + os.chdir("win32/shellext") + os.environ["DEBUG"] = "1" + os.system("mingw32-make") + os.chdir(cwd)    build.sub_commands.append(('build_mo', None)) +build.sub_commands.append(('build_shellext', None))    Distribution.pure = 0  Distribution.global_options.append(('pure', None, "use pure (slow) Python " @@ -174,7 +179,8 @@
   cmdclass = {'install_data': install_package_data,   'build_mo': build_mo, - 'build_py': hg_build_py} + 'build_py': hg_build_py, + 'build_shellext' : build_shellext}    ext_modules=[   Extension('mercurial.base85', ['mercurial/base85.c']), @@ -185,8 +191,8 @@
  ]    packages = ['mercurial', 'mercurial.hgweb', 'hgext', 'hgext.convert', - 'hgext.highlight', 'hgext.zeroconf', 'hggtk', 'hggtk.vis', - 'hggtk.iniparse', 'tortoise'] + 'hgext.highlight', 'hgext.zeroconf', 'hggtk', + 'hggtk.logview', 'thgutil', 'thgutil.iniparse']    try:   import msvcrt
Change 1 of 1 Show Entire File hggtk/​hgthread.py Stacked
 
177
178
179
180
 
181
182
183
 
177
178
179
 
180
181
182
183
@@ -177,7 +177,7 @@
  self.ret = ret or 0   if self.postfunc:   self.postfunc(ret) - except RepoError, e: + except hglib.RepoError, e:   self.ui.write_err(str(e))   except util.Abort, e:   self.ui.write_err(str(e))
Change 1 of 2 Show Entire File hggtk/​hgtk.py Stacked
 
22
23
24
25
 
26
27
28
 
526
527
528
529
530
531
532
 
533
534
535
 
22
23
24
 
25
26
27
28
 
526
527
528
 
529
530
 
531
532
533
534
@@ -22,7 +22,7 @@
 from mercurial import hg, util, fancyopts, cmdutil, extensions    from thgutil.i18n import _ -from thgutil import hglib, paths +from thgutil import hglib, paths, shlib    nonrepo_commands = 'userconfig clone debugcomplete init about help version'   @@ -526,10 +526,9 @@
   def version(ui, **opts):   """output version and copyright information""" - import hggtk.shlib   ui.write(_('TortoiseHg Dialogs (version %s), '   'Mercurial (version %s)\n') % - (hggtk.shlib.version(), util.version())) + (shlib.version(), util.version()))   if not ui.quiet:   ui.write(shortlicense)  
Change 1 of 1 Show Entire File setup.py Stacked
 
46
47
48
49
50
 
 
51
52
53
 
46
47
48
 
 
49
50
51
52
53
@@ -46,8 +46,8 @@
  # the dist directory created by py2exe.   # also needed is the GTK's share/themes (as dist/share/themes),   # for dialogs to display in MS-Windows XP theme. - "includes" : includes - "optimize" : 1, + "includes" : includes, + "optimize" : 1   }   }  
Change 1 of 1 Show Entire File thgutil/​i18n.py Stacked
 
10
11
12
13
14
 
 
 
10
11
12
 
 
13
14
@@ -10,5 +10,5 @@
 from gettext import gettext as _  import paths   -gettext.bindtextdomain("thg", paths.get_locale_path()) -gettext.textdomain("thg") +gettext.bindtextdomain("tortoisehg", paths.get_locale_path()) +gettext.textdomain("tortoisehg")
 
6
7
8
9
 
10
11
12
 
15
16
17
18
19
20
21
 
22
23
24
 
25
26
27
28
29
30
31
32
33
 
 
 
 
 
34
35
36
 
38
39
40
41
42
43
44
 
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
 
 
66
67
68
 
69
70
71
 
136
137
138
139
 
140
141
142
 
144
145
146
147
 
148
149
 
6
7
8
 
9
10
11
12
 
15
16
17
 
 
 
 
18
19
20
 
21
22
23
24
 
25
26
27
28
 
29
30
31
32
33
34
35
36
 
38
39
40
 
 
 
 
41
42
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
43
44
45
46
 
47
48
49
50
 
115
116
117
 
118
119
120
121
 
123
124
125
 
126
127
128
@@ -6,7 +6,7 @@
 #include <stdio.h>  #include <vector>   -void CShellExt::DoHgProc(const std::string &cmd, bool nofiles, bool nogui) +void CShellExt::DoHgProc(const std::string &cmd)  {   std::string dir = GetTHgProgRoot();   TDEBUG_TRACE("DoHgProc: THG root = " << dir); @@ -15,22 +15,22 @@
  TDEBUG_TRACE("DoHgProc: THG root is empty");   return;   } - std::string hgcmd = Quote(dir + "\\hgproc.bat") + " --command " + cmd; - - if (nogui) - hgcmd += " --nogui"; + std::string hgcmd = Quote(dir + "\\hgtk.exe") + " " + cmd;     std::string cwd; - std::vector<std::string> filelist; + std::string filelist;   if (!myFolder.empty())   {   cwd = myFolder; - filelist.push_back(GetHgRepoRoot(myFolder));   }   else if (!myFiles.empty())   {   cwd = IsDirectory(myFiles[0])? myFiles[0] : DirName(myFiles[0]); - filelist = myFiles; + for( DWORD i = 0 ; i < myFiles.size() ; i++ ) + { + filelist += myFiles[i]; + filelist += "\n"; + }   }   else   { @@ -38,34 +38,13 @@
  return;   }   - hgcmd += " --cwd " + Quote(cwd); - hgcmd += " --root " + Quote(GetHgRepoRoot(cwd)); - - if (!nofiles) + if ( !filelist.empty() )   { - std::string tempfile = GetTemporaryFile(); - SECURITY_ATTRIBUTES sa; - memset(&sa, 0, sizeof(sa)); - sa.nLength = sizeof(sa); - sa.bInheritHandle = TRUE; - - TDEBUG_TRACE("DoHgProc: temp file = " << tempfile); - HANDLE tempfileHandle = CreateFileA(tempfile.c_str(), GENERIC_WRITE, - FILE_SHARE_READ, &sa, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); - - for (int i=0; i<filelist.size(); i++) - { - DWORD dwWritten; - TDEBUG_TRACE("DoHgProc: temp file adding " << filelist[i]); - WriteFile(tempfileHandle, filelist[i].c_str(), - static_cast<DWORD>(filelist[i].size()), &dwWritten, 0); - } - CloseHandle(tempfileHandle); - hgcmd += " --listfile " + Quote(tempfile); - hgcmd += " --deletelistfile" ; + TDEBUG_TRACE("filelist: " << filelist); + hgcmd += " --listfile -";   }   - LaunchCommand(hgcmd); + LaunchCommand(hgcmd, cwd, filelist);  }    STDMETHODIMP @@ -136,7 +115,7 @@
 CShellExt::CM_Userconf(HWND hParent, LPCSTR pszWorkingDir, LPCSTR pszCmd,   LPCSTR pszParam, int iShowCmd)  { - DoHgProc("config", true); + DoHgProc("userconfig");   return NOERROR;  }   @@ -144,6 +123,6 @@
 CShellExt::CM_Repoconf(HWND hParent, LPCSTR pszWorkingDir, LPCSTR pszCmd,   LPCSTR pszParam, int iShowCmd)  { - DoHgProc("config"); + DoHgProc("repoconfig");   return NOERROR;  }
 
67
68
69
70
 
71
72
73
 
67
68
69
 
70
71
72
73
@@ -67,7 +67,7 @@
  std::string myFolder;     protected: - void CShellExt::DoHgProc(const std::string &, bool=false, bool=false); + void CShellExt::DoHgProc(const std::string &);     public:   // context menu actions
 
19
20
21
22
 
23
24
25
 
30
31
32
33
 
 
19
20
21
 
22
23
24
25
 
30
31
32
 
33
@@ -19,7 +19,7 @@
 VersionInfoCompany=TK Soh and others  InternalCompressLevel=max  SolidCompression=true -;SetupIconFile=icons\tortoise\hg.ico +;SetupIconFile=icons\hg.ico  AllowNoIcons=true  DefaultGroupName=TortoiseHg  PrivilegesRequired=poweruser @@ -30,4 +30,4 @@
 Source: THgShell.dll; DestDir: {app}; Flags: ignoreversion  Source: ..\..\icons\*; DestDir: {app}\icons ; Flags: ignoreversion recursesubdirs createallsubdirs   -#include "registry.iss" +#include "../../contrib/win32/registry.iss"
 
91
92
93
94
 
95
96
97
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
98
99
100
101
102
103
 
 
 
 
104
105
 
 
106
107
108
109
 
 
 
 
110
111
 
112
113
114
 
 
 
 
 
 
 
 
 
 
 
115
116
117
 
177
178
179
180
 
181
182
183
 
209
210
211
 
 
91
92
93
 
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
 
 
 
126
127
128
129
130
 
131
132
133
134
 
 
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
 
218
219
220
 
221
222
223
224
 
250
251
252
253
@@ -91,27 +91,68 @@
 // Note: if the command is a batch file and the [full] path to the  // batch contains spaces, the path must be double-quoted.  // (see http://www.encocoservices.com/createprocess.html) -bool LaunchCommand(const std::string& command, bool minimized) +bool LaunchCommand(const std::string& command, const std::string& cwd, const std::string& filelist)  {   TDEBUG_TRACE("LaunchCommand: " << command);   PROCESS_INFORMATION processInfo; + memset(&processInfo, 0, sizeof(processInfo)); + + HANDLE hChildStd_IN_Rd = NULL; + HANDLE hChildStd_IN_Wr = NULL; + + SECURITY_ATTRIBUTES saAttr; + // Set the bInheritHandle flag so pipe handles are inherited. + saAttr.nLength = sizeof(SECURITY_ATTRIBUTES); + saAttr.bInheritHandle = TRUE; + saAttr.lpSecurityDescriptor = NULL; + + // Create a pipe for the child process's STDIN. + if (!CreatePipe(&hChildStd_IN_Rd, &hChildStd_IN_Wr, &saAttr, 0)) + { + TDEBUG_TRACE("LaunchCommand: unable to create stdin pipe"); + return false; + } + + // Ensure the write handle to the pipe for STDIN is not inherited. + if (!SetHandleInformation(hChildStd_IN_Wr, HANDLE_FLAG_INHERIT, 0) ) + { + TDEBUG_TRACE("LaunchCommand: unable to clear stdin write handle"); + return false; + } +   STARTUPINFOA startupInfo;   memset(&startupInfo, 0, sizeof(startupInfo));   startupInfo.cb = sizeof(startupInfo); - startupInfo.dwFlags = minimized ? STARTF_USESHOWWINDOW : 0; - startupInfo.wShowWindow = SW_SHOWMINIMIZED; - int res = CreateProcessA(0, + startupInfo.hStdInput = hChildStd_IN_Rd; + startupInfo.dwFlags |= STARTF_USESTDHANDLES; + + int res = CreateProcessA(NULL, // No module name, use command line   const_cast<char*>(command.c_str()), - 0, 0, + NULL, // Process handle not inherited + NULL, // Thread handle not inherited   FALSE,   CREATE_NO_WINDOW, - 0, 0, &startupInfo, &processInfo); - TDEBUG_TRACE("LaunchCommand: res = " << res); + NULL, // use parent's environment + const_cast<char*>(cwd.c_str()), + &startupInfo, + &processInfo);   if (res == 0)   { + TDEBUG_TRACE("LaunchCommand: failed to launch");   return false;   }   + if( !filelist.empty() ) + { + DWORD dwWritten; + WriteFile(hChildStd_IN_Wr, filelist.c_str(), filelist.size(), &dwWritten, NULL); + } + + if ( !CloseHandle(hChildStd_IN_Wr) ) + { + TDEBUG_TRACE("LaunchCommand: Unable to close process stdin"); + } +   CloseHandle(processInfo.hProcess);   CloseHandle(processInfo.hThread);   return true; @@ -177,7 +218,7 @@
  return NULL;   }   - std::string iconpath = thgdir + "\\icons\\tortoise\\" + iconname; + std::string iconpath = thgdir + "\\icons\\" + iconname;   TDEBUG_TRACE(" GetTortoiseIcon: loading " + iconpath);   HICON h = (HICON) LoadImageA(0, iconpath.c_str(), IMAGE_ICON,   16, 16, LR_LOADFROMFILE); @@ -209,3 +250,4 @@
 {   return !GetHgRepoRoot(path).empty();  } +
 
31
32
33
34
 
35
36
37
 
31
32
33
 
34
35
36
37
@@ -31,7 +31,7 @@
 bool IsDirectory(const std::string&);  std::string DirName(const std::string&);  std::string BaseName(const std::string&); -bool LaunchCommand(const std::string& command, bool minimized=false); +bool LaunchCommand(const std::string& command, const std::string& cwd, const std::string& filelist);  HICON GetTortoiseIcon(const std::string & iconname);  std::string GetHgRepoRoot(const std::string& path);  bool IsHgRepo(const std::string& path);