Announcement

Collapse
No announcement yet.

Objekt-Übergabe an .NET Anwendung

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Objekt-Übergabe an .NET Anwendung

    Hallo,

    Ich habe eine kleine .NET Anwendung geschrieben, die labidar zusammengefasst dazu dient, Daten für einen Auftrag zu sammeln.
    Dieses Formular möchte ich nun dahingehend erweitern, dass ich aus diesen Daten direkt einen Beleg erzeugen kann.
    Für die Beleginitialisierung benötige ich allerdings ein Mandanten-Objekt, das mir an der Stelle nicht zur Verfügung steht.

    Dieses Objekt steht mir allerdings zum Zeitpunkt des Aufrufs des Formulars zur Verfügung, so dass ich eine Möglichkeit suche, diese an die Anwendung zu übergeben.
    Per CommandLineArgs bekomme ich ja nur String-Werte übergeben.

    Gibt es eine Möglichkeit, dass ich der Main() oder der Form1() auf ein externes Objekt zugreife?
    Die entsprechenden Assemblies, um mit dem Objekt zu handeln habe ich bereits als Verweis in meinem Projekt hinterlegt und habe darauf auch Zugriff.
    Ich müsste jetzt nur noch ein entsprechendes Objekt damit casten.

    Danke für Tipps und/oder Hinweise
    Gruß Arne
    PHP rocks!
    Eine Initiative der PHP Community

  • #2
    Mir ist nicht ganz klar was du möchtest aber google mal nach WCF oder "Interprocess Communication"

    Comment


    • #3
      Hi,

      Danke für den Hinweis.
      Der Begriff "Interprocess Communication" war mir nicht geläufig, denke aber dass ich den Ansatz schon getestet habe.

      Ich habe hierfür die Methode über das Clipboard-Objekt gewählt.
      Diesem habe ich mit Clipboard.setData( "my.object.type", myObject ) das Objekt zugewiesen und erhalte auch ein true in der .NET Applikation, wenn ich das mit Clipboard.ContainsData( "my.object.type" ) abfrage.
      Im nächsten Step bekommt er allerdings die Zuweisung nicht sauber hin.

      Ich werde die anderen Wege der IC auch noch mal testen, danke!


      Gruß Arne


      Originally posted by Wernfried
      Mir ist nicht ganz klar was du möchtest [...]
      Wir arbeiten mit einer Warenwirtschaft, die über Schnittstellen anpassbar/erweiterbar ist. Diese Schnittstellen kann ich mit C#.NET tlw. befüllen.
      Innerhalb dieser Schnittstellen sind aber Formulare und Listen "größerer" Datenmengen sehr langsam, weshalb ich die Möglichkeit nutze für bestimmte Dinge "auszubrechen".

      Ich schnappe mir dann mein Visual Studio und erstelle eine kleine Form-Applikation, die schnell und individuell für die User bedienbar ist.
      Den "Ausbruch" führe ich über einen Process und den entsprechenden ProcessStartInfo-Informationen aus.
      Wenn der User die Arbeit am Formular beendet hat, läuft die Funktion aus der Schnittstelle automatisch weiter un verarbeitet die Daten, die von der .NET Applikation in einer Datenbank abgelegt wurden.

      Ich würde nun diese Weiterverarbeitung gerne im .NET Formular integrieren.
      Mein Problem dabei ist, dass ich für bestimmte Aufgaben das Mandanten-Objekt der WaWi benötige, das mir natürlich in der Schnittstelle selbst zur Verfügung steht.
      Dieses Mandanten-Objekt möchte ich an die .NET-Applikation weiterreichen, um es dort zu verwenden.

      Mir geht es nicht um Lizenz-Umgehung. Mir ist klar, dass bei meinem Vorhaben temporär eine Lizenz "verbraucht" wird, was absolut akzeptabel ist.
      Mit dem Tool arbeitet eh nur eine Person maximal zur selben Zeit, so dass sich das mit den Lizenzen in Grenzen hält.
      Und i.d.R. sollte man innerhalb von einigen Minuten mit dem Formular durch sein, so dass die Lizenz wieder frei wird.

      Ich hoffe, das gibt es etwas verständlicher wieder?
      PHP rocks!
      Eine Initiative der PHP Community

      Comment


      • #4
        Tatsächlich schwer verständlich vielleicht die Frage mit ein paar mehr Details anreichern.

        Man könnte erraten das das Formular und das Beleg erzeugen 2 verschiedene Programme sind? Gleichzeitig sprichst du von Referenzen auf irgendwas. Ist damit etwas 3.tes gemeint das die Programmteile bezüglich Mandant enthalten? Wenn ja wo ist dann das Problem du hast ein Referenz also benutz einfach die Dinge die in dieser Assembly stecken?

        Comment


        • #5
          Ev. das Objekt serialisieren und als String dem anderen Prozess übergeben
          Christian

          Comment


          • #6
            Originally posted by Ralf Jansen View Post
            Tatsächlich schwer verständlich vielleicht die Frage mit ein paar mehr Details anreichern.

            Man könnte erraten das das Formular und das Beleg erzeugen 2 verschiedene Programme sind? Gleichzeitig sprichst du von Referenzen auf irgendwas. Ist damit etwas 3.tes gemeint das die Programmteile bezüglich Mandant enthalten? Wenn ja wo ist dann das
            Problem du hast ein Referenz also benutz einfach die Dinge die in dieser Assembly stecken?
            Nein, nicht ganz, also nochmal Schritt für Schritt:

            Ich befinde mich grundsätzlich in der Umgebung der hier eingesetzten WaWi ( Warenwirtschaft ).
            Diese kann ich über Schnittstellen erweitern, wozu ich C#.NET verwende.

            Innerhalb dieser Schnittstelle habe ich alles, was ich benötige, eben auch das Mandantenobjekt!
            Nur sind die Formulare innerhalb dieser Schnittstellen sehr langsam und nicht schön zu bedienen.

            Daher "springe" ich aus der Schnittstelle mittels Process.Start() in eine eigene kleine .NET-Applikation, in der die Benutzer über DataGridViews deutlich performanter und effektiver die Daten "verwalten" können.
            Aus diesen Daten möchte ich nun bestimmte Belegarten erstellen, wozu ich aber das Mandantenobjekt benötige.
            Da ich das nicht in der .NET-Applikation habe, beende ich diese und lande wieder in der WaWi-Schnittstelle, in der ich das entsprechende Objekt habe und Belege erzeugen kann.

            Dieses Hin- und Hergespringe gefällt mir nicht, weshalb ich gerne die Belegerzeugung in der .NET Applikation machen möchte.

            Ich suche also nur eine Möglichkeit, vor bzw. bei dem Aufruf der .NET Applikation das Mandantenobjekt zu übergeben.
            Nichts drittes also, sondern einfach nur zwei Komponenten: WaWi-Schnittstelle und eigene .NET Applikation


            Originally posted by Christian Marquardt
            Ev. das Objekt serialisieren und als String dem anderen Prozess übergeben
            Das werde ich nochmal probieren, danke!
            PHP rocks!
            Eine Initiative der PHP Community

            Comment


            • #7
              Daher "springe" ich aus der Schnittstelle mittels Process.Start()
              Und wieso kannst du an der Stelle wo du Process.Start() aufrufst nicht einfach ein Form.Show() aufrufen? Oder irgendwas equivalentes das auch in der anderen Anwendung passiert? Wenn du ein Process.Start() da hinprogrammiert bekommst dann kannst du bestimmt auch die Anwendung die du da startest auch direkt referenzieren und entsprechend denn darin enthaltenen Code ausführen ohne einen neuen Prozess abzuspalten.

              Comment


              • #8
                Originally posted by Ralf Jansen View Post
                Und wieso kannst du an der Stelle wo du Process.Start() aufrufst nicht einfach ein Form.Show() aufrufen? Oder irgendwas equivalentes das auch in der anderen Anwendung passiert? Wenn du ein Process.Start() da hinprogrammiert bekommst dann kannst du bestimmt auch die Anwendung die du da startest auch direkt referenzieren und entsprechend denn darin enthaltenen Code ausführen ohne einen neuen Prozess abzuspalten.
                Wenn das geht, gerne. Aber wie soll ich denn das Formular aus meiner eigenen .exe direkt ansprechen?!
                Ich befinde mich doch an der Stelle noch gar nicht in meiner eigenen .NET Applikation.

                Um das mal auf ein simpelstes Beispiel runterzubrechen:
                Stell Dir vor, Du hast zwei von einander völlig unabhängige .exe-Dateien, nennen wir sie WaWi.exe und Formular.exe.
                Du startest und arbeitest innerhalb der WaWi.exe und alles ist soweit gut.
                Jetzt kommt aber der Moment, in dem ich eine weitere Anwendung starte ( mein .NET Formular! ), welche sich in Formular.exe befindet.
                Wenn Du mir sagst, wie ich nun anders als mit Process.Start() die Formular.exe sinnvoll starten soll, versuche ich das gerne.

                Hinweis: Mit WaWi.exe ist hier nur beispielhaft die Warenwirtschaft gemeint, in der sich der Benutzer im Standard aufhält.


                Gruß Arne
                PHP rocks!
                Eine Initiative der PHP Community

                Comment


                • #9
                  Wenn ich es richtig verstanden habe dann hast du es geschafft innerhalb der WaWi.exe deinen eigenen Code auszuführen eben denn Process.Start Aufruf. Dann solltest du da doch auch genauso anderen Code ausgeführt bekommen?

                  Wenn das geht, gerne. Aber wie soll ich denn das Formular aus meiner eigenen .exe direkt ansprechen?!
                  Ich befinde mich doch an der Stelle noch gar nicht in meiner eigenen .NET Applikation.
                  Ich bezweifle noch das du einen weiteren Prozess brauchst. Nach dem was du beschreibst kann man Code in der anderen Anwendung auch ausführen. Zumindest hast du nirgendwo explizit von Einschränkungen gesprochen. Das was wir wissen ist das du dort ein Process.Start() ausgeführt hast udn über Net Funktionen auch am Clibboard rumgespiel hast. Mir ist nicht ersichtlich warum dieser Code geht aber was anderes geht nicht.
                  Zuletzt editiert von Ralf Jansen; 13.04.2017, 18:49.

                  Comment


                  • #10
                    Sorry, weiß gerade nicht, ob ich nicht verstehe, was Du meinst oder umgekehrt.
                    Du hast gesagt:
                    Und wieso kannst du an der Stelle wo du Process.Start() aufrufst nicht einfach ein Form.Show() aufrufen?
                    Die Antwort ist: Weil ich an der Stelle kein Objekt meiner der Form habe! Die WaWi bietet mir Schnittstellen, in denen ich in begrenztem Rahmen .NET anwenden kann.
                    Eigene Masken kann ich an der Stelle nur aufrufen, indem ich sie direkt über das System, in diesem Falle über Process.Start() aufrufe.
                    Wie soll ich denn die Form referenzieren, wenn es sie an der Stelle noch gar nicht gibt?!

                    Nach dem was du beschreibst kann man Code in der anderen Anwendung auch ausführen. Zumindest hast du nirgendwo explizit von Einschränkungen gesprochen.
                    Dass aber nicht alles möglich ist, lässt sich bereits in #3 vermuten:
                    Wir arbeiten mit einer Warenwirtschaft, die über Schnittstellen anpassbar/erweiterbar ist. Diese Schnittstellen kann ich mit C#.NET tlw. befüllen.
                    Innerhalb dieser Schnittstellen sind aber Formulare und Listen "größerer" Datenmengen sehr langsam, weshalb ich die Möglichkeit nutze für bestimmte Dinge "auszubrechen".
                    Wenn ich Dich nicht recht verstehe, kläre mich bitte auf.
                    Ich weiß nur nicht, wie ich das Problem noch beschreiben soll, weil ich finde, dass es ziemlich eindeutig ist.

                    Innerhalb der Schnittstelle habe ich zwar auch die Möglichkeit, Formulare zu verwenden, ( nicht TForm von VS! ), aber die haben für meine Zwecke einfach zu wenig Controls.
                    Ich kann mir wohl Controls aus dem DevExpresss-Repertoire zusammenklöppeln, aber nur über einen Weg, der das Formular nicht mehr besonders benutzerfreundlich und langsam macht.
                    Das ist aber ein Schnittstellenproblem, würde ich mal behaupten.

                    Da jetzt die meiste Arbeit der Ansicht Datenbank lastig ist, habe ich mit Visual Studio unabhängig von der WaWi eine Windows-Form-Anwendung erstellt, die alles schnell und benutzerfreundlich zur Verfügung stellt.
                    D.h., man kann grundsätzlich auch mit dem Formular auch arbeiten, wenn man die WaWi deinstallieren würde!

                    Diese Windows-Form Anwendung ist aber eben wie gesagt unabhängig von der WaWi und kann auch nicht einfach so da hinein kopiert o.ä. werden.
                    Ich muß diese explizit aufrufen/starten. Das mache ich wie gesagt über Process.Start() ( anstatt Doppelklick wenn ich an der Stelle auf die WaWi verzichten würde ).
                    Ich nutze die Schnittstelle der WaWi an der Stelle also nur, um eigene Formulare zu starten, damit die User alles an einer Stelle verwalten können.
                    So selten ist die Vorgehensweise eigentlich nicht, denke ich...

                    Gibt es einen besseren Weg, bin ich gern bereit diesen zu erfahren und evtl. zu nutzen.
                    Bisher bleibt mir nur die Möglichkeit, eigene Windows-Form-Anwendungen über bspw. Process.Start() aufzurufen.

                    Ich bin Dir wirklich dankbar, dass Du Dich zumindest damit befasst, aber ich weiß echt nicht, wie ich das noch erklären soll/kann.

                    Erstmal schöne Ostertage
                    Danke Arne
                    PHP rocks!
                    Eine Initiative der PHP Community

                    Comment


                    • #11
                      Ich weiß nur nicht, wie ich das Problem noch beschreiben soll, weil ich finde, dass es ziemlich eindeutig ist.
                      Ich nutze die Schnittstelle der WaWi an der Stelle also nur, um eigene Formulare zu starten, damit die User alles an einer Stelle verwalten können.
                      So selten ist die Vorgehensweise eigentlich nicht, denke ich...
                      Entweder so ein Produkt hat eine Schnittstelle (REST, SOAP) wo man Daten in einem serialisierbaren Format bekommt oder sie bieten eine Plugin Schnittstelle wo man dann im Prozessraum der Anwendung jeden eigenen Code ausführen kann. Eine Umgebung in der ein bisschen .Net geht ist alles andere als was eindeutiges oder übliches. Aber letztlich bin ich nur neugierig und dein Problem ist dein Problem Du musst das nicht verteidigen.

                      Weil ich an der Stelle kein Objekt meiner der Form habe!
                      Reflection benutzen?

                      [HIGHLIGHT=C#]var assembly = Assembly.LoadFile(@"C:\MeineLiebeProduktErweiterun gen\MeinLiebeDll.dll");
                      var type = assembly.GetType("meinLíeberNamespace.meineLiebeFo rm");
                      var form = (Form)Activator.CreateInstance(type);
                      form.ShowDialog(); // oder form.Show() oder falls keine Messageschleife läuft stattdessen hier Application.Run(form) benutzen.
                      [/HIGHLIGHT]

                      Falls es eine DevEx Form ist die nicht im Framework definiert ist dann einen statischen Einsprungspunkt (wie z.B. die übliche Main Methode) definieren und denn per Reflection aufrufen. Falls der Call häufig passiert dann kann man auch dynamisch Code erzeugen(siehe DynamicMethod im System.Reflection.Emit Namespace). Es läuft immer darauf hinaus das du keine Referenz auf irgendwas zwingend brauchst du kannst dir das auch zur Laufzeit holen.
                      Letztlich kenne ich zuwenig Details deiner Umgebung um dein Vorgehen zu verstehen und was passendes (anstatt nur was anderes ) vorzuschlagen. Ich habe mich nur gewundert.

                      Comment


                      • #12
                        Hi Ralf,

                        Wie ich vermutet habe, weißt Du wie immer mehr.

                        Mit der Reflection funktioniert der Aufruf auch, danke für den Tipp.
                        Mir stellen sich allerdings an der Stelle wieder zwei Fragen


                        1. Wie "entleere" ich die Assembly?
                        Wenn ich den Weg über die Reflection nutze, öffnet sich das Formular, wie es soll. ich kann darin arbeiten, soweit passt alles.
                        Nachdem das Formular allerdings einmal geöffnet wurde, kann ich das Visual Studio Project nicht mehr anpassen. Beim Erstellen des Build meldet er mir, dass der Instanzverweis von einem anderen Programm genutzt wird.
                        Innerhalb meiner Form nutze ich zum Schließen diesen Code:
                        [highlight=csharp]
                        Form1.Close();
                        Application.Exit();
                        [/highlight]Beim Schließen bekomme ich übrigens einen Fehler, dass eine Methode nicht auf ein Objektverweis angewendet wurde.
                        Das ist meines Erachtens die zweite Zeile, die ich dann auskommentiert habe. Nun kann ich den Build allerdings nicht mehr erstellen, solange die Warenwirtschaft noch offen ist.
                        Innerhalb der Warenwirtschaft habe ich versucht, das Form Objekt ebenfalls zu schließe, was aber leider nichts an der Problem ändert:
                        [highlight=csharp]
                        oForm.Close();
                        oForm.Dispose();
                        [/highlight]


                        2. Wie bringt mich das in meiner Ausgangsproblematik weiter?
                        Ich kann jetzt das Formular über eine Reflection aufrufen, schön. Aber die Ausgangsfrage bleibt, wie ich darin jetzt auf das Mandanten-Objekt der Warenwirtschaft zugreifen kann?
                        Das ist mir leider noch nicht ganz klar. Denn in dem Scope der Form ist diese ja weiterhin nicht vorhanden. Oder habe ich jetzt eine bessere Möglichkeit, der Assembly dieses Objekt bekannt zu machen?


                        Danke für Deine Tipps!
                        Gruß Arne
                        PHP rocks!
                        Eine Initiative der PHP Community

                        Comment


                        • #13
                          1. Wie "entleere" ich die Assembly?
                          AppDomains benutzen. Das Thema ist aber eher was dem man sich nicht freiwillig nähert. Da würde ich dann, wenn es ein wichtiges Feature ist die Assembly ohne Prozess-Neustart austauschen zu könen und nicht einfach nur beim entwickeln stört, auch eher auf multiple Prozesse setzen. Selbst Microsoft sucht mittlerweile andere Lösungen (in .Net Core gibt es den AssemblyLoadContext anstat AppDomains).

                          2. Wie bringt mich das in meiner Ausgangsproblematik weiter?
                          Nun ja der Typ für dein Mandanten muss ja irgendwo definiert sein. Der taucht nicht irgendwie magisch in dem Context auf wo du Zugriff auf ihn hast. Die Assembly die den Typ definiert solltest du doch auch von deiner Assembly in dem deine Form definiert ist referenzieren können. Wenn nicht wird deine Umgebung noch merkwürdiger. Oder du hast uns verschwiegen das die Wawi gar keine .Net Anwendung ist und der Context auch nix mit .Net zu tun hat sondern etwas COM basiertes ist und du heftig an Interop Typen arbeitest.

                          Wenn du den Typ referenzieren kannst dann gibt deiner Form eine Methode/Property dem du die Instanz mitgeben kannst. Da du deine Form nur als Form ansprechen kannst und nicht als konkreten Typen musst du hier dann wieder Reflection anwenden.

                          Im Falle einer Property wie folgt (Property sollte logischerweise nicht statisch, public mit setter sein)
                          [HIGHLIGHT=C#]var propertyInfo = oForm.GetType().GetProperty("meineLiebeProperty");
                          propertyInfo.SetValue(oForm, meinLiebesMandantenObject);[/HIGHLIGHT]

                          Comment


                          • #14
                            Oder du hast uns verschwiegen das die Wawi gar keine .Net Anwendung ist und der Context auch nix mit .Net zu tun hat sondern etwas COM basiertes ist und du heftig an Interop Typen arbeitest.
                            Ich denke, das ist entscheidend.
                            Das habe ich sicher nicht absichtlich vorenthalten, sorry. Hatte gar nicht daran gedacht, gut dass Dir die Idee kam.

                            Es läuft tatsächlich COM basiert, daher gibt es auch in den möglichen Funktionen, wo ich in C# verwenden darf/kann auch oft Probleme mit der Wandlung von COM- zu .NET-Objekten.

                            Der property-Gedanke ist allerdings interessant, wenn es zu 1. eine sinnvolle Lösung gäbe. AppDomains ist hier denke ich fehl am Platz.
                            Das ganze läuft über Process.Start() wesentlich unkomplizierter. Kann ich dort auch eine Property nicht auch in einer ähnlichen Form, wie bei der Reflection übergeben?

                            Danke für Deine ausführlichen Hinweise.
                            Gruß Arne
                            PHP rocks!
                            Eine Initiative der PHP Community

                            Comment


                            • #15
                              [HIGHLIGHT=C#]Kann ich dort auch eine Property nicht auch in einer ähnlichen Form, wie bei der Reflection übergeben?
                              [/HIGHLIGHT]

                              Nein. Da ist dann eine Prozessgrenze dazwischen und du landest bei irgendeinen IPC Mechanismus.

                              Comment

                              Working...
                              X