Copiar archivos

Intento hacer una copia de archivos de un origen a un destino, pero si el archivo de origen esta abierto me sale el error 70 porque no tiene permiso para acceder a el.
¿Hay algún modo de hacerlo sin utilizar el método Filecopy?
Me interesaría poder llamar de alguna manera al "Copiar" y "Pegar" del Windows, porque he probado que si lo hago así, manualmente, no hay problema.
Respuesta
1
Meté esto en un móduulo bas, con esto podrás:
ShellCopy 'Copiar un archivo
ShellRename ' Renombrar un Archivo
ShellMove 'Moverlo
y
ShellDelete 'Borrarlo
Attribute VB_Name = "Win95_Functions"
Option Explicit
Public Type SHFILEOPSTRUCT
hWnd As Long
wFunc As Long
pFrom As String
pTo As String
fFlags As Integer
fAborted As Boolean
hNameMaps As Long
sProgress As String
End Type
Public Type BrowseInfo
hwndOwner As Long
pIDLRoot As Long
pszDisplayName As Long
lpszTitle As Long
ulFlags As Long
lpfnCallback As Long
lParam As Long
iImage As Long
End Type
Global FileDestination As String
Public Const BIF_RETURNONLYFSDIRS = 1
Public Const MAX_PATH = 260
Public Declare Sub CoTaskMemFree Lib "ole32.dll" (ByVal hMem As Long)
Public Declare Function lstrcat Lib "kernel32" Alias "lstrcatA" _
(ByVal lpString1 As String, ByVal lpString2 As String) As Long
Public Declare Function SHBrowseForFolder Lib "shell32" _
(lpbi As BrowseInfo) As Long
Public Declare Function SHGetPathFromIDList Lib "shell32" _
(ByVal pidList As Long, ByVal lpBuffer As String) As Long
Public Const FO_COPY = &H2
Public Const FO_DELETE = &H3
Public Const FO_MOVE = &H1
Public Const FO_RENAME = &H4
Public Const FOF_ALLOWUNDO = &H40
Public Const FOF_CONFIRMMOUSE = &H2
Public Const FOF_FILESONLY = &H80 ' on *.*, do only files
Public Const FOF_MULTIDESTFILES = &H1
Public Const FOF_NOCONFIRMATION = &H10 ' Don't prompt the user.
Public Const FOF_NOCONFIRMMKDIR = &H200 ' don't confirm making any needed dirs
Public Const FOF_RENAMEONCOLLISION = &H8
Public Const FOF_SILENT = &H4 ' don't create progress/report
Public Const FOF_SIMPLEPROGRESS = &H100 ' means don't show names of files
Public Const FOF_WANTMAPPINGHANDLE = &H20 ' Fill in SHFILEOPSTRUCT.hNameMappings
Public Declare Function SHFileOperation Lib "shell32.dll" Alias _
"SHFileOperationA" (lpFileOp As SHFILEOPSTRUCT) As Long
Public Function ShellRename(ParamArray vntFileName() As Variant) As Long
Dim i As Integer
Dim sFileNames As String
Dim Dick As String
Dim SHFileOp As SHFILEOPSTRUCT
For i = LBound(vntFileName) To UBound(vntFileName)
sFileNames = sFileNames & vntFileName(i) & vbNullChar
Next
sFileNames = sFileNames & vbNullChar
Dick = FileDestination
With SHFileOp
.wFunc = &H4
.pFrom = sFileNames
.fFlags = FOF_ALLOWUNDO
.pTo = Dick
End With
ShellRename = SHFileOperation(SHFileOp)
End Function
Public Function ShellCopy(ParamArray vntFileName() As Variant) As Long
Dim i As Integer
Dim sFileNames As Variant
Dim Dick As String
Dim SHFileOp As SHFILEOPSTRUCT
For i = LBound(vntFileName) To UBound(vntFileName)
sFileNames = sFileNames & vntFileName(i) & vbNullChar
Next
sFileNames = sFileNames & vbNullChar
Dick = FileDestination
With SHFileOp
.wFunc = &H2
.pFrom = sFileNames
.fFlags = FOF_ALLOWUNDO
.pTo = Dick
End With
ShellCopy = SHFileOperation(SHFileOp)
End Function
Public Function ShellMove(ParamArray vntFileName() As Variant) As Long
Dim i As Integer
Dim sFileNames As Variant
Dim Dick As String
Dim SHFileOp As SHFILEOPSTRUCT
For i = LBound(vntFileName) To UBound(vntFileName)
sFileNames = sFileNames & vntFileName(i) & vbNullChar
Next
sFileNames = sFileNames & vbNullChar
Dick = FileDestination
With SHFil

5 respuestas más de otros expertos

Respuesta
3
Este es un método más efectivo de copia de archivos:
Dim ArchivoOrigen As String
Dim ArchivoDestino As String
Set fs = CreateObject("Scripting.FileSystemObject")
ArchivoOrigen = "archivo rigen"
ArchivoDestino = "archivo destino"
Fs. CopyFile ArchivoOrigen, ArchivoDestino
Cualquier duda estoy a tu disposición.
Respuesta
2
Por lo que parece ese error se origina si tienes el fichero abierto en algún otro sitio, ya que la función requiere abrirlo en modo exclusivo.
Además de esto debes poner bien los parámetros de origen y destino, o te saldrá el mismo error de acceso denegado. El destino debe contener la ruta y nombre del fichero destino.
La verdad que no he usado nunca esto, y si existe otro método de copiar, lo desconozco. He estado mirando pero no he visto nada... en principio lo normal es usar el FileSystemObject, igual que para otras operaciones con ficheros.
Respecto a copiar y pegar de windows... no se exactamente que estas haciendo o que quieres hacer. Lo digo porque estoy anotado para Visual Basic y para Desarrollo Web. En el caso de que lo quieras para una web los ficheros están en el servidor con lo que estas limitado respecto a operaciones, pero si es para un programa en VB en el ordenador local tienes medios para copiar archivos de otra forma si no recuerdo mal.
Creo que esto que te dije te habrá servido de bien poco, así que si quieres dime tu caso (web o vb) y qué quieres hacer exactamente o para que, y a ver si te puedo ayudar mejor.
Gracias por tu interés.
Veras, es para hacer un activex en VB y ya se que me da el error por culpa de tener el fichero abierto desde otra aplicación, pero ya quiero hacer esto.
Quiero copiar un archivo aunque esté en uso. Y lo del "copiar y pegar" lo digo, porque si intento duplicar el fichero, aunque esté abierto, mediante "copiar y pegar" si se puede duplicar. Entonces pensé que una solución seria llamar a estos métodos de windows dese VB (si se puede) y sino, buscar otra manera de copiar archivos (bit a bit, por ejemplo...). No se...
Supongo que ahora si me explique, sino pide más aclaraciones.
Gracias por todo.
Veamos, he estado mirando y a mi con el método FileCopy me va bien aunque tenga el fichero abierto (aunque no en exclusivo claro, para eso no hay método que sirva, es cosa del sistema).
Aun así he visto el método CopyFile, del objeto FileSystemObject. He hecho una prueba con un botón en un formulario y sale bien, con este código:
Private Sub Command1_Click()
Dim lala As Integer
Dim lFso As Object
Set lFso = CreateObject("Scripting.FileSystemObject")
lala = lFso.CopyFile("C:\odbcconf.log", "C:\odbcconf2.log")
End Sub
Quizás quieras probar con eso a ver si sale bien... pero en principio no deberías tener problema siempre que el fichero este abierto sin más. También puedes usar funciones de VB de apertura de ficheros en binario (no se la sintaxis ni instrucciones ahora, tendría que mirarlo), pero estamos en las mismas... si el fichero lo tiene abierto en exclusivo otro proceso, es el sistema el que denegara CUALQUIER acceso al mismo.
Asegurate de que la apertura que haces sea normal (típica de acceso de una base de datos, o un bloc de notas, etc., y no una apertura donde bloquees cualquier otro acceso... es decir, en exclusivo).
Ya me dirás,
Respuesta
1
Prueba con el método CopyFile del objeto FileSystemObject. Se encuentra en la librería Microsoft Scripting Runtime (SCRRUN.DLL):
Dim fso As New FileSystemObject
fso.CopyFile "c:\temp\prueba.sql", "c:\temp\prueba2.sql", True
Respuesta
1
Se puede utilizar lo que tú quieres. Ahora de memoria no recuerdo exactamente cómo, pero se trata de utilizar la API de Shell32.dll. Creo que la función en concreto se llama ShellOperation o algo así, y permite copiar, mover y borrar, apareciéndote la ventanita de progreso con los documentos volando de un lado a otro. Busca por Internet información al respecto, porque ahora no te lo podría explicar con detalle.
Otra posibilidad, más cercana al Cut&Paste sería utilizar el objeto Clipboard, pero nunca lo he utilizado con archivos.
Una posibilidad más el utilizar el objeto Scripting. FileSystemObject, que creo que permite copiar archivos abiertos.
Por último, puedes hacerte una función FileCopy utilizando Open, Input, etc.
Respuesta
1
No, no conozco la forma de utilizar el copiar pegar de windows. Debería ser igual, debido a que un fichero abierto en Windows tiene tamaño 0, por lo que no deja copiarse y eso es válido para todo. Lo que puedes hacer es controlar el error y mostrar un mensaje y seguir adelante. No lo considero un error.

Añade tu respuesta

Haz clic para o

Más respuestas relacionadas