Ir al contenido


Foto

Parámetro incorrecto en copia de archivos en red


Mejor respuesta escafandra , 11 enero 2017 - 06:16

Gracias escafandra, viendo SHFileOperation hice lo siguiente:


delphi
  1. function TFUpdater.DescargaExe(const AFrom: string; const ADestino: string): Boolean;
  2. Var FileOptions: TShFileOpStruct;
  3. begin
  4. FileOptions.Wnd := Application.MainForm.Handle;
  5. //Función Copiar (Hay FO_DELETE, FO_MOVE, FO_RENAME, Etc)
  6. FileOptions.wFunc := FO_COPY;
  7.  
  8. //Archivo a copiar
  9. FileOptions.pFrom := PWideChar(AFrom);
  10. //Destino
  11. FileOptions.pTo := PWideChar(ADestino);
  12.  
  13. //Activamos que creemos la carpeta automáticamente en caso de no existir
  14. FileOptions.fFlags := FOF_NOCONFIRMMKDIR;
  15.  
  16. //Executamos la operación y devolvemos su resultado
  17. Result := SHFileOperation(FileOptions) = 0;
  18. end;

Hágame saber si es necesario algo más, dado que las copias es mayormente desde el Servidor al equipo local, ¿Con eso Bastará?, no puedo probarlo aún, y será mañana en la oficina.

 

Saludos.

 

Fíjate en este código:


delphi
  1. uses ShellApi;
  2.  
  3. function SHCopy(Source, Target: String): integer;
  4. var
  5. FS: SHFILEOPSTRUCT;
  6. begin
  7. ZeroMemory(@FS, sizeof(SHFILEOPSTRUCT));
  8. FS.wFunc:= FO_COPY;
  9. FS.pFrom:= PCHAR(Source + #0 + #0);
  10. FS.pTo:= PCHAR(Target + #0 + #0);
  11. FS.fFlags:= FOF_NOCONFIRMATION or FOF_RENAMEONCOLLISION;
  12. Result:= SHFileOperation(FS);
  13. end;

Entiendo que usas UNICODE, y por lo tanto SHFileOperationW. Posíblemente si usas un Delphi moderno ya asuma SHFileOperationW, pero las cadenas deben terminar en un doble nulo que te falta en el código. ;)

 

También debes inicializar a 0 los miembros de la estructura SHFILEOPSTRUCT que no uses.

 

 

Saludos.

Ir al mensaje completo


  • Por favor identifícate para responder
9 respuestas en este tema

#1 enecumene

enecumene

    Webmaster

  • Administrador
  • 7.419 mensajes
  • LocationRepública Dominicana

Escrito 11 enero 2017 - 02:16

Amigos, estoy teniendo problemas al realizar copia de un archivo vía red, en algunos equipos funciona sin problemas y en otros casi terminando ó al terminar la descarga me manda el error de parámetro incorrecto y no se realiza la copia, utilizo la rutina de escafandra CopyFileEx, aquí es cómo lo tengo implementado:


delphi
  1. procedure TFUpdater.btnUpdateClick(Sender: TObject);
  2. var Error: DWORD;
  3. begin
  4. btnUpdate.Enabled := False;
  5. btnReady.Caption := 'Espere...';
  6. Cancel:= false;
  7. CopyFileEx(PWideChar(Fuente),PWideChar(Destino), @ProgressRoutine, nil, @Cancel, 0);
  8.  
  9. Error := GetLastError();
  10.  
  11. if Error = 0 then begin
  12. btnReady.Enabled := True;
  13. btnReady.Caption := 'Listo!';
  14. lbUpdate.Caption := 'Actualizado!';
  15. end else begin
  16. MessageDLG(SysErrorMessage(GetLastError()),mtError,[mbOk],0);
  17. Application.Terminate;
  18. end;
  19. end;

Y aquí es como obtengo las variables Fuente y Destino:


delphi
  1. ...
  2. //Versions.Values['APP_PATH'] es la ruta donde está el archivo a copiar
  3. DownloadNewVersion(Versions.Values['APP_PATH'] + 'Helper\SisAuto.exe',ExtractFilePath(Application.ExeName) + 'SisAuto.exe');

Están causando ese problemas en equipos con Win 8/8.1 64Bits, está probado en equipos con Win 10 64Bits, Win7 64Bits, aún no se ha probado en equipos de 32Bits.

 

¿Qué podrá ser?.

 

Saludos.


  • 0

#2 escafandra

escafandra

    Advanced Member

  • Administrador
  • 4.107 mensajes
  • LocationMadrid - España

Escrito 11 enero 2017 - 03:54

Imagino que tienes implementada la función ProgressRoutine...
¿El error se produce en CopyFileEx o en otro punto? Ten en cuenta que depende de los permisos de red puede que no tengas acceso a determinado equipo o subred.

 

Para identificarte en un equipo debes usar WNetAddConnection2 como describí aquí

 

SHFileOperation te permite hacer copias a un nivel de implementación más alto pero la vista de la progresión la hará el Windows.

 

 

Saludos.


  • 0

#3 enecumene

enecumene

    Webmaster

  • Administrador
  • 7.419 mensajes
  • LocationRepública Dominicana

Escrito 11 enero 2017 - 05:05

Gracias escafandra, viendo SHFileOperation me topé con ésta otra MoveFileWithProgress, ¿Qué diferencia hay entre una y la otra?


  • 0

#4 escafandra

escafandra

    Advanced Member

  • Administrador
  • 4.107 mensajes
  • LocationMadrid - España

Escrito 11 enero 2017 - 05:47

Gracias escafandra, viendo SHFileOperation me topé con ésta otra MoveFileWithProgress, ¿Qué diferencia hay entre una y la otra?

CopyFileEx copia solo archivos con una función de progreso diseñada por el usuario, MoveFileWithProgres, mueve (copia y borra) un archivo o carpeta con una función de progreso también diseñada por el usuario, y SHFileOperation copia, mueve, borra o renombra un archivo o carpeta según los parámetros usados, con una función de progreso, visible o no, que hace el mismo Windows, no el usuaro.

 

Saludos.


  • 1

#5 enecumene

enecumene

    Webmaster

  • Administrador
  • 7.419 mensajes
  • LocationRepública Dominicana

Escrito 11 enero 2017 - 06:07

Gracias escafandra, viendo SHFileOperation hice lo siguiente:


delphi
  1. function TFUpdater.DescargaExe(const AFrom: string; const ADestino: string): Boolean;
  2. Var FileOptions: TShFileOpStruct;
  3. begin
  4. FileOptions.Wnd := Application.MainForm.Handle;
  5. //Función Copiar (Hay FO_DELETE, FO_MOVE, FO_RENAME, Etc)
  6. FileOptions.wFunc := FO_COPY;
  7.  
  8. //Archivo a copiar
  9. FileOptions.pFrom := PWideChar(AFrom);
  10. //Destino
  11. FileOptions.pTo := PWideChar(ADestino);
  12.  
  13. //Activamos que creemos la carpeta automáticamente en caso de no existir
  14. FileOptions.fFlags := FOF_NOCONFIRMMKDIR;
  15.  
  16. //Executamos la operación y devolvemos su resultado
  17. Result := SHFileOperation(FileOptions) = 0;
  18. end;

Hágame saber si es necesario algo más, dado que las copias es mayormente desde el Servidor al equipo local, ¿Con eso Bastará?, no puedo probarlo aún, y será mañana en la oficina.

 

Saludos.


  • 0

#6 escafandra

escafandra

    Advanced Member

  • Administrador
  • 4.107 mensajes
  • LocationMadrid - España

Escrito 11 enero 2017 - 06:16   Mejor respuesta

Gracias escafandra, viendo SHFileOperation hice lo siguiente:


delphi
  1. function TFUpdater.DescargaExe(const AFrom: string; const ADestino: string): Boolean;
  2. Var FileOptions: TShFileOpStruct;
  3. begin
  4. FileOptions.Wnd := Application.MainForm.Handle;
  5. //Función Copiar (Hay FO_DELETE, FO_MOVE, FO_RENAME, Etc)
  6. FileOptions.wFunc := FO_COPY;
  7.  
  8. //Archivo a copiar
  9. FileOptions.pFrom := PWideChar(AFrom);
  10. //Destino
  11. FileOptions.pTo := PWideChar(ADestino);
  12.  
  13. //Activamos que creemos la carpeta automáticamente en caso de no existir
  14. FileOptions.fFlags := FOF_NOCONFIRMMKDIR;
  15.  
  16. //Executamos la operación y devolvemos su resultado
  17. Result := SHFileOperation(FileOptions) = 0;
  18. end;

Hágame saber si es necesario algo más, dado que las copias es mayormente desde el Servidor al equipo local, ¿Con eso Bastará?, no puedo probarlo aún, y será mañana en la oficina.

 

Saludos.

 

Fíjate en este código:


delphi
  1. uses ShellApi;
  2.  
  3. function SHCopy(Source, Target: String): integer;
  4. var
  5. FS: SHFILEOPSTRUCT;
  6. begin
  7. ZeroMemory(@FS, sizeof(SHFILEOPSTRUCT));
  8. FS.wFunc:= FO_COPY;
  9. FS.pFrom:= PCHAR(Source + #0 + #0);
  10. FS.pTo:= PCHAR(Target + #0 + #0);
  11. FS.fFlags:= FOF_NOCONFIRMATION or FOF_RENAMEONCOLLISION;
  12. Result:= SHFileOperation(FS);
  13. end;

Entiendo que usas UNICODE, y por lo tanto SHFileOperationW. Posíblemente si usas un Delphi moderno ya asuma SHFileOperationW, pero las cadenas deben terminar en un doble nulo que te falta en el código. ;)

 

También debes inicializar a 0 los miembros de la estructura SHFILEOPSTRUCT que no uses.

 

 

Saludos.


  • 0

#7 enecumene

enecumene

    Webmaster

  • Administrador
  • 7.419 mensajes
  • LocationRepública Dominicana

Escrito 11 enero 2017 - 06:20

¿Y Cual es la razón de eso de los nulos?, y ¿qué función hace ZeroMemory?, perdón por las dudas.


  • 0

#8 escafandra

escafandra

    Advanced Member

  • Administrador
  • 4.107 mensajes
  • LocationMadrid - España

Escrito 11 enero 2017 - 06:27

¿Y Cual es la razón de eso de los nulos?, y ¿qué función hace ZeroMemory?, perdón por las dudas.

 

La razón es que se puede meter una lista de nombres y no sólo uno. Cada nombre termina en 0 (cadenas estilo C) y al final de la lista se añade un doble 0 para indicar que ya no hay más elementos.

La API ZeroMemory pone una cantidad de nulos en la dirección apuntada por un puntero. Quizás estés más acostumbrado a ver FillChar, propia de delphi.

 

 

Saludos.


  • 0

#9 enecumene

enecumene

    Webmaster

  • Administrador
  • 7.419 mensajes
  • LocationRepública Dominicana

Escrito 12 enero 2017 - 06:25

Gracias por la explicación mi estimado, hoy haré las pruebas y luego le comento.

 

Saludos.


  • 0

#10 enecumene

enecumene

    Webmaster

  • Administrador
  • 7.419 mensajes
  • LocationRepública Dominicana

Escrito 12 enero 2017 - 08:36

Probado con satisfacción en equipos con Win 8/8.1 64Bits, Win 7 64Bits y Win 7 32Bits, sin problemas alguno, gracias mis estimado.

 

Saludos.


  • 0




IP.Board spam blocked by CleanTalk.