How to stay logged in browser CEF4Delphi, without all browser history? - delphi

In CEF4Delphi it is possible to maintain the browser session with
GlobalCEFApp.PersistSessionCookies := True;
GlobalCEFApp.Cache := 'cache_folder';
thanks to this, one can keep embeed browser logged in, for example, mail. Unfortunately, this solution saves the entire cache of the browser, including attachments etc., which makes the cache folder very large after a while. In the previous version (CEF3) was an option to manage only a component that took up very little on the disk:
CookieManager := TCefCookieManagerRef.Global(nil);
CookieManager.FlushStore(nil);
but I have not found a similar solution for CEF4, while the command
GlobalCEFApp.PersistUserPreferences := True;
GlobalCEFApp.UserDataPath := 'User_Data_folder';
does not save any information in the created folder at all.
Is there any method to keep logging only without saving the entire cache? Or maybe some philosophy which i did not figured out yet, for example deleting some specific folders with a saved cache?
Note: My version of CEF4Delphi uses CEF 86.0.21 which includes Chromium 86.0.4240.183; i'm using TChromium component.

If you are using Global Cookie manager you should also set GlobalCEFApp.PresistSessionCookies to True
CEF4Delphi also has two properties which you can use to delet od cache or cookies upon CEF application initialization. These are DeleteCache and DeleteCookies.

Related

How can I save a WhatsApp session using Delphi and Chromium?

I'm using the CEF3 2378.1280 branch and Delphi 10.1. I'm using the following code to save sessions:
var
CookieManager: ICefCookieManager;
FromCreate:
CookiesPath := ExtractFilePath(Application.ExeName) + 'cookies';
CookieManager := TCefCookieManagerRef.Global(nil);
CookieManager.SetStoragePath(CookiesPath, true, nil);
This code work fine with Facebook and a lot of other sites. But for web.whatsapp.com it can't save the session: After restarting the program, I must do tge QR-code validation again.
How can I save a WhatsApp session?
I'm sorry I asked you to move your question here. Usually, all questions that may have something to do with CEF bindings are redirected to their respective forums and this is a pure DCEF3 question.
You don't need to specify a separate cookies directory. All you need is to set a cache directory using the 'CefCache' variable.
The CEF3 2378.1280 branch is too old and that website may not support it. Upgrade to CEF3.2623 if you still need to support Windows XP and Vista, or upgrade to CEF3.3440 if you want the latest branch.
If you decide to use CEF3.2623 you can use DCEF3 or OldCEF4Delphi.
To use the latest branch you will have to use CEF4Delphi.

How to destroy the Tchromium (Delphi) component dynamically created?

How to destroy the Tchromium component dynamically created ? I'm using in a DLL , the component necessary to create and destroy it several times without deallocate the DLL, the problem is that is not releasing memory and is unable to clear the cache folder. If I use CefShutDown problems occur in time to recreate the browser again. I'm using the latest version of DCEF3 .
Create dynamically like this:
crm := TChromium.Create(Form1);
crm.SetParentComponent (Panel2);
crm.Align := alClient;
to destroy tried in several ways:
FreeAndNil(crm);
crm.free;
crm := nil;
CefShutDown;
The CefShutDown resolved in time to destroy , the problem is occurring by the time I try again recreate the component without deallocate my DLL.
Also solve another problem I'm having with the UserAgent can not change the recreation of the browser.
I appreciate any suggestions to solve my problem.
This behaviour is as designed. Issue 1237 on the Chromium issue tracker is identical to your issue. The relevant excerpt is:
CefInitialize/CefShutdown cannot be called multiple times in the same process. You can create/destroy multiple browser windows without re-initializing CEF.
You will have to refrain from calling CefShutDown.

SelectDirectory/ShBrowseForFolder issue when having a lot of shell items

I'm running into a very strange problem with the Vcl.FileCtrl function SelectDirectory (which is a thin wrapper around the ShBrowseForFolder Win32 API).
I'm using the following code to allow the user to browse for a file or a folder:
if SelectDirectory('Sélectionnez un élément à ajouter :', '', S, [sdNewFolder,
sdShowFiles, sdNewUI]) then
When executing this code, the "Browse for folder" dialog is correctly shown, displaying the content of the user's Desktop:
But when the number of items in the Desktop folder is excessively large (on my computer, I can reproduce the problem by having approx. 100 desktop icons), the same call produces a totally different display:
In this case, the Desktop items aren't shown anymore. I'm only allowed to explore my home folder and since I've lost the "My Computer" icon I cannot select a file/folder outside of this directory.
I'm searching what I'm missing here. Is there a limit in the number of subitems a root item can have for a correct display? Having a lot of desktop icons is certainely not a good practice, but as far as I know that shouldn't prevent this dialog to operate normally. I'm not sure if there is something wrong in the Delphi wrapper, or if that's a limitation of the API I didn't see on MSDN...
Any hint appreciated!
Yes, I can reproduce this behaviour. It's clearly a Windows limitation and the API in question does not offer you any way to increase buffers. I think your chances of working around it using SHBrowseForFolder are close to zero. Because SHBrowseForFolder is now a a legacy API.
If you are browsing for folders then you should use IFileOpenDialog in folder selection mode. That's a a much nicer dialog that uses the new Vista dialogs. In Delphi that is wrapped by TFileOpenDialog. Only use that if Win32MajorVersion>=6 though! For XP you need to call back on SHBrowseForFolder.
if Win32MajorVersion>=6 then
begin
FileOpenDialog1.Title := 'Sélectionnez un élément à ajouter :';
FileOpenDialog1.Options := FileOpenDialog1.Options + [fdoPickFolders];
if FileOpenDialog1.Execute then
Beep;
end else
begin
// revert to SelectDirectory
end;
The workaround I came to is to use the "old" (Win XP) UI, which can be done by not specifying the [sdNewUI] flag. In this case, all the items are correctly displayed.
That seems to be the only valid solution when the user must select files OR folders, something TFileOpenDialog is not capable of.

Launching application from a database

I have many users using my application. However if I do some update, which I put on the server, not all of them are willing to update it (they sometimes afraid of changes they do not want to accustom).
So I speculate, how to force them to launch the latest application. There are surely several ways how to do it, but I have heard, that it is possible to launch an application stored in a blob field of a database.
Does anybody knows how it can be accomplished? (I am using MySQL database)
thanx
Without judging on meaningful or nonsense ....
You could use uExecFromMem .....
There is a Memoryleak in this unit which can be fixed by adding:
ResumeThread(PI.hThread);
Result := PI.hThread;
FreeMem(pFile); // added here
end;
an example call using a TBlobField would be
var
ms:TMemoryStream;
begin
ms:=TMemoryStream.Create;
try
TBlobField(YouDBBlobField).SaveToStream(ms);
ms.Position := 0;
ExecuteFromMem(Application.ExeName,'',ms.Memory); // pointing to an existing executable
finally
ms.Free;
end;
end;
My advice is to use libraries.
You can have a small main executable file (some kind of "launcher"), which won't do nothing but launch external .dll fields. Just like a kernel does load modules at runtime (think about how Windows or Linux work).
Then you download an updated version of a .dll, stop and unload the old one, then load and initialize the new version.
Of course, your code has to be "clean", with proper startup and shutdown functions for each .dll.
But I suspect it would be much less error prone than ExecuteFromMem(). In this respect, good old load + execute of an .exe file (as Remy suggested) sounds like a much better option to me.

Can MS Access 2007 support multiuser environment?

There is an application which is running on several machines(say roughly on 2).This application updates an shared mdb placed on network.Both users are trying to update the shared mdb at one time but the problem is only one user is able to update mdb at one time.Another user is not able to open it.Can anyone suggest that access support multiuser environment?
edit:
There is one form TFormRoadAttrib.When it activates following function is called
procedure TFrmRoadAttrib.FormActivate(Sender: TObject);
if dmTimeDomain <> nil then
begin
if not (dmTimeDomain.dbTimeDomain.InTransaction) then
begin
dmTimeDomain.dbTimeDomain.BeginTrans;
end;
end;
where dbTimeDomain=TADOConnection and its value is
'Provider=Microsoft.ACE.OLEDB.12.0;
Mode=Share Deny None;
Extended Properties="";
Locale Identifier=1033;
Jet OLEDB:Registry Path="";
Jet OLEDB:Database Password="";
Jet OLEDB:Engine Type=4;
Jet OLEDB:Database Locking Mode=0;
Jet OLEDB:Global Partial Bulk Ops=2;
Jet OLEDB:Global Bulk Transactions=1;
Jet OLEDB:New Database Password="";
Jet OLEDB:Create System Database=False;
Jet OLEDB:Encrypt Database=False;
Jet OLEDB:Don't Copy Locale on Compact=False;
Jet OLEDB:Compact Without Replica Repair=False;
Jet OLEDB:SFP=False;
Data Source=Q:\BEL_01\BEL_GADM\ACCESS\Restrictions.mdb;
Jet OLEDB:System database=C:\Program Files\Tele Atlas\Common Files\DPT.MDW;
User ID=dbadpt;
Password=dbadpt;
When we click on Ok button following code executes
if dmTimeDomain <> nil then
begin
if (dmTimeDomain.dbTimeDomain.InTransaction) then
dmTimeDomain.dbTimeDomain.CommitTrans;
end;
end;
Kindly suggest.
Access definitely supports a multi-user environment, but your permissions must be set correctly. All users must be able to create files in the directory where the database is located, and all users must have permission to modify files created in that directory by other users. There are many ways to mess that up. This is because Access uses a separate .ldb file as part of its mechanism for managing concurrent, multi-user access.
A good test is to have one user create a text file in the shared directory, and then make sure the other user can open that file, and then save a change to it.
Both should be able to use the app. If one user is editing a form or table, the others are locked out of editing those same objects. But that should have no bearing on the app once it's in "production" state. A few years ago I helped convert a large app to MS SQL Server backend (stil MS Access frontend) and until that point, they had been successfully using the app with 15 users simultaneously. The app just got too big (100 forms, 100 tables, some with a million rows) so they moved for performance reasons. Otherwise they'd still be totally on Access.
Consider using an Access Project (adp extension) instead of a normal access mdb file. An access project works with SQL server desktop engine which you will find as a separate install file on you Office CD. This essentially means you have a slightly watered down version of SQL server running and this server will take care of all your concurrency issues for you. Also, if your DB becomes too big for an Access Project, you can easily port your DB to a fully fledged SQL Server machine. You can do most of the things in an Access Project that you can do with SQL Server, including Stored Procedures etc, and it's pretty easy to setup and connect to.

Resources