Laden...

Forenbeiträge von DannyDzWare Ingesamt 5 Beiträge

29.03.2022 - 07:17 Uhr

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

28.03.2022 - 21:02 Uhr

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.

28.03.2022 - 20:33 Uhr

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

28.03.2022 - 20:20 Uhr

Super. Vielen Dank für die Hinweise und die Gedankenhilfe.
Ich werde mich damit weiter beschäftigen.

22.02.2022 - 18:41 Uhr

Hallo zusammen.
Ich habe eine Frage, die mir gerne Denkanstöße bzw. Lösungsvorschläge liefern sollte.
Ich habe ein Programm geschrieben, dass im Netzwerk arbeitet. Es gibt dabei einen Master und theoretisch beliebig viele Clients (wobei im Anwendungsfall maximal 4 vorhanden sein werden). Im Hauptprogramm habe ich eine CSV in ein DGV geladen. Dort stehen unter anderem Schaltzeiten drin. Die CSV Datei befindet sich auf dem Master PC und die Clients haben quasi ihren Zugriff im Netzwerk auf den Ordner mit den entsprechenden Dateien.
Nun möchte ich, dass alle Clients auch diese Tabelle sehen und auch bearbeiten können. Lediglich die Ausführung, also das was geschalten werden soll, soll beim Master passieren. Ich habe das bisher so gelöst, dass ich in der Ini Datei jeweils vorgebe, ob es sich um Master oder Client handelt und dementsprechend werden einige Funktionen gestartet oder eben nicht.
Dann benutze ich einen Textdatei, die von allen gelesen wird, wo drin steht, welcher Client/Master gerade aktiv im Bearbeitungsmodus ist. Der Aktive Bearbeiter schreibt seinen eindeutigen Namen da rein und nach Abmeldung wird es wieder zurückgesetzt.
Bei allen, die nicht bearbeiten, ist dann quasi die Oberfläche gesperrt(mittels panel.enabled= false). Die Tabelle kann immer nur von einem bearbeitet werden und wird dann gespeichert. Dabei wird die CSV Datei auf dem Master PC überschrieben. In regelmäßigen Abständen schauen alle (Master/Clients) ob sich die Datei verändert hat und lesen sie dann neu ein.
Meine Frage ist jetzt, kann man das relativ einfach im Hintergrund laufen lassen?
Ich stelle mir das ungefähr so vor. Auf PC_Master wird z.B. eine Variable definiert mit dem Namen "aktiverBenutzer", und wenn ich jetzt bearbeiten will, dann schauen die Clients im Netzwerk auf PC_Master.aktiverBenutzer und sehen, dass sie den Wert "Frei"/"Belegt" hat. Oder so ähnlich. Geht das einfach umzusetzen oder muss ich mich da schon in die Tiefen reinbegeben und lasse es erstmal bei meiner "einfachen" Lösung.

Ich möchte quasi weg von den Dateien, die man ja auch manipulieren kann. Jeder kann eine Textdatei öffnen und dann Werte da verändern und so weiter.

Ich arbeite mit Visual Studio 2022 und erstelle immer Windows Forms.

Ich hoffe, es macht etwas Sinn.

vielen Dank für eure Hilfe im voraus.

LG
Daniel