Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Otros temas > Trucos
Registrarse FAQ Miembros Calendario Guía de estilo Buscar Temas de Hoy Marcar Foros Como Leídos

Los mejores trucos

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 30-06-2006
Avatar de seoane
[seoane] seoane is offline
Miembro Premium
 
Registrado: feb 2004
Ubicación: A Coruña, España
Posts: 3.717
Poder: 24
seoane Va por buen camino
Reemplazar archivo al reinicar el equipo

El objetivo es reemplazar un archivo por otro, si se puede en el momento, se reemplaza pero si no se puede la operacion se deja pendiente hasta el siguiente reinicio del equipo. Windows se encargara de realizar la operacion antes de cargar ningun otro programa.

Lo primero es hacer una funcion que compruebe si sobre alguno de los archivos existe ya alguna operacion pendiente ya que eso podria llevar a erroes. La funcion seria la siguiente:

Código Delphi [-]
uses Registry;

function Pendiente(Archivo: string): Boolean;
var
  Buffer: PChar;
  Size: Integer;
  i: integer;
begin
  Result := FALSE;
  with TRegistry.Create do
  try
    Access := KEY_READ;
    RootKey := HKEY_LOCAL_MACHINE;
    if OpenKey('\SYSTEM\CurrentControlSet\Control\Session Manager', FALSE) then
    begin
      if ValueExists('PendingFileRenameOperations') then
      begin
        Size := GetDataSize('PendingFileRenameOperations');
        if Size > 0 then
        try
          GetMem(Buffer, Size);
          try
            Fillchar(Buffer^, Size, #0);
            ReadBinaryData('PendingFileRenameOperations', Buffer^, Size);
            for i := 0 to Size - 2 do
              if Buffer[i] = #0 then
                Buffer[i] := #13
              else
                Buffer[i] := upcase(Buffer[i]);
            if StrPos(Buffer, PChar(Uppercase(Archivo))) <> nil then
              Result := TRUE;
          finally
            FreeMem(Buffer);
          end;
        except
        end;
      end;
      CloseKey;
    end;
  finally
    Free;
  end;
end;

Una vez tomada esa precaucion podemos reemplzara un archivo por otro, o si el archivo de destino es una cadena vacia, borrar el original.

Código Delphi [-]
procedure Reemplazar(Viejo, Nuevo: string);
begin
  if Pendiente(Viejo) or Pendiente(Nuevo) then
    Exit;
  if Nuevo = '' then
  begin
    if FileExists(Viejo) then
      if not DeleteFile(Viejo) then
        MoveFileEx(PChar(Viejo), nil, MOVEFILE_DELAY_UNTIL_REBOOT or
          MOVEFILE_REPLACE_EXISTING);
  end
  else
  begin
    if not MoveFileEx(PChar(Nuevo), PChar(Viejo), MOVEFILE_REPLACE_EXISTING) then
    begin
      MoveFileEx(PChar(Nuevo), PChar(Viejo), MOVEFILE_DELAY_UNTIL_REBOOT or
        MOVEFILE_REPLACE_EXISTING)
    end;
  end;
end;

Ejemplos de uso:
Código Delphi [-]
  Reemplazar('Viejo.txt','Nuevo.txt');
  // Incluso podemos borrarnos a nosotros mismos
  Reemplazar(ParamStr(0),'');
Responder Con Cita
  #2  
Antiguo 20-03-2008
jhonalone jhonalone is offline
Miembro
 
Registrado: sep 2007
Ubicación: Madrid
Posts: 545
Poder: 17
jhonalone Va por buen camino
No se si esto es para alguna versión determinada de Windows. Lo estoy probando con Windows ME y no funciona. No sé si será porque el fichero Viejo es un .exe o por la versión de Windows. En el código no puede haber errores, pues lo he pegado directamente, y ha complilado perfectamente.

Es una lástima, porque para el proyecto que estoy desarrollando me venía fenomenal la función.

Gracias Soane, porque tu producción de trucos y apoyos es superior.

Un Saludo.
Responder Con Cita
  #3  
Antiguo 20-03-2008
Avatar de seoane
[seoane] seoane is offline
Miembro Premium
 
Registrado: feb 2004
Ubicación: A Coruña, España
Posts: 3.717
Poder: 24
seoane Va por buen camino
Como informa aquí microsoft, esta función MoveFileEx solo esta disponible en Windows 2000/XP o superior:

http://msdn2.microsoft.com/en-us/library/aa365240(VS.85).aspx

Lo siento.
Responder Con Cita
  #4  
Antiguo 21-03-2008
jhonalone jhonalone is offline
Miembro
 
Registrado: sep 2007
Ubicación: Madrid
Posts: 545
Poder: 17
jhonalone Va por buen camino
Gracias Seoane, cada vez me sorprendes más con tus conocimientos. Todos agradecemos tu esfuerzo. Buscaré otra solución.

De nuevo Gracias por responderme tan pronto.
Responder Con Cita
  #5  
Antiguo 23-03-2008
jhonalone jhonalone is offline
Miembro
 
Registrado: sep 2007
Ubicación: Madrid
Posts: 545
Poder: 17
jhonalone Va por buen camino
Hola Domingo:
Estoy intentando desarrollar una función para haga la misma tarea en W98 y ME y todos los posteriores, creo que voy a aprovechar parte de la tuya. Pero tengo un problema que no he solucionado aún: no sé cómo puedo obtener la ruta completa de un fichero en formato MS-DOS, es decir en 8 caracteres con su extensión y sus CCCCCC~1.CCC. Si tú lo sabes, me ahorrarás mucho tiempo. Cuando tenga la función te la cuento.

Un saludo
Responder Con Cita
  #6  
Antiguo 23-03-2008
Avatar de seoane
[seoane] seoane is offline
Miembro Premium
 
Registrado: feb 2004
Ubicación: A Coruña, España
Posts: 3.717
Poder: 24
seoane Va por buen camino
Hola jhonalone, creo que encontraras el siguiente enlace interesante.

http://www.clubdelphi.com/foros/showpost.php?p=167116&postcount=11
Responder Con Cita
  #7  
Antiguo 23-03-2008
jhonalone jhonalone is offline
Miembro
 
Registrado: sep 2007
Ubicación: Madrid
Posts: 545
Poder: 17
jhonalone Va por buen camino
Muy interesante, (como todo lo que tú haces), pero creo que tiene un par de inconvenientes:
1.-En Windows antiguos (ME) que es donde lo estoy probando,
no te deja renombrar el fichero .exe ni desde su propio
DOS, si el fichero está en uso.
2.-Ya había yo estado probando con GetShortPathName. Pero
tiene el inconveniente de que la ruta larga no puede ser
mayor de 67 bytes. Sólo vale con rutas próximas a C:\.

Seguiré investigando, pues me cuesta trabajo rendirme.

Un Saludo
Responder Con Cita
  #8  
Antiguo 23-03-2008
jhonalone jhonalone is offline
Miembro
 
Registrado: sep 2007
Ubicación: Madrid
Posts: 545
Poder: 17
jhonalone Va por buen camino
Me estoy temiendo, que voy a tener que confeccionar la ruta a "pedal", con FindFirstFile o algo así.
Si al final consigo hacer la rutina, ya la colgaré para que otro no tenga que currárselo.

Voy a ver.
Responder Con Cita
  #9  
Antiguo 23-03-2008
jhonalone jhonalone is offline
Miembro
 
Registrado: sep 2007
Ubicación: Madrid
Posts: 545
Poder: 17
jhonalone Va por buen camino
Compañeros, TENGO QUE RECTIFICARME. Pensaba que el problema estaba en la longitud de la cadena. Pues haciendo pruebas, he comprobado que es porque existen mas de 4 subdirectorios que comienzan con las mismas 8 letras dentro del mismo directorio. Hasta el cuarto todo va bien. Si intentas averiguar la cadena corta desde el quinto, por orden de creación, ya se desmadra el GetShortPaathName. Si alguien quiere comprobarlo, puede hacerlo con esta sencilla función.

Function Ruta:string;
var
DirActual:String;
corto:array [1..400] of char;
longitud:Cardinal;
begin
GetDir(0,DirActual);
GetShortPathName(PChar(DirActual),@corto,longitud);
Ruta:=corto;
end;
Responder Con Cita
Respuesta


Herramientas Buscar en Tema
Buscar en Tema:

Búsqueda Avanzada
Desplegado

Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro


La franja horaria es GMT +2. Ahora son las 10:18:23.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi