создание ланчера С#
Цитата: Алик от 23.02.2025, 13:37Всем привет!
Смотрю ролики Хачатура по С#, местами тяжеловато для понимания, первый язык все таки, дошел до ролика по созданию собственного ланчера и понимаю, что пока на этом этапе нужно остановиться и наработать практику, тем более интересно: работаешь с программой, файловой системой, службами и реестром
Так вот вопрос по поводу создания ланчера, если кто-нибудь ответит, объяснит буду благодарен
1. Как дать понять С#, что папка с программой, которую мы хотим создать портативной и есть искомая директория, нужно ли какие-то аргумерты писать, что программа должна запускаться из любой директории?
2. Я так понимаю, что лучший вариант для портативности - это симлинки, так вот, как их можно сделать более грамотно, может есть какие-то уловки и лайфхаки, либо можете дать ссылку на какой-нибудь пример, я попробую сам изучить. Ну и возможно я правильно понимаю, что симлинки бывают динамические и статичные, если так можно выразиться, то есть, какие-то остаются в системе всегда, а какие-то "подчишаются" после завершения работы. Пример статичных симлинков - это версия дискорд портабл, которую выкладывали здесь на форуме
Пока, наверное, это главное вопросы, буду благодарен любимым ответам, спасибо
Всем привет!
Смотрю ролики Хачатура по С#, местами тяжеловато для понимания, первый язык все таки, дошел до ролика по созданию собственного ланчера и понимаю, что пока на этом этапе нужно остановиться и наработать практику, тем более интересно: работаешь с программой, файловой системой, службами и реестром
Так вот вопрос по поводу создания ланчера, если кто-нибудь ответит, объяснит буду благодарен
1. Как дать понять С#, что папка с программой, которую мы хотим создать портативной и есть искомая директория, нужно ли какие-то аргумерты писать, что программа должна запускаться из любой директории?
2. Я так понимаю, что лучший вариант для портативности - это симлинки, так вот, как их можно сделать более грамотно, может есть какие-то уловки и лайфхаки, либо можете дать ссылку на какой-нибудь пример, я попробую сам изучить. Ну и возможно я правильно понимаю, что симлинки бывают динамические и статичные, если так можно выразиться, то есть, какие-то остаются в системе всегда, а какие-то "подчишаются" после завершения работы. Пример статичных симлинков - это версия дискорд портабл, которую выкладывали здесь на форуме
Пока, наверное, это главное вопросы, буду благодарен любимым ответам, спасибо
Цитата: Алик от 26.02.2025, 02:33всем доброго времени суток!
изучаю работу с реестром в С#, не могу понять, как сделать так, чтобы программа проверила наличие ключа реестра и, например, написала в textbox об этом, код выглядит так:void button1_Click(object sender, EventArgs e) { RegistryKey key = Registry.LocalMachine.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\CrystalDiskMark8_is1"); if (key != null) { textBox1.Text = key.ToString(); } else { textBox1.Text = "нет такого"; }примечательно, что если задать переменной следующий путь: "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall", то все получится, а вот в первоначальном варианте код уходит в "else"
пока не пойму в чем дело, может кто подскажет
всем доброго времени суток!
изучаю работу с реестром в С#, не могу понять, как сделать так, чтобы программа проверила наличие ключа реестра и, например, написала в textbox об этом, код выглядит так:
void button1_Click(object sender, EventArgs e)
{
RegistryKey key = Registry.LocalMachine.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\CrystalDiskMark8_is1");
if (key != null)
{
textBox1.Text = key.ToString();
}
else
{
textBox1.Text = "нет такого";
}
примечательно, что если задать переменной следующий путь: "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall", то все получится, а вот в первоначальном варианте код уходит в "else"
пока не пойму в чем дело, может кто подскажет
Цитата: Никита от 26.02.2025, 03:45Алик, привет!
Этот ключ реестра находится в 64-битном разделе реестра, а твоя программа компилируется в 32 битах, потому и не может получит доступ к этом ключу.
Выход, два варианта:
1. Либо в настройках компиляции указать преимущество на 64-битную компиляцию.
2. Либо ничего не менять в компиляторе и заставить программу получить данные из 64-битного раздела ресстра [simple_tooltip content='RegistryKey key = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64).OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\CrystalDiskMark8_is1");']такой[/simple_tooltip] командой
Алик, привет!
Этот ключ реестра находится в 64-битном разделе реестра, а твоя программа компилируется в 32 битах, потому и не может получит доступ к этом ключу.
Выход, два варианта:
1. Либо в настройках компиляции указать преимущество на 64-битную компиляцию.
2. Либо ничего не менять в компиляторе и заставить программу получить данные из 64-битного раздела ресстра такой командой
Цитата: Никита от 26.02.2025, 03:59По поводу прошлых двух вопросов.
Первое: Не особо понял.Второе: Симлинк, он просто Симлинк. Будет он удаляться или нет зависит только от того, как Ты напишешь код в лончере, а не от того, какими свойствами обладает симлинк.
Надо, чтобы удалился, пропиши Directory.Delete() или File.Delete(), надо, чтобы остался, не удаляй его. Если делаешь портативку для себя, просто чтобы было всё в ажуре, то лучше не удалять этот симлинк. Память не жрёт, диск не насилует (даже HDD). Зато, всегда будешь спокоен, что программа не поломается, если попробует обновится например.
По поводу прошлых двух вопросов.
Первое: Не особо понял.
Второе: Симлинк, он просто Симлинк. Будет он удаляться или нет зависит только от того, как Ты напишешь код в лончере, а не от того, какими свойствами обладает симлинк.
Надо, чтобы удалился, пропиши Directory.Delete() или File.Delete(), надо, чтобы остался, не удаляй его. Если делаешь портативку для себя, просто чтобы было всё в ажуре, то лучше не удалять этот симлинк. Память не жрёт, диск не насилует (даже HDD). Зато, всегда будешь спокоен, что программа не поломается, если попробует обновится например.
Цитата: Алик от 26.02.2025, 04:08Никита, спасибо, как я сразу не подумал о разрядности - не опытность да и только
крайне благодарю, буду дальше изучать😊
На счет первого вопроса в первом моем сообщении, тут я сам немного запутался, но просто я не могу понять, как программа понимает свою директорию. Попробую привести пример: у нас есть папка, в этой папке лаунчер - наша программа, собственно, которая что-то делает, например, те же симлинки, или же наоборот, что-то забирает из системы себе в папку - как это в коде отобразить? Пример, вы делали PortableCreator, у вас сама папка с портабл понимается как %portable%, соответственно, указав это программа понимает что это за папка
Никита, спасибо, как я сразу не подумал о разрядности - не опытность да и только
крайне благодарю, буду дальше изучать😊
На счет первого вопроса в первом моем сообщении, тут я сам немного запутался, но просто я не могу понять, как программа понимает свою директорию. Попробую привести пример: у нас есть папка, в этой папке лаунчер - наша программа, собственно, которая что-то делает, например, те же симлинки, или же наоборот, что-то забирает из системы себе в папку - как это в коде отобразить? Пример, вы делали PortableCreator, у вас сама папка с портабл понимается как %portable%, соответственно, указав это программа понимает что это за папка
Цитата: Сергей от 26.02.2025, 10:00Алик, привет 🖐
При запуске программы желательно указать (для надёжности, windows не идеальна):
Directory.SetCurrentDirectory(AppContext.BaseDirectory); // Жестко указываем рабочую папкуПосле этого можно не использовать полный путь для некоторых действий, например, команда
File.Delete("123.txt");удалит 123.txt возле программы.
Ну уровне полей можно добавить:string ProgramDir => AppContext.BaseDirectory;
И использовать в нужных местах:Cmd($"mklink /d \"C:\\MyFolder\" \"{ProgramDir}MyFolder\"");P.S. Команда
AppContext.BaseDirectoryвозвращает путь с слэшом в конце, если нужно и удобней, можно его убрать:
string ProgramDir => AppContext.BaseDirectory.TrimEnd('\\');
Алик, привет 🖐
При запуске программы желательно указать (для надёжности, windows не идеальна):
СкопированоDirectory.SetCurrentDirectory(AppContext.BaseDirectory); // Жестко указываем рабочую папку
После этого можно не использовать полный путь для некоторых действий, например, команда СкопированоFile.Delete("123.txt"); удалит 123.txt возле программы.
Ну уровне полей можно добавить: Скопированоstring ProgramDir => AppContext.BaseDirectory;
И использовать в нужных местах: СкопированоCmd($"mklink /d \"C:\\MyFolder\" \"{ProgramDir}MyFolder\"");
P.S. Команда СкопированоAppContext.BaseDirectory возвращает путь с слэшом в конце, если нужно и удобней, можно его убрать:
Скопированоstring ProgramDir => AppContext.BaseDirectory.TrimEnd('\\');
Цитата: Алик от 26.02.2025, 11:16Сергей, привет!
ага, значит,Directory.SetCurrentDirectory(AppContext.BaseDirectory);мы указываем рабочую папку, затем командойstring ProgramDir => AppContext.BaseDirectory;в полях вносим в переменную, чтобы к ней можно было обращаться и использовать, а эта команда,Cmd($"mklink /d \"C:\\MyFolder\" \"{ProgramDir}MyFolder\"");могу догадываться, создает символическую ссылку, где ..."C:\\MyFolder\...путь для символической ссылки, а...{ProgramDir}MyFolder\"");- директория для которой создается ссылка
Сергей, привет!
ага, значит, СкопированоDirectory.SetCurrentDirectory(AppContext.BaseDirectory); мы указываем рабочую папку, затем командой Скопированоstring ProgramDir => AppContext.BaseDirectory; в полях вносим в переменную, чтобы к ней можно было обращаться и использовать, а эта команда, СкопированоCmd($"mklink /d \"C:\\MyFolder\" \"{ProgramDir}MyFolder\""); могу догадываться, создает символическую ссылку, где ...Скопировано"C:\\MyFolder\... путь для символической ссылки, а Скопировано...{ProgramDir}MyFolder\""); - директория для которой создается ссылка