Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(229)

Side by Side Diff: visual_studio/NativeClientVSAddIn/InstallerResources/install.py

Issue 14122017: [VS Addin] Add visual studio 2012 support (Closed) Base URL: https://nativeclient-sdk.googlecode.com/svn/trunk/src
Patch Set: Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be 3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file. 4 # found in the LICENSE file.
5 5
6 """Copies necessary add-in files into place to install the add-in. 6 """Copies necessary add-in files into place to install the add-in.
7 7
8 This script will copy the necessary files for the Visual Studio add-in 8 This script will copy the necessary files for the Visual Studio add-in
9 to where Visual Studio can find them. It assumes the current directory 9 to where Visual Studio can find them. It assumes the current directory
10 contains the necessary files to copy. 10 contains the necessary files to copy.
11 """ 11 """
12 12
13 import create_ppapi_platform 13 import create_ppapi_platform
14 import ctypes 14 import ctypes
15 import os 15 import os
16 import optparse 16 import optparse
17 import platform 17 import platform
18 import shutil 18 import shutil
19 import sys 19 import sys
20 import time 20 import time
21 21
22 NACL32_PLATFORM = 'NaCl32' 22 NACL32_PLATFORM = 'NaCl32'
23 NACL64_PLATFORM = 'NaCl64' 23 NACL64_PLATFORM = 'NaCl64'
24 NACLARM_PLATFORM = 'NaClARM' 24 NACLARM_PLATFORM = 'NaClARM'
25 PNACL_PLATFORM = 'PNaCl' 25 PNACL_PLATFORM = 'PNaCl'
26 NACL_PLATFORM_OLD = 'NaCl' 26 NACL_PLATFORM_OLD = 'NaCl'
27 PEPPER_PLATFORM = 'PPAPI' 27 PEPPER_PLATFORM = 'PPAPI'
28 28
29 DEFAULT_VS_USER_DIRECTORY = os.path.expandvars( 29 DEFAULT_VS_DIRECTORIES = ('%USERPROFILE%\\My Documents\\Visual Studio 2010',
30 '%USERPROFILE%\\My Documents\\Visual Studio 2010') 30 '%USERPROFILE%\\My Documents\\Visual Studio 2012')
31 31
32 SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__)) 32 SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
33 33
34 ADDIN_FILES = ['NativeClientVSAddIn.AddIn', 'NativeClientVSAddIn.dll'] 34 ADDIN_FILES = ['NativeClientVSAddIn.AddIn', 'NativeClientVSAddIn.dll']
35 35
36 options = None
37
38 if sys.version_info < (2, 6, 2):
39 print "\n\nWARNING: Python version 2.6.2 or greater is required. " \
40 "Current version is %s\n\n" % (sys.version_info[:3],)
41
36 42
37 class InstallError(Exception): 43 class InstallError(Exception):
38 """Error class for this installer indicating a fatal but expected error.""" 44 """Error class for this installer indicating a fatal but expected error."""
39 pass 45 pass
40 46
41 47
42 def UninstallDirectory(directory): 48 def UninstallDirectory(directory):
43 if os.path.exists(directory): 49 if os.path.exists(directory):
44 shutil.rmtree(directory) 50 shutil.rmtree(directory)
45 print 'Removed: %s' % (directory) 51 print 'Removed: %s' % (directory)
46 52
47 53
48 def UninstallFile(file_path): 54 def UninstallFile(file_path):
49 if os.path.exists(file_path): 55 if os.path.exists(file_path):
50 if not os.access(file_path, os.W_OK): 56 if not os.access(file_path, os.W_OK):
51 raise InstallError("File is marked as read-only: %s.\n" 57 raise InstallError("File is marked as read-only: %s.\n"
52 "Please correct and try again." % file_path) 58 "Please correct and try again." % file_path)
53 os.remove(file_path) 59 os.remove(file_path)
54 print 'Removed: %s' % (file_path) 60 print 'Removed: %s' % (file_path)
55 61
56 62
57 def Uninstall(platform_dirs, addin_dir):
58 for dirname in platform_dirs:
59 UninstallDirectory(dirname)
60 for file_name in ADDIN_FILES:
61 UninstallFile(os.path.join(addin_dir, file_name))
62
63 63
64 def CheckForRunningProgams(): 64 def CheckForRunningProgams():
65 tasklist = os.popen('tasklist.exe').readlines() 65 tasklist = os.popen('tasklist.exe').readlines()
66 tasklist = [l for l in tasklist if 'MSBuild' in l or 'devenv' in l] 66 tasklist = [l for l in tasklist if 'MSBuild' in l or 'devenv' in l]
67 return tasklist 67 return tasklist
68 68
69 69
70 def Ask(question): 70 def Ask(question):
71 while True: 71 while True:
72 print '\n' 72 print '\n'
73 print question 73 print question
74 print "Continue? ((Yes))/((No))" 74 print "Continue? ((Yes))/((No))"
75 answer = raw_input().strip().lower() 75 answer = raw_input().strip().lower()
76 if answer in ('y', 'yes'): 76 if answer in ('y', 'yes'):
77 return True 77 return True
78 if answer in ('n', 'no'): 78 if answer in ('n', 'no'):
79 return False 79 return False
80 80
81 81
82 def UninstallAddin(vsuser_path):
83 addin_dir = os.path.join(vsuser_path, 'Addins')
84 for file_name in ADDIN_FILES:
85 UninstallFile(os.path.join(addin_dir, file_name))
86
87
88 def InstallAddin(vsuser_path):
89 vsuser_path = os.path.expandvars(vsuser_path)
90
91 vsname = os.path.basename(vsuser_path)
92 if '2012' in vsname:
93 vs_version = '2012'
94 elif '2010' in vsname:
95 vs_version = '2010'
96 else:
97 raise InstallError("Unable to determine valid VS version (2010 or 2012) "
98 "from path: %s" % vsuser_path)
99
100 # Ensure install directories exist.
101 if not os.path.exists(vsuser_path):
102 raise InstallError("Could not find user Visual Studio directory: %s" % (
103 vsuser_path))
104
105 addin_dir = os.path.join(vsuser_path, 'Addins')
106
107 if not os.path.exists(addin_dir):
108 os.makedirs(addin_dir)
109
110 print "\nInstalling Add-in: %s" % vsuser_path
111 # Copy the necessary files into place.
112 for file_name in ADDIN_FILES:
113 shutil.copy(os.path.join(SCRIPT_DIR, vs_version, file_name), addin_dir)
114
115 print "Add-in installed."
116
117
118 def InstallMSBuildPlatforms(platform_root):
119 if not os.path.exists(platform_root):
120 raise InstallError("Could not find path: %s" % platform_root)
121
122 if not os.access(platform_root, os.W_OK):
123 # Admin is needed to write to the default platform directory.
124 if ctypes.windll.shell32.IsUserAnAdmin() != 1:
125 raise InstallError("Not running as administrator. The install script "
126 "needs write access to protected Visual Studio "
127 "directories.")
128 raise InstallError("install script needs write access to: %s"
129 % platform_root)
130
131 nacl_dir_32 = os.path.join(platform_root, NACL32_PLATFORM)
132 nacl_dir_64 = os.path.join(platform_root, NACL64_PLATFORM)
133 nacl_dir_arm = os.path.join(platform_root, NACLARM_PLATFORM)
134 pnacl_dir = os.path.join(platform_root, PNACL_PLATFORM)
135 nacl_dir_old = os.path.join(platform_root, NACL_PLATFORM_OLD)
136 nacl_common = os.path.join(os.path.dirname(platform_root), 'NaCl')
137 all_dirs = (nacl_dir_32, nacl_dir_64, nacl_dir_arm,
138 pnacl_dir, nacl_dir_old, nacl_common)
139
140 # Remove existing installation.
141 if any(os.path.exists(d) for d in all_dirs):
142 # If not forced then ask user permission.
143 if not options.force:
144 if not Ask("Warning: Pre-existing add-in installation "
145 "will be overwritten."):
146 raise InstallError('User did not allow overwrite of existing install.')
147 print "Removing existing install..."
148 UninstallMSBuild(platform_root)
149
150 print "\nInstalling MSBuild components..."
151
152 shutil.copytree(os.path.join(SCRIPT_DIR, 'NaCl'), nacl_common)
153 print "NaCl common resources installed."
154
155 shutil.copytree(os.path.join(SCRIPT_DIR, NACL32_PLATFORM), nacl_dir_32)
156 print "%s platform installed." % NACL32_PLATFORM
157
158 shutil.copytree(os.path.join(SCRIPT_DIR, NACL64_PLATFORM), nacl_dir_64)
159 print "%s platform installed." % NACL64_PLATFORM
160
161 shutil.copytree(os.path.join(SCRIPT_DIR, NACLARM_PLATFORM), nacl_dir_arm)
162 print "%s platform installed." % NACLARM_PLATFORM
163
164 shutil.copytree(os.path.join(SCRIPT_DIR, PNACL_PLATFORM), pnacl_dir)
165 print "PNaCl platform installed."
166
167
168 def InstallMSBuild():
169
170 # Ask user before installing PPAPI template.
171 if options.install_ppapi is None:
172 ppapi_answer = Ask("Set up configuration to enable Pepper development "
173 "with Visual Studio?\n"
174 "((Yes)) - I want to create and copy relevant files into a "
175 "Pepper subdirectory\n"
176 "((No)) - I am not interested or will set up the configuration later")
177 if ppapi_answer:
178 options.install_ppapi = True
179 print "Confirmed installer will include PPAPI platform."
180 else:
181 options.install_ppapi = False
182 print "Will not install PPAPI platform during installation."
183
184 if not os.path.exists(options.msbuild_path):
185 raise InstallError("Could not find MS Build directory: %s" % (
186 options.msbuild_path))
187
188 root_2010 = os.path.join(options.msbuild_path,
189 'Microsoft.Cpp', 'v4.0', 'Platforms')
190 InstallMSBuildPlatforms(root_2010)
191
192 root_2012 = os.path.join(options.msbuild_path,
193 'Microsoft.Cpp', 'v4.0', 'V110', 'Platforms')
194 InstallMSBuildPlatforms(root_2012)
195
196 if options.install_ppapi:
197 pepper_dir = os.path.join(root_2010, PEPPER_PLATFORM)
198 pepper_dir2 = os.path.join(root_2012, PEPPER_PLATFORM)
199 UninstallDirectory(pepper_dir)
200 UninstallDirectory(pepper_dir2)
201 create_ppapi_platform.CreatePPAPI(options.msbuild_path)
202 print "PPAPI platform installed."
203
204
205 def UninstallMSBuild(platform_root):
206 nacl_dir_32 = os.path.join(platform_root, NACL32_PLATFORM)
binji 2013/05/25 00:02:55 make getting these paths into a function?
207 nacl_dir_64 = os.path.join(platform_root, NACL64_PLATFORM)
208 nacl_dir_arm = os.path.join(platform_root, NACLARM_PLATFORM)
209 pnacl_dir = os.path.join(platform_root, PNACL_PLATFORM)
210 nacl_dir_old = os.path.join(platform_root, NACL_PLATFORM_OLD)
211 nacl_common = os.path.join(os.path.dirname(platform_root), 'NaCl')
212 remove_dirs = (nacl_dir_32, nacl_dir_64, nacl_dir_arm,
213 pnacl_dir, nacl_dir_old, nacl_common)
214 for dirname in remove_dirs:
215 UninstallDirectory(dirname)
216
217
218 def Uninstall():
219 root_2010 = os.path.join(options.msbuild_path,
220 'Microsoft.Cpp', 'v4.0', 'Platforms')
221 root_2012 = os.path.join(options.msbuild_path,
222 'Microsoft.Cpp', 'v4.0', 'V110', 'Platforms')
223 UninstallMSBuild(root_2010)
224 UninstallMSBuild(root_2012)
225
226 for vsuser_path in options.vsuser_path:
227 UninstallAddin(vsuser_path)
228
229
82 def main(): 230 def main():
231 global options
83 parser = optparse.OptionParser(usage='Usage: %prog [options]') 232 parser = optparse.OptionParser(usage='Usage: %prog [options]')
84 parser.add_option('-b', '--msbuild-path', dest='msbuild_path', 233 parser.add_option('-b', '--msbuild-path',
85 metavar='PATH', help='Provide the path to the MSBuild directory') 234 metavar='PATH', help='Provide the path to the MSBuild directory')
86 parser.add_option('-a', '--vsuser-path', dest='vsuser_path', 235 parser.add_option('-a', '--vsuser-path',
87 default=DEFAULT_VS_USER_DIRECTORY, metavar='PATH', 236 default=DEFAULT_VS_DIRECTORIES, metavar='PATH', action='append',
88 help='Provide the path to the Visual Studio user directory') 237 help='Provide the path to the Visual Studio user directory')
89 parser.add_option('-f', '--force', action="store_true", 238 parser.add_option('-f', '--force', action="store_true",
90 default=False, help='Force an overwrite of existing files') 239 default=False, help='Force an overwrite of existing files')
91 parser.add_option('-p', '--ppapi', action="store_true", dest='install_ppapi', 240 parser.add_option('-p', '--ppapi', action="store_true", dest='install_ppapi',
92 help='Install PPAPI template without asking.') 241 help='Install PPAPI template without asking.')
93 parser.add_option('-n', '--no-ppapi', action="store_false", 242 parser.add_option('-n', '--no-ppapi', action="store_false",
94 dest='install_ppapi', help='Do not install PPAPI template and do not ask') 243 dest='install_ppapi', help='Do not install PPAPI template and do not ask')
95 parser.add_option('-u', '--uninstall', action="store_true", 244 parser.add_option('-u', '--uninstall', action="store_true",
96 dest='uninstall', help='Remove the add-in.') 245 help='Remove the add-in.')
97 (options, args) = parser.parse_args() 246 options, args = parser.parse_args()
98 247
99 print "*************************************************" 248 print "*********************************************"
100 print "Native-Client Visual Studio 2010 Add-in Installer" 249 print "Native-Client Visual Studio Add-in Installer"
101 print "*************************************************\n" 250 print "*********************************************\n"
102 251
103 if platform.system() != 'Windows': 252 if platform.system() != 'Windows':
104 raise InstallError('Must install to Windows system') 253 raise InstallError('Must install to Windows system')
105 254
106 if not options.msbuild_path: 255 if not options.msbuild_path:
107 # Find the x86 program files folder. If we are uing a 64-bit version of 256 # Find the x86 program files folder. If we are uing a 64-bit version of
108 # python.exe then ProgramFiles(x86). If we using a 32-bit python then 257 # python.exe then ProgramFiles(x86). If we using a 32-bit python then
109 # ProgramFiles will always be set to point the x86 program files even 258 # ProgramFiles will always be set to point the x86 program files even
110 # under W0W64. 259 # under W0W64.
111 if 'ProgramFiles(x86)' in os.environ: 260 if 'ProgramFiles(x86)' in os.environ:
112 options.msbuild_path = os.path.expandvars('%ProgramFiles(x86)%\\MSBuild') 261 options.msbuild_path = os.path.expandvars('%ProgramFiles(x86)%\\MSBuild')
113 else: 262 else:
114 options.msbuild_path = os.path.expandvars('%ProgramFiles%\\MSBuild') 263 options.msbuild_path = os.path.expandvars('%ProgramFiles%\\MSBuild')
115 264
116
117 if CheckForRunningProgams(): 265 if CheckForRunningProgams():
118 if not options.force: 266 if not options.force:
119 print "Visual Studio and MSBuild must be closed during installation" 267 print "Visual Studio and MSBuild must be closed during installation"
120 if not Ask("Kill all instances now?"): 268 if not Ask("Kill all instances now?"):
121 raise InstallError('Please close all Visual Studio or MSBuild ' 269 raise InstallError('Please close all Visual Studio or MSBuild '
122 'instances before installing') 270 'instances before installing')
123 os.system("taskkill.exe /IM MSBuild.exe /f") 271 os.system("taskkill.exe /IM MSBuild.exe /f")
124 os.system("taskkill.exe /IM devenv.exe") 272 os.system("taskkill.exe /IM devenv.exe")
125 if CheckForRunningProgams(): 273 if CheckForRunningProgams():
126 for i in xrange(10): 274 for i in xrange(10):
127 if not CheckForRunningProgams(): 275 if not CheckForRunningProgams():
128 break 276 break
129 time.sleep(1) 277 time.sleep(1)
130 if not CheckForRunningProgams(): 278 if not CheckForRunningProgams():
131 break 279 break
132 if i == 5: 280 if i == 5:
133 print "Trying taskkill with /f" 281 print "Trying taskkill with /f"
134 os.system("taskkill.exe /IM devenv.exe /f") 282 os.system("taskkill.exe /IM devenv.exe /f")
135 if CheckForRunningProgams(): 283 if CheckForRunningProgams():
136 raise InstallError('Failed to kill Visual Studio and MSBuild instances') 284 raise InstallError('Failed to kill Visual Studio and MSBuild instances')
137 285
138 if sys.version_info < (2, 6, 2):
139 print "\n\nWARNING: Only python version 2.6.2 or greater is supported. " \
140 "Current version is %s\n\n" % (sys.version_info[:3],)
141
142 # Ensure install directories exist.
143 if not os.path.exists(options.vsuser_path):
144 raise InstallError("Could not find user Visual Studio directory: %s" % (
145 options.vsuser_path))
146 if not os.path.exists(options.msbuild_path):
147 raise InstallError("Could not find MS Build directory: %s" % (
148 options.msbuild_path))
149
150 addin_dir = os.path.join(options.vsuser_path, 'Addins')
151 platform_root = os.path.join(options.msbuild_path,
152 'Microsoft.Cpp', 'v4.0', 'Platforms')
153 if not os.path.exists(platform_root):
154 raise InstallError("Could not find path: %s" % platform_root)
155
156 if not os.access(platform_root, os.W_OK):
157 # Admin is needed to write to the default platform directory.
158 if ctypes.windll.shell32.IsUserAnAdmin() != 1:
159 raise InstallError("Not running as administrator. The install script "
160 "needs write access to protected Visual Studio "
161 "directories.")
162 raise InstallError("install script needs write access to: %s"
163 % platform_root)
164
165 nacl_dir_32 = os.path.join(platform_root, NACL32_PLATFORM)
166 nacl_dir_64 = os.path.join(platform_root, NACL64_PLATFORM)
167 nacl_dir_arm = os.path.join(platform_root, NACLARM_PLATFORM)
168 pnacl_dir = os.path.join(platform_root, PNACL_PLATFORM)
169 nacl_dir_old = os.path.join(platform_root, NACL_PLATFORM_OLD)
170 nacl_common = os.path.join(os.path.dirname(platform_root), 'NaCl')
171 pepper_dir = os.path.join(platform_root, PEPPER_PLATFORM)
172 remove_dirs = (nacl_dir_32, nacl_dir_64, nacl_dir_arm,
173 pnacl_dir, nacl_dir_old, pepper_dir,
174 nacl_common)
175 # If uninstalling then redirect to uninstall program.
176 if options.uninstall:
177 Uninstall(remove_dirs, addin_dir)
178 print "\nUninstall complete!\n"
179 sys.exit(0)
180
181 if not os.path.exists(platform_root):
182 raise InstallError("Could not find path: %s" % platform_root)
183 if not os.path.exists(addin_dir):
184 os.makedirs(addin_dir)
185
186 # Ensure environment variables are set. 286 # Ensure environment variables are set.
187 if not options.force: 287 if not options.force:
188 nacl_sdk_root = os.getenv('NACL_SDK_ROOT', None) 288 nacl_sdk_root = os.getenv('NACL_SDK_ROOT', None)
189 chrome_path = os.getenv('CHROME_PATH', None) 289 chrome_path = os.getenv('CHROME_PATH', None)
190 if nacl_sdk_root is None: 290 if nacl_sdk_root is None:
191 raise InstallError('Environment Variable NACL_SDK_ROOT is not set') 291 raise InstallError('Environment Variable NACL_SDK_ROOT is not set')
192 if chrome_path is None: 292 if chrome_path is None:
193 raise InstallError('Environment Variable CHROME_PATH is not set') 293 raise InstallError('Environment Variable CHROME_PATH is not set')
194 294
195 # Remove existing installation. 295 # If uninstalling then redirect to uninstall program.
196 if any(os.path.exists(d) for d in remove_dirs): 296 if options.uninstall:
197 # If not forced then ask user permission. 297 Uninstall()
198 if not options.force: 298 print "\nUninstall complete!\n"
199 if not Ask("Warning: Pre-existing add-in installation " 299 return 0
200 "will be overwritten."):
201 raise InstallError('User did not allow overwrite of existing install.')
202 print "Removing existing install..."
203 Uninstall(remove_dirs, addin_dir)
204
205 # Ask user before installing PPAPI template.
206 if options.install_ppapi is None:
207 ppapi_answer = Ask("Set up configuration to enable Pepper development "
208 "with Visual Studio?\n"
209 "((Yes)) - I want to create and copy relevant files into a "
210 "Pepper subdirectory\n"
211 "((No)) - I am not interested or will set up the configuration later")
212 if ppapi_answer:
213 options.install_ppapi = True
214 print "Confirmed installer will include PPAPI platform."
215 else:
216 options.install_ppapi = False
217 print "Will not install PPAPI platform during installation."
218
219 print "\nBegin installing components..."
220 300
221 try: 301 try:
222 # Copy the necessary files into place. 302 InstallMSBuild()
223 for file_name in ADDIN_FILES:
224 shutil.copy(os.path.join(SCRIPT_DIR, file_name), addin_dir)
225 print "Add-in installed."
226 303
227 shutil.copytree(os.path.join(SCRIPT_DIR, 'NaCl'), nacl_common) 304 for vsuser_path in options.vsuser_path:
228 print "NaCl common resources installed." 305 InstallAddin(vsuser_path)
229
230 shutil.copytree(os.path.join(SCRIPT_DIR, NACL32_PLATFORM), nacl_dir_32)
231 print "%s platform installed." % NACL32_PLATFORM
232
233 shutil.copytree(os.path.join(SCRIPT_DIR, NACL64_PLATFORM), nacl_dir_64)
234 print "%s platform installed." % NACL64_PLATFORM
235
236 shutil.copytree(os.path.join(SCRIPT_DIR, NACLARM_PLATFORM), nacl_dir_arm)
237 print "%s platform installed." % NACLARM_PLATFORM
238
239 shutil.copytree(os.path.join(SCRIPT_DIR, PNACL_PLATFORM), pnacl_dir)
240 print "PNaCl platform installed."
241
242 if options.install_ppapi:
243 create_ppapi_platform.CreatePPAPI(options.msbuild_path)
244 print "PPAPI platform installed."
245 except: 306 except:
246 print "\nException occured! Rolling back install...\n" 307 print "\nException occured! Rolling back install...\n"
247 Uninstall(remove_dirs, addin_dir) 308 Uninstall()
248 raise 309 raise
249 else: 310 else:
250 print "\nInstallation complete!\n" 311 print "\nInstallation complete!\n"
251 312
252 return 0 313 return 0
253 314
254 if __name__ == '__main__': 315 if __name__ == '__main__':
255 rtn = 1 316 rtn = 1
256 try: 317 try:
257 rtn = main() 318 rtn = main()
258 except InstallError as e: 319 except InstallError as e:
259 print 320 print
260 print e 321 print e
261 except shutil.Error as e: 322 except shutil.Error as e:
262 print "Error while copying file. Please ensure file is not in use." 323 print "Error while copying file. Please ensure file is not in use."
263 print e 324 print e
264 except WindowsError as e: 325 except WindowsError as e:
265 if e.winerror == 5: 326 if e.winerror == 5:
266 print e 327 print e
267 print("The install script failed to write to the files mentioned above") 328 print("The install script failed to write to the files mentioned above")
268 if ctypes.windll.shell32.IsUserAnAdmin() != 1: 329 if ctypes.windll.shell32.IsUserAnAdmin() != 1:
269 print("Please try running as administrator.") 330 print("Please try running as administrator.")
270 else: 331 else:
271 print("Please check for any running programs that might " 332 print("Please check for any running programs that might "
272 "have them locked.") 333 "have them locked.")
273 else: 334 else:
274 raise 335 raise
275 sys.exit(rtn) 336 sys.exit(rtn)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698