Two problems with using workflow 2.4

I use  workflow 2.4 and encounter 2 problems.

1,in workflow define form,we can add attachments,if I add a text file and save this workflowdefination,
later I reopen this  workflowdefination,and open this text file,all is ok.But if I add a binarry file(such as
jpg,doc,pdf,etc) as an attachment,save to Database,when I reopen it,errors occured:wrong data format.It seems some data lost when being saved to Database.Strangely,Adding and opening attachments in tasklistview seems OK;
2,After I create and run workflowinstane,Can I free it mannually? ex:wfi.free?When I do this,always raises some errors.Can it be free automatically?,if so,under which condition it be freed?

please help me!

thanks.
  Wangxuebin mar 31,2016
  1. Can you please contact our support e-mail with more details about how to reproduce the problem. Have you created the database structure exactly as provided by the SQL scripts, or did you use a different structure? what database and what component to access it are you using?

    2. If you call RunWorkflow, the instance will be freed when workflow finishes. Otherwise, you must destroy it.

Thanks.

1,I use unidac and MySQL.I update table structures using SQL scripts.I write a workflowDB for connecting to mysql using unidac as follwing:

unit wsunidb;

//{$I wsdefs.inc}

interface
uses SysUtils, Classes, Dialogs,strutils,
  Variants,
  DB,wsDB, MemDS, DBAccess, Uni,
  UniProvider;

type
  TWorkflowUNIDB = class(TCustomWorkflowDB)
  private
    FConnection: TUniConnection;
    procedure SetConnection(const Value: TUniConnection);
  protected
    procedure Notification(AComponent: TComponent; Operation: TOperation); override;
    function DoCreateQuery(SQL: string): TDataset; override;
    function DoExecuteQuery(Dataset: TDataset): integer; override;
    procedure DoAssignSQLParams(Dataset: TDataset; AParams: TParams); override;
    function BlobFieldToString(AField: TField): string; override;
  public
    constructor Create(AOwner: TComponent); override;
  published
    property Connection: TUniConnection read FConnection write SetConnection;
  end;

procedure Register;

implementation
uses wsRes;

function Max(A, B: Integer): Integer;
begin
  if A > B then
    Result := A
  else
    Result := B;
end;

{ TWorkflowUNIDB }

constructor TWorkflowUNIDB.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  DestroyQueries := true;
end;

function TWorkflowUNIDB.BlobFieldToString(AField: TField): string;
var
  BlobField: TBlobField;
  StrStream: TStringStream;
  c: integer;
  IsOleStr: boolean;
begin
  if AField is TBlobField then
  begin
    BlobField := TBlobField(AField);
    StrStream := TStringStream.Create('');
    try
      BlobField.SaveToStream(StrStream);
      StrStream.Position := 0;
      result := StrStream.ReadString(StrStream.Size);
    finally
      StrStream.Free;
    end;
  end else
    result := AField.AsString;

  //{workaround to "tell" if the string is an Ole string}
  IsOleStr := true;
  c := 2;
  while c < length(result) do
  begin
    if result[c] <> chr(0) then
    begin
      IsOleStr := false;
      break;
    end;
    c := c + 2;
  end;

  //{remove #0 characters}

  if IsOleStr then
  begin
    c := 2;
    while c < length(result) do
    begin
      Delete(result, c, 1);
      inc(c);
    end;
  end;
end;

function TWorkflowUNIDB.DoExecuteQuery(Dataset: TDataset): integer;
begin
  TUniQuery(Dataset).Execute;
end;

function TWorkflowUNIDB.DoCreateQuery(SQL: string): TDataset;
var
  Q: TUniQuery;
begin
  Q := TUniQuery.Create(nil);
  Q.Connection := FConnection;
  Q.Params.Clear;
  Q.SQL.Text := SQL;
  result := Q;
end;

procedure TWorkflowUNIDB.DoAssignSQLParams(Dataset: TDataset; AParams: TParams);
var
  Q: TUniQuery;
  c: integer;
  AParam: TParam;
begin
  Q := TUniQuery(Dataset);
  //Q.Parameters.ParseSQL(Q.SQL.Text, true);
  q.Params.ParseSQL(Q.SQL.Text, true);
  for c := 0 to Q.Params.Count - 1 do
  begin
    AParam := AParams.FindParam(Q.Params[c].Name);
    if AParam = nil then
    begin
      wsDBError(Format(_str(SErrorParamNotFound),
        [Q.Params[c].Name]));
    end;

    Q.Params[c].DataType := AParam.DataType;
    //Q.Params[c].Direction := pdInput;
    Q.Params[c].Value := AParam.Value;
    if Q.Params[c].DataType in [ftString] then
      Q.Params[c].Size := Max(1, Length(VarToSTr(Q.Params[c].Value)));
  end;
end;

procedure TWorkflowUNIDB.Notification(AComponent: TComponent;
  Operation: TOperation);
begin
  if (Operation = opRemove) and (AComponent = FConnection) then
    FConnection := nil;
  inherited Notification(AComponent, Operation);
end;

procedure TWorkflowUNIDB.SetConnection(const Value: TUniConnection);
begin
  if (FConnection <> Value) then
  begin
    FConnection := Value;
    if Value <> nil then
      Value.FreeNotification(Self);
  end;
end;

procedure Register;
begin
  RegisterComponents('Workflow Studio', [TWorkflowUNIDB]);
end;
end.

2,for example:
rwww:=WorkflowStudio.WorkflowManager.FindWorkflowInstanceByKey(wkfid);
rwww must be free manually?
  1. Thank you, I was not aware that you were using custom-made code, since UniDac is not officially supported. I'd first suggest you to build your UniDac support based on the wsFireDac.pas, which is more modern code and cleaner. I also think UniDac works more similar to FireDac when it comes to params support so probably it will work.

    2. You must destroy it, yes.

thanks for your replies.

for the first problem,I run your demo(WorkflowDemo.exe,wihich uses workflowadodb connectting an Access DB),the problem still exists,you can try this:in workflow defination form,add a binary attchament(for example,a pdf file),save the workflow defination,then reopen it,open the  attchament,It is impossible to open  attchament correctly!

Sorry, but it's working here, the demo. I can save a binary file and then reopen it with no problem...