Как использовать встроенный файл из Assembly для контекстов SoundPlayer внутри приложения C # - PullRequest
0 голосов
/ 13 июня 2018

Hello Stack Overflow community,

Я работал над созданием пользовательского установщика / средства запуска для создаваемой игры, но в настоящее время он работает в непереносимом контексте, однако, если я хочу поставитьон находится внутри игры для распространения, он должен работать внутри переносимого контекста (то есть он не должен обращаться к диску для своих собственных нужд, только для потребностей другого программного обеспечения) /

В текущий момент он загружаетсяпесню с диска для воспроизведения, а также загружает предварительные условия для игры, если средство запуска никогда не открывалось ранее или не завершилось успешно.Для всех файлов установлено значение «EmbeddedResource» внутри SharpDevelop, и они являются частью окончательного скомпилированного сценария.

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

Текущий код, который у меня пока есть, ниже, «programpath» относится к каталогу, из которого выполняется файл, «MainText» - главное окно вывода, которое лучше видно в thisВопрос переполнения стека , а label1 - это строка отладки, которая используется только для отображения пути текущей запущенной команды (будет удалена, когда все объекты будут внедрены).

public MainForm()
    {
        //Open Window
        InitializeComponent();
        CenterToScreen();
        //Start song
        System.Media.SoundPlayer player = new System.Media.SoundPlayer(programpath+"\\Resonance.wav");
        player.PlayLooping();
        this.Shown+=(s,e)=>{
            if(File.Exists(programpath+"\\FirstLaunch.lic")&&File.ReadAllText(programpath+"\\FirstLaunch.lic").IndexOf("Installation Successful")>=0){
            BackColor=System.Drawing.Color.OrangeRed;
            MainText.BackColor=System.Drawing.Color.OrangeRed;
            MainText.ForeColor=System.Drawing.Color.Aquamarine;
            MainText.Text="Starting game..";
            Process game = new Process();
            //placeholder executable, will be finished game executable
            game.StartInfo.FileName="D:\\UT2004\\System\\UT2004.exe";
            game.StartInfo.ErrorDialog=true;
            game.Start();
            //stop playing music, 
            player.Stop();
            //when game stops, close the launcher
            game.WaitForExit();
            Application.Exit();
            }else{
                //Start prerequisite installation
                newLaunch();
            }
        };
}
    //if the launcher has not been open before OR the last installation was not successful
        void newLaunch(){
        //Creates and makes a stream to the file
        StreamWriter writer = new StreamWriter(programpath+"\\FirstLaunch.lic");
        //Changing color scheme
            BackColor=System.Drawing.Color.Chartreuse;
            MainText.BackColor=System.Drawing.Color.Chartreuse;
            MainText.ForeColor=System.Drawing.Color.Black;
            MainText.Text="Configuring Prerequisites....\nInstalling DirectX";
            //write to file about stage
            writer.Write("Installing DirectX");
            //start DirectX installer
            Process prerequisite = new Process();
            prerequisite.StartInfo.FileName=programpath+"\\dxwebsetup.exe";
            prerequisite.StartInfo.ErrorDialog=true;
            prerequisite.Start();
            //debug line
            label1.Text=programpath+"\\dxwebsetup.exe";
            //wait for installer to finish and close
            prerequisite.WaitForExit();
            //remove refernce to DirectX installer
            prerequisite.Close();
            //write to file about stage
            writer.WriteLine("...true");
            //Changing color scheme
            BackColor=System.Drawing.Color.DarkMagenta;
            MainText.BackColor=System.Drawing.Color.DarkMagenta;
            MainText.ForeColor=System.Drawing.Color.Yellow;
            MainText.Text="Configuring Prerequisites....\nInstalling Microsoft VC++2015 Update RC3";
            //write to file about stage
            writer.Write("Installing VCRedist");
            //start VC Redistributable installer
            prerequisite.StartInfo.FileName=programpath+"\\vc_redist.x86.exe";
            prerequisite.StartInfo.ErrorDialog=true;
            prerequisite.Start();
            //debug line
            label1.Text=programpath+"\\vc_redist.x86.exe";
            //wait for installer to finish and close
            prerequisite.WaitForExit();
            //remove reference to VC Redistributable installer
            prerequisite.Close();
            //write to file about stage
            writer.WriteLine("...true");
            writer.WriteLine("Installation Successful");
            writer.Close();
            //re-open launcher from open context
            label1.Text=programpath+"\\ColorLoop.exe";
            Process.Start(programpath+"\\ColorLoop.exe");
            Application.Exit();
        }
    }
}

Как сделатьЯ получаю программу для воспроизведения музыки и загружаю предварительные требования из себя, а не из отдельных файлов дисков внутри кода.Все это уже встроено, просто не используется.

Ответы [ 2 ]

0 голосов
/ 14 июня 2018

Я наконец-то понял это, поэтому я отвечаю на свой вопрос в надежде, что люди, которые борются в будущем, смогут это понять.

Используя ссылку , предоставленную @ Jimi для доступа к ресурсам в SharpDevelop и прокрутки вниз до раздела «Внедрение файлов напрямую» показывает контекст, в котором можно получить доступ к встроенному ресурсу.Здесь следует отметить, что тип возвращаемого значения GetManifestStream (string) является System.IO.Stream объектом.Это важно, так как нам нужно, чтобы SoundPlayer как-то принял объект System.IO.Stream.Это можно сделать двумя способами, используя перегруженный конструктор или свойство класса SoundPlayer.Как определено страницей MSDN для класса SoundPlayer .

Однако, когда я тестировал это, я не мог получить звук для воспроизведения.Продолжая свое исследование, я обнаружил, что Assembly.GetExecutingAssembly () имеет доступный метод с именем «GetManifestResourceNames ()», который возвращает строковый массив всех ресурсов и их корректирующие имена для доступа к ним.Я смог увидеть результат, создав метку формы Windows с именем «ExecutingAssem» и используя инструкции из DotNetPerls для создания статического метода с именем «ConvertStringArrayToStringJoin ()», но изменив его разделитель с «.»к "|"чтобы лучше прочитать ресурсы.

После этого в окончательной программе будет показан список встроенных ресурсов со строкой: ExecutingAssem.Text = ConvertStringArrayToStringJoin (Assembly.GetExecutingAssembly (). GetManifestResourceNames ());

И окончательная программа выглядит так: Программа, показывающая все ресурсы в углу

Интересно, что ресурс песни (Resonance) на самом деле не является частью пространства имен,или MainForm ... а скорее его собственное имя в качестве заголовка ресурса.

После обнаружения этой недостающей информации мне нужно было изменить программу с чтения диска на чтение потока манифеста.Используя перегруженный конструктор, который использует объект System.IO.Stream в качестве параметра, а не строку в расположении файла, я изменил место инициализации объекта проигрывателя для использования этого конструктора.

SoundPlayer player =new SoundPlayer(Assembly.GetExecutingAssembly().GetManifestResourceStream("Resonance"));

Наконец, финальное приложение воспроизвело песню с возможностью переместить файл .exe в другое место и по-прежнему иметь возможность воспроизводить ту же песню без необходимости, чтобы Resonance.wav находился в той же директории.

0 голосов
/ 13 июня 2018
private void button1_Click(object sender, EventArgs e)
{
    SoundPlayer player = new SoundPlayer();

    //Add TestSound.wav file to the built-in resource file Project>Properties>Resources.resx
    player.Stream = Properties.Resources.TestSound;

    //Add TestSound.wav file to a new resource file Resource1.resx
    //player.Stream = Resource1.TestSound;
    player.Play();
}
...