Shoutbox

copy file - Printable Version

-Shoutbox (https://shoutbox.menthix.net)
+-- Forum: MsgHelp Archive (/forumdisplay.php?fid=58)
+--- Forum: Messenger Plus! for Live Messenger (/forumdisplay.php?fid=4)
+---- Forum: Scripting (/forumdisplay.php?fid=39)
+----- Thread: copy file (/showthread.php?tid=90779)

copy file by ainain on 05-25-2009 at 05:20 PM

how to copy and overwrite the file?

for example: c:\a.txt copy to c:\b


RE: copy file by matty on 05-25-2009 at 05:36 PM

js code:
CopyFile('c:\\test.log', 'c:\\test.txt');

function CopyFile(src, dest) {
    Interop.Call('kernel32', 'CopyFileW', src, dest, false);
}

js code:
RenameFile('c:\\test.log', 'c:\\test.txt');

function RenameFile(src, dest) {
    Interop.Call('kernel32', 'MoveFileW', src, dest);
}

RE: copy file by ainain on 05-30-2009 at 03:38 PM

thanks a lot, how about "rename"?


RE: copy file by Mnjul on 05-30-2009 at 03:49 PM

Just replace "CopyFileW" with "MoveFileW" :)


RE: copy file by wincy on 05-30-2009 at 10:29 PM

Here's my code:

CopyFile('c:\\boh.txt', 'c:\\bah.gif');
function CopyFile(src, dest) {
    Interop.Call('user32', 'CopyFileW', src, dest, false);
}


Debugger shows this error:
CallDll has failed collocation of the function "CopyFileW"
(in row containing "Interop.Call..ecc")

What's the problem? :(

// EDIT: I see that works using "kernel32" instead of "user32"...


RE: copy file by whiz on 07-14-2009 at 01:10 PM

I'd like to ask a related question.  How can you delete a file?  And does it work with folders?


RE: copy file by NanaFreak on 07-14-2009 at 01:15 PM

http://www.pinvoke.net/ that site should help you with your kernel32 and user32 stuff ;) though you may have to get someone to help translate it from vb or C into the JScript version for plus...


RE: copy file by matty on 07-14-2009 at 01:51 PM

quote:
Originally posted by whiz
I'd like to ask a related question.  How can you delete a file?  And does it work with folders?
No offence but you should start trying the easy stuff yourself first then post if you cannot get it to work...

js code:
function DeleteFile(lpstrFile) {
    return Interop.Call('kernel32', 'DeleteFileW', lpstrFile) !== 0;
}

To remove a directory:
js code:
/* do not include trailing slashes, pass the path as c:\\test */
function RemoveDirectory(sPath) {
    var WIN32_FIND_DATA = Interop.Allocate(592);
    var hSearch = Interop.Call('kernel32', 'FindFirstFileW', sPath+'\\*.*', WIN32_FIND_DATA);
    var hResult;
    while(hResult != 0){
        if(!(WIN32_FIND_DATA.ReadDWORD(0) & 0x10 /* FILE_ATTRIBUTE_DIRECTORY */)){
            Interop.Call('kernel32', 'DeleteFileW', sPath+'\\'+WIN32_FIND_DATA.ReadString(44));
        } else {
            RemoveDirectory(sPath+WIN32_FIND_DATA.ReadString(44));
            Interop.Call('kernel32', 'RemoveDirectoryW', '\\\\?\\'+sPath+'\\'+WIN32_FIND_DATA.ReadString(44));
        }
        hResult = Interop.Call('kernel32', 'FindNextFileW', hSearch, WIN32_FIND_DATA)
    }
    Interop.Call('kernel32', 'FindClose', hSearch);
}

RE: RE: copy file by whiz on 07-14-2009 at 02:22 PM

quote:
Originally posted by matty
js code:
function DeleteFile(lpstrFile) {
    return Interop.Call('user32', 'DeleteFileW', lpstrFile) !== 0;
}

To remove a directory:
js code:
function RemoveDirectory(sPath) {
    var WIN32_FIND_DATA = Interop.Allocate(592);
    var hSearch = Interop.Call('kernel32', 'FindFirstFileW', sPath+'\\*.*', WIN32_FIND_DATA);
    var hResult;
    while(hResult != 0){
        if(!(WIN32_FIND_DATA.ReadDWORD(0) & 0x10 /* FILE_ATTRIBUTE_DIRECTORY */)){
            DeleteFile(sPath+WIN32_FIND_DATA.ReadString(44));
        } else {
            RemoveDirectory(sPath+WIN32_FIND_DATA.ReadString(44));
            Interop.Call('kernel32', 'RemoveDirectoryW', '\\\\?\\'+sPath+WIN32_FIND_DATA.ReadString(44));
        }
        hResult = Interop.Call('kernel32', 'FindNextFileW', hSearch, WIN32_FIND_DATA)
    }
    Interop.Call('kernel32', 'FindClose', hSearch);
}

quote:
Originally posted by JavaScript Debugger
Error: unknown (code: -2147467259)
js code:
/* error: */ return Interop.Call('user32', 'DeleteFileW', lpstrFile) !== 0;

RE: copy file by matty on 07-14-2009 at 02:29 PM

Made a mistake should be kernel32 not user32.


RE: copy file by whiz on 07-14-2009 at 02:51 PM

quote:
Originally posted by matty
Made a mistake should be kernel32 not user32.
No error now, but it still does nothing.  :S
RE: copy file by matty on 07-14-2009 at 02:53 PM

The delete file does nothing or the recursive delete does nothing?

I updated the recursive function.


RE: copy file by whiz on 07-14-2009 at 02:58 PM

Assuming that I call it with "RemoveDirectory(/* path */)", both the folder and the files inside remain, with no apparent actions taken.


RE: copy file by matty on 07-14-2009 at 03:03 PM

Try this:

js code:
RemoveDirectory('C:\\This\\Is\\The\\Directory\\To\\Delete\\');

function RemoveDirectory(sPath) {
    var WIN32_FIND_DATA = Interop.Allocate(592);
    var hSearch = Interop.Call('kernel32', 'FindFirstFileW', sPath+'*', WIN32_FIND_DATA);
    var hResult = -1;
    while(hResult != 0){
        if(!(WIN32_FIND_DATA.ReadDWORD(0) & 0x10 /* FILE_ATTRIBUTE_DIRECTORY */)){
            Interop.Call('kernel32', 'DeleteFileW', '\\\\?\\'+sPath+WIN32_FIND_DATA.ReadString(44));
        } else {
            RemoveDirectory(sPath+WIN32_FIND_DATA.ReadString(44));
            Interop.Call('kernel32', 'RemoveDirectoryW', '\\\\?\\'+sPath+WIN32_FIND_DATA.ReadString(44));
        }
        hResult = Interop.Call('kernel32', 'FindNextFileW', hSearch, WIN32_FIND_DATA)
    }
    Interop.Call('kernel32', 'FindClose', hSearch);
}

RE: copy file by whiz on 07-14-2009 at 03:19 PM

Still nothing...?

js code:
RemoveDirectory("C:\\Documents and Settings\\ __________\\My Documents\\New Folder");
I made a folder in My Documents called "New Folder", and added two Notepad documents.  But they're still there...
RE: copy file by matty on 07-14-2009 at 03:27 PM

quote:
Originally posted by whiz
Still nothing...?
js code:
RemoveDirectory("C:\\Documents and Settings\\ __________\\My Documents\\New Folder");
I made a folder in My Documents called "New Folder", and added two Notepad documents.  But they're still there...
js code:
RemoveDirectory("C:\\Documents and Settings\\ __________\\My Documents\\New Folder\\");
I forgot to mention I made the code dependent on having trailing slashes.
RE: copy file by whiz on 07-14-2009 at 03:33 PM

Well, the files have gone.  Does it not delete the folder as well?


RE: copy file by matty on 07-14-2009 at 06:17 PM

It should I will look at it later. I am not at home so I cannot test it.

Take a look at this and post the Debug information.

js code:
RemoveDirectory('C:\\This\\Is\\The\\Directory\\To\\Delete\\');

function RemoveDirectory(sPath) {
    var WIN32_FIND_DATA = Interop.Allocate(592);
    var hSearch = Interop.Call('kernel32', 'FindFirstFileW', sPath+'*', WIN32_FIND_DATA);
    var hResult = -1;
    while(hResult != 0){
        if(!(WIN32_FIND_DATA.ReadDWORD(0) & 0x10 /* FILE_ATTRIBUTE_DIRECTORY */)){
            Interop.Call('kernel32', 'DeleteFileW', '\\\\?\\'+sPath+WIN32_FIND_DATA.ReadString(44));
        } else {
            RemoveDirectory(sPath+WIN32_FIND_DATA.ReadString(44));
            if ( Interop.Call('kernel32', 'RemoveDirectoryW', '\\\\?\\'+sPath+WIN32_FIND_DATA.ReadString(44)) === 0 ) TraceWin32Error()
        }
        hResult = Interop.Call('kernel32', 'FindNextFileW', hSearch, WIN32_FIND_DATA)
    }
    Interop.Call('kernel32', 'FindClose', hSearch);
}

function TraceWin32Error(){
    var LastError = Interop.GetLastError();
    if(LastError != 0) {
        var MsgBuffer = Interop.Allocate(1024);
        Interop.Call("Kernel32", "FormatMessageW", 0x1000, 0, LastError, 0, MsgBuffer, 1024, 0);
        Debug.Trace(MsgBuffer.ReadString(0));
    }
}

RE: copy file by whiz on 07-14-2009 at 07:24 PM

Well, it deleted the two files in the folder, but...

quote:
Originally posted by JavaScript Debugger
code:
The system cannot find the file specified.

The system cannot find the file specified.

The filename, directory name, or volume label syntax is incorrect.

The system cannot find the file specified.

The filename, directory name, or volume label syntax is incorrect.

The system cannot find the file specified.

The system cannot find the file specified.

The filename, directory name, or volume label syntax is incorrect.

The system cannot find the file specified.

The directory is not empty.


Folder contents:
code:
| Test // root folder, not deleted
+-| Test1 // folder, not deleted
| +-> New Notepad++ Document.txt // not deleted
+-> New Notepad++ Document.txt // deleted successfully
+-> New Notepad++ Document (2).txt // deleted successfully

When tested without the "Test1" folder, the two documents were removed, but the folder remained, and the debugger showed the same.  :S
RE: copy file by matty on 07-15-2009 at 12:43 PM

I did a little testing and noticed a few things.

- Firstly FindFirstFileW and FindNextFileW will find . and .. as well
- I forgot to append the path with slashes

js code:
RemoveDirectory('C:\\Documents and Settings\\__________\\My Documents\\New Folder', true);

function RemoveDirectory(sPath, bFirstFolder) {
    sPath='\\\\?\\'+sPath;
    var WIN32_FIND_DATA = Interop.Allocate(592);
    var hSearch = Interop.Call('kernel32', 'FindFirstFileW', sPath+'\\*', WIN32_FIND_DATA);
    var hResult = -1;
    var sFile;
    while(hResult != 0){
        sFile = WIN32_FIND_DATA.ReadString(44);
        if (sFile !== '.' && sFile !== '..') {
            if(!(WIN32_FIND_DATA.ReadDWORD(0) & 0x10 /* FILE_ATTRIBUTE_DIRECTORY */)){
                Debug.Trace(sPath+sFile);
                Interop.Call('kernel32', 'DeleteFileW', sPath+'\\'+sFile);
            } else {
                Debug.Trace(sPath+sFile);
                RemoveDirectory(sPath+'\\'+sFile false);
                if ( Interop.Call('kernel32', 'RemoveDirectoryW', sPath+'\\'+sFile) === 0 ) TraceWin32Error()
            }
        }
        hResult = Interop.Call('kernel32', 'FindNextFileW', hSearch, WIN32_FIND_DATA)
    }
    Interop.Call('kernel32', 'FindClose', hSearch);
    if (bFirstFolder === true) Interop.Call('kernel32', 'RemoveDirectoryW', sPath)
}

function TraceWin32Error(){
    var LastError = Interop.GetLastError();
    if(LastError != 0) {
        var MsgBuffer = Interop.Allocate(1024);
        Interop.Call("Kernel32", "FormatMessageW", 0x1000, 0, LastError, 0, MsgBuffer, 1024, 0);
        Debug.Trace(MsgBuffer.ReadString(0));
    }
}

No idea if this will work I would have to do a bit more troubleshooting as to why it doesn't.
RE: RE: copy file by whiz on 07-15-2009 at 06:31 PM

quote:
Originally posted by matty
I did a little testing and noticed a few things.

- Firstly FindFirstFileW and FindNextFileW will find . and .. as well
- I forgot to append the path with slashes

js code:
RemoveDirectory('C:\\Documents and Settings\\__________\\My Documents\\New Folder', true);

function RemoveDirectory(sPath, bFirstFolder) {
    sPath='\\\\?\\'+sPath;
    var WIN32_FIND_DATA = Interop.Allocate(592);
    var hSearch = Interop.Call('kernel32', 'FindFirstFileW', sPath+'\\*', WIN32_FIND_DATA);
    var hResult = -1;
    var sFile;
    while(hResult != 0){
        sFile = WIN32_FIND_DATA.ReadString(44);
        if (sFile !== '.' && sFile !== '..') {
            if(!(WIN32_FIND_DATA.ReadDWORD(0) & 0x10 /* FILE_ATTRIBUTE_DIRECTORY */)){
                Debug.Trace(sPath+sFile);
                Interop.Call('kernel32', 'DeleteFileW', sPath+'\\'+sFile);
            } else {
                Debug.Trace(sPath+sFile);
>>>                RemoveDirectory(sPath+'\\'+sFile false); <<<
                if ( Interop.Call('kernel32', 'RemoveDirectoryW', sPath+'\\'+sFile) === 0 ) TraceWin32Error()
            }
        }
        hResult = Interop.Call('kernel32', 'FindNextFileW', hSearch, WIN32_FIND_DATA)
    }
    Interop.Call('kernel32', 'FindClose', hSearch);
    if (bFirstFolder === true) Interop.Call('kernel32', 'RemoveDirectoryW', sPath)
}

function TraceWin32Error(){
    var LastError = Interop.GetLastError();
    if(LastError != 0) {
        var MsgBuffer = Interop.Allocate(1024);
        Interop.Call("Kernel32", "FormatMessageW", 0x1000, 0, LastError, 0, MsgBuffer, 1024, 0);
        Debug.Trace(MsgBuffer.ReadString(0));
    }
}

No idea if this will work I would have to do a bit more troubleshooting as to why it doesn't.

The highlighted line...  should it be like this (with a comma)?
js code:
                RemoveDirectory(sPath+'\\'+sFile, false);

Even then...
quote:
Originally posted by JavaScript Debugger
code:
\\?\C:\Documents and Settings\__________\My Documents\My Downloads\Test\


The debug line worked, although I don't know what's with the "\\?\" bit.
js code:
                Debug.Trace(sPath+sFile);

However, nothing in the folder was deleted.  The folder remained, and so did the files inside.  :S  Although...  the "TraceWin32Error()" wasn't called.  I suppose that's a good thing.
RE: copy file by matty on 07-15-2009 at 07:57 PM

Take a look at this: http://msdn.microsoft.com/en-us/library/aa365488%28VS.85%29.aspx

Anyways it looks like I completly screwed it up that time. I will have another stab at it.

js code:
RemoveDirectory('C:\\Documents and Settings\\User\\My Documents\\Test');

function RemoveDirectory(sPath) {
    var FO_DELETE = 0x3
    var FOF_ALLOWUNDO = 0x40;
    var SHFILEOPSTRUCT = Interop.Allocate(30);
    var strPath = Interop.Allocate(sPath.length*2+2);
        strPath.WriteString(0, sPath);
    with (SHFILEOPSTRUCT) {
        WriteDWORD(0, 0);
        WriteDWORD(4, FO_DELETE);
        WriteDWORD(8, strPath.DataPtr);
        //WriteWORD(16, FOF_ALLOWUNDO); // If you want the files to be sent to the recycle bin uncomment the following
    }

    if ( Interop.Call('shell32', 'SHFileOperationW', SHFILEOPSTRUCT) > 0 ) TraceWin32Error();
}

function TraceWin32Error(){
    var LastError = Interop.GetLastError();
    if(LastError != 0) {
        var MsgBuffer = Interop.Allocate(1024);
        Interop.Call("Kernel32", "FormatMessageW", 0x1000, 0, LastError, 0, MsgBuffer, 1024, 0);
        Debug.Trace(MsgBuffer.ReadString(0));
    }
}

RE: copy file by whiz on 07-15-2009 at 08:14 PM

quote:
Originally posted by matty
js code:
function RemoveDirectory(sPath) {
    var FO_DELETE = 0x3
    var FOF_ALLOWUNDO = 0x40;
    var SHFILEOPSTRUCT = Interop.Allocate(30);
    var strPath = Interop.Allocate(sPath.length*2+2);
        strPath.WriteString(0, sPath);
    with (SHFILEOPSTRUCT) {
        WriteDWORD(0, 0);
        WriteDWORD(4, FO_DELETE);
        WriteDWORD(8, strPath.DataPtr);
        //WriteWORD(16, FOF_ALLOWUNDO); // If you want the files to be sent to the recycle bin uncomment the following
    }

    if ( Interop.Call('shell32', 'SHFileOperationW', SHFILEOPSTRUCT) > 0 ) TraceWin32Error();
}

function TraceWin32Error(){
    var LastError = Interop.GetLastError();
    if(LastError != 0) {
        var MsgBuffer = Interop.Allocate(1024);
        Interop.Call("Kernel32", "FormatMessageW", 0x1000, 0, LastError, 0, MsgBuffer, 1024, 0);
        Debug.Trace(MsgBuffer.ReadString(0));
    }
}

The folder and files remain, along with two errors.  One in the debugger...
quote:
Originally posted by JavaScript Debugger
code:
The handle is invalid.

...and a Windows alert (title: "Error Deleting File or Folder", message: "Cannot delete file: Cannot read from the source file or disk.").

EDIT: No... you don't need trailing slashes.  Let me try again.

EDIT 2: It works!  And it has a Windows confirm dialog box.  Thank you!
RE: copy file by CookieRevised on 07-15-2009 at 11:23 PM

quote:
Originally posted by whiz
although I don't know what's with the "\\?\" bit.
In a very simple nutshell, that is a special indication, prefix if you will, to tell Windows that a (very) long path name will follow.

More and proper details can be found on the MSDN library.

Also see the very first link in that article about the RemoveDirectory API, which Matty pointed to earlier:
quote:
In the ANSI version of this function, the name is limited to MAX_PATH characters. To extend this limit to 32,767 wide characters, call the Unicode version of the function and prepend "\\?\" to the path. For more information, see Naming a File.



Anyways, the point is that it is not wrong. In fact, it is mandatory to be there for many Unicode APIs if you don't want the run into the default path length limitation (which is normally just 260 characters).

;)