Archaic Chaos Ответов: 1

Как добраться ядре WPF приложение, чтобы запустить конкретные .exe-файла со случайным путем


Я использую ядро WPF на VS Community 2019 в Windows. Я создаю программу запуска game .exe для 'AoK HD.exe". И я использую это видео в качестве базового руководства:https://www.youtube.com/watch?v=tDopNcE9lOU Путь к файлу обычно находится в Program Files или Program Files (x86). Хотя пусковая установка, скорее всего, будет находиться в том же каталоге, что и 'AoK HD.exe-это может быть по-разному. Мне нужно было бы, чтобы он автоматически находил файл .exe только с заданным именем. Вот мой код на данный момент. У меня есть MainWindow.xaml.cs, и еще один класс под названием 'ButtonLauncher.cs', и, конечно же, MainWindow.xaml, где кнопка уже добавлена.

'Файл MainWindow.язык XAML.КС':
private void Button_Click(object sender, RoutedEventArgs e)
        {
            ButtonLauncher.PlayGame();
        }


"ButtonLauncher.cs":
using System.Diagnostics;

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


Что я уже пробовал:

Я перепробовал много вещей, но ни одна из них, кажется, не работает, и я заканчиваю со многими ошибками. Моя проблема, возможно, только в том, что я не понимаю, как использовать их в моем контексте.

Например:
string rootDirectory = System.IO.DriveInfo.GetDrives()[0].RootDirectory.FullName;

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


"Корневой каталог" отбрасывает эту ошибку назад:
Описание Кода Серьезности Состояние Подавления Строки Файла Проекта
Ошибка CS0236 инициализатор поля не может ссылаться на нестатические поля, метод или свойство 'файл MainWindow.корневой каталог каталог' аое II В Е запуска exe-файла C:\Program файлы (х86)\пара\выйдите\общие\Age2HD\модов\интерфейс эволюционировали\лаунчер\аое II В Е запуска exe-файла\файл MainWindow.язык XAML.в CS 85 активный


А это:
FileInfo[] subFiles = di.GetFiles("AoK HD.exe", SearchOption.AllDirectories);


FileInfo выдает эту ошибку:
Описание Кода Серьезности Состояние Подавления Строки Файла Проекта
Ошибка CS0246 не удалось найти тип или имя пространства имен "FileInfo" (отсутствует ли директива using или ссылка на сборку?) Аое II В Е запуска EXE файлы C:\Program (х86)\пара\выйдите\общие\Age2HD\модов\интерфейс эволюционировали\лаунчер\аое II В Е запуска exe-файла\файл MainWindow.язык XAML.КС 82 активный

di выдает эту ошибку:
Описание Кода Серьезности Состояние Подавления Строки Файла Проекта
Ошибка CS0103 имя 'Ди' не существует в текущем контексте аое II В Е запуска exe-файла C:\Program файлы (х86)\пара\выйдите\общие\Age2HD\модов\интерфейс эволюционировали\лаунчер\аое II В Е запуска exe-файла\файл MainWindow.язык XAML.КС 82 активный

И SearchOption возвращает эту ошибку:
Описание Кода Серьезности Состояние Подавления Строки Файла Проекта
Ошибка CS0103 searchoption указывает, нужно имя '' не существует в текущем контексте аое II В Е запуска exe-файла C:\Program файлы (х86)\пара\выйдите\общие\Age2HD\модов\интерфейс эволюционировали\лаунчер\аое II В Е запуска exe-файла\файл MainWindow.язык XAML.КС 82 активный

Я пробовал много других вещей, и действительно не уверен в этом пункте. Как я уже сказал, Я думаю, что проблема в том, что я не знаю, куда поместить этот код. Я нашел эти фрагменты кода здесь: https://stackoverflow.com/questions/2698801/find-a-application-path
а также как ими пользоваться.

Кроме того, я предполагаю, что в процессе.Во-первых, он должен был бы также включать имя пути, так что имя пути должно быть строкой? Что-то вроде этого (предполагая, что идея строки действительна, а имя строки-AppPath):

"ButtonLauncher.cs":
using System.Diagnostics;

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

Участвуют ли в этом и реестры?

Я хочу сделать его похожим на эту пусковую установку, у него есть та же предпосылка: https://www.moddb.com/games/age-of-empires-ii-hd/downloads/age-of-empires-ii-hd-custom-launcher

Однако эта пусковая установка устарела, и команды на данный момент бесполезны. Я хотел бы обновить его новыми командами и новым пользовательским интерфейсом. Я использовал dotPeek для декомпиляции, но не получил от него многого, что только привело к еще большей путанице, возможно, кто-то может мне в этом помочь?

Richard MacCutchan

- и в итоге я совершаю много ошибок."
Если вы не объясните, что это такое и где они встречаются в вашем коде, мы не сможем помочь их диагностировать.

Archaic Chaos

Все они были "Exeptions", позвольте мне просто запустить его снова. Я думаю, что проблема только в том, что я не знаю, как и где поместить этот код и как его связать. Я добавил к этому вопросу еще и свои пояснения.

Richard MacCutchan

Это не исключения, а сообщения компилятора, сообщающие вам, что не так с вашим кодом. Я бы предложил вернуться к документации по C# для лучшего понимания языка, а не полагаться на видео.

Archaic Chaos

Где находится документация по C#? На самом деле у меня нет времени изучать весь язык целиком. Я просто создаю небольшую пусковую установку в качестве побочного проекта для чего-то большего. Кроме того, я думаю, что реальная проблема здесь заключается в том, что я не знаю, куда поместить этот код и как его связать, как я уже сказал. И действительно, нет ясного намерения, куда его девать. Может быть, на это можно пролить свет? На данный момент я в значительной степени построил все приложение, пользовательский интерфейс закончен и т. д. Это действительно единственное, чего не хватает.

Richard MacCutchan

Документация находится на веб-сайте Microsoft; Google найдет ее для вас. Если у вас нет времени, чтобы выучить язык, который вы пытаетесь использовать, тогда вы просто будете продолжать бить стену.

Archaic Chaos

Так что, по сути, здесь нет никакого решения. Без необходимости изучать весь язык C#, а затем закончить это.

Richard MacCutchan

Нет, но вам нужно изучить основы классов и ссылок. А также специфическое .Чистые классы, которые вы пытаетесь использовать. Вы не будете пытаться построить автомобиль после просмотра одного видео; программирование-это почти то же самое.

Dave Kreskowiak

Он может быть "маленьким" для вас, но даже "маленькие" приложения требуют от вас понимания множества различных концепций.

Archaic Chaos

Так что я согласен с вами. Единственная причина, по которой я должен сделать свое "маленькое" приложение, заключается в том, что мой друг, который умеет писать на C#, недоступен, и я был в состоянии думать и сделал предположение, что кто-то сможет объяснить эту единственную вещь и кратко объяснить ее мне, потому что я искал во многих местах и на разных форумах ответ на этот единственный вопрос без удачи. На этом этапе я полностью создал "маленькое" приложение. Это вишенка на самом верху.

1 Ответов

Рейтинг:
9

Richard Deeming

Цитата:
Ошибка CS0236 инициализатор поля не может ссылаться на нестатическое поле, метод или свойство ...
Вы объявили переменные на уровне класса, а не на уровне метода. Поскольку вы не указали никаких модификаторов, они являются частными полями экземпляра. Назначение полю является "инициализатором поля", и оно не может ссылаться на другие нестатические поля.
class ButtonLauncher
{
    string rootDirectory = ...; // <-- This is a field
    
    public static void PlayGame()
    {
        string rootDirectory = ...; // <-- This is a local variable
        ...
    }
}

Цитата:
Ошибка CS0246 не удалось найти тип или имя пространства имен "FileInfo"...
Ошибка CS0103 имя 'SearchOption' не существует в текущем контексте ...
Ты упускаешь что-то важное. using System.IO; строка в верхней части вашего файла.

Цитата:
Ошибка CS0103 имя " di " не существует в текущем контексте...
Либо вы не объявили переменную с именем di, или предыдущая ошибка препятствует ее разрешению.

Цитата:
Кроме того, я предполагаю, что в процессе.Во-первых, он должен был бы также включать имя пути
Значение, возвращаемое из GetFiles будет включать в себя путь и имя файла, так что вам просто нужно передать это Process.Start.


Вы столкнетесь с проблемой поиска по всему диску: ваша учетная запись не имеет доступа к чтению каждого отдельного каталога на диске, поэтому вы получите UnauthorisedAccessException из GetFiles метод.

Вы можете попробовать что-то вроде этого, но это не будет особенно быстро:
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);
        }
    }
}


Archaic Chaos

Ух ты! Ты легенда! Огромное спасибо за ответ. Ваши объяснения по всем ошибкам были точными и помогли мне понять, как это работает. Ваш код тоже работал отлично, и это мне очень помогло! После столь долгих поисков повсюду это первый полностью исчерпывающий ответ, который я получил. Большое вам спасибо!

Одна вещь, в вашем коде, в разделе 'throw new InvalidOperation("невозможно найти приложение AoK HD"), он вернулся как ошибка. Я посмотрел throw new in C# online и нашел это https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/exceptions/creating-and-throwing-exceptions -да . Когда я перешел с InvalidOperation на InvalidOperationException, он снова работал отлично. Знаете ли вы, почему это произошло? Является ли это специфическим отличием класса C#?

Во всяком случае, ответ был фантастическим, и вы сделали мой день! Большое спасибо.

Richard Deeming

Извините, это была просто опечатка в моем решении. InvalidOperationException правильно. :)