I am using FreePascal/Lazarus, and I am trying to find the correct ShlObj/ShellApi calls to copy all files from a Device's DCIM Folder (i.e. a Camera) to another folder on the filesystem.
Here is the code to select to select the device:
r:= ShlObj.SHBrowseForFolder(x);
But from, there all I have is r, which is a LPITEMIDLIST variable.
Does anyone know the correct code to copy all files inside the Device's DCIM Folder 'r', to a destination folder (i.e. strDest)?
Note: I must use the ShellApi/ShlObj interface to do the copying
I assume that the PIDL specifies an item that is part of the file system, but I believe that is what you intend since you go on to say "copy all files". In which case, call SHGetPathFromIDList to obtain the file system path from the PIDL, and then call SHFileOperation to copy the files.
If you want to perform copying at the shell level, and not be restricted to files, then it's a little more complex. Probably the simplest will be to use IFileOperation, specifically the CopyItem and CopyItems methods. You'll need to be able to go from a PIDL to an IShellItem which can be done with SHCreateItemFromIDList.
Related
I have a folder that has around 400 subfolders each with ONE .jpeg file in them. I need to get all the pictures into 1 new folder using SSIS, everything is on my local (no connecting through different servers or DBs) just subfolders to one folder so that I can pull out those images without going one by one into each subfolder.
I would create 3 variables, all of type String. CurrentFile, FolderBase, FolderOutput.
FolderBase is going to be where we start searching i.e. C:\ssisdata
FolderOutput is where we are going to move any .jpg files that we find rooted under FolderBase.
Use a Foreach File Enumerator (sample How to import text files with the same name and schema but different directories into database?) configured to process subfolders looking for *.jpg. Map the first element on the Variable tab to be our CurrentFile. Map the Enumerator to start in FolderBase. For extra flexibility, create an additional variable to hold the file mask *.jpg.
Run the package. It should quickly zip through all the folders finding and doing nothing.
Drag and drop a file system task into the Foreach Enumerator. Make it a Move file (or maybe it's rename) type. Use a Variable source and destination. The Source will be CurrentFile and the destination will be FolderOutput
We have source "S" folder, destination "D" and Original "O".
D is a copy of O using NTFS hard link for all files.
Now we need to synchronize S and D and copy only changed files from S to D.
Robocopy.exe does that, however it overwrites files and as a result files are changed in both D and O, but we want files in O to remain intact, no matter what.
To correctly update hard link copy one needs to delete file in D (in order to break the link) and then create file with the same name instead of override.
Does robocopy supports that? Perhaps there is a special parameter for that, or is there any other free utility (preferable open source) that knows how to correctly update file if it's a hard link?
You could try using rsync - see this post for details, including readymade backup scripts:
How to create rsync-like hard link backups with VSS on Windows
I want to copy an entire folder without resolving the hardlinks
example:
Folder1
|
+---File1
File2
HardLink3 -> File3
(HardLink3 created using fsutil hardlink create or mklink)
I want to copy this folder to
Folder2
|
+---File1
File2
HardLink3 -> File3
keeping Folder2\HardLink3 as a hardlink pointing to File3
Is there an Win32 API call to copy a entire folder with
this semantic, or, if I need to do CopyFile / CreateHardLink
file by file, what's the API call to check if a given file is
a hardlink or not?
If you're absolutely sure that this is what you want to do, the easiest way to determine whether a file has multiple links (i.e., "is a hard link") is probably GetFileInformationByHandle.
The nNumberOfLinks value returned will be 1 for a normal file and more than 1 if the file is (or has) a hard link.
If I've understood your scenario correctly, it might be more sensible to check whether a file is hard linked to one of a specific set of files (the files in the "shared folder") rather than whether it is hard linked to any file anywhere. To do this, look at the File ID (nFileIndexHigh and nFileIndexLow) which for a hard link is the same as for the original file.
In the latter case, as an optimization you could use GetFileInformationByHandleEx with the FileIdBothDirectoryInfo option to read the names and file IDs for all the files in a given directory in a single operation.
I do not think there is a Win32 API call to do what you want all in one go, so you probably need to do this by hand.
Checking if a file is a hard-link or not is probably not what you want to do. If a file is not a symbolic link, directory (or reparse point or some other obscure thing) it is actually a hard link, i.e. the name of the file points to a stored file on disk. So if two files are pointing to the same data they are both hard links to that file.
Anyway, the Win32 methods to enumerate all hard links to a file are FindFirstFileNameW and FindNextFileNameW.
I'm trying to run a batch file that exists in one folder, from a batch file in another folder:
Parent folder Big containes 2 folders BatchFolder and Medium.
BatchFolder contains a batch file called Batch1.
Medium contains another folder called Small.
Small contains a batch file called Batch2 that needs to run Batch1.
The command prompt is run from the location of Batch2
Therefor, how do I navigate up the folders To Big, and then navigate into the BatchFolder?
I've been trying alsorts to achieve this with no success, such as Bacth2 containing the following "call ../BatchFolder/Batch1.bat"
I'm not sure whether you really need to navigate to the required folder (i.e. set it as the current one) or you simply need a way to call the batch script in that folder using a relative path notation. Navigating, from how I understand the term, means the former, but your last sentence seem to show that you need the latter.
First, the answer:
call %~dp0%..\..\BatchFolder\Batch1.bat
Next, what it means. %~dp0% is a variation of %0: the latter is the full path to this batch file (i.e. Batch2.bat) including the file name, and the former is the full path to this batch's folder (including the trailing \).
.. points to the immediate parent folder. It is repeated twice because we need to access the 'grand-parent' of the Batch2.bat's folder, and the grand-parent is Big. Once we are pointing to Big, we can address the files/folders in it, in this case it's BatchFolder that we need, and eventually we can put the name of Batch1.bat.
This works regardless of what the current folder is. That is, in case I wasn't clear on that head, by simply calling a batch file you are not yet changing the current folder. You would have to use the CD command for that. That would be navigating (but I'm still open to being corrected as to my understanding of this term).
Please help me to acheive the following using VBScript
1.Messagebox with three tabs Copy,Update,Cancel and displaying "Welcome to the AVG
definition fies copier/updater module.Click on Copy to copy files or Update to update
definition files.
2.If copy selected,the drive letter from where the script is run(usb drive) stored as
variable,directory "(usb drive)Update" created if not exist,new and files not existing
in update folder copied to(eg=xcopy /d), from
"%allusersprofile%\applic~1\avg8\update\download"
3.If possible display message 'copying files, while copying.After completion of
copying display 'Files copied successfully'.
4.If update selected,tdirectory "c:\Update" created if not exist,new and files not
existing in "c:\Update" copied to, from (usb drive) update folder
5.If possible display message 'Updating files' while copying.After completion of
updating, display 'Files Updated successfully'.After clicking OK exit and start
"C:\progra~1\avg\avg8\avgui.exe"
Well, the way that I would do it is to make stand alone functions for each of the functional tasks that you have then wrap those functions inside an HTA to give you the interface layer that you want.
As I understand from your other question, you managed to find solutions to most of these tasks yourself. Here's a tip for your #2, which I haven't noticed implemented in that your script.
2.If copy selected,the drive letter from where the script is run(usb drive) stored as variable
You can retrieve the full path of the current script file using the WScript.ScriptFullName property and then use the FileSystemObject.GetDriveName method to extract the drive letter:
Set objFSO = CreateObject("Scripting.FileSystemObject")
strUSBDrive = objFSO.GetDriveName(WScript.ScriptFullName)
This will give you the drive letter followed by a colon (e.g. J:). You can then concatenate this value with the target folder name to get the full path, e.g.:
MsgBox strUSBDrive & "\Update"