My program is a Delphi ISAPI DLL built with Delphi 2007.
I'm migrating to Delphi 10.2 Tokyo and TWebModuleList is gone from Web.WebReq.
With D2007, when the application starts, the following code is called in order to pre instanciate a pool of 5 WebModules.
procedure TSWebApplication.CreationWebModules;
var
i: integer;
TabDataModules : array of TWebModuleList;
begin
SetLength(TabDataModules,1);
TabDataModules[0] := ActivateWebModules;
if Assigned(TabDataModules[0]) then
TabDataModules[0].AutoCreateModules;
SetLength(TabDataModules, NbInstances);
for i := 1 to NbInstances - 1 do
begin
TabDataModules[i] := ActivateWebModules;
if Assigned(TabDataModules[i]) then
TabDataModules[i].AutoCreateModules;
end;
for i := 0 to NbInstances - 1 do
DeActivateWebModules(TabDataModules[i]);
end;
This way, instead of having the (first 5) WebModules created on demand, they are created when the application starts, then deactivated and auto activated on demand.
I know WebModules are managed by IIS and we don't necessary need this behavior, but it is the way it worked (pretty well).
TWebModuleList seems gone since Delphi XE8 (no page on docwiki.embarcadero.com whereas it was still there on the XE7 site).
I couldn't find ANY changelog, or other information on why it is gone et how we can build the same behavior...
Does anyone have any information?
Thanks
Related
I am trying to accept file uploads in a Delphi 7 Webbroker CGI.
I'm using Shiv Kumar's TMsMultipartParser, but I have a problem with Chrome. I can't access the parsed data (surprisingly, Explorer works fine).
This is my code:
with TMsMultipartFormParser.Create do
begin
Parse(Request);
lsExternalID:=ContentFields.Values['external_id'];
if (lsExternalID='') then
raise Exception.Create('No external ID');
for i := 0 to Files.Count -1 do
begin
lsFileName:=files[i].FileName;
//Rename file using external ID (not included for simplicity)
Files[i].SaveToFile(lsFilename);
end;
Response.Content := 'OK';
free;
end;
As suggested here, I tried to use http://www.mrsoft.org/Delphi/MultipartParser.pas but I can't compile it. It uses a unit called UniversalUtils that I can't find anywhere.
I know this is a very obsolete technology. Almost all references to it have already disappeared from the web (believe me, I have searched). Buy any help would be deeply appreciated.
Thanks.
I finally solved my problem, thanks to #mrabat.
This project started in Delphi 5. It was later upgraded to Delphi 7 (it can't be upgraded further, because many parts can't support Unicode strings, we use ANSI).
We were using Shiv's TMsMultipartParser because Delphi 5 didn't have any parser included.
Delphi 7 has TMultipartContentParser in unit ReqMulti.pas, and it works perfectly.
For anyone that need an example, I'll post my working code:
with TMultipartContentParser.Create(Request) do
begin
lsExternalID:=ContentFields.Values['external_id'];
if (lsExternalID='') then
raise Exception.Create('No external ID');
for i := 0 to Request.Files.Count -1 do
begin
lsFileName:=Request.Files[i].FileName;
//Rename file using external ID (not included for simplicity)
TMemoryStream(Request.Files[i].Stream).SaveToFile(lsFilename);
end;
Response.Content := 'OK';
Free;
end;
I wrote something similar once here:
https://github.com/stijnsanders/xxm/blob/master/Delphi/common/xxmParams.pas#L159
but that may be tightly coupled with SplitHeaderValue that parses the header lines, and TStreamNozzle that throttles incoming data. (and TXxmReqPar... objects, and IXxmContext...)
(Of course you're warmly welcomed to accept file uploads with xxm...)
Does anyone know how (if) I can obtain bug fixes for Delphi for known, fixed bugs (specifically QC report #125506 relating to indexes in Clientdatasets)
I understand that it has been fixed in XE7 but I object(!!!) to paying £1,000+ to update from XE6 to XE7 when I have only had XE6 for a matter of months, I have spent the time identifying the bug and the ONLY reason I have for moving from XE6 to XE7 is to fix the bug (rant over)!
Apologies for posting this as an "answer" but there are a few things worth mentioning that won't fit comfortably in a comment (or two).
As you've probably gathered, the "Resolution comments" on QC #125506 don't say anything useful, in particular about what was changed or where e.g. in DBClient.Pas or Midas.Dll. I've just run Beyond Compare on the sources of DBClient.Pas in XE6 & XE7, and the changes are minimal: The declaration of TCustomClientDataSet has had a local class declaration of "TPersistDataPacket" added to it and there are a few consequential changes, but whether they bear on QC #125506 is impossible to say. I wondered about quoting the changes here, but decided not to in view of possible copyright or T&C problems.
The versions of MidasLib.Pas in XE6 and XE7 are identical, but the size of the 32-bit release build of MidasLib.Dcu has increased marginally, from 241447 to 241646 bytes. Oddly, Midas.Dll has actually reduced in size, from 451960 to 437632 bytes.
A couple of obvious suggestions:
I'm not sure if the trial version of XE7 includes the Datasnap stuff, but in view of the expense, it would definitely be worth "trying before you buy" if you can manage it. If it doesn't include Datasnap, you might nevertheless see if you can get hold of a copy of the XE7 Midas.Dll - once upon a time Borland-as-was was quite liberal in allowing the latest Midas.Dll to be used with earlier versions. Might be worthwhile asking about both these points on the EMBA newgroups.
In QC #125506, the reporter seems to have run into the problem when using the CDS IndexFieldNames property. If that's how your getting it, have you tried defining a persistent IndexDef instead? The following code works for me (tested on the Authors table of the Sql Server Pubs demo database).
Dynamically adding/using an IndexDef.
procedure TDefaultForm.AddIndex(AFieldName: String; CaseInsensitive: Boolean);
var
AIndexDef : TIndexDef;
AIndexName : String;
Options : TIndexOptions;
BM : TBookmark;
begin
if CDS1.IndexDefs.GetIndexForFields(AFieldName, CaseInsensitive) = Nil then begin
BM := CDS1.GetBookmark;
try
CDS1.DisableControls;
AIndexName := 'By' + AFieldName;
Options := [];
if CaseInsensitive then
Options := Options + [ixCaseInsensitive];
AIndexDef := TIndexDef.Create(CDS1.IndexDefs, AIndexName, AFieldName, Options);
CDS1.IndexName := AIndexName;
finally
CDS1.GotoBookmark(BM);
CDS1.FreeBookmark(BM);
CDS1.EnableControls;
end;
end;
end;
procedure TDefaultForm.btnAddClick(Sender: TObject);
begin
AddIndex('au_lname', True);
end;
I'm using Delphi XE5.
On my GroupFooter I try to hide several memos in a conditional is met
procedure GroupFooter1OnBeforePrint(Sender: TfrxComponent);
begin
ShowMessage('a');
if <frxDB."total_payment"> <= 0 then begin
Memo27.Visible := False;
Memo28.Visible := False;
Memo29.Visible := False;
Memo30.Visible := False;
end;
end;
This is my calling code in Delphi
Report.LoadFromFile(CurDir+'reports/invoice/'+ReportName);
if Report.PrepareReport then
Report.ShowPreparedReport;
I found that the OnBeforePrint event never fires when the report was showing after frxReport.ShowPreparedReport command, but when I tries to preview it in the designer, it works just as normal.
I keep wondering what did I miss.
Anyone can help?
Thanks
I recently found out that this is due to FastReport 4 demo version that is bundled along with Embarcadero RAD Studio XE5. The full version works perfectly, but any fr3 file created from demo-bundled version can't be opened in full version.
Data processing with XE3 programs take up to 10 times more than with same programs compiled with XE2. This is known issue (probably refers mainly to TStringField), reported to QC 111942, but it is not fixed yet. Does anybody have a fix / workaround for this issue?
TIA Branko
Same in XE5. Plus extra traffic and all this client-server thing require >5 Mbit per second (!) to work normally. I am using only TFDConnection and TFDQuery. Specially for MySQL the speed is the same with Delphi components and with third-party driver (libmysql.dll). If you have no FireDAC you can replace TFDQuery with TSQLQuery. Here is a procedure how to fill a string grid:
procedure SelGrid(sql:ansiString;Q:TFDQuery;grid:TStringGrid);
var i: integer;
begin
Q.Close;
Q.SQL.Text:='';
Q.Open(sql);
grid.ColCount:=Q.FieldCount;
grid.RowCount:=1;
while not Q.Eof do begin
for i := 0 to grid.ColCount-1 do grid.Cells[i,grid.RowCount-1]:=Q.Fields.Fields[i].AsString;
grid.RowCount:=grid.RowCount+1;
Q.Next;
end;
Q.Close;
if grid.RowCount>1 then grid.RowCount:=grid.RowCount-1;
grid.Row:=0;
//AutoSizeGridColumns(grid,30,200);
end;
This is VCL string grid. Of course you muse deal with updates and so on, but you'll have no more performance problems.
In Delphi 2009 I'm finding that any time I do perform both a connection to Oracle (via OCI.dll) and a call to a web service method I get an exception in ntdll.dll when closing my application in the IDE.
For the connection to Oracle I tried using both DOA (Direct Oracle Access) 4.1.1.0 and ODAC components (latest trial version);
For the web service method call (just a simple "function HelloWorld: string") I am using Delphi stock capabilities, after importing the WSDL from the web service.
If I use ODAC components in "direct" mode, that is not using OCI.dll, no exception occurs on closing.
If I call a web service method only (without connecting to Oracle), no exception occurs on closing (even if I use either DOA or ODAC components).
If I connect to Oracle (via OCI.dll) only (without calling a web service method), everything goes fine too (no matter if I use either DOA or ODAC components).
The very same code runs perfect when executed both in Delphi 7 and Delphi XE2: no exception occurs on application closing.
Some information:
Delphi 2009 (stock and Update 3 version)
OS: Windows 7 32 bit
Oracle Instant Client 10.2.0.4 and Oracle Instant Client 10.2.0.5
I start suspecting that it might be an issue related to heap corruption in Delphi 2009 on application closing...
Any help please?
Steps to reproduce (from the comment):
Create a new VCL Forms Application
Place a TOracleSession DOA component (named OracleSession1) on the Form
Place a TButton on the Form (named Button1)
Place this event handler for the button click event:
Here is the code:
procedure TForm1.Button1Click(Sender: TObject);
var
MyWebService3Soap: WebService3Soap;
s: string;
begin
OracleSession1.LogonDatabase := 'SomeLogonDB';
OracleSession1.LogonUsername := 'SomeUsername';
OracleSession1.LogonPassword := 'SomePassword';
OracleSession1.Connected := True;
ShowMessage('Connected');
MyWebService3Soap := GetWebService3Soap();
s := MyWebService3Soap.HelloWorld(); // Just returns a string such as "Hello World"
ShowMessage(s);
end;
The "WebService3Soap" interface is the one automatically generated by Delphi 2009 WSDL Importer. Here is the meaningful part:
WebService3Soap = interface(IInvokable)
['{F6F12FA6-3881-8BB5-AD71-2408B47692CD}']
function HelloWorld: string; stdcall;
end;
function GetWebService3Soap(UseWSDL: Boolean=System.False; Addr: string=''; HTTPRIO: THTTPRIO = nil): WebService3Soap;
initialization
InvRegistry.RegisterInterface(TypeInfo(WebService3Soap), 'http://mytest.it/Test3', 'utf-8');
InvRegistry.RegisterDefaultSOAPAction(TypeInfo(WebService3Soap), 'http://mytest.it/Test3/HelloWorld');
InvRegistry.RegisterInvokeOptions(TypeInfo(WebService3Soap), ioDocument);
end.
Run the application inside the IDE, press the button (close the 2 following ShowMessages) and then close the form.
Given the hint that it might be a "DLL hell" issue, I was able to run a test both on Windows XP and on Vista: everything went fine. So I started thinking that this issue had somehow to be related to Delphi 2009 on Windows 7.
I was right and I found that there is an issue In Delphi 2009 with debugging on Windows 7.
Fortunately a patch is available:
ID: 27476, Hotfix 2 for Delphi 2009 and C++Builder 2009
Applying the patch solved!