Skip to content

Commit

Permalink
Merge pull request #23 from dafzor/fixlaunch
Browse files Browse the repository at this point in the history
Fixlaunch
  • Loading branch information
dafzor authored Jun 25, 2018
2 parents f99e4fa + bc54f78 commit 2bb5b30
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 120 deletions.
114 changes: 22 additions & 92 deletions bnetlauncher/BnetClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,9 @@ public static List<BnetGame> Games
new BnetGame("Pro", "Overwatch", "ow"),
new BnetGame("S2", "Starcraft 2", "sc2"),
new BnetGame("Hero", "Heroes of the Storm", "hots"),
new BnetGame("SCR", "Starcraft Remastered", "scr"),
new BnetGame("DST2", "Destiny 2", "dst2")
new BnetGame("S1", "Starcraft Remastered", "scr"),
new BnetGame("DST2", "Destiny 2", "dst2"),
new BnetGame("VIPR", "Call of Duty: Black Ops 4", "codbo4")
};
}
}
Expand Down Expand Up @@ -105,6 +106,8 @@ public static int HelperProcessCount
/// <summary>
/// Returns the installation folder of the battle.net client using the installation path
/// stored in the uninstall entry.
///
/// TODO: Make sure this is the best way to get the installation path now that it's so important.
/// </summary>
/// <returns>The path to the battle.net client folder without trailing slash</returns>
public static string InstallLocation
Expand Down Expand Up @@ -133,11 +136,23 @@ public static string InstallLocation
{
Shared.Logger("Exception while trying to retrieve battle.net client path:");
Shared.Logger(ex.ToString());
return "";
return String.Empty;
}
}
}

/// <summary>
/// Returns InstallLocation combined with battle.net.exe which seems to always the be main exe for the client now
/// even when beta is installed.
/// </summary>
public static string ClientExe
{
get
{
return Path.Combine(InstallLocation, "battle.net.exe");
}
}

/// <summary>
/// Returns the process Id of the currently running Battle.Net instance.
/// </summary>
Expand Down Expand Up @@ -265,10 +280,10 @@ public static bool WaitUntilReady(int timeout = 120)
/// the battle.net client.</param>
public static bool Launch(string bnet_command = "")
{
var bnet_cmd = "battlenet://" + bnet_command;
var bnet_cmd = string.Format("--exec=\"launch {0}\"", bnet_command);
try
{
Process.Start(bnet_cmd);
Process.Start(ClientExe, bnet_cmd);
}
catch (Exception ex)
{
Expand All @@ -284,8 +299,8 @@ public static bool Launch(string bnet_command = "")
/// <returns>The result of the WaitUntilReady call.</returns>
public static bool Start()
{
// Calling Launch without any game parameter can serve to open the client.
Launch();
// Just launches the client which is required for it to interpret launch commands properly.
Process.Start(ClientExe);

// If battle.net client is starting fresh it will use a intermediary Battle.net process to start, we need
// to make sure we don't get that process id but the actual client's process id. To work around it we wait
Expand All @@ -297,90 +312,5 @@ public static bool Start()
//
return WaitUntilReady();
}

/// <summary>
/// Attempts to verify if the battle.net client URI handler is present in the registry.
/// This however can't check if it's actually functional.
/// </summary>
/// <returns>true if everything seems to be in order, false otherwise.</returns>
public static bool IsUriHandlerPresent()
{
try
{
// Does the battle.net URI registry key exists?
using (var battlenet_regkey = Registry.ClassesRoot.OpenSubKey(@"Blizzard.URI.Battlenet\shell\open\command"))
{
if (battlenet_regkey == null)
{
Shared.Logger("battlenet URI subkey doesn't exist");
return false;
}

// does it actually properly link to the battle.net exe?
var valid_value = String.Format("\"{0}\\Battle.net.exe\" \"%1\"", InstallLocation);
var actual_value = battlenet_regkey.GetValue("").ToString();

if (valid_value.ToLower() == actual_value.ToLower())
{
Shared.Logger("battlenet URI handler appears to present and correct");
return true;
}
}
}
catch (Exception ex)
{
Shared.Logger("Exception when attempting to determine if battle.net URI is present:");
Shared.Logger(ex.ToString());
}
return false;
}

/// <summary>
/// Attempts to repair battle.net URI handler by creating a reg file with the missing entries
/// and prompting the user to add them to their registry. This method was chosen to avoid elevating
/// bnetlauncher itself to administrator rights.
/// </summary>
/// <returns>Returns if the repair was completed or not</returns>
public static bool RepairUriHandler()
{
var reg_content = String.Join("\n",
@"Windows Registry Editor Version 5.00",
@"[HKEY_CLASSES_ROOT\Blizzard.URI.Battlenet]",
@"@= ""URL:Blizzard Battle.net Protocol""",
@"""URL Protocol"" = ""{0}""",
@"[HKEY_CLASSES_ROOT\Blizzard.URI.Battlenet\DefaultIcon]",
@"@=""\""{0}\"",0""",
@"[HKEY_CLASSES_ROOT\Blizzard.URI.Battlenet\shell]",
@"[HKEY_CLASSES_ROOT\Blizzard.URI.Battlenet\shell\open]",
@"[HKEY_CLASSES_ROOT\Blizzard.URI.Battlenet\shell\open\command]",
@"@= ""\""{0}\"" \""%1\""""");

// Creates the battle.net path and replaces \ with \\ since that's what's used in registry files
var bnet_path = Path.Combine(InstallLocation, "Battle.net.exe").Replace("\\", "\\\\");
var reg_file = Path.Combine(Shared.DataPath, "battlenet_uri_fix.reg");

// create reg file with valid entries
using (var file = new StreamWriter(reg_file))
{
file.Write(String.Format(reg_content, bnet_path));
}

// Call regedit with the silent switch to merge reg file to registry and wait, this still shows
// the UAC prompt that the user may still cancel causing an exception which we check for.
try
{
var process = Process.Start("regedit.exe", String.Format("/s \"{0}\"", reg_file));
process.WaitForExit();
}
catch (Exception ex)
{
Shared.Logger(ex.ToString());
return false;
}

// clean up
File.Delete(reg_file);
return true;
}
}
}
43 changes: 17 additions & 26 deletions bnetlauncher/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -85,33 +85,24 @@ static void Main(string[] args)
// Logs generic Machine information for debugging purposes.
LogMachineInformation();

// Checks if the battle.net client URI handler is registered in the registry
if (!BnetClient.IsUriHandlerPresent())

// Checks if the battle.net client installLocation property is not returning an empty path

if (BnetClient.InstallLocation == String.Empty)
{
// Show message asking if user wants to try and repair
var reply = MessageBox.Show("Some of the battle.net client functionality seem to be missing, without it bnetlauncher" +
" will not be able to function. Please reinstall the battle.net to fix the situation.\n\n" +
"Alternatively, if you're still getting this message after reinstalling the client a repair can be attempted," +
" this will create the missing registry keys and prompt you to add them to your registry (you must answer yes).\n\n" +
"Would you like to attempt the repair?\nIf you choose No bnetlauncher will exit.",
"Error: URI handle broken", MessageBoxButtons.YesNo, MessageBoxIcon.Question);

// call repair or not and exit
if (reply == DialogResult.Yes)
{
var did_repair = BnetClient.RepairUriHandler();
if (!did_repair && !BnetClient.IsUriHandlerPresent())
{
ShowMessageAndExit("Repair attempt failed or was canceled.\nbnetlauncher will now exit.",
"Failed Repair");
}
// continue normal execution
}
else
{
Shared.Logger("User choose to not attempt repair, exiting");
return;
}
ShowMessageAndExit("Couldn't retrive Battle.net Client install location.\n\n" +
"Please reinstall the Battle.net Client to fix the issue\n");
}

// logging the client used in case something weird happens...
Shared.Logger(String.Format("ClientExe = '{0}'", BnetClient.ClientExe));

// Checks if the battle.net client exe exists
if (!File.Exists(BnetClient.ClientExe))
{
ShowMessageAndExit("Couldn't find the Battle.net Client exe in the following location:\n" +
"'" + BnetClient.ClientExe + "'\n\n" +
"Please check if Battle.net Client is properly Installed.");
}

// We use a Local named Mutex to keep two instances of bnetlauncher from working at the same time.
Expand Down
4 changes: 2 additions & 2 deletions bnetlauncher/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,5 +49,5 @@
// Build Number
// Revision
//
[assembly: AssemblyVersion("1.19.*")]
//[assembly: AssemblyFileVersion("1.19.*")]
[assembly: AssemblyVersion("1.21.*")]
//[assembly: AssemblyFileVersion("1.21.*")]
9 changes: 9 additions & 0 deletions bnetlauncher/instructions.txt
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ How to Use
hots = Heroes of the Storm
scr = Starcraft Remastered
dst2 = Destiny 2 (Overlay will not work!!! See notes bellow)
codbo4 = Call of Duty: Black Ops 4

the result should look something like this:
"G:\Steam\bnetlauncher.exe" wow
Expand Down Expand Up @@ -75,12 +76,20 @@ I can be reached by email at [email protected]

Special Thanks
--------------
github Ethan-BB for the new parameters to launch games on battle.net.
github RobFreiburger and iMintty for Starcraft Remastered and Destiny 2 support respectivly.
/u/fivetwofoureight for creating and allowing me to use his icon.
/u/malecden, Maverick, /u/sumphatguy and others for their help pointing out bugs.

Version History
---------------
1.21
* Proper fix thanks to Ethan-BB for the new battle.net client method to launch games.

1.20 (unreleased)
* Changed how bnetlauncher starts games to simulating a enter key on the client due to
breaking changes made by blizzard on how battlenet:// URI are handled

1.19
+ Added notes clarifying Destiny 2 compatibility issues.
* Possibly resolved some issues with incorrect checking of helpers in the previous version
Expand Down

0 comments on commit 2bb5b30

Please sign in to comment.