from .UnrealManagerException import UnrealManagerException from .UnrealManagerBase import UnrealManagerBase from .Utility import Utility import glob, os, platform # The (_)winreg module is named differently between Python 2.x and Python 3.x try: import winreg except: import _winreg as winreg class UnrealManagerWindows(UnrealManagerBase): def getPlatformIdentifier(self): if platform.machine().endswith('64'): return 'Win64' else: return 'Win32' def getBuildScript(self): return self.getEngineRoot() + '\\Engine\\Build\\BatchFiles\\Build.bat' def getGenerateScript(self): # Under Windows, GenerateProjectFiles.bat only exists for source builds of the engine batFile = self.getEngineRoot() + '\\Engine\\Build\\BatchFiles\\GenerateProjectFiles.bat' if os.path.exists(batFile): return batFile # For versions of the engine installed using the launcher, we need to query the shell integration # to determine the location of the Unreal Version Selector executable, which generates VS project files try: key = winreg.OpenKey(winreg.HKEY_CLASSES_ROOT, 'Unreal.ProjectFile\\shell\\rungenproj\\command') if key: command = winreg.QueryValue(key, None) if len(command) > 0: # Write the command to run UnrealVersionSelector.exe to our own batch file customBat = os.path.join(self._customBatchScriptDir(), 'GenerateProjectFiles.bat') Utility.writeFile(customBat, command.replace('"%1"', '%1') + '\r\n') return customBat except: pass raise UnrealManagerException('could not detect the location of GenerateProjectFiles.bat or UnrealVersionSelector.exe.\nThis typically indicates that .uproject files are not correctly associated with UE4.') def getRunUATScript(self): return self.getEngineRoot() + '\\Engine\\Build\\BatchFiles\\RunUAT.bat' def generateProjectFiles(self, dir=os.getcwd(), args=[]): # If we are using our custom batch file, use the appropriate arguments genScript = self.getGenerateScript() projectFile = self.getProjectDescriptor(dir) print(projectFile) if '.ue4\\GenerateProjectFiles.bat' in genScript: Utility.run([genScript, projectFile], raiseOnError=True) else: super(UnrealManagerWindows, self).generateProjectFiles(dir, args) def _detectEngineRoot(self): # Under Windows, the default installation path is `%PROGRAMFILES%\Epic Games` baseDir = os.environ['PROGRAMFILES'] + '\\Epic Games\\' prefix = 'UE_4.' versionDirs = glob.glob(baseDir + prefix + '*') if len(versionDirs) > 0: installedVersions = sorted([int(os.path.basename(d).replace(prefix, '')) for d in versionDirs]) newestVersion = max(installedVersions) return baseDir + prefix + str(newestVersion) # Could not auto-detect the Unreal Engine location raise UnrealManagerException('could not detect the location of the latest installed Unreal Engine 4 version') def _editorPathSuffix(self, cmdVersion): return '-Cmd.exe' if cmdVersion == True else '.exe' def _runDotNetApplication(self, exeFile, args = []): return Utility.capture([exeFile] + args, raiseOnError=True) def _buildDotNetProject(self, projectFile): msbuildExe = self._getMsbuildLocation() return Utility.capture([msbuildExe, '/property:Configuration=Release', '/property:TargetFrameworkVersion=v4.5', projectFile], raiseOnError=True) # "Private" methods def _customBatchScriptDir(self): # If the script directory doesn't already exist, attempt to create it scriptDir = os.path.join(os.environ['HOMEDRIVE'] + os.environ['HOMEPATH'], '.ue4') try: os.makedirs(scriptDir) except: pass return scriptDir def _getMsbuildLocation(self): # `GetMSBuildPath.bat` sets the path to an environment variable instead of printing it, # so we need to wrap it in another script to print the value so it can be captured msbuildBat = os.path.join(os.path.dirname(self.getBuildScript()), 'GetMSBuildPath.bat') customBat = os.path.join(self._customBatchScriptDir(), 'PrintMSBuildPath.bat') Utility.writeFile(customBat, '@echo off\r\ncall "' + msbuildBat + '"\r\necho %MSBUILD_EXE%') return Utility.capture([customBat], raiseOnError=True).stdout.strip().strip('"')