Suppression d'un dossier impossible

ludo2223 Messages postés 49 Date d'inscription jeudi 4 septembre 2008 Statut Membre Dernière intervention 31 janvier 2010 - 15 avril 2009 à 10:56
cs_cantador Messages postés 4720 Date d'inscription dimanche 26 février 2006 Statut Modérateur Dernière intervention 31 juillet 2021 - 15 juin 2009 à 10:26
Bonjour à tous,

Je travaille sur une application utilisant des bases de données Paradox.

Lorsque l'utilisateur supprime un élément depuis l'application je supprime sa base de données associée (fonctionne).
Le répertoire est donc vide mais je ne peux pas le supprimer, windows indique que le répertoire est en cours d'utilisation.
(si je ferme mon programme la suppression redeviens possible. Je pense donc à une ressource non libérée mais je ne vois pas laquelle étant donné que le répertoire ne contient que la base que je libère pour la supprimer.)

Je fait donc appel à vous, si vous avez des idées ?

(Je suis sous Delphi 2009)

Merci d'avance pour votre aide.

Ludovic

35 réponses

cs_cantador Messages postés 4720 Date d'inscription dimanche 26 février 2006 Statut Modérateur Dernière intervention 31 juillet 2021 13
15 avril 2009 à 11:52
bonjour,

Je travaille sur une application utilisant des bases de données Paradox.
Est-ce une application en mode Client/Server (réseau) ou Locale ?

cantador
0
ludo2223 Messages postés 49 Date d'inscription jeudi 4 septembre 2008 Statut Membre Dernière intervention 31 janvier 2010
15 avril 2009 à 12:06
Bonjour,

Merci pour votre réponse.

Il s'agit d'une application en local.

Petite précision, pour fermer la base je fait :
Table.Active := False;
Table.Free;

Merci d'avance pour votre aide.

ludovic
0
Guillemouze Messages postés 991 Date d'inscription samedi 25 octobre 2003 Statut Membre Dernière intervention 29 août 2013 6
15 avril 2009 à 14:02
peut etre que le repertoire courant est ton dossier en question (que tu peux verifier par un getDir), il faut donc que tu fasse un ChDir si c'est le cas
0
cs_cantador Messages postés 4720 Date d'inscription dimanche 26 février 2006 Statut Modérateur Dernière intervention 31 juillet 2021 13
15 avril 2009 à 14:17
Si ta table n'est pas créée dynamiquement Table.free ne sert à rien..


Il faut simplement fermer la(es) table(s) en cours d'utilisation et faire une déconnexion (disconnect)

et après tu peux tout supprimer ce que tu veux.

cantador
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
ludo2223 Messages postés 49 Date d'inscription jeudi 4 septembre 2008 Statut Membre Dernière intervention 31 janvier 2010
15 avril 2009 à 14:56
Bonjour,

Merci pour votre réponse.

Je viens de tester getDir mais il ne me renvoie pas le dossier en question, de même avec GetCurrentDir.
J'ai tout de même testé un ChDir avant la suppression au cas où mais malheureusement cela n'a pas résolu le problème.

En tout cas merci pour l'info, je ne connaissais pas.
0
ludo2223 Messages postés 49 Date d'inscription jeudi 4 septembre 2008 Statut Membre Dernière intervention 31 janvier 2010
15 avril 2009 à 15:19
Pour ouvrir la base, je fait :

(TABLE_Cellule est de type TTable)

TABLE_Cellule.TableName := chemin

ensuite je fait mes modifications dedans

et pour finir je fait un Active:=False et un free.

Pour répondre à votre question, l'objet est créé dynamiquement.

Je n'ai pas trouvé de méthode disconnect.

Je vous remercie pour votre aide.
0
cs_cantador Messages postés 4720 Date d'inscription dimanche 26 février 2006 Statut Modérateur Dernière intervention 31 juillet 2021 13
15 avril 2009 à 15:46
Je n'ai pas trouvé de méthode disconnect.
Une gestion de bdd, c'est d'abord une connexion où alors elle est implicite avec l'ouverture d'une table..


dans ce cas, il faut la dissocier de manière à avoir la maîtrise de sa connexion et de sa déconnection.

cantador
0
Guillemouze Messages postés 991 Date d'inscription samedi 25 octobre 2003 Statut Membre Dernière intervention 29 août 2013 6
15 avril 2009 à 16:03
@cantador : je suis pas sur que la piste de la connexion a la base soit en cause, vu qu'il arrive bien a supprimer le fichier (donc il ne doit pas etre verouillé). Apres, je sais pas tout ce qui se passe derriere la connexion mais je suis pas sur que ce soit ca qui verouille le dossier.
0
cs_cantador Messages postés 4720 Date d'inscription dimanche 26 février 2006 Statut Modérateur Dernière intervention 31 juillet 2021 13
15 avril 2009 à 16:28
hummhhhh, oui c'est bien vu mais la connexion est établie
soit sur un .db ou un alia, c'est-à-dire le chemin d'accès à la base et ensuite on choisit la table, donc le dossier est verrouillé d'après moi..
on a pas suffisamment (comme dab..) d'élèments pour se prononcer.

En tout cas, ça ne coûte rien d'essayer cette déconnexion

cantador
0
ludo2223 Messages postés 49 Date d'inscription jeudi 4 septembre 2008 Statut Membre Dernière intervention 31 janvier 2010
16 avril 2009 à 09:37
Bonjour,

Merci pour vos réponses. Je vais essayer d'être plus précis.

Je travaille sur une base paradox (fichier de type .db) située en local sur le même disque que mon application.

Pour l'utiliser dans une procédure par exemple, j'ai un objet de type TTable, je lui donne le chemin de ma table (C:\maTable.db) à l'aide de TableName.
Ensuite je met l'attribut Active à True et je fait mes modification dedans.

Une fois que tout est terminé et fait un commit (méthode post par exemple), je rends la table inactive (Active := False) et je fait un Free dessus pour libérer la mémoire.

Je n'utilise par de méthode qui permettent de choisir une base et mon dossier ne contient que le fichier maTable.db et ses index.
Une fois le Free effectué je supprime le contenu du répertoire (cela fonctionne parfaitement) et ensuite j'essaie de supprimer le répertoire (et là, ça ne fonctionne pas). Le message d'erreur dit que le dossier est en cours d'utilisation.
J'ai affiché les fichiers caché et les fichiers système et le dossier est bien vide.

(Comme dis précedemment le getDir ne me retourne pas le répertoire bloqué et le ChDir juste avant de supprimer ne corrige pas le problème mais ces deux méthodes me rendront service pour la suite ;) )

J'espère avoir été plus clair.

Je vous remercie d'avance pour vos réponses.

ludovic
0
cs_cantador Messages postés 4720 Date d'inscription dimanche 26 février 2006 Statut Modérateur Dernière intervention 31 juillet 2021 13
16 avril 2009 à 09:51
hé !

(C:\maTable.db)

il est où le dossier qui contient le .db ???

cantador
0
ludo2223 Messages postés 49 Date d'inscription jeudi 4 septembre 2008 Statut Membre Dernière intervention 31 janvier 2010
16 avril 2009 à 10:03
C'était juste pour l'exemple désolé, à remplacer par C:\toto\maTable.db. (Le blocage étant sur toto).
Le blocage persiste même après la fermeture de la fenêtre concernée mais disparait lorsque je fermer l'appli.
0
ludo2223 Messages postés 49 Date d'inscription jeudi 4 septembre 2008 Statut Membre Dernière intervention 31 janvier 2010
16 avril 2009 à 10:47
Petite question pour un test, si je fait : Self.RemoveComponent(TABLE_Cellule);
(Self étant ma Form)
c'est correct pour supprimer l'objet de la form ?

Merci ;)
0
ludo2223 Messages postés 49 Date d'inscription jeudi 4 septembre 2008 Statut Membre Dernière intervention 31 janvier 2010
16 avril 2009 à 11:30
J'ai créé une maquette qui ne fait que se "connecter" à la base et fermer la connexion avec un bouton par action.
Pour que le dossier soit libéré je suis obligé de faire ouvrir une autre base au composant.

Voici mon code de création de l'objet et connexion :
(code d'un bouton)

  Table1 := TTable.Create(nil);
  Table1.IndexFieldNames := 'xxx';
  Table1.TableName := 'C:\...\xxx.db';
  Table1.Active := True;

Voici mon code de "fermeture" :
(code d'un bouton)

Bloc 1 :
  Table1.Open;
  Table1.Edit;
  Table1.Post;
  Table1.Active := False;
  Table1.close;

Bloc 2 :
  Table1.TableName := 'C:\...\xxx.db';
  Table1.Open;
  Table1.Active := False;
  Table1.Close;

Bloc 3 :
  Table1.Free;
  Table1 := nil;

Si je ne met pas le bloc 2 mon dossier n'est pas libéré.
De même dans le bloc 2 si je ne fait pas le "Open" je rencontre le même problème. Je suis obligé de charger une autre table (d'un autre répertoire) pour libérer le précédent.

Si vous avez des idées ;)

Merci d'avance

ludovic
0
cs_cantador Messages postés 4720 Date d'inscription dimanche 26 février 2006 Statut Modérateur Dernière intervention 31 juillet 2021 13
16 avril 2009 à 15:52
La réfléxion continue...

ne règle toujours pas le truc, mais permet d'avancer un peu :

unit Unit1;


interface


uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, DB, Grids, DBGrids, DBTables, StdCtrls, ShellAPI;


type
  TForm1 = class(TForm)
    Table1: TTable;
    DataSource1: TDataSource;
    DBGrid1: TDBGrid;
    Table1CustNo: TAutoIncField;
    Table1Last_Name: TStringField;
    Table1First_Name: TStringField;
    Table1VIP_Status: TStringField;
    Table1Address1: TStringField;
    Table1Address2: TStringField;
    Table1City: TStringField;
    Table1StateProv: TStringField;
    Table1Post_Code: TStringField;
    Table1Country: TStringField;
    Table1Phone: TStringField;
    Table1Fax: TStringField;
    Table1EMail: TStringField;
    Table1Remarks: TMemoField;
    Button1: TButton;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { Déclarations privées }
  public
    { Déclarations publiques }
  end;


var
  Form1: TForm1;


implementation


{$R *.dfm}




function DelDir(Dir: string): Boolean;
var
  fos: TSHFileOpStruct;
begin
  ZeroMemory(@fos, SizeOf(fos));
  with fos do
  begin
    wFunc := FO_DELETE;
    fFlags := FOF_SILENT or FOF_NOCONFIRMATION;
    pFrom := PChar(Dir + #0);
  end;  Result :(0 ShFileOperation(fos));
end;


procedure EffaceFichier(CurDir: string);
var
  searchResult: TSearchRec;
begin
  SetCurrentDir(CurDir);


  if FindFirst('*.*', faAnyFile, searchResult) = 0 then
  begin
    repeat
      DeleteFile(searchResult.Name);
    until FindNext(searchResult) <> 0;


    FindClose(searchResult);
  end;
end;


procedure TForm1.FormCreate(Sender: TObject);
begin
  Table1.Open;
end;


procedure TForm1.Button1Click(Sender: TObject);
begin
  Table1.Close;                           // ferme la table
  EffaceFichier('c:\Test');             // efface tous les fichiers du dossier 
  if DelDir('c:\Test\') then             // et là ce p.. de dossier devrait virer mais 
    showmessage('ok')                 // quedal !
  else
    showmessage('no');
end;
end.

il doit peut-être rester un process en cours..

cantador
0
ludo2223 Messages postés 49 Date d'inscription jeudi 4 septembre 2008 Statut Membre Dernière intervention 31 janvier 2010
16 avril 2009 à 16:04
Merci beaucoup pour vos recherches.

Ce que je ne comprend pas dans cette histoire c'est que j'ai l'impression que même si on fait un close puis un free, BDE ne veut pas lâcher le morceau !

Je continue aussi de mon coté ;)
0
cs_cantador Messages postés 4720 Date d'inscription dimanche 26 février 2006 Statut Modérateur Dernière intervention 31 juillet 2021 13
16 avril 2009 à 16:56
il faut dire aussi que la connexion par le path du .db dans TableName est peu utilisé..
on lui préfère la déclaration d'un alia qui pointe sur le dossier et on choisit ensuite le .db dans une liste déroulante

mais l'explication est quand même un peu juste..

cantador
0
ludo2223 Messages postés 49 Date d'inscription jeudi 4 septembre 2008 Statut Membre Dernière intervention 31 janvier 2010
16 avril 2009 à 18:03
Oui vous avez raison. J'ai cherché du coté des alias pour savoir si ils se créaient automatiquement et j'ai parcouru la liste pour les supprimer mais le problème reste présent.

La seule méthode qui a fonctionné jusqu'à présent c'est de lui faire ouvrir une autre base. Je sais pas si on peut lui donner une constante particulière parce que si le chemin est incorrect le Open échoue et le problème persiste.

J'ai également tenté une suppression manuelle des index puis de celle de table : ca me vide le dossier mais il reste bloqué.

Je travaille sur une application assez importante qui existe déjà donc changer la méthode de connexion et d'exécution représente un travail énorme. C'est pour ca que je cherche une alternative ;)

Merci beaucoup pour vos recherches en tout cas. Je continue encore demain ! ;)

bonne soirée
0
ludo2223 Messages postés 49 Date d'inscription jeudi 4 septembre 2008 Statut Membre Dernière intervention 31 janvier 2010
12 mai 2009 à 16:11
Bonjour,

Depuis cette semaine je recommence à travailler sur ce projet. Je me suis donc penché à nouveau sur le problème et j'ai donc essayé les sessions et alias.

Voici mon code (qui compile et ne génère pas d'erreur mais continue de bloquer le répertoire) :

procedure TForm1.Button1Click(Sender: TObject);
var Session : TSession;
    List : TStringList;
    base:TDatabase;
    TableSession:TTable;
begin

  Session:=TSession.Create(self);
  Session.SessionName:='DBSession';
  Session.DeleteAlias('mb2');
  Session.AddStandardAlias('mb2', 'C:\xxx', 'Paradox');

  Session.Open;

  try

      Session.SaveConfigFile;

      TableSession := TTable.Create(self);
      TableSession.SessionName := Session.SessionName;
      //TableTest.TableName := 'Multibouton.db';

      base := TDatabase.Create(self);
      base.Directory := 'C:\xxx';
      base.DatabaseName := 'mb2';

      TableSession.DatabaseName := base.DatabaseName;
      TableSession.TableName := 'xxx.db';

      MessageDlg('Ouverture', mtWarning,[mbOk], 0);
      TableSession.Open;

      MessageDlg('Fermeture et suppression table', mtWarning,[mbOk], 0);
      TableSession.Close;
      TableSession.DeleteTable;

      MessageDlg('Fermeture session', mtWarning,[mbOk], 0);
      Session.DeleteAlias('mb2');
      Session.Close;

      MessageDlg('Fermeture base', mtWarning,[mbOk], 0);
      base.CloseDataSets;
      base.Close;

      ChDir('C:\Windows');

  finally
    base.Free;
    TableSession.Free;
    Session.Free;
  end;

  MessageDlg('Fin', mtWarning,[mbOk], 0);

L'alias que je crée apparait bien dans l'administrateur bde du poste de travail.

Si vous pouvez me dire si mon code est correct et si ce n'est pas le cas, qu'elle est mon erreur.

Merci d'avance pour vos réponse.

Cordialement

ludovic charollais
0
cs_cantador Messages postés 4720 Date d'inscription dimanche 26 février 2006 Statut Modérateur Dernière intervention 31 juillet 2021 13
12 mai 2009 à 19:20
Lorsque l'utilisateur supprime un élément depuis l'application je supprime sa base de données associée (fonctionne).
Le répertoire est donc vide mais je ne peux pas le supprimer, windows indique que le répertoire est en cours d'utilisation.



il y a manifestement encore quelque chose qui est loggé sur le dossier...
essaie de voir avec le directory
base.Directory := 'C:\xxx';
si tu ne peux pas le vider..

Quand on est bloqué, il faut chercher à contourner l'obstacle et reprendre l'hypothèse de départ que j'ai rappelée.

Est-ce vraiment nécessaire de supprimer ce dossier ?

cantador
0
Rejoignez-nous