Como criar um aplicativo .NET Windows Forms que seja executado apenas na bandeja do sistema?

216

O que preciso fazer para executar um aplicativo Windows Forms na bandeja do sistema?

Não é um aplicativo que pode minimizar a bandeja, mas existe apenas na bandeja, com nada mais que um ícone, dica de ferramenta e menu "clique com o botão direito".

xyz
fonte
9
Há algo faltando na maioria das respostas - não esqueça de definir e icon.Visible = false, em seguida, Dispose()o ícone ao sair do aplicativo. Caso contrário, você ainda verá o ícone após a saída do programa. Depois de testá-lo algumas vezes, você não saberá mais qual ícone é real.
Tomasz Gandor
Se você é depois de uma abordagem WPF mais moderno - você pode tentar este: codeproject.com/Articles/36788/...
Murray Foxcroft

Respostas:

85

O artigo do projeto de código Criando um aplicativo da bandeja de tarefas fornece uma explicação e um exemplo muito simples da criação de um aplicativo que só existe na bandeja do sistema.

Altere basicamente a Application.Run(new Form1());linha Program.cspara iniciar uma classe que herda de ApplicationContexte faça com que o construtor dessa classe inicialize umNotifyIcon

static class Program
{
    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);

        Application.Run(new MyCustomApplicationContext());
    }
}


public class MyCustomApplicationContext : ApplicationContext
{
    private NotifyIcon trayIcon;

    public MyCustomApplicationContext ()
    {
        // Initialize Tray Icon
        trayIcon = new NotifyIcon()
        {
            Icon = Resources.AppIcon,
            ContextMenu = new ContextMenu(new MenuItem[] {
                new MenuItem("Exit", Exit)
            }),
            Visible = true
        };
    }

    void Exit(object sender, EventArgs e)
    {
        // Hide tray icon, otherwise it will remain shown until user mouses over it
        trayIcon.Visible = false;

        Application.Exit();
    }
}
Fawzan Izy
fonte
13
Este é um ótimo ponto de partida. Observe que "AppIcon" deve ser o nome de um recurso adicionado com "Projeto -> Propriedades -> Recursos -> Adicionar recurso" e recompile o projeto.
Lavamantis 8/09/16
1
Eu fiz propriedades .. recursos .. adicionar recurso .. ícone .. recompilado, ainda recebo "Erro CS0103 O nome 'Recursos' não existe no contexto atual" "
barlop
@ barlop Eu tive que escrevê-lo assim: Properites.Resources.AppIcon
Simon Perepelitsa
@SimonPerepelitsa obrigado, não tenho certeza do que fiz nas minhas experiências, quis comentar o que funcionou, mas devo ter esquecido algumas das coisas que fiz que funcionaram. Mas, em última análise, o método que usei foi arrastar um ícone de notificação da paleta de coisas que você pode arrastar. Em seguida, clique nele no formulário, clicando em uma pequena seta que abre um menu para escolher um ícone para ele!
barlop
17

Como o mat1t diz - você precisa adicionar um NotifyIcon ao seu aplicativo e, em seguida, usar algo como o código a seguir para definir a dica de ferramenta e o menu de contexto:

this.notifyIcon.Text = "This is the tooltip";
this.notifyIcon.ContextMenu = new ContextMenu();
this.notifyIcon.ContextMenu.MenuItems.Add(new MenuItem("Option 1", new EventHandler(handler_method)));

Este código mostra o ícone apenas na bandeja do sistema:

this.notifyIcon.Visible = true;  // Shows the notify icon in the system tray

O seguinte será necessário se você tiver um formulário (por qualquer motivo):

this.ShowInTaskbar = false;  // Removes the application from the taskbar
Hide();

O clique direito para acessar o menu de contexto é tratado automaticamente, mas se você deseja executar alguma ação com o botão esquerdo, precisará adicionar um manipulador de cliques:

    private void notifyIcon_Click(object sender, EventArgs e)
    {
        var eventArgs = e as MouseEventArgs;
        switch (eventArgs.Button)
        {
            // Left click to reactivate
            case MouseButtons.Left:
                // Do your stuff
                break;
        }
    }
ChrisF
fonte
15

Eu escrevi um aplicativo traybar com o .NET 1.1 e não precisava de um formulário.
Primeiro, defina o objeto de inicialização do projeto como um Sub Main, definido em um módulo.
Em seguida, crie programaticamente os componentes: o NotifyIcone ContextMenu.
Certifique-se de incluir um MenuItem"Sair" ou similar.
Vincule o ContextMenuao NotifyIcon.
Invocar Application.Run().
No manipulador de eventos para Quit, MenuItemcertifique-se de chamar set NotifyIcon.Visible = False, então Application.Exit(). Adicione o que você precisa ContextMenue manipule adequadamente :)

M.Turrini
fonte
10
  1. Crie um novo aplicativo do Windows com o assistente.
  2. Exclua Form1do código.
  3. Remova o código em Program.cs iniciando o Form1.
  4. Use a NotifyIconclasse para criar o ícone da bandeja do sistema (atribua um ícone a ela).
  5. Adicione um menu de contexto a ele.
  6. Ou reaja ao NotifyIconclique do mouse e à diferenciação entre o clique direito e esquerdo, configurando o menu de contexto e mostrando para qual botão foi pressionado (sempre / direito / esquerdo).
  7. Application.Run()para manter o aplicativo em execução e Application.Exit()sair. Ou a bool bRunning = true; while(bRunning){Application.DoEvents(); Thread.Sleep(10);}. Em seguida, defina bRunning = false;para sair do aplicativo.
Wolf5
fonte
O programa para de executar quando você chega ao final do Main e não possui thread da interface do usuário. Como você cuida disso é a sua solução? Se você resolveu esses problemas, então você começa meu voto :)
Matthew Steeples
Você recebe meu voto. Talvez apenas mencione que você ainda precisa chamar o Application.Run sem nenhum parâmetro.
Atualizado com uma alternativa ao App.Run.
Wolf5
O Thread.sleep é um exagero eu sei, mas se você tem uma melhor "dormir" alternativa loop para Application.Run fazer publicá-la :)
Wolf5
Thread.Sleep é uma péssima idéia: você acabará usando mais CPU e bateria do que se tivesse feito o Application.Run como deveria.
Sneftel 18/06
8

O aplicativo "Bandeja do sistema" é apenas um aplicativo regular de formulários de vitória, a única diferença é que ele cria um ícone na área de bandeja do sistema do Windows. Para criar o ícone sys.tray, use o componente NotifyIcon, você pode encontrá-lo na Caixa de ferramentas (controles comuns) e modificar suas propriedades: Ícone, dica de ferramenta. Também permite lidar com mensagens de clique e clique duplo do mouse.

E mais uma coisa, para obter aparência e funcionalidade ou aplicativo de bandeja padrão. adicione linhas followinf no seu evento principal show de formulário:

private void MainForm_Shown(object sender, EventArgs e)
{
    WindowState = FormWindowState.Minimized;
    Hide();
} 
Gordon Freeman
fonte
6

Tanto quanto sei, você ainda precisa escrever o aplicativo usando um formulário, mas não tem controles no formulário e nunca o define como visível. Use o NotifyIcon (uma amostra do MSDN pode ser encontrada aqui ) para gravar seu aplicativo.

Matthew Steeples
fonte
1
Não é bem assim. Seus formulários podem conter controles, mas devem estar ocultos por padrão.
Rune Grimstad
5
Você não precisa de nenhum formulário. Após um novo assistente de criação do Windows App, exclua o Form1 e remova o código que o abre. Você pode escrever tudo no Program.cs com o NotifyIcon e o ContextMenu. Nada mais necessário.
Wolf5
1
Eu sei que pode conter controles, mas não OP não quer que ele
Matthew Steeples
2

Aqui está como eu fiz isso com o Visual Studio 2010 , .NET 4

  1. Crie um aplicativo Windows Forms, defina 'Criar aplicativo de instância única' nas propriedades
  2. Adicionar um ContextMenuStrip
  3. Adicione algumas entradas à faixa do menu de contexto, clique duas vezes nelas para obter os manipuladores, por exemplo, 'exit' (clique duas vezes) -> manipulador -> me.Close ()
  4. Adicione um NotifyIcon, no conjunto de designers contextMenuStrip ao que você acabou de criar, escolha um ícone (você pode encontrar alguns na pasta VisualStudio em 'common7 ...')
  5. Defina propriedades para o formulário no designer: FormBorderStyle: none, ShowIcon: false, ShowInTaskbar: false, Opacidade: 0%, WindowState: Minimized
  6. Adicione Me.Visible = false no final do Form1_Load, isso ocultará o ícone ao usar Ctrl+Tab
  7. Execute e ajuste conforme necessário.
Evoluído
fonte
2

É uma estrutura muito amigável para o aplicativo da área de notificação ... basta adicionar o NotificationIcon ao formulário base e alterar o código gerado automaticamente para o código abaixo:

public partial class Form1 : Form
{
    private bool hidden = false;

    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        this.ShowInTaskbar = false;
        //this.WindowState = FormWindowState.Minimized;
        this.Hide();
        hidden = true;
    }

    private void notifyIcon1_Click(object sender, EventArgs e)
    {
        if (hidden) // this.WindowState == FormWindowState.Minimized)
        {
            // this.WindowState = FormWindowState.Normal;
            this.Show();
            hidden = false;
        }
        else
        {
            // this.WindowState = FormWindowState.Minimized;
            this.Hide();
            hidden = true;
        }
    }
}
Sebastian Xawery Wiśniowiecki
fonte
-2

Basta adicionar

this.WindowState = FormWindowState.Minimized;
this.ShowInTaskbar = false;

ao seu objeto de formulário. Você verá apenas um ícone na bandeja do sistema.

YTerle
fonte
Isso coloca o formulário acima da barra de tarefas. Não é a mesma coisa. Você está tentando responder a outra postagem?
LarsTech 01/07
1
Não há um ícone na barra de tarefas, não vemos o formulário. Visualmente, o programa existe apenas na bandeja do sistema. O que significa acima ?
YTerle
Sua resposta não contém nenhum contexto. Você está usando a classe NotifyIcon? Caso contrário, seu formulário será minimizado no canto inferior esquerdo acima da barra de tarefas.
LarsTech 01/07
1
Se você não estiver ocupado, tente escrever e executá-lo.
YTerle