Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Fremdes C# Steuern (https://www.delphipraxis.net/175875-fremdes-c-steuern.html)

achi 3.0 25. Jul 2013 10:37

Fremdes C# Steuern
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo,

ich muss an eine Steuerung eine Datei senden. Hierfür gibt es ein C# Programm. Nun würde ich das ganze gerne über Delphi machen. Das Programm starte ich wie folgt:


Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);

begin

ShellExecute(Handle, nil, 'c:\Programme\Borland\Delphi5\Projects\Http\HTTPCSharp\bin\Debug\HttpCSharp.exe', nil, nil, SW_SHOW);         // Um im Hintergrund zu laufen machen wir SW_HIDE

end;


Das Programm hat ein paar Edits, eine Combobox und ein paar Buttons. Jetzt würde ich gerne einige dieser Komponenten mit Daten versehen und dann einen Button betätigen. Alles über Delphi. Anbei ein Bild des Programms.

Anhang 39639

Habt ihr eine Idee wie ich das machen könnte???

Gruß Achi

Bernhard Geyer 25. Jul 2013 10:44

AW: Fremdes C# Steuern
 
Und wieso nicht gleich direkt selbst über die TCP/IP-Schnittstelle der Steuerung?

Der schöne Günther 25. Jul 2013 10:47

AW: Fremdes C# Steuern
 
Also das Delphi-Programm soll
  • das externe Programm unsichtbar starten
  • Edit-Felder des Programms finden
  • dort Werte eintragen
  • einen Button finden
  • diesen Button drücken
  • das Programm irgendwann auch wieder beenden

richtig?

Phoenix 25. Jul 2013 10:52

AW: Fremdes C# Steuern
 
Das GUI zu steuern wäre die letzte Idee die mir einfallen würde.

Ich würde mir das Ding mal mit dotPeek im Detail angucken. Vermutlich gibts da ne einfache Klasse die man mit den Daten direkt ansteuern kann. Die wenigsten Tools sind obfuskiert so das das vermutlich sehr gut einsehbar ist.

Wenn ja ist es vermutlich deutlich einfacher, Dir dazu ein kleines Command-Line Interface zu bauen. Schnapp Dir Prism (falls Du das hast) oder, wenns Object Pascal sein soll, den kostenlosen Oxygene Command Line Compiler (http://www.remobjects.com/oxygene, unten rechts) oder freilich das Visual Studio Express. Mache ein kleines .NET Projekt, füge eine Referenz auf das C#-Programm hinzu, und dann kannst Du die Klassen dort direkt anprogrammieren.

Du schreibst dann kurz ein Tool das die nötigen Parameter über die Kommandozeile annimmt, die Klasse dort drin genau so ansteuert wie das GUI, und die Rückgabe entsprechend formatiert. Dieses Commandline-Tool rufst Du dann aus Deinem Programm heraus aus. Dann hast Du kein gefrickel mit GUI fernsteuern etc.

Alternativ kannst Du mit reverse P/Invoke das Ding auch direkt aus Deinem Prozess heraus aufrufen (oder mit Hydra).

achi 3.0 25. Jul 2013 10:55

AW: Fremdes C# Steuern
 
Liste der Anhänge anzeigen (Anzahl: 1)
@ Der schöne Günther
Jaist richtig.


Ich glaube nicht das ich einfach per TCP/IP etwas an die Steuerung senden kann. Hier eine Beschreibung was das C# Programm macht.
Anhang 39640

Es verwendet irgendein Yaskawa.IEC61131.RMI.Modules. Ich weiß nicht was ich damit anfangen soll.

Phoenix 25. Jul 2013 11:06

AW: Fremdes C# Steuern
 
Laut der Doku ist das ein einfaches HTTP POST. Das müsstest Du mit Indy problemlos nachbauen können.

Furtbichler 25. Jul 2013 11:09

AW: Fremdes C# Steuern
 
Die Anforderung ist ziemlich schwammig und dein Lösungsversuch sehr unprofessionell.

Arbeite Dich in die API ein und steuere die API direkt von Delphi aus an. Meistens ist so eine API auch mit Win32-DLLs ansprechbar. Wenn nicht, wenn also nur C#-Klassen vorhanden sind, dann verwende z.B. unmanaged exports

Das ist doch sogar eine Beispielanwendung, da wirst du doch wohl den Aufruf der Methode Yaskawa.IEC61131.RMI.Modules namespace.HttpUtility.CreatePOSTRequest finden und einen kleinen Wrapper drumwickeln können.

Pillepalle.

EDIT: @Phoenix: Das wäre die Notlösung. Ich würde immer versuchen, die Hersteller-API zu verwenden.

achi 3.0 25. Jul 2013 11:13

AW: Fremdes C# Steuern
 
Es wird doch auch eine DLL verwendet. Das wird doch seinen Grund haben. Ich werde es mal mit IdHTTP. Nur ist die frage an welche URL sende ich die Daten

IP 192.168.1.1
Location soll /flash/user/data sein.
Datei müsste in ein multipart/form Data stream gepackt werden

Hatte das mal mit ner FastNet komponente versucht und bin gescheitert.


@Furtbichler
Pillepalle sagt der experte ;-) leider bin ich keiner?

Gruß

Phoenix 25. Jul 2013 11:20

AW: Fremdes C# Steuern
 
Zitat:

Zitat von achi 3.0 (Beitrag 1222634)
Es wird doch auch eine DLL verwendet. Das wird doch seinen Grund haben.

Ja: Bequemlichkeit. Damit .NET Entwickler die ohne das GUI-Zeug direkt weiterverwenden können.

In der von Dir verlinkten Doku auf seite 6 steht drin, das in dem Namespace Yaskawa.IEC61131.RMI.Modules eine Klasse HttpUtility ist, und was die genau macht.

Schau Dir doch diese Assembly mal mit dem Tool dotPeek an und schau, was die macht. Die erzeugt vermutlich nur einen HttpRequest, setzt den auf Post, hängt dort das File dran und setzt den Pfad korrekt.

Das ganze ist vermutlich deutlich schneller und einfacher selber gebaut als sich hier mit Delphi / .NET Interop zu versuchen. Das ist gleich mal einige Größenordnungen komplexer. Das würde ich nicht anfangen wenn einfaches HTTP POST eines Files schon zu kompliziert ist.

Klaus01 25. Jul 2013 11:21

AW: Fremdes C# Steuern
 
Hallo,

du kannst doch den TCP Traffic mit z.B. Wireshark tracen wenn Du das binary benutzt.
Es sollte sich dann doch feststellen lassen, welches Protokol verwendet wird und wo Daten abgelegt werden.

Grüße
Klaus

Phoenix 25. Jul 2013 11:28

AW: Fremdes C# Steuern
 
Das geht doch alles aus dem Dokument hervor. Es ist ein einfaches HTTP Post. Da brauchts kein Wireshark. Das ist vermutlich deutlich zu komplex. Da würde es genügen, sich kurz mit Fiddler als HTTP-Proxy dazwischen zu klemmen und zu gucken auf welchen Pfad der Request geht, welches Encoding benutzt wird und ob ggf. neben dem File sonst noch zusätzliche Felder mitgesendet werden.

achi 3.0 25. Jul 2013 12:20

AW: Fremdes C# Steuern
 
Hallo,

werde mal mit Wireshark versuchen den Pfad an den die Daten geschickt werden usw. rauszubekommen. Dann kann ich ja den unten stehenden code anpassen und versuchen die Daten zu senden oder?

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
  DataStream : TIdMultiPartFormDataStream;
  URL       : string;
  response  : string;

begin
URL := '192.168.1.1/flash/user/data';
IdHTTP1.Request.CacheControl:='no cache';
IdHTTP1.Request.ContentType :='multipart/form-data';

try
      DataStream := TIdMultiPartFormDataStream.Create;
      DataStream.AddFile('file','c:\Yaskawa\Cam_Y.csv', 'multipart/form-data');
      response := IdHTTP1.Post(URL, DataStream);
      DataStream.Free;
except

end;

end;

Phoenix 25. Jul 2013 12:25

AW: Fremdes C# Steuern
 
Vielleicht heisst das Feld für das File auch nicht unbedingt file. Musst halt mal rein gucken. Also entweder mit dotPeek in die dll oder mit Wireshark / Fiddler in die Kommunikation. Das erstere ist meiner Meinung nach das einfachste weil schnellste und unkomplizierteste.

achi 3.0 25. Jul 2013 14:23

AW: Fremdes C# Steuern
 
Also habe mal mit dotPeek die DLL decompiliert. Werde daraus aber nicht schlau, keine hilfreiche info wie ich finde aber vielleicht sieht ihr was?

Hier der Inhalt der HttpCSharp.dll
Delphi-Quellcode:
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

// Assembly HttpCSharp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
// MVID: 58ebf0ab-8e1a-4c99-97b5-f9d1226feecb
// References: mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
// References: System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
// References: System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
// References: HttpUtil, Version=2.0.1.1, Culture=neutral, PublicKeyToken=d7bba6a0fdc5f725
// References: System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a

[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Yaskawa")]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: AssemblyTitle("HttpCSharp")]
[assembly: AssemblyDescription("HttpUtil Library C# Test Application")]
[assembly: AssemblyProduct("HttpCSharp")]
[assembly: AssemblyCopyright("Copyright © Yaskawa America, Inc. 2011")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("b21abef5-0ace-4c65-b49f-915debf72ad8")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: CompilationRelaxations(8)]
[assembly: AssemblyVersion("1.0.0.0")]

Morphie 25. Jul 2013 14:48

AW: Fremdes C# Steuern
 
Kannst du die DLL hier anhängen, oder uns einen Download geben?

Phoenix 25. Jul 2013 14:50

AW: Fremdes C# Steuern
 
Zitat:

Zitat von achi 3.0 (Beitrag 1222674)
Hier der Inhalt der HttpCSharp.dll

Das ist nur die AssemblyInfo.......

achi 3.0 25. Jul 2013 15:08

AW: Fremdes C# Steuern
 
Liste der Anhänge anzeigen (Anzahl: 1)
Auf der ersten seite hab ich einen Zipordner angehängt da sind alle Dateien drin auch die exe. Hier die DLL Anhang 39643

Musste die Datei zippen. Anscheinend kann man hier keine DLL's hochladen.

Gruß

achi 3.0 25. Jul 2013 15:13

AW: Fremdes C# Steuern
 
Ups, habs jetzt gesehen. Da steht noch ne Menge anderer zeugs drin. Aber wie packe ich das in meine IdHttp komponente.

Gruß

achi 3.0 25. Jul 2013 15:19

AW: Fremdes C# Steuern
 
Das hier müsste man entschlüsseln. Was bedeutet hier "http://{0}/upload/{1}/"

Wahrscheinlich steht {0} für die ip und {1} für directory also müsste die url wie folgt lauten: http://192.168.1.1/upload/data/cam



 
public string SendFileToUserDirectory(string ipAddress, string filePath, string directory)
{
HttpUtility.UpdateBoundary();
string uri = string.Format("http://{0}/upload/{1}/", (object) ipAddress, (object) directory);
string methodPostDataString = HttpUtility.CreateNonMethodPostDataString();
return this.PostUploadFile(filePath, uri, methodPostDataString, false);
}


sollte doch so funktionieren oder muss ich auf noch etwas achten????

Delphi-Quellcode:
var
  DataStream : TIdMultiPartFormDataStream;
  FURL      : string;
  response  : string;

begin
FURL := 'http://192.168.1.1/upload/data/cam';
IdHTTP1.Request.CacheControl:='no cache';
IdHTTP1.Request.ContentType :='multipart/form-data';

try
      DataStream := TIdMultiPartFormDataStream.Create;
      DataStream.AddFile('archive','c:\Yaskawa\Cam_Y.csv', 'multipart/form-data');
      response := IdHTTP1.Post(FURL, DataStream);
      DataStream.Free;
except

end;

end;

Morphie 25. Jul 2013 15:21

AW: Fremdes C# Steuern
 
Die Methode hat drei Parameter:
ipAddress
filePath
directory

Code:
string uri = string.Format("http://{0}/upload/{1}/", (object) ipAddress, (object) directory);
Das beudetet im Prinzip, dass für {0} der Parameter ipAddress eingesetzt wird und für {1} der Parameter directory


edit:
je nachdem wie fit du in C# bist, würde ich an deiner Stelle die C#-Bibliothek einfach nach Delphi übersetzen... Das ist relativ schnell gemacht, wenn man den C#-Code lesen und mit Delphi umgehen kann

achi 3.0 25. Jul 2013 15:33

AW: Fremdes C# Steuern
 
Mir gehts ja nur darum eine Datei zu senden. Müsste dann der folgende code nicht reichen.

Bin mir nur hier ataStream.AddFile('archive','c:\Yaskawa\Cam_Y.csv' , 'multipart/form-data'); nicht sicher.

Kenn mich mit C# leider nicht aus!!


Delphi-Quellcode:
var
  DataStream : TIdMultiPartFormDataStream;
  FURL : string;
  response : string;

begin
FURL := 'http://192.168.1.1/upload/data/cam';
IdHTTP1.Request.CacheControl:='no cache';
IdHTTP1.Request.ContentType :='multipart/form-data';

try
      DataStream := TIdMultiPartFormDataStream.Create;
      DataStream.AddFile('archive','c:\Yaskawa\Cam_Y.csv', 'multipart/form-data');
      response := IdHTTP1.Post(FURL, DataStream);
      DataStream.Free;
except

end;

end;

achi 3.0 25. Jul 2013 15:46

AW: Fremdes C# Steuern
 
Ich denke mal das ich das hier auch irgendwie entschlüsseln muss. Weil hier wird der stream ja wirklich gesendet. Ich weiß nicht ob da mein Delphicode so direkt passt.

 
private string PostUploadFile(string filePath, string uri, string postMethod, bool validate)
{
string fileName = this.ExtractFileName(filePath);
if (validate && !this.IsValidFileName(fileName))
return "Invalid file name! File name must match one of those found in default configuration!";
HttpWebRequest postRequest = HttpUtility.CreatePostRequest(uri);
byte[] bytes1 = Encoding.UTF8.GetBytes(HttpUtility.CreateFilePostDataString(filePath, "text/xml"));
byte[] bytes2 = Encoding.UTF8.GetBytes(postMethod);
byte[] bytes3 = Encoding.UTF8.GetBytes(HttpUtility.CreateBoundaryPostDataString());
FileStream fileStream = new FileInfo(filePath).Open(FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
long num = (long) bytes1.Length + fileStream.Length + (long) bytes2.Length + (long) bytes3.Length;
postRequest.ContentLength = num;
Stream requestStream = ((WebRequest) postRequest).GetRequestStream();
requestStream.Write(bytes1, 0, bytes1.Length);
byte[] buffer = new byte[fileStream.Length];
int count;
while ((count = fileStream.Read(buffer, 0, buffer.Length)) != 0)
requestStream.Write(buffer, 0, count);
requestStream.Write(bytes2, 0, bytes2.Length);
requestStream.Write(bytes3, 0, bytes3.Length);
requestStream.Close();
fileStream.Close();
new StreamReader(postRequest.GetResponse().GetResponseStream()).ReadToEnd();
return "";
}

achi 3.0 26. Jul 2013 16:47

AW: Fremdes C# Steuern
 
Hallo leute es klappt.

Echt super.
Ich danke euch sehr für die Hilfe.
Hab vieles dazu gelernt und die Idee mit dem Decodieren der dll war super. Danke nochmal.


Gibt es eine Möglichkeit die geschwindigkeit zu erhöhen. benötige für 800kb datengröße ca. 50s


Gruß

Achi

Sir Rufo 26. Jul 2013 18:46

AW: Fremdes C# Steuern
 
Zitat:

Zitat von achi 3.0 (Beitrag 1222800)
Hallo leute es klappt.

Echt super.
Ich danke euch sehr für die Hilfe.
Hab vieles dazu gelernt und die Idee mit dem Decodieren der dll war super. Danke nochmal.


Gibt es eine Möglichkeit die geschwindigkeit zu erhöhen. benötige für 800kb datengröße ca. 50s


Gruß

Achi

Wie lange dauert denn der Vorgang mit dem beiliegenden Programm?
Geht das schneller?

OlafSt 26. Jul 2013 18:56

AW: Fremdes C# Steuern
 
Da die Daten an eine nicht näher bezeichnete Steuerung gesendet werden, wird die wohl der Flaschenhals sein.

achi 3.0 29. Jul 2013 09:23

AW: Fremdes C# Steuern
 
Warum an eine nicht näher beschriebene Steuerung? Die Steuerung ist eine Yaskawa MP2300s.

Es ist doch nicht normal das 800kb datengröße ca. 50s dauern oder?

achi 3.0 29. Jul 2013 11:53

AW: Fremdes C# Steuern
 
Achja. Momentan ist es sehr blöd, da es lange dauert und man auch nicht weiß wie lange noch. Hat einer ne idee wie ich einfach eine Fortschrittsanzeige angezeigt bekomme. Bietet da Indy was an?


Gruß

Morphie 29. Jul 2013 12:08

AW: Fremdes C# Steuern
 
Du hast Sir Rufos Frage noch nicht beantwortet...
Zitat:

Zitat von Sir Rufo (Beitrag 1222803)
Wie lange dauert denn der Vorgang mit dem beiliegenden Programm?
Geht das schneller?


achi 3.0 29. Jul 2013 16:03

AW: Fremdes C# Steuern
 
Sorry hatte die Frage wohl übersehen. Mit dem beiligendem Programm dauert es auch lange. Werde mal die Zeit stoppen um einen genauen vergleich zu machen.


Gruß

guinnes 29. Jul 2013 16:43

AW: Fremdes C# Steuern
 
Zitat:

Zitat von achi 3.0 (Beitrag 1222926)
Achja. Momentan ist es sehr blöd, da es lange dauert und man auch nicht weiß wie lange noch. Hat einer ne idee wie ich einfach eine Fortschrittsanzeige angezeigt bekomme. Bietet da Indy was an?

Ja, die Events OnWorkBegin, OnWork und OnWorkEnd


Alle Zeitangaben in WEZ +1. Es ist jetzt 09:50 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz