3
3
# file included in this repository.
4
4
5
5
import os
6
- import re
7
6
import sys
8
7
import pprint
9
8
import json
10
9
10
+ import sgtk
11
11
from sgtk .platform import SoftwareLauncher , SoftwareVersion , LaunchInformation
12
12
13
13
@@ -33,6 +33,10 @@ class EngineLauncher(SoftwareLauncher):
33
33
"darwin" : [
34
34
"/Users/Shared/Epic Games/UE_{version}/Engine/Binaries/Mac/UE{major}Editor.app"
35
35
],
36
+ "win32" : [
37
+ "C:/Program Files/Epic Games/UE_{version}/Engine/Binaries/Win64/UE{major}Editor.exe" ,
38
+ "C:/Program Files/Epic Games/UE_{version}EA/Engine/Binaries/Win64/UnrealEditor.exe"
39
+ ],
36
40
}
37
41
38
42
@property
@@ -137,17 +141,18 @@ def _find_software(self):
137
141
:returns: List of :class:`SoftwareVersion` instances.
138
142
"""
139
143
self .logger .info ("Finding Unreal Engine executables" )
144
+ sw_versions = []
145
+
146
+ # Get the executable templates for the current OS
147
+ executable_templates = None
148
+ if sgtk .util .is_macos ():
149
+ executable_templates = self .EXECUTABLE_TEMPLATES .get ("darwin" )
150
+ elif sgtk .util .is_windows ():
151
+ executable_templates = self .EXECUTABLE_TEMPLATES .get ("win32" )
152
+ elif sgtk .util .is_linux ():
153
+ executable_templates = self .EXECUTABLE_TEMPLATES .get ("linux" )
140
154
141
- if sys .platform == "win32" :
142
- # Determine a list of paths to search for Unreal Editor executables based on the windows registry
143
- search_paths = self ._get_installation_paths_from_registry ()
144
- sw_versions = self ._get_software_from_search_paths (search_paths , "Unreal Engine" )
145
- # Also look for custom developer builds
146
- search_paths = self ._get_development_builds_paths_from_registry ()
147
- sw_versions = sw_versions + self ._get_software_from_search_paths (search_paths , "Unreal Engine (Dev Build)" )
148
- elif sys .platform == "darwin" :
149
- executable_templates = self .EXECUTABLE_TEMPLATES ["darwin" ]
150
- sw_versions = []
155
+ if executable_templates :
151
156
for executable_template in executable_templates :
152
157
self .logger .debug ("Processing template %s." , executable_template )
153
158
executable_matches = self ._glob_and_match (
@@ -158,6 +163,13 @@ def _find_software(self):
158
163
# extract the matched keys form the key_dict (default to None if
159
164
# not included)
160
165
executable_version = key_dict .get ("version" )
166
+ details = self ._get_unreal_version_details (executable_path )
167
+ if details and all (x in details for x in ["MajorVersion" , "MinorVersion" , "PatchVersion" ]):
168
+ executable_version = "%s.%s.%s" % (
169
+ details ["MajorVersion" ],
170
+ details ["MinorVersion" ],
171
+ details ["PatchVersion" ],
172
+ )
161
173
sw_versions .append (
162
174
SoftwareVersion (
163
175
executable_version ,
@@ -171,155 +183,19 @@ def _find_software(self):
171
183
172
184
return sw_versions
173
185
174
- def _get_software_from_search_paths (self , search_paths , display_name ):
175
- """
176
- :returns: List of :class:`SoftwareVersion` instances.
177
- """
178
- sw_versions = []
179
- for search_path in search_paths :
180
- # Construct the expected executable name for this path.
181
- # If it exists, add it to the list of exec_paths to check.
182
- exec_path , executable_version = self ._find_exec_and_version (search_path )
183
-
184
- if exec_path :
185
- # Create a SoftwareVersion using the information from executable
186
- # path(s) found in default locations.
187
- self .logger .debug ("Creating SoftwareVersion for executable '%s'." % exec_path )
188
- sw_versions .append (SoftwareVersion (
189
- executable_version ,
190
- display_name ,
191
- exec_path ,
192
- os .path .join (self .disk_location , "icon_256.png" )
193
- ))
194
-
195
- return sw_versions
196
-
197
- def _find_exec_and_version (self , root_path ):
198
- """
199
- Check if there's an Unreal executable in the given path.
200
-
201
- :returns: A tuple with the path to executable and its version as a string
202
- or `None`, ``None`.
203
- """
204
- # With the given root path, check if there's an Unreal executable in it and its version
205
- binary_folder = "Engine\\ Binaries\\ Win64"
206
- executable_filename = "UE4Editor.exe"
207
- version_filename = "UE4Editor.version"
208
-
209
- # Construct the expected executable name for this root path.
210
- exec_path = os .path .join (root_path , binary_folder , executable_filename )
211
- exec_path = os .path .normpath (exec_path )
212
- versionfile_path = os .path .join (root_path , binary_folder , version_filename )
213
- self .logger .debug ("Checking installation path %s" % exec_path )
214
-
215
- if os .path .exists (exec_path ):
216
- self .logger .debug ("Found executable in installation path %s" % exec_path )
217
-
218
- if os .path .exists (versionfile_path ):
219
- self .logger .debug ("Version file found in installation path %s" % versionfile_path )
220
- else :
221
- self .logger .debug ("Version file not found in installation path %s" % versionfile_path )
222
- versionfile_path = None
223
- else :
224
- return None , None
225
-
226
- executable_version = "0"
227
- # First, try to find the executable version from the version file
228
- if versionfile_path is not None :
229
- self .logger .debug ("Parsing version from file '%s'." % versionfile_path )
230
- version_data = json .load (open (versionfile_path ))
231
- executable_version = str (version_data ["MajorVersion" ]) + "." + str (version_data ["MinorVersion" ]) + "." + str (version_data ["PatchVersion" ])
232
- else :
233
- # As a fallback method:
234
- # Check to see if the version number can be parsed from the path name.
235
- # It's expected to find a subdir named "ue_x.yy", where x is the major, and yy the minor version
236
- self .logger .debug ("Parsing version from path '%s'." % exec_path )
237
- path_sw_versions = [p .lower () for p in exec_path .split (os .path .sep )
238
- if re .match ("ue_[0-9]+[.0-9]*$" , p .lower ()) is not None
239
- ]
240
- if path_sw_versions :
241
- # Use this sub dir to determine the version of the executable
242
- executable_version = path_sw_versions [0 ].replace ("ue_" , "" )
243
- self .logger .debug (
244
- "Resolved version '%s' from executable '%s'." %
245
- (executable_version , exec_path )
246
- )
247
-
248
- return exec_path , executable_version
249
-
250
- def _get_installation_paths_from_registry (self ):
251
- """
252
- Query Windows registry for Unreal installations.
253
-
254
- :returns: List of paths where Unreal is installed
255
- """
256
- try :
257
- import _winreg
258
- except ImportError :
259
- import winreg as _winreg
260
- self .logger .debug ("Querying windows registry for key HKEY_LOCAL_MACHINE\\ SOFTWARE\\ EpicGames\\ Unreal Engine" )
261
-
262
- base_key_name = "SOFTWARE\\ EpicGames\\ Unreal Engine"
263
- sub_key_names = []
264
-
265
- # find all subkeys in key HKEY_LOCAL_MACHINE\SOFTWARE\EpicGames\Unreal Engine
266
- try :
267
- key = _winreg .OpenKey (_winreg .HKEY_LOCAL_MACHINE , base_key_name )
268
- sub_key_count = _winreg .QueryInfoKey (key )[0 ]
269
- i = 0
270
- while i < sub_key_count :
271
- sub_key_names .append (_winreg .EnumKey (key , i ))
272
- i += 1
273
- _winreg .CloseKey (key )
274
- except WindowsError :
275
- self .logger .error ("error opening key %s" % base_key_name )
276
-
277
- install_paths = []
278
- # Query the value "InstalledDirectory" on all subkeys.
279
- try :
280
- for name in sub_key_names :
281
- key_name = base_key_name + "\\ " + name
282
- key = _winreg .OpenKey (_winreg .HKEY_LOCAL_MACHINE , key_name )
283
- try :
284
- install_paths .append (_winreg .QueryValueEx (key , "InstalledDirectory" )[0 ])
285
- self .logger .debug ("Found InstalledDirectory value for key %s" % key_name )
286
- except WindowsError :
287
- self .logger .debug ("value InstalledDirectory not found for key %s, skipping key" % key_name )
288
- _winreg .CloseKey (key )
289
- except WindowsError :
290
- self .logger .error ("error opening key %s" % key_name )
291
-
292
- return install_paths
293
-
294
- def _get_development_builds_paths_from_registry (self ):
186
+ def _get_unreal_version_details (self , executable_path ):
295
187
"""
296
- Query Windows registry for Unreal custom developer builds .
188
+ Return version details for the given Unreal executable, if any .
297
189
298
- :returns: List of paths where Unreal executable is found
190
+ :param str executable_path: Full path to an Unreal Editor executable.
191
+ :returns: A dictionary with version details retrieved from the side car file for the
192
+ given Unreal Editor executable, or ``None``.
299
193
"""
300
- try :
301
- import _winreg
302
- except ImportError :
303
- import winreg as _winreg
304
-
305
- self .logger .debug ("Querying windows registry for key HKEY_CURRENT_USER\\ SOFTWARE\\ Epic Games\\ Unreal Engine\\ Builds" )
306
-
307
- base_key_name = "SOFTWARE\\ Epic Games\\ Unreal Engine\\ Builds"
308
- install_paths = []
309
-
310
- # find all values in key HKEY_CURRENT_USER\SOFTWARE\Epic Games\Unreal Engine\Builds
311
- try :
312
- key = _winreg .OpenKey (_winreg .HKEY_CURRENT_USER , base_key_name )
313
- values_count = _winreg .QueryInfoKey (key )[1 ]
314
- self .logger .debug ("Found %d values." % values_count )
315
- i = 0
316
- while i < values_count :
317
- value = _winreg .EnumValue (key , i )
318
- install_paths .append (value [1 ])
319
- self .logger .debug ("Found Unreal executable path '%s'." % value [1 ])
320
- i += 1
321
- _winreg .CloseKey (key )
322
- except WindowsError :
323
- self .logger .error ("error opening key %s" % base_key_name )
324
-
325
- return install_paths
194
+ version_details = None
195
+ path , exe = os .path .split (executable_path )
196
+ version_file = "%s.version" % os .path .splitext (exe )[0 ]
197
+ full_path = os .path .join (path , version_file )
198
+ if os .path .exists (full_path ):
199
+ with open (full_path ) as pf :
200
+ version_details = json .load (pf )
201
+ return version_details
0 commit comments