Autor Beitrag
vreden123
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 95
Erhaltene Danke: 2



BeitragVerfasst: Mo 03.01.11 22:40 
Hallo,

ich habe folgendes Problem, wenn mein Programm aus den Autostart gestartet wird soll es nur im Tray starten. Wird es per Desktopverknüpfung gestartet, soll es ganz normal starten, also sich auch richtig öffnen.

Ich mein ich habe schon irgendwo gelesen bzw. gehört das man Variablen genauso wie bei PHP Variablen per GET Methode übergeben kann, oder liege ich da falsch?

Also ich habe eine .exe Datei und einmal muss ich der Datei sagen das, dass Programm nur im Tray gestartet werden muss und einmal nicht, wie mache ich das am besten?
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4808
Erhaltene Danke: 1061

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Mo 03.01.11 23:01 
Am einfachsten per "Kommandozeilenparameter" (bzw. auch "Befehlszeilenparameter" genannt): openbook.galileocomp.../kap26.htm#Xxx758525

Und dann für den Autostart z.B. "/tray" als Parameter angeben.
Und im Code dann entsprechend abfragen:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
void Main(string[] args)
{
  if(args.Length > 0 && args[0].ToLower() == "/tray")
  {
    // im Tray starten
  }
  else
  {
    // normal starten
  }
Yogu
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2598
Erhaltene Danke: 156

Ubuntu 13.04, Win 7
C# (VS 2013)
BeitragVerfasst: Di 04.01.11 00:24 
Oder, wenn es sich nicht um eine Konsolen-, sondern um eine Windows-Forms-Anwendung handelt, Environment.GetCommandLineArgs() :les:
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4808
Erhaltene Danke: 1061

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Di 04.01.11 12:12 
Hallo Yogu,

das spielt keine Rolle (auch eine GUI-Anwendung kann die Parameter direkt so abfragen) - nur bei C bzw. C++ Programmen gibt es diesen Unterschied bzgl. main() und WinMain()!
Yogu
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2598
Erhaltene Danke: 156

Ubuntu 13.04, Win 7
C# (VS 2013)
BeitragVerfasst: Di 04.01.11 13:14 
user profile iconTh69 hat folgendes geschrieben Zum zitierten Posting springen:
das spielt keine Rolle

Es spielt in sofern eine Rolle, dass in Windows-Forms-Anwendungen die Program.cs normalerweise nicht geändert wird, sondern die Parameterabfrage im Quelltext des Hauptformulars stattfindet. Schließlich muss das Fenster erstmal geladen werden, bevor das Tray-Icon verfügbar ist.

Denkbar wäre es natürlich auch, den args-Parameter in der Program.cs auszuwerten und dem Konstruktor der Fensterklasse mitzuteilen, ob das Programm in den Tray verschwinden soll oder nicht.
vreden123 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 95
Erhaltene Danke: 2



BeitragVerfasst: Di 04.01.11 13:47 
Also ich habe jetzt folgenden Code:

String[] arguments = Environment.GetCommandLineArgs();

Wie muss ich jetzt das Programm starten damit, ein wert übergeben wird?

Muss das folgerndermaßen lauten:

programm.exe/tray

oder wie muss ich das Programm starten, damit die Variable arguments den wert tray bekommt?
Yogu
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2598
Erhaltene Danke: 156

Ubuntu 13.04, Win 7
C# (VS 2013)
BeitragVerfasst: Di 04.01.11 14:16 
user profile iconvreden123 hat folgendes geschrieben Zum zitierten Posting springen:
Muss das folgerndermaßen lauten:

programm.exe/tray

Da fehlt noch ein Leerzeichen. Und wenn der Dateiname Leerzeichen enthält, muss er in Anführungszeichen gesetzt werden.

ausblenden Quelltext
1:
"Pfad zur Datei\programm.exe" /tray					

user profile iconvreden123 hat folgendes geschrieben Zum zitierten Posting springen:
oder wie muss ich das Programm starten, damit die Variable arguments den wert tray bekommt?

Die Variable arguments wird ein Array mit einem Element "/tray" sein.
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4808
Erhaltene Danke: 1061

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Di 04.01.11 16:43 
Yogu hat folgendes geschrieben:

Denkbar wäre es natürlich auch, den args-Parameter in der Program.cs auszuwerten und dem Konstruktor der Fensterklasse mitzuteilen, ob das Programm in den Tray verschwinden soll oder nicht.

Genau das ist der richtige Weg :)

Und zu
Yogu hat folgendes geschrieben:

Es spielt in sofern eine Rolle, dass in Windows-Forms-Anwendungen die Program.cs normalerweise nicht geändert wird, ...

Ein sauberes Exception-Handling gehört auf jeden Fall in die Main-Methode (und dafür muß eben die Program.cs - oder wie sie auch immer heißt :wink: - geändert werden)!
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4708
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Di 04.01.11 17:23 
Zitat:
Ein sauberes Exception-Handling gehört auf jeden Fall in die Main-Methode


Da muss ich zumindest bei einer Winforms Anwendung widersprechen. Sobald kein Debugger attached ist wird eine Exception bereits in Application.Run gefangen und wird es nicht bis zur Main Methode schaffen. Ein Exception-Handling in der Main Methode um Application.Run ist also sinnfrei (bei einer Winforms Anwendung!) da man da nie im catch landen wird.

Persönlich würde ich unabhängig davon eher zu Environment.GetCommandLineArgs() greifen. Das kann ich von überall her benutzen, z.B von einem Plugin das von n verschiedenen Anwendungen benutzt wird ohne die konkret verwendete Main Methode zu kennen. Ich schreibe aber explizit eher. Beides geht und beides hat je nach Anwendungsfall mehr oder weniger Sinn.
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4808
Erhaltene Danke: 1061

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Di 04.01.11 19:59 
Hallo Ralf,

hast du das alles schon ausprobiert oder schreibst du das nur, weil du denkst, daß es so ist?
Ich frage, weil sonst meine ganzen Logging-Routinen (bzw. im Debug-Modus auch MessageBoxen) dann ja gar nicht ausgegeben werden dürften ;-)
Und jedes professionelle WinForms-Programm, das ich gesehen habe, hat eine ähnliche Behandlung (d.h. try/catch als auch Abfangen des Application.ThreadException sowie AppDomain.UnhandledException-Ereignisses).
(s.a. msdn.microsoft.com/e...sw%28v=vs.80%29.aspx unter 'When to handle "Exception" sowie ein sehr guter Beitrag unter Getting Better Information on Unhandled Exceptions).

Nichts für ungut, bist du aber vllt. noch auf dem Stand von .NET 1.x?
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4708
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Di 04.01.11 21:38 
Habe ich probiert. Ich bezog mich auf deine Aussage 'es gehört in die Main-Methode'. Und das impliziert für mich den folgenden naiven Ansatz des Kapseln von Application.Run mit einem try ... catch.

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
try
{
   Application.Run(new MeineLiebeForm())
}
catch(Exception e)
{
   MeinLiebesExceptionHandling(e);
}


Das wird wie gesagt nicht funktionieren. In keiner Version des Frameworks. Du wirst immer im Standard ExceptionHandler der Application Klasse(Annahme Single Thread Anwendung) landen. Das angesprochene Application.ThreadException ist der richtige Weg. Es ist aber nicht ganz das was ich unter 'in der Main-Methode behandeln' verstehen würden nur weil der Event in der Main Methode verdrahtet wurde. Die Exception wird natürlich in der Application Klasse behandelt und an den eventuell vorhandene EventHandler geroutet und eben nicht in Main.

Das ganze ist wahrscheinlich mehr Haarspalterei meinerseits als Unverständnis auf meiner oder deiner Seite ;)
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4808
Erhaltene Danke: 1061

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Mi 05.01.11 13:03 
Hallo Ralf,

ok, dann haben wir uns wohl mißverstanden.
Ich bezog mich ja auch generell auf eine Änderung in der Main-Methode, d.h. auch das Hinzufügen von
ausblenden C#-Quelltext
1:
Application.ThreadException += Application_ThreadException;					

sollte ja in der Main-Methode (d.h. vor Application.Run(...)) passieren.

Ich hatte mal Source-Code bekommen, wo jemand grundsätzlich in alle EventHandler ein
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
try
{
  ...
}
catch
{
}

eingebaut hatte (d.h. wirklich alle Exceptions gefangen, ohne sie zu behandeln, d.h. das Programm lief einfach "munter" weiter...)!!!
(und das selbst noch bei Portierung auf 2.0!), so daß ich in Bezug auf (falsches) ExceptionHandling allergisch reagiere...

Dein Satz
Ralf Jansen hat folgendes geschrieben:

... wird eine Exception bereits in Application.Run gefangen ...

liest sich, als ob es gar keine Möglichkeit gibt, die Exception selber zu behandeln (daher mein Hinweis auf Application.ThreadException und AppDomain.UnhandledException).

P.S. Ein try/catch um Application.Run ist z.B. dann sinnvoll, um Exceptions zubehandeln, welche im Konstruktor der aufgerufenen MainForm auftreten, z.B.
ausblenden volle Höhe C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
// Program.cs
namespace TestApp
{
  static class Program
  {
    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main()
    {
      try
      {
        Application.ThreadException += Application_ThreadException;

        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new TestForm());
      }
      catch (Exception e)
      {
        MessageBox.Show(e.Message, "Main Error");
      }
    }

    static void Application_ThreadException(object sender, ThreadExceptionEventArgs e)
    {
      MessageBox.Show(e.Exception.Message, "Thread Exception Error");
    }
  }
}

// TestForm.cs
namespace TestApp
{
  public partial class TestForm : Form
  {
    public TestForm()
    {
      InitializeComponent();

      throw new Exception("Exception");
    }
  }
}

Ohne den try/catch in der Main-Methode käme dann der tolle Windows-Dialog "TestApp hat ein Problem festgestellt und muß beendet werden!".
Sobald jedoch die Run-Methode läuft, so werden dann wirklich alle Exceptions (des Mainthreads) an Application.ThreadException weitergeleitet.