diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a0c3133 --- /dev/null +++ b/.gitignore @@ -0,0 +1,71 @@ +# Visual Studio files +.vs/ +*.user +*.userosscache +*.sln.docstates +*.userprefs + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +[Ww][Ii][Nn]32/ +[Aa][Rr][Mm]/ +[Aa][Rr][Mm]64/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ +[Ll]ogs/ + +# Visual Studio cache/options directory +.vs/ + +# ReSharper +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# Visual Studio code coverage results +*.coverage +*.coveragexml + +# NuGet Packages +*.nupkg +# NuGet Symbol Packages +*.snupkg +# The packages folder can be ignored because of Package Restore +**/[Pp]ackages/* +# except build/, which is used as an MSBuild target. +!**/[Pp]ackages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/[Pp]ackages/repositories.config +# NuGet v3's project.json files produces more ignorable files +*.nuget.props +*.nuget.targets + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!?*.[Cc]ache/ + +# Others +*.swp +*.*~ +project.lock.json +.DS_Store +*.pyc +nupkg/ + +# IDE +.idea/ +.vscode/ +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..7db85ce --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 kromskii2 + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/OBSLauncher.csproj b/OBSLauncher.csproj new file mode 100644 index 0000000..70c84f5 --- /dev/null +++ b/OBSLauncher.csproj @@ -0,0 +1,9 @@ + + + + WinExe + net6.0-windows + true + app.manifest + + \ No newline at end of file diff --git a/Program.cs b/Program.cs new file mode 100644 index 0000000..57102c1 --- /dev/null +++ b/Program.cs @@ -0,0 +1,189 @@ +using System; +using System.Diagnostics; +using System.Drawing; +using System.Windows.Forms; +using System.Security.Principal; +using System.IO; +using Microsoft.Win32; +using System.Runtime.InteropServices; + +namespace OBSLauncher +{ + public class Program : Form + { + private NotifyIcon trayIcon; + private ProcessMonitor processMonitor; + private const string GTA_PROCESS_NAME = "gta_sa"; + private const string OBS_SHORTCUT_PATH = @"C:\ProgramData\Microsoft\Windows\Start Menu\Programs\OBS Studio\OBS Studio (64bit).lnk"; + + [STAThread] + public static void Main() + { + if (!IsAdministrator()) + { + RestartAsAdmin(); + return; + } + + Application.EnableVisualStyles(); + Application.SetCompatibleTextRenderingDefault(false); + Application.Run(new Program()); + } + + private static bool IsAdministrator() + { + WindowsIdentity identity = WindowsIdentity.GetCurrent(); + WindowsPrincipal principal = new WindowsPrincipal(identity); + return principal.IsInRole(WindowsBuiltInRole.Administrator); + } + + private static void RestartAsAdmin() + { + ProcessStartInfo proc = new ProcessStartInfo(); + proc.UseShellExecute = true; + proc.WorkingDirectory = Environment.CurrentDirectory; + proc.FileName = Application.ExecutablePath; + proc.Verb = "runas"; + + try + { + Process.Start(proc); + } + catch + { + MessageBox.Show("Программа требует прав администратора для работы!", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + Environment.Exit(0); + } + + public Program() + { + InitializeTrayIcon(); + AddToStartup(); + processMonitor = new ProcessMonitor(GTA_PROCESS_NAME, OBS_SHORTCUT_PATH); + processMonitor.StartMonitoring(); + + // Настройка формы + this.ShowInTaskbar = false; + this.WindowState = FormWindowState.Minimized; + } + + private void InitializeTrayIcon() + { + trayIcon = new NotifyIcon(); + trayIcon.Icon = SystemIcons.Application; + trayIcon.Text = "OBS Launcher"; + trayIcon.Visible = true; + trayIcon.DoubleClick += TrayIcon_DoubleClick; + + ContextMenuStrip contextMenu = new ContextMenuStrip(); + contextMenu.Items.Add("Показать", null, (s, e) => ShowForm()); + contextMenu.Items.Add("Закрыть", null, (s, e) => Application.Exit()); + trayIcon.ContextMenuStrip = contextMenu; + } + + private void TrayIcon_DoubleClick(object sender, EventArgs e) + { + ShowForm(); + } + + private void ShowForm() + { + this.Show(); + this.WindowState = FormWindowState.Normal; + this.ShowInTaskbar = true; + } + + protected override void OnResize(EventArgs e) + { + base.OnResize(e); + if (this.WindowState == FormWindowState.Minimized) + { + this.Hide(); + this.ShowInTaskbar = false; + } + } + + private void AddToStartup() + { + try + { + string appPath = Application.ExecutablePath; + RegistryKey rk = Registry.CurrentUser.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", true); + rk.SetValue("OBSLauncher", appPath); + } + catch (Exception ex) + { + MessageBox.Show($"Ошибка при добавлении в автозагрузку: {ex.Message}", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + } + + public class ProcessMonitor + { + private string targetProcessName; + private string shortcutPath; + private Timer checkTimer; + private Timer delayTimer; + private bool obsRunning = false; + private bool gtaDetected = false; + private const int DELAY_SECONDS = 50; + + public ProcessMonitor(string targetProcessName, string shortcutPath) + { + this.targetProcessName = targetProcessName; + this.shortcutPath = shortcutPath; + checkTimer = new Timer(); + checkTimer.Interval = 1000; // Проверка каждую секунду + checkTimer.Tick += CheckTimer_Tick; + + delayTimer = new Timer(); + delayTimer.Interval = DELAY_SECONDS * 1000; // 50 секунд в миллисекундах + delayTimer.Tick += DelayTimer_Tick; + } + + public void StartMonitoring() + { + checkTimer.Start(); + } + + private void CheckTimer_Tick(object sender, EventArgs e) + { + bool gtaRunning = Process.GetProcessesByName(targetProcessName).Length > 0; + + if (gtaRunning && !gtaDetected) + { + gtaDetected = true; + delayTimer.Start(); + } + else if (!gtaRunning && gtaDetected) + { + gtaDetected = false; + delayTimer.Stop(); + obsRunning = false; + } + } + + private void DelayTimer_Tick(object sender, EventArgs e) + { + if (gtaDetected && !obsRunning) + { + try + { + Process.Start(new ProcessStartInfo + { + FileName = shortcutPath, + UseShellExecute = true, + WorkingDirectory = Path.GetDirectoryName(shortcutPath) + }); + obsRunning = true; + } + catch (Exception ex) + { + MessageBox.Show($"Ошибка при запуске OBS: {ex.Message}", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + delayTimer.Stop(); + } + } +} \ No newline at end of file diff --git a/README.md b/README.md index 7f8dba5..8ae917a 100644 Binary files a/README.md and b/README.md differ diff --git a/app.manifest b/app.manifest new file mode 100644 index 0000000..14958f6 --- /dev/null +++ b/app.manifest @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file