C# i komunikaty z wysyłane z Delphi

0

Witam.
Ponieważ nie udało mi się napisać pod delphi obsługi podpisu (eDeklaracje), więc napisałem taki programik pod C#.
Pomysł jest taki, że:
Aplikacja w delphi wywoła program w C# i poda ścieżkę do pliku XML , nazwę pliku docelowego, numer certyfikatu i inne takie, jako parametr.
Do tego miejsca jest OK.
Ale nie chcę zamykać aplikacji(C#) i uruchamiać jej 40 razy bo mam 40 plików do podpisania, więc wpadłem na pomysł że zrobię to komunikatami.

Z delphi wysyłam sobie komunikat:

 
const
  WM_FileSign = WM_USER + 3131;

procedure TfrmDeklaracje.Button1Click(Sender: TObject);
var
  Uchwyt : THandle;
begin
  Uchwyt := FindWindow(nil, 'ePodpis(XML)2014');
  if Uchwyt>0 then begin
    ShowMessage('Wysyłam komunikat');
    if SendMessage(Uchwyt,WM_FileSign, 0, longint(pchar('c:\aaa.xml c:\aaa.sign 1 y')) )= 1 then
      ShowMessage('Komunikat przekazany!')
    else
      ShowMessage('Błąd. Komunikat nie został przekazany!');
  end else begin
    UruchomProgramCS;
    ShowMessage('Uruchamiam');
  end;  
end;

i tu zaczyna się problem bo nie wiem, jak bo odebrać w C#, a dokładnie jak wyciągnąć z parametru lParam string z parametrami.

         protected override void WndProc(ref Message m)
        {
            string res;
            base.WndProc(ref m);
                                                
            if (m.Msg==wm_FileSign) {
                textBox1.Text = "Odebrano komunikat \"wm_FileSign\"";

                byte[] buff = new byte[512];
                unsafe
                {
                    fixed (byte* pbuff = buff) m.LParam.ToPointer();
                }
                ASCIIEncoding ae = new ASCIIEncoding();
                res = ae.GetString(buff);
                textBox1.AppendText(res);

            }    
        }

W google są przykłady odnośnie C# i odczytu bufora, ale albo ja ich nie rozumiem, albo to nie oto mi chodzi, bo oni w przykładach mają wskaźnik, a ja mam w LParam INT a nie pointer i nie wiem co mam z tym zrobić.

W C# niewiele qmam, bo próbuję coś robić dopiero od miesiąca więc proszę o wyrozumiałość.

Streszczenie problemu:
Mam aplikację w delphi która robi wszystko oprócz podpisywania dokumentów.
Dlatego do tego celu napisałem programik w C#.
Teraz muszę przekazać programowi w C# parametry do podpisu(nawy plików, id certyfikatu, ścieżkę itp).
Pierwszy pomysł był taki aby uruchomić program z parametrami i to zadziałało. Niestety przy podpisywaniu seryjnym jest to trochę nieeleganckie rozwiązanie.
Wpadł mi pomysł wykorzystania komunikatów, ale nie wiem jak do C# przekazać w komunikacie string.

1

A nie "najczyściej" będzie zrobić to przez standardowe wejście/wyjście. Tworzysz aplikację konsolową odpalasz ją z Delphi (powinno to się dać tak zrobić żeby okno konsoli nie było widoczne). W aplikacji C# korzystasz z klasy Console (metody ReadLine/WriteLine), niestety nie wiem jak to ugryźć od strony Delphi, ale nie powinno być trudno.

0

Częściowym rozwiązaniem może być wykorzystanie rejestrów windows-a w których mogę zapisać parametry(scieżki i inne) a komunikatem wysłać polecenie podpisu.
Program w C# odczyta sobie dane z rejestrów.
Pozostaje jednak nadal jeden mały problem z komunikacją między apliakcjami.

  1. Jak w C# zwrócić do Delphi informację o otrzymaniu komunikatu. (W delphi używam SendMessage a nie PostMessage)
  2. Jak zwrócić do Delphi informację o wykonaniu podpisu (chyba najprościej też komunikatem).

@misiakufal
Dzięki za info o pipach. dzisiaj się z tym zapoznam.

0
<quote> ```csharp fixed (byte* pbuff = buff) m.LParam.ToPointer(); ```

ToPointer() jest funkcją. Służy do konwersji typu IntPtr na void*. Ale ty nie korzystasz ze zwracanej wartości.
Zatem ten kod nic nie robi.

0
if (m.Msg==wm_FileSign) unsafe
{
    string s = new String((sbyte*)m.LParam);
    textBox1.AppendText(s);
}
0

Co prawda problem rozwiązałem posługując się "pipes", ale chętnie bym dokończył ten temat i spróbował również przekazać string za pomocą komunikatu.
Niestety ze wskaźnikami zawsze miałem problemy, a w C# to już zupełnie się gubię.

Na razie udało mi sięprzekazać, liczbę i znak.

 
P1 = m.WParam.ToString(); //liczba
P2 = ((Char)m.LParam).ToString(); //znak

@Azarien
Dzięki za podpowiedź,ale ten kod mi nie działa( w sensie, że zwraca mi jakoś ciąg 'H9÷ä', podczas gdy ja wysyłam 'c:\aaa.txt'#13'c:\bbb.txt' ). Niestety nie wiem dlaczego.

Będę wdzięczny za podpowiedź jak w C# wyciągnąć string mając wskaźnik w postaci INTa.
No chyba że to z delphi coś źle wysyłam.

1

Nie można tak po prostu przekazać wskaźnika między jednym programem a drugim.
Każdy proces ma własną przestrzeń adresową.

http://msdn.microsoft.com/en-us/library/windows/desktop/aa365574%28v=vs.85%29.aspx

0

@Azarien
Tego się obawiałem, ale miałem nadzieję że może jest to adres (bezwzględny, obsolutny - nie wiem jak to nazwać).

Tak czy inaczej. Problem rozwiązany za pomocą PIPEs więc - Dziękuję za wszelkie podpowiedzi.

1 użytkowników online, w tym zalogowanych: 0, gości: 1