Click here to Skip to main content
15,867,330 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
I am using WPF Core on VS Community 2019 on Windows. I am creating a game .exe launcher for 'AoK HD.exe'. And am using this video as a base guide:https://www.youtube.com/watch?v=tDopNcE9lOU. The path of the file is usually in Program Files or Program Files (x86). Although the launcher will most likely be in the same directory as 'AoK HD.exe', it may vary. I would need it to automatically find the .exe only only with the given name. Here is my code so far. I have the MainWindow.xaml.cs, and another class called 'ButtonLauncher.cs', and of course, MainWindow.xaml, where the button is already added.

'MainWindow.xaml.cs':
C#
private void Button_Click(object sender, RoutedEventArgs e)
        {
            ButtonLauncher.PlayGame();
        }


'ButtonLauncher.cs':
C#
using System.Diagnostics;

namespace AoE_II_E_Launcher_EXE
{
    class ButtonLauncher
    {
         public static void PlayGame()
        {
            Process.Start("AoK HD.exe");
        }


What I have tried:

I have tried many things, but none seem to work, and I end up with many errors. My problem is perhaps only me not understanding how to use them in my context.

For example:
C#
string rootDirectory = System.IO.DriveInfo.GetDrives()[0].RootDirectory.FullName;

string[] files = System.IO.Directory.GetFiles(
            rootDirectory, 
            "AoK HD.exe", System.IO.SearchOption.AllDirectories);


The 'rootDirectory' shoves back this error:
Severity Code Description Project File Line Suppression State
Error CS0236 A field initializer cannot reference the non-static field, method, or property 'MainWindow.rootDirectory' AoE II E Launcher EXE C:\Program Files (x86)\Steam\steamapps\common\Age2HD\mods\Interface Evolved\Launcher\AoE II E Launcher EXE\MainWindow.xaml.cs 85 Active


And this:
C#
FileInfo[] subFiles = di.GetFiles("AoK HD.exe", SearchOption.AllDirectories);


FileInfo gives this error:
Severity Code Description Project File Line Suppression State
Error CS0246 The type or namespace name 'FileInfo' could not be found (are you missing a using directive or an assembly reference?) AoE II E Launcher EXE C:\Program Files (x86)\Steam\steamapps\common\Age2HD\mods\Interface Evolved\Launcher\AoE II E Launcher EXE\MainWindow.xaml.cs 82 Active

di gives this error:
Severity Code Description Project File Line Suppression State
Error CS0103 The name 'di' does not exist in the current context AoE II E Launcher EXE C:\Program Files (x86)\Steam\steamapps\common\Age2HD\mods\Interface Evolved\Launcher\AoE II E Launcher EXE\MainWindow.xaml.cs 82 Active

And SearchOption gives back this error:
Severity Code Description Project File Line Suppression State
Error CS0103 The name 'SearchOption' does not exist in the current context AoE II E Launcher EXE C:\Program Files (x86)\Steam\steamapps\common\Age2HD\mods\Interface Evolved\Launcher\AoE II E Launcher EXE\MainWindow.xaml.cs 82 Active

I have tried many other things, and am really unsure at this point. As I said, I think the problem is that I don't know where to put this code. I found these snippets of code here: https://stackoverflow.com/questions/2698801/find-a-application-path
and also how to use them.

Also, I presume that in Process.Start, it would have to include the path name as well, so would the path name have to be a string? Something like this (assuming that the string idea is valid and the string name is AppPath):

'ButtonLauncher.cs':
C#
using System.Diagnostics;

namespace AoE_II_E_Launcher_EXE
{
    class ButtonLauncher
    {
         public static void PlayGame()
        {
            Process.Start(AppPath + "AoK HD.exe");
        }

Do registries come into this also?

I want to make it like this launcher, it has the same premise: https://www.moddb.com/games/age-of-empires-ii-hd/downloads/age-of-empires-ii-hd-custom-launcher

However, this launcher is outdated and the commands are useless at this point. I would like to update it with new commands and new UI. I used dotPeek to decompile, but did not get much from it, which only led to more confusion, perhaps someone can help me with this?
Posted
Updated 14-Apr-20 5:43am
v8
Comments
Richard MacCutchan 12-Apr-20 11:56am    
"and I end up with many errors."
Unless you explain what they are, and where they occur in your code, we cannot help to diagnose them.
Archaic Chaos 12-Apr-20 12:08pm    
They were all 'Exeptions', let me just run it again. I think the problem is only that I dont know how and where to put that code and how to link it up. I added the exeptions to the question.
Richard MacCutchan 12-Apr-20 12:47pm    
They are not exceptions., they are compiler messages telling you what is wrong with your code. I would suggest going back to the C# documentation for a better understanding of the language, rather than relying on a video.
Archaic Chaos 12-Apr-20 12:52pm    
Where is the C# documentation? I don't really have time to be going learning the entire language. I'm just creating a small launcher as a side project for something bigger. Also, I think that the actual problem here, is that I don't know where to put that code and how to link it, as I said. And there really is no clear inclination as to where to put it. Perhaps some light could be shed on this? I have pretty much built the entire application at this point, UI is finished, etc. This really is the only thing that is missing.
Richard MacCutchan 12-Apr-20 13:12pm    
The documentation is on the Microsoft website; Google will find it for you. If you don't have time to learn the language you are trying to use, then you are just going to keep hitting the wall.

1 solution

Quote:
Error CS0236 A field initializer cannot reference the non-static field, method, or property ...
You've declared the variables at the class level, rather than the method level. Since you haven't specified any modifiers, they are private instance fields. The assignment to the field is a "field initializer", and that cannot reference other non-static fields.
C#
class ButtonLauncher
{
    string rootDirectory = ...; // <-- This is a field
    
    public static void PlayGame()
    {
        string rootDirectory = ...; // <-- This is a local variable
        ...
    }
}

Quote:
Error CS0246 The type or namespace name 'FileInfo' could not be found ...
Error CS0103 The name 'SearchOption' does not exist in the current context ...
You're missing a using System.IO; line at the top of your file.

Quote:
Error CS0103 The name 'di' does not exist in the current context...
Either you haven't declared a variable called di, or the previous error is preventing it from being resolved.

Quote:
Also, I presume that in Process.Start, it would have to include the path name as well
The value returned from GetFiles will include the path and file name, so you just need to pass that to Process.Start.


You're going to run into a problem searching the entire drive: your account doesn't have access to read every single directory on the drive, so you'll get an UnauthorisedAccessException from the GetFiles method.

You could try something like this, but it's not going to be particularly quick:
C#
using System;
using System.Diagnostics;
using System.IO;

namespace AoE_II_E_Launcher_EXE
{
    static class ButtonLauncher
    {
        private const string TargetFileName = "AoK HD.exe";
        
        private static string FindTargetFileInPath(string folderPath)
        {
            if (!Directory.Exists(folderPath)) return null;
            
            string result = Path.Combine(folderPath, TargetFileName);
            if (File.Exists(result)) return result;
            
            try
            {
                foreach (string subFolder in Directory.EnumerateDirectories(folderPath))
                {
                    result = FindTargetFileInPath(subFolder);
                    if (result != null) return result;
                }
            }
            catch (UnauthorizedAccessException)
            {
            }
            catch (PathTooLongException)
            {
            }
            
            return null;
        }
        
        private static string FindTargetFile()
        {
            // Check common locations first:
            string folderPath = Directory.GetCurrentDirectory();
            string result = FindTargetFileInPath(folderPath);
            if (result != null) return result;
            
            folderPath = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86);
            result = FindTargetFileInPath(folderPath);
            if (result != null) return result;
            
            folderPath = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles);
            result = FindTargetFileInPath(folderPath);
            if (result != null) return result;
            
            // Give up and search all folders on all drives (sloooooow):
            foreach (DriveInfo drive in DriveInfo.GetDrives())
            {
                if (drive.IsReady && drive.DriveType == DriveType.Fixed && drive.RootDirectory != null)
                {
                    result = FindTargetFileInPath(drive.RootDirectory.FullName);
                    if (result != null) return result;
                }
            }
            
            return null;
        }
        
        public static void PlayGame()
        {
            string filePath = FindTargetFile();
            if (string.IsNullOrEmpty(filePath) || !File.Exists(filePath))
            {
                throw new InvalidOperationException("Unable to locate the AoK HD application.");
            }
            
            Process.Start(filePath);
        }
    }
}
 
Share this answer
 
v2
Comments
Archaic Chaos 17-Apr-20 20:31pm    
Wow! You legend! Thanks a million for the response. Your explanation on all the errors were spot on and helped me understand how it worked. Your code also worked perfectly, and this helped me so much! After so long searching everywhere, this is the first entirely comprehensive answer I have gotten. Thank you so much!

One thing, in your code, under 'throw new InvalidOperation("Unable to locate the AoK HD application"), it came back as an error. I looked up throw new in C# online and found this https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/exceptions/creating-and-throwing-exceptions . When I changed from InvalidOperation to InvalidOperationException, it worked perfectly again. Do you know why this happenend? Is this a specific C# class difference?

Anyway, the answer was fantastic and you have made my day! Thanks a lot.
Richard Deeming 20-Apr-20 6:10am    
Sorry, that was just a typo in my solution. InvalidOperationException is correct. :)

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900