Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Invalid Class Typecast (https://www.delphipraxis.net/176643-invalid-class-typecast.html)

Andidreas 18. Sep 2013 15:10

Datenbank: MS SQL Server • Version: 2008 • Zugriff über: UniDac

Invalid Class Typecast
 
Hallo,

ich steh grad ziemlich aufm Schlauch...

Ich hab eine MS SQL Tabelle in der sich zehn Blob Daten Felder befinden --> Typ varbinary(max)
In diese will ich Attachments für einen Mail Versand einfügen...

Zum Testen habe ich mir eine Form gebastelt in der der folgende Source ausgeführt wird:

Delphi-Quellcode:
procedure Tmaintenance_testmailing_form.advglowbtn_sendmailClick(Sender: TObject);

var
i                                                          : Integer;
ms1, ms2, ms3, ms4, ms5, ms6, ms7, ms8, ms9, ms10           : TMemoryStream;
sfn1, sfn2, sfn3, sfn4, sfn5, sfn6, sfn7, sfn8, sfn9, sfn10 : String;

begin

  //Check Entries
  If (StringReplace(edt_mailproject.Text, ' ', '', [rfReplaceAll]) = EmptyStr) Or
     (StringReplace(edt_mailapplication.Text, ' ', '', [rfReplaceAll]) = EmptyStr) Or
     (StringReplace(edt_mailsubject.Text, ' ', '', [rfReplaceAll]) = EmptyStr) Or
     (StringReplace(edt_mailsenderadress.Text, ' ', '', [rfReplaceAll]) = EmptyStr) Or
     (StringReplace(edt_mailsendertext.Text, ' ', '', [rfReplaceAll]) = EmptyStr) Or
     (StringReplace(edt_mailrecipient.Text, ' ', '', [rfReplaceAll]) = EmptyStr) Then
  Begin
    fnDisplayMyActionBox('ERR', 'Error', 'Entries are not complete!', EmptyStr, EmptyStr, EmptyStr, True);
    Exit;
  End;

  //Check count of Attachments
  If lstbox_attachments.Count > 10 Then
  Begin
    fnDisplayMyActionBox('ERR', 'Error', 'More than 10 Attachments!', 'Only max. 10 Attachments allowed!', EmptyStr, EmptyStr, True);
    Exit;
  End;


  Try
    //Load Attachments in Memory Streams
    For i := 0 To lstbox_attachments.Count -1 Do
    Begin
      Try
        Case i of
          //Attachment #1
          0: begin
            ms1 := TMemoryStream.Create;
            ms1.LoadFromFile(lstbox_Attachments.Items.Strings[i]);
            sfn1 := fnGetFileName(lstbox_Attachments.Items.Strings[i]);
          end;
          //Attachment #2
          1: begin
            ms2 := TMemoryStream.Create;
            ms2.LoadFromFile(lstbox_Attachments.Items.Strings[i]);
            sfn2 := fnGetFileName(lstbox_Attachments.Items.Strings[i]);
          end;
          //Attachment #3
          2: begin
            ms3 := TMemoryStream.Create;
            ms3.LoadFromFile(lstbox_Attachments.Items.Strings[i]);
            sfn3 := fnGetFileName(lstbox_Attachments.Items.Strings[i]);
          end;
          //Attachment #4
          3: begin
            ms4 := TMemoryStream.Create;
            ms4.LoadFromFile(lstbox_Attachments.Items.Strings[i]);
            sfn4 := fnGetFileName(lstbox_Attachments.Items.Strings[i]);
          end;
          //Attachment #5
          4: begin
            ms5 := TMemoryStream.Create;
            ms5.LoadFromFile(lstbox_Attachments.Items.Strings[i]);
            sfn5 := fnGetFileName(lstbox_Attachments.Items.Strings[i]);
          end;
          //Attachment #6
          5: begin
            ms6 := TMemoryStream.Create;
            ms6.LoadFromFile(lstbox_Attachments.Items.Strings[i]);
            sfn6 := fnGetFileName(lstbox_Attachments.Items.Strings[i]);
          end;
          //Attachment #7
          6: begin
            ms7 := TMemoryStream.Create;
            ms7.LoadFromFile(lstbox_Attachments.Items.Strings[i]);
            sfn7 := fnGetFileName(lstbox_Attachments.Items.Strings[i]);
          end;
          //Attachment #8
          7: begin
            ms8 := TMemoryStream.Create;
            ms8.LoadFromFile(lstbox_Attachments.Items.Strings[i]);
            sfn8 := fnGetFileName(lstbox_Attachments.Items.Strings[i]);
          end;
          //Attachment #9
          8: begin
            ms9 := TMemoryStream.Create;
            ms9.LoadFromFile(lstbox_Attachments.Items.Strings[i]);
            sfn9 := fnGetFileName(lstbox_Attachments.Items.Strings[i]);
          end;
          //Attachment #10
          9: begin
            ms10 := TMemoryStream.Create;
            ms10.LoadFromFile(lstbox_Attachments.Items.Strings[i]);
            sfn10 := fnGetFileName(lstbox_Attachments.Items.Strings[i]);
          end;
        End;
      Except
        On E:Exception Do
        Begin
          fnDisplayMyActionBox('ERR', 'Error', 'Could not load Attachment into Memory Stream', lstbox_Attachments.Items.Strings[i], E.Message, EmptyStr, True);
        End;
      End;
    End;

    //Insert Test Record into MS SQL Table Mail
    Try
      With (MSSQL_Query1) Do
      Begin
        Active := False;
        SQL.Clear;
        SQL.Add(' Insert Into "' + ModuleUniDBSchema + '.Mail" ');
        SQL.Add(' ( ');
        SQL.Add(' Mail_Project, Mail_Application, Mail_Subject, Mail_SenderAdress, Mail_SenderText, ');
        SQL.Add(' Mail_Recipient, Mail_CC, Mail_Message, Mail_AttachmentCount, Mail_Stati ');

        For i := 0 To lstbox_Attachments.Count -1 Do
        Begin
          SQL.Add(' , Mail_AttachmentName' + IntToStr(i+1));
          SQL.Add(' , Mail_Attachment' + IntToStr(i+1));
        End;

        SQL.Add(' ) ');

        SQL.Add(' Values( ');
        SQL.Add(' :Mail_Project, :Mail_Application, :Mail_Subject, :Mail_SenderAdress, :Mail_SenderText, ');
        SQL.Add(' :Mail_Recipient, :Mail_CC, :Mail_Message, :Mail_AttachmentCount, :Mail_Stati ');

        For i := 0 To lstbox_Attachments.Count -1 Do
        Begin
          SQL.Add(' , :Mail_AttachmentName' + IntToStr(i+1));
          SQL.Add(' , :Mail_Attachment' + IntToStr(i+1));
        End;

        SQL.Add(' ) ');

        ParamByName('Mail_Project').AsString := edt_mailproject.Text;
        ParamByName('Mail_Application').AsString := edt_mailapplication.Text;
        ParamByName('Mail_Subject').AsString := edt_mailsubject.Text;
        ParamByName('Mail_SenderAdress').AsString := edt_mailsenderadress.Text;
        ParamByName('Mail_SenderText').AsString := edt_mailsendertext.Text;
        ParamByName('Mail_Recipient').AsString := edt_mailrecipient.Text;
        ParamByName('Mail_CC').AsString := edt_mailcc.Text;
        ParamByName('Mail_Message').AsString := mem_mailtext.Text;
        ParamByName('Mail_AttachmentCount').AsString := IntToStr(lstbox_attachments.Count);
        ParamByName('Mail_Stati').AsString := '10';

        For i := 0 To lstbox_Attachments.Count -1 Do
        Begin
          Case i of
            //Attachment #1
            0: begin
              ParamByName('Mail_AttachmentName1').AsString := sfn1;
              ParamByName('Mail_Attachment1').SetBlobData(ms1.Memory, ms1.Size);
            end;
            //Attachment #2
            1: begin
              ParamByName('Mail_AttachmentName2').AsString := sfn2;
              ParamByName('Mail_Attachment2').SetBlobData(ms2.Memory, ms2.Size);
            end;
            //Attachment #3
            2: begin
              ParamByName('Mail_AttachmentName3').AsString := sfn3;
              ParamByName('Mail_Attachment3').SetBlobData(ms3.Memory, ms3.Size);
            end;
            //Attachment #4
            3: begin
              ParamByName('Mail_AttachmentName4').AsString := sfn4;
              ParamByName('Mail_Attachment4').SetBlobData(ms4.Memory, ms4.Size);
            end;
            //Attachment #5
            4: begin
              ParamByName('Mail_AttachmentName5').AsString := sfn5;
              ParamByName('Mail_Attachment5').SetBlobData(ms5.Memory, ms5.Size);
            end;
            //Attachment #6
            5: begin
              ParamByName('Mail_AttachmentName6').AsString := sfn6;
              ParamByName('Mail_Attachment6').SetBlobData(ms6.Memory, ms6.Size);
            end;
            //Attachment #7
            6: begin
              ParamByName('Mail_AttachmentName7').AsString := sfn7;
              ParamByName('Mail_Attachment7').SetBlobData(ms7.Memory, ms7.Size);
            end;
            //Attachment #8
            7: begin
              ParamByName('Mail_AttachmentName8').AsString := sfn8;
              ParamByName('Mail_Attachment8').SetBlobData(ms8.Memory, ms8.Size);
            end;
            //Attachment #9
            8: begin
              ParamByName('Mail_AttachmentName9').AsString := sfn9;
              ParamByName('Mail_Attachment9').SetBlobData(ms9.Memory, ms9.Size);
            end;
            //Attachment #10
            9: begin
              ParamByName('Mail_AttachmentName10').AsString := sfn10;
              ParamByName('Mail_Attachment10').SetBlobData(ms10.Memory, ms10.Size);
            end;
          End;
        End;

        ExecSQL;
      End;
    Except
      On E:Exception Do
      Begin
        fnDisplayMyActionBox('ERR', 'MS SQL Error', 'Could not insert Record into Mail Table!', E.Message, EmptyStr, EmptyStr, True);
      End;
    End;
  Finally
    For i := 0 To lstbox_Attachments.Count -1 Do
    Begin
      Case i of
        0: begin
          If (ms1 <> Nil) Then ms1.Free;
          sfn1 := EmptyStr;
        end;
        1: begin
          If (ms2 <> Nil) Then ms2.Free;
          sfn2 := EmptyStr;
        end;
        2: begin
          If (ms3 <> Nil) Then ms3.Free;
          sfn3 := EmptyStr;
        end;
        3: begin
          If (ms4 <> Nil) Then ms4.Free;
          sfn4 := EmptyStr;
        end;
        4: begin
          If (ms5 <> Nil) Then ms5.Free;
          sfn5 := EmptyStr;
        end;
        5: begin
          If (ms6 <> Nil) Then ms6.Free;
          sfn6 := EmptyStr;
        end;
        6: begin
          If (ms7 <> Nil) Then ms7.Free;
          sfn7 := EmptyStr;
        end;
        7: begin
          If (ms8 <> Nil) Then ms8.Free;
          sfn8 := EmptyStr;
        end;
        8: begin
          If (ms9 <> Nil) Then ms9.Free;
          sfn9 := EmptyStr;
        end;
        9: begin
          If (ms10 <> Nil) Then ms10.Free;
          sfn10 := EmptyStr;
        end;
      End;
    End;
  End;
In der ListBox lstbox_attachments befindet sich der Pfad inkl. Dateinamen zu den Attachments...
Der jeweilige MemoryStream ist auch befüllt (im Debug habe ich die Size überprüft, diese ist > 0)...
Überseh ich hier grad nen Fehler oder warum bekomm ich immer die Fehlermeldung Invalid class Typecast

Andidreas 18. Sep 2013 15:29

AW: Invalid Class Typecast
 
Kann das daran liegen das dass ganze über eine DLL ausgeführt wird die mit Laufzeit Packages (also in den Projekt Optionen ist der Hacken bei "Laufzeit-Packages verwenden" gesetzt) arbeitet?

Andidreas 18. Sep 2013 16:39

AW: Invalid Class Typecast
 
Mittlerweile weiß ich das es an der DLL liegt...

Zur Erklärung...
Wir haben ein Hauptprogramm das viele Funktionen starten kann die als DLL erstellt wurden. Verfügt eine DLL über ein Frontend, so wird die DLL bzw. die Form der DLL in das Fenster des Hauptprogrammes geladen...
Da wir hier am Anfang einige Exceptions erhalten haben, haben wir die Laufzeit Packages ausgewählt bzw. diese Option aktiviert (also in den jeweiligen DLL Projekten)...
Bisher hat es genügt wenn wir in den DLLs das vcl Package angegeben haben...

Der in meinem ersten Post beschrieben Source funktioniert einwandfrei... aber eben nicht wenn diese Funktion als DLL mit Laufzeit Packages erstellt wird...

Muss ich hier nun ein Package angeben damit ich die DLL Version wieder verwenden kann?
Wenn ja welches?


P.S.: Wenn der Beitrag im falschen Themenbereich liegt und der Titel auch nicht mehr passt, bitte verschieben und umbenennen... Danke!

mjustin 18. Sep 2013 16:50

AW: Invalid Class Typecast
 
Zitat:

Zitat von Andidreas (Beitrag 1228949)
Überseh ich hier grad nen Fehler oder warum bekomm ich immer die Fehlermeldung Invalid class Typecast

Wo denn genau (in welcher Zeile)?

Uwe Raabe 18. Sep 2013 16:53

AW: Invalid Class Typecast
 
Wenn die DLL mit Runtime-Packages compiliert ist, dann muss auch die Anwendung selbst damit compiliert werden. Andernfalls verwenden beide Module unterschiedliche Klassensysteme und dann ist z.B. eine TStringList in der DLL nicht dieselbe Klasse wie die TStringList in der EXE.

Andidreas 19. Sep 2013 08:56

AW: Invalid Class Typecast
 
Zitat:

Zitat von mjustin (Beitrag 1228974)
Zitat:

Zitat von Andidreas (Beitrag 1228949)
Überseh ich hier grad nen Fehler oder warum bekomm ich immer die Fehlermeldung Invalid class Typecast

Wo denn genau (in welcher Zeile)?

Beim "ExecSQL"

Zitat:

Zitat von Uwe Raabe (Beitrag 1228975)
Wenn die DLL mit Runtime-Packages compiliert ist, dann muss auch die Anwendung selbst damit compiliert werden. Andernfalls verwenden beide Module unterschiedliche Klassensysteme und dann ist z.B. eine TStringList in der DLL nicht dieselbe Klasse wie die TStringList in der EXE.

Hätte dann aber zur folge das ich alle Packages im exe Verzeichnis ablegen muss die verwendet werden. Also wenn die Anwendung dann an einem PC ausgeführt wird auf dem kein Delphi installiert ist...

Andidreas 19. Sep 2013 09:16

AW: Invalid Class Typecast
 
@Uwe Raabe
Das haben wir so sogar schon gemacht...
Sowohl die DLL als auch das Hauptprogramm werden mit Runtime Packages kompiliert...

Union 19. Sep 2013 09:30

AW: Invalid Class Typecast
 
Hat zwar nichts driekt mit Deiner Frage zu tun, aber könntest Du den Source nicht aufräumen?

Durch Verwendung einer Liste für die Verwaltung Deiner Dateinamen und Memory Streams würde das um 80% schrumpfen und auf jeden Fall übersichtlicher werden. Und natürlich auch flexibler - Was geschieht denn momentan wenn Du ein Attachment 11 dazunimmst? Das SQL wird automatisch erweitert, aber Du müsstest dann neue Variablen einführen und an diversen Stellen Änderungen vornehmen.

Andidreas 19. Sep 2013 09:35

AW: Invalid Class Typecast
 
Zitat:

Zitat von Union (Beitrag 1229063)
Hat zwar nichts driekt mit Deiner Frage zu tun, aber könntest Du den Source nicht aufräumen?

Durch Verwendung einer Liste für die Verwaltung Deiner Dateinamen und Memory Streams würde das um 80% schrumpfen und auf jeden Fall übersichtlicher werden. Und natürlich auch flexibler - Was geschieht denn momentan wenn Du ein Attachment 11 dazunimmst? Das SQL wird automatisch erweitert, aber Du müsstest dann neue Variablen einführen und an diversen Stellen Änderungen vornehmen.

Wie meinst Du das mit der Liste? Ich hab gestern z.B. sowas versucht:
Delphi-Quellcode:
   compName := 'ms' + IntToStr(i);
  (compName as TMemoryStream) := TMemoryStream.Create;
Hat aber nicht funktioniert...

Ein 11. Attachment ist nicht vorgesehen (und darf es nach meinen Vorgaben auch nie geben [wers glaubt...])...

Union 19. Sep 2013 10:04

AW: Invalid Class Typecast
 
Z.b. so (ungeprüft):
Delphi-Quellcode:
type
  TAttachmentInfo = class
    Ms : TMemorystream;
    Fn : string;
  public
    destructor destroy; override;
  end;

{ TAttachmentInfo }

destructor TAttachmentInfo.destroy;
begin
  if Assigned(Ms) then
    Ms.Free;
  if fn <> '' then
    fn := emptystr;
  inherited;
end;

procedure TTmaintenance_testmailing_form.advGlowBtnClick(Sender: TObject);
var
 i : Integer;
 AttachInfo : TAttachmentInfo;
 AttachInfoList : TObjectList;
begin

   //Check Entries
   If (StringReplace(edt_mailproject.Text, ' ', '', [rfReplaceAll]) = EmptyStr) Or
      (StringReplace(edt_mailapplication.Text, ' ', '', [rfReplaceAll]) = EmptyStr) Or
      (StringReplace(edt_mailsubject.Text, ' ', '', [rfReplaceAll]) = EmptyStr) Or
      (StringReplace(edt_mailsenderadress.Text, ' ', '', [rfReplaceAll]) = EmptyStr) Or
      (StringReplace(edt_mailsendertext.Text, ' ', '', [rfReplaceAll]) = EmptyStr) Or
      (StringReplace(edt_mailrecipient.Text, ' ', '', [rfReplaceAll]) = EmptyStr) Then
   Begin
     fnDisplayMyActionBox('ERR', 'Error', 'Entries are not complete!', EmptyStr, EmptyStr, EmptyStr, True);
     Exit;
   End;

   //Check count of Attachments
   If lstbox_attachments.Count > 10 Then
   Begin
     fnDisplayMyActionBox('ERR', 'Error', 'More than 10 Attachments!', 'Only max. 10 Attachments allowed!', EmptyStr, EmptyStr, True);
     Exit;
   End;

   AttachInfoList := TObjectList.Create;
   Try
     //Load Attachments in Memory Streams
     For i := 0 To lstbox_attachments.Count -1 Do
     Begin
       AttachInfo := TAttachmentInfo.Create;
       AttachInfo.Ms := TMemoryStream.Create;
       try
         AttachInfo.Ms.LoadFromFile(lstbox_Attachments.Items.Strings[i]);
         AttachInfo.Fn := fnGetFileName(lstbox_Attachments.Items.Strings[i]);
         AttachInfoList.Add(AttachInfo);
       Except
         On E:Exception Do
         Begin
           fnDisplayMyActionBox('ERR', 'Error', 'Could not load Attachment into Memory Stream', lstbox_Attachments.Items.Strings[i], E.Message, EmptyStr, True);
         End;
       End;
     End;

     //Insert Test Record into MS SQL Table Mail
     Try
       With (MSSQL_Query1) Do
       Begin
         Active := False;
         SQL.Clear;
         SQL.Add(' Insert Into "' + ModuleUniDBSchema + '.Mail" ');
         SQL.Add(' ( ');
         SQL.Add(' Mail_Project, Mail_Application, Mail_Subject, Mail_SenderAdress, Mail_SenderText, ');
         SQL.Add(' Mail_Recipient, Mail_CC, Mail_Message, Mail_AttachmentCount, Mail_Stati ');

         For i := 0 To lstbox_Attachments.Count -1 Do
         Begin
           SQL.Add(' , Mail_AttachmentName' + IntToStr(i+1));
           SQL.Add(' , Mail_Attachment' + IntToStr(i+1));
         End;

         SQL.Add(' ) ');

         SQL.Add(' Values( ');
         SQL.Add(' :Mail_Project, :Mail_Application, :Mail_Subject, :Mail_SenderAdress, :Mail_SenderText, ');
         SQL.Add(' :Mail_Recipient, :Mail_CC, :Mail_Message, :Mail_AttachmentCount, :Mail_Stati ');

         For i := 0 To lstbox_Attachments.Count -1 Do
         Begin
           SQL.Add(' , :Mail_AttachmentName' + IntToStr(i+1));
           SQL.Add(' , :Mail_Attachment' + IntToStr(i+1));
         End;

         SQL.Add(' ) ');

         ParamByName('Mail_Project').AsString := edt_mailproject.Text;
         ParamByName('Mail_Application').AsString := edt_mailapplication.Text;
         ParamByName('Mail_Subject').AsString := edt_mailsubject.Text;
         ParamByName('Mail_SenderAdress').AsString := edt_mailsenderadress.Text;
         ParamByName('Mail_SenderText').AsString := edt_mailsendertext.Text;
         ParamByName('Mail_Recipient').AsString := edt_mailrecipient.Text;
         ParamByName('Mail_CC').AsString := edt_mailcc.Text;
         ParamByName('Mail_Message').AsString := mem_mailtext.Text;
         ParamByName('Mail_AttachmentCount').AsString := IntToStr(lstbox_attachments.Count);
         ParamByName('Mail_Stati').AsString := '10';

         For i := 0 To lstbox_Attachments.Count -1 Do
         Begin
           ParamByName('Mail_AttachmentName'+IntToStr(i+1)).AsString := TAttachmentInfo(AttachInfoList[i]).fn;
           ParamByName('Mail_Attachment'+IntToStr(i+1)).SetBlobData(TAttachmentInfo(AttachInfoList[i]).ms.Memory, TAttachmentInfo(AttachInfoList[i]).ms.Size);
         End;

         ExecSQL;
       End;
     Except
       On E:Exception Do
       Begin
         fnDisplayMyActionBox('ERR', 'MS SQL Error', 'Could not insert Record into Mail Table!', E.Message, EmptyStr, EmptyStr, True);
       End;
     End;
   Finally
     AttachInfoList.Free;
   End;
end;


Alle Zeitangaben in WEZ +1. Es ist jetzt 19:56 Uhr.
Seite 1 von 2  1 2      

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