/// <summary>
		/// Returns Hook names as needed by the platform
		/// (e.g. can be overridden with custom executables or scripts)
		/// </summary>
		/// <param name="Hook">Hook type</param>
		protected virtual string GetHookExecutableName(SDKHookType Hook)
		{
			if (Hook == SDKHookType.Uninstall)
			{
				return "unsetup.bat";
			}

			return "setup.bat";
		}
		/// <summary>
		/// Runs install/uninstall hooks for SDK
		/// </summary>
		/// <param name="PlatformSDKRoot">absolute path to platform SDK root</param>
		/// <param name="SDKVersionString">version string to run for (can be empty!)</param>
		/// <param name="Hook">which one of hooks to run</param>
		/// <param name="bHookCanBeNonExistent">whether a non-existing hook means failure</param>
		/// <returns>true if succeeded</returns>
		protected virtual bool RunAutoSDKHooks(string PlatformSDKRoot, string SDKVersionString, SDKHookType Hook, bool bHookCanBeNonExistent = true)
		{
			if (!IsAutoSDKSafe())
			{
				Console.ForegroundColor = ConsoleColor.Red;
				LogAutoSDK(GetSDKTargetPlatformName() + " attempted to run SDK hook which could have damaged manual SDK install!");
				Console.ResetColor();

				return false;
			}
			if (SDKVersionString != "")
			{
				string SDKDirectory = Path.Combine(PlatformSDKRoot, SDKVersionString);
				string HookExe = Path.Combine(SDKDirectory, GetHookExecutableName(Hook));

				if (File.Exists(HookExe))
				{
					LogAutoSDK("Running {0} hook {1}", Hook, HookExe);

					// run it
					Process HookProcess = new Process();
					HookProcess.StartInfo.WorkingDirectory = SDKDirectory;
					HookProcess.StartInfo.FileName = HookExe;
					HookProcess.StartInfo.Arguments = "";
					HookProcess.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;

					// seems to break the build machines?
					//HookProcess.StartInfo.UseShellExecute = false;
					//HookProcess.StartInfo.RedirectStandardOutput = true;
					//HookProcess.StartInfo.RedirectStandardError = true;					

					using (ScopedTimer HookTimer = new ScopedTimer("Time to run hook: ", bShouldLogInfo ? LogEventType.Log : LogEventType.Verbose))
					{
						//installers may require administrator access to succeed. so run as an admmin.
						HookProcess.StartInfo.Verb = "runas";
						HookProcess.Start();
						HookProcess.WaitForExit();
					}

					//LogAutoSDK(HookProcess.StandardOutput.ReadToEnd());
					//LogAutoSDK(HookProcess.StandardError.ReadToEnd());
					if (HookProcess.ExitCode != 0)
					{
						LogAutoSDK("Hook exited uncleanly (returned {0}), considering it failed.", HookProcess.ExitCode);
						return false;
					}

					return true;
				}
				else
				{
					LogAutoSDK("File {0} does not exist", HookExe);
				}
			}
			else
			{
				LogAutoSDK("Version string is blank for {0}. Can't determine {1} hook.", PlatformSDKRoot, Hook.ToString());
			}

			return bHookCanBeNonExistent;
		}
        /// <summary>
        /// Runs install/uninstall hooks for SDK
        /// </summary>
        /// <param name="OutputLevel">The output level for diagnostic messages</param>
        /// <param name="PlatformSDKRoot">absolute path to platform SDK root</param>
        /// <param name="SDKVersionString">version string to run for (can be empty!)</param>
        /// <param name="Hook">which one of hooks to run</param>
        /// <param name="bHookCanBeNonExistent">whether a non-existing hook means failure</param>
        /// <returns>true if succeeded</returns>
        protected virtual bool RunAutoSDKHooks(SDKOutputLevel OutputLevel, string PlatformSDKRoot, string SDKVersionString, SDKHookType Hook, bool bHookCanBeNonExistent = true)
        {
            if (!IsAutoSDKSafe())
            {
                Console.ForegroundColor = ConsoleColor.Red;
                LogAutoSDK(OutputLevel, GetSDKTargetPlatformName() + " attempted to run SDK hook which could have damaged manual SDK install!");
                Console.ResetColor();

                return(false);
            }
            if (SDKVersionString != "")
            {
                string SDKDirectory = Path.Combine(PlatformSDKRoot, SDKVersionString);
                string HookExe      = Path.Combine(SDKDirectory, GetHookExecutableName(Hook));

                if (File.Exists(HookExe))
                {
                    LogAutoSDK(OutputLevel, "Running {0} hook {1}", Hook, HookExe);

                    // run it
                    Process HookProcess = new Process();
                    HookProcess.StartInfo.WorkingDirectory = SDKDirectory;
                    HookProcess.StartInfo.FileName         = HookExe;
                    HookProcess.StartInfo.Arguments        = "";
                    HookProcess.StartInfo.WindowStyle      = ProcessWindowStyle.Hidden;

                    // seems to break the build machines?
                    //HookProcess.StartInfo.UseShellExecute = false;
                    //HookProcess.StartInfo.RedirectStandardOutput = true;
                    //HookProcess.StartInfo.RedirectStandardError = true;

                    using (ScopedTimer HookTimer = new ScopedTimer("Time to run hook: ", (OutputLevel >= SDKOutputLevel.Minimal) ? LogEventType.Log : LogEventType.Verbose))
                    {
                        //installers may require administrator access to succeed. so run as an admmin.
                        HookProcess.StartInfo.Verb = "runas";
                        HookProcess.Start();
                        HookProcess.WaitForExit();
                    }

                    //LogAutoSDK(HookProcess.StandardOutput.ReadToEnd());
                    //LogAutoSDK(HookProcess.StandardError.ReadToEnd());
                    if (HookProcess.ExitCode != 0)
                    {
                        LogAutoSDK(OutputLevel, "Hook exited uncleanly (returned {0}), considering it failed.", HookProcess.ExitCode);
                        return(false);
                    }

                    return(true);
                }
                else
                {
                    LogAutoSDK(OutputLevel, "File {0} does not exist", HookExe);
                }
            }
            else
            {
                LogAutoSDK(OutputLevel, "Version string is blank for {0}. Can't determine {1} hook.", PlatformSDKRoot, Hook.ToString());
            }

            return(bHookCanBeNonExistent);
        }