Search code examples
c#viber

How to close viber main window


I'm developing a tiny launcher. Its main idea is to fix the lack of functionality in Viber for Windows. I want it to make start Viber minimized to tray only. Normally, when Viber is starting, it appears a Viber main window on desktop and an icon - in system tray. All the time I should close this obsolete window manually. So, I have written a few lines of code, but I found that it still couldn't close the window:

using System;
using System.Diagnostics;

class ViberStrt {
    static void Main() {

        Process newProc = Process.Start("c:\\Users\\Dmytro\\AppData\\Local\\Viber\\Viber.exe");
        Console.WriteLine("New process has started");
        //newProc.CloseMainWindow();
        newProc.WaitForExit();
        newProc.Close();
        newProc.Dispose();
        Console.WriteLine("Process has finished");
        //newProc.Kill();
    }
}

But whatever I tried (Close, Dispose) - it does not work. Method Kill does not fit, because it kills all. But the only thing I need is to close Viber main window and leave the process in the System Tray.

There is also another way: to start Viber minimized at once:

using System;
using System.Diagnostics;

class LaunchViber
{
    void OpenWithStartInfo()
    {
        ProcessStartInfo startInfo = new ProcessStartInfo("c:\\Users\\Dmytro\\AppData\\Local\\Viber\\Viber.exe");
        startInfo.WindowStyle = ProcessWindowStyle.Minimized;        
        Process.Start(startInfo);
    }
    static void Main()
    {
        //Process newProc = Process.Start("c:\\Users\\Dmytro\\AppData\\Local\\Viber\\Viber.exe");
        LaunchViber newProc = new LaunchViber();
        newProc.OpenWithStartInfo();
    }
}

In such a case, we receive a minimized window on the TaskPane and an icon in the SystemTray. But in this case I have absolutely no idea how to get rid of the icon (how to close minimized window) on the TaskPane.

I shall appreciate any help/ ideas in finding a solution for this problem.


Solution

  • Using Pinvoke, you can try getting the handle for the actual window if you know what the window caption will be.

    First, import these functions:

    [DllImport("user32.dll", EntryPoint = "FindWindow", SetLastError = true)]
    static extern IntPtr FindWindowByCaption(IntPtr ZeroOnly, string lpWindowName);
    
    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);
    

    And you may want to declare the WM_CLOSE constant:

    const UInt32 WM_CLOSE = 0x0010;
    

    Then the code to close the window (but keep the process running the in background):

    var startInfo = new ProcessStartInfo(@"c:\Users\Dmytro\AppData\Local\Viber\Viber.exe");
    startInfo.WindowStyle = ProcessWindowStyle.Hidden;
    var newProc = Process.Start(startInfo);
    
    var name = "Viber +381112223344";
    var windowPtr = FindWindowByCaption(IntPtr.Zero, name);
    
    while (windowPtr == IntPtr.Zero)
    {
        windowPtr = FindWindowByCaption(IntPtr.Zero, name);
    }
    
    System.Threading.Thread.Sleep(100);
    
    SendMessage(windowPtr, WM_CLOSE, IntPtr.Zero, IntPtr.Zero);