Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

  • »
  • Community
  • |
  • Diskussionsforum
Via cmd Befehl in laufendes Programm schreiben
DannyDzWare
myCSharp.de - Member



Dabei seit:
Beiträge: 5

Themenstarter:

Via cmd Befehl in laufendes Programm schreiben

beantworten | zitieren | melden

Hallo zusammen und Guten Abend,

ich bin erneut auf der Suche nach einer Gedankenstütze. Ich habe bereits einige Zeit dem Googeln gewidmet, bisher aber ohne Erfolg. Ich schätze aber, es liegt daran, dass ich nicht genau weiß, wonach ich suche. Ok, das klingt witzig. Ich versuche mal zu erklären, wonach ich suche:

Ich habe folgende Herausforderung: Ich verwende ein Programm, dass in der Ausführung einen vereinfachten Codeeditor besitzt. Mit diesem ist es immerhin möglich, dass man via Run Befehl ein Programm mit Argumenten starten kann. Ich habe ein eigenes Programm geschrieben, was ein paar Funktionen ergänzt. Bisher nutze ich aber die umständliche Möglichkeit, dass ich Befehle in eine Textdatei schreibe, die dann wiederum von meinem Programm ausgelesen werden. Ich würde es lieber haben, dass ich quasi mein Programm starte und dann via cmd Befehl direkt in das offene Programm auf Variablen schreiben bzw. Ereignisse auslösen kann. Z.B. MeinProgramm -StarteProgramm1 -Variable2:IrgendeinWert
Welche Möglichkeit habe ich? Wonach muss ich gezielter Suchen?
Ist es überhaupt möglich?

Wie gesagt, die Herausforderung ist, dass das verwendete Programm eigentlich keine Möglichkeiten bereitstellt mit der Außenwelt zu kommunizieren.
Vielen Dank für eure Hilfe. Wenn ihr weiterführende Fragen habt, lasst es mich bitte wissen.

Liebe Grüße
Daniel Dzierzon
private Nachricht | Beiträge des Benutzers
Platoon
myCSharp.de - Member



Dabei seit:
Beiträge: 55
Herkunft: NRW

beantworten | zitieren | melden

Hallo,

wenn es sich um eine Konsolenapplikation dreht, dann nutze doch Command Line Args aus der Main-Methode dafür.

Du kannst das auch auf andere Applikationstypen (Winforms, WPF etc.) recht leicht adaptieren.

Gruß :-)
.....an unhandled exception is the first way to think about your pattern of programming....
.....nur weil ich nicht weiß was dort passiert, bedeutet es nicht, dass ich nicht weiß, wie man es lösen kann - aber das ist wahrscheinlich....
private Nachricht | Beiträge des Benutzers
DannyDzWare
myCSharp.de - Member



Dabei seit:
Beiträge: 5

Themenstarter:

beantworten | zitieren | melden

Hi Platoon, vielen Dank für die Antwort.
Dabei fiel mir auf, dass ich total vergessen habe, zu sagen, was ich nutze. Mein Programm ist eine Windows Form.
Dass mit den Command Line Args ist mir ein bisschen geläufig.
Ich habe es geschafft, dass das Programm gestartet werden kann mit Argumenten. Das funktioniert sehr gut.
Das Problem was ich gerade sehe, ist, dass ich damit ja immer wieder ein "neues" Programm Aufrufe.
Wie muss ich es schreiben, dass diese Argumente in das bereits offene Programm einfließen?

Danke nochmal für die Antwort.
Schönen Abend noch.
private Nachricht | Beiträge des Benutzers
Palladin007
myCSharp.de - Member

Avatar #avatar-4140.png


Dabei seit:
Beiträge: 1.782
Herkunft: Düsseldorf

beantworten | zitieren | melden

Zitat
Wie muss ich es schreiben, dass diese Argumente in das bereits offene Programm einfließen?
Das ist deutlich komplexer

Es gibt verschiedene Wege, der heute vermutlich einfachste Weg (weil es sehr gutes Tools gibt) wäre eine Web-API, die Du aus deinem ominösen Skript-Programm heraus aufrufst.
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von Palladin007 am .
private Nachricht | Beiträge des Benutzers
FZelle
myCSharp.de - Experte



Dabei seit:
Beiträge: 9.976

beantworten | zitieren | melden

Ist eigentlich nicht so schwer.

Es gibt im Namespace Microsoft.VisualBasic die Klasse https://docs.microsoft.com/en-us/dotnet/api/microsoft.visualbasic.applicationservices.windowsformsapplicationbase?view=windowsdesktop-6.0
Wenn du deine Program Klasse davon ableitest, bekommst du z.b. die überschreibbare Methode OnStartupNextInstance
Siehe what-is-the-correct-way-to-create-a-single-instance-wpf-application/19326#19326
Die frage ist zwar über WPF, aber als das "erfunden" wurde gab es WPF noch garnicht
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von FZelle am .
private Nachricht | Beiträge des Benutzers
dannoe
myCSharp.de - Member



Dabei seit:
Beiträge: 218

beantworten | zitieren | melden

Suchst du vielleicht eine REPL (Read-Eval-Print-Loop)?
Also eine Schleife (Loop), in der du immer wieder Eingaben vom Benutzer abfragen kannst (Read), diese verarbeitest (Eval) und anschließend das Ergebnis ausgibst (Print).
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von dannoe am .
private Nachricht | Beiträge des Benutzers
DannyDzWare
myCSharp.de - Member



Dabei seit:
Beiträge: 5

Themenstarter:

beantworten | zitieren | melden

Guten Morgen,
danke für die vielen Antworten bereits. Ich muss sagen, dass ich die Verlinkung, die FZelle gegeben hat, sehr hilfreich schon finde.
Ich habe das jetzt schon mal in ein neues Testprogramm integriert. Es sieht so aus:

Klasse NativeMethods.cs


using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace Testen
{
    internal class NativeMethods
    {
        public const int HWND_BROADCAST = 0xffff;
        public static readonly int WM_SHOWME = RegisterWindowMessage("WM_SHOWME");
        [DllImport("user32")]
        public static extern bool PostMessage(IntPtr hwnd, int msg, IntPtr wparam, IntPtr lparam);
        [DllImport("user32")]
        public static extern int RegisterWindowMessage(string message);

        public static string[] Argumente;
    }
}

Program.cs


using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Testen
{
    internal static class Program
    {
        /// <summary>
        /// Der Haupteinstiegspunkt für die Anwendung.
        /// </summary>
        static Mutex mutex = new Mutex(true, "{8F6F0AC4-B9A1-45fd-A8CF-72F04E6BDE8F}");
       
        [STAThread]
        static void Main(string[] args)
        {
            string[] CommandLineArgs;
            if (mutex.WaitOne(TimeSpan.Zero, true))
            {
                CommandLineArgs = Environment.GetCommandLineArgs();
                Application.EnableVisualStyles();
                Application.SetCompatibleTextRenderingDefault(false);
                Application.Run(new Form2(CommandLineArgs));
                mutex.ReleaseMutex();
            }
            else
            {
                // send our Win32 message to make the currently running instance
                // jump on top of all the other windows
               CommandLineArgs = Environment.GetCommandLineArgs(); //Hier werden nochmal die Argumente abgefragt
                NativeMethods.Argumente = CommandLineArgs;
                MessageBox.Show("Test " + CommandLineArgs[1]);
                NativeMethods.PostMessage(
                    (IntPtr)NativeMethods.HWND_BROADCAST,
                    NativeMethods.WM_SHOWME,
                    IntPtr.Zero,
                    IntPtr.Zero);
            }
        }
    }
}

Die eigentliche Form Form2.cs


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Testen
{
    public partial class Form2 : Form
    {
        public string[] parameter;
        public Form2(string[] args)
        {
            parameter = args;
            InitializeComponent();
        }

        private void Form2_Load(object sender, EventArgs e)
        {
            if(parameter.Length > 1)
            {
                this.Text += parameter[1];
            }
        }
        protected override void WndProc(ref Message m)
        {
            if (m.Msg == NativeMethods.WM_SHOWME)
            {
               parameter = NativeMethods.Argumente;
               MessageBox.Show(parameter[1].ToString()); 
                
                ShowMe();
                if (parameter != null && parameter.Length > 1)
                {
                    this.Text = parameter[1];
                }
            }
            base.WndProc(ref m);
        }
        private void ShowMe()
        {
            if (WindowState == FormWindowState.Minimized)
            {
                WindowState = FormWindowState.Normal;
            }
            // get our current "TopMost" value (ours will always be false though)
            bool top = TopMost;
            // make our form jump to the top of everything
            TopMost = true;
            // set it back to whatever it was
            TopMost = top;
        }
    }
}


Was das Programm bisher macht ist, dass es beim ersten Aufruf startet und der Wert unter parameter[1] wird dem Form Titel Text hinzugefügt. Das funktioniert einwandfrei.
Wenn ich das Programm ein weiteres Mal starte mit einem anderen Argument[1], dann erscheint auch brav die "Messagebox" mit "Test xxxx" und danach "Es läuft doch schon" und dann wird aber der Titel nicht geändert. Ich hatte es vorher etwas anders gehabt, da sagte es mir, dass die Variable parameter = null ist. Wenn ich so drüber nachdenke, ist es ja auch logisch, weil ich ja quasi zwei Programme betrachten muss. Und das eine bekommt nicht die Variable, die in dem anderen Programm gesetzt wird. Das 2. Programm hat lediglich die Info, ob ein gleiches Programm bereits läuft.
Jetzt stehe ich aber auf dem Schlauch. Wie kann ich denn die argumente aktualisieren? Also, dass die Argumente von Programm 2 in das bereits offene Programm gelangen?
Ich hätte daran gedacht, dass er unter dem void WndProc wieder neu ausgewertet werden muss, leider weiß ich nicht, wie ich das hinkriege.

Könnt ihr mir da nochmal helfen bitte.

Vielen Dank auf jeden Fall für euer Feedback. Das hilft mir sehr und Danke auch für die Gedankenstütze, sodass ich schon mal auf dem richtigeren Weg bin.

Liebe Grüße
Daniel
Dieser Beitrag wurde 2 mal editiert, zum letzten Mal von DannyDzWare am .
private Nachricht | Beiträge des Benutzers
Th69
myCSharp.de - Experte

Avatar #avatar-2578.jpg


Dabei seit:
Beiträge: 4.358

beantworten | zitieren | melden

Hallo,

in "Nur eine Instanz pro Anwendung" featuring IPC gibt es dafür eine Klasse, welche das kapselt.
Und auf Seite 2 habe ich dafür eine aktualisierte und verbesserte Version zur Verfügung gestellt (du müßtest dort nur einen Account anlegen, um die Anhänge zu sehen).
Mittels des Delegat OnAddArgs werden dann die neuen Parameter übergeben.

In deinem Code müßtest du ja mittels des Broadcast die Parameter an die andere (Haupt)Anwendung senden (und gerade das ist ja der entscheidende Teil der Inter-Process-Communication [IPC]).
private Nachricht | Beiträge des Benutzers
FZelle
myCSharp.de - Experte



Dabei seit:
Beiträge: 9.976

beantworten | zitieren | melden

Was hat das mit dem zu tun was ich verlinkt habe?

Mit mit WindowsFormsApplicationBase brauchst du das ganze geraffel nicht.

Hier noch einmal wie es einfacher geht
using-microsoft-visualbasic-applicationservices-to-manage-an-applications-singl
private Nachricht | Beiträge des Benutzers