malxau/yori

MOVE and ERASE do not raise ERRORLEVEL when file is locked with another process

Closed this issue · 9 comments

Hi!

Another finding... let's create C:\temp\raiser.txt and lock it with following:

CMD> notepad.exe > "C:\temp\raiser.txt"

so this file will be locked until notepad.exe will be closed... and now try to move or erase this file:

CMD> "ymove.exe" "C:\temp\raiser.txt" "C:\temp\deraiser.txt"
CMD> ECHO.!ERRORLEVEL!
0

ymove.exe "C:\temp" "C:\tempNew" with locked file in C:\temp leads to the same... and almost same thing with ERASE:

CMD> "yerase.exe" "C:\temp\raiser.txt"
erase: delete of \\?\C:\temp\raiser.txt failed: <<here goes localized error message>>
CMD> ECHO.!ERRORLEVEL!
0

at least error message is shown, but ERRORLEVEL becomes 0

And by the way when COPY is used with -p switch to preserve existing files and it comes in situation where no files can be copied due to all files are already exist and all is fine... but COPY raises ERRORLEVEL and as for me this is obviously not an error

Is it consistent to say that MKDIR should fail if the object exists but COPY -P should succeed if the object exists? In both cases the outcome is the same: the tool has performed no processing and the system has achieved its requested state.

Yes, I can agree that in case of MKDIR and COPY -P the result is the same that it was expected... the thing with COPY -P is that I need to check the ERRORLEVEL in script after COPY -P to be sure that all was copied without any errors, but ERRORLEVEL was raised due to nothing to copy reason, and script fails since it need to check that all is fine before continue, and all is fine in real, but there is an error... and there is no way to check that all is fine in that case! In MKDIR scenario we can check the directory exist but with recursive COPY -S -P we can not

The thing I'm trying to point out though is that success means different things to different people, and I can't write a single-bit return value that is correct for everyone. Creating an existing directory or deleting a nonexistent file could easily be considered success in the right context.

Because all of these tools allow for an arbitrary number of arguments, each of which contain wildcards, they can be asked to do an arbitrarily large number of things. The pattern I've been following is that if they successfully do any one thing, they were successful. But it's easy to imagine cases where this is not success in a particular application, and this comment is about a case where they didn't do anything which might be successful in a particular application.

I think the focus here needs to switch to stderr parsing, and I should be trying to ensure that stderr contains accurate output for issues that were encountered. This means instead of a single bit of information there's an arbitrary number of errors that can be returned to express the arbitrary number of conditions which the commands might encounter.

This is tough enough even to discuss =) Since you are right, there is too many different people with too different point of view! The situation becomes more difficult due to already existing script and there is no way something can be changed in principle without hurting somebody so basically parsing stderr is only option we have in such situation... So wrote CMD-variant that way:

    @FOR /F "usebackq tokens=*"delims^=^ eol^= %%E IN (

        `""C:\yori\ycopy.exe" -s -p "C:\temp\2\*" "C:\temp\3" 2>&1 1>nul"`

    ) DO @(

        @IF NOT "[ %%~E ]" == "[ copy: no matching files found ]" @(

            @ECHO.  Can not copy directory contents: "C:\temp\2" to "C:\temp\3"
            @GOTO :label_exit

        )

    )

despite as for me it is horroble, awful and terrible =) This seems pretty obvious and straightforward... The only thing I can not understand how to do this with Yori shell, so simply how to write Yori script .ys1 which will parse only STDERR during command execution?

Anyway this gone too far away from the original subject!

I've hit another issue with ymove.exe... this works from Yori:

YORI > move C:\temp\file D:\file

and this is not from CMD:

CMD > ymove.exe C:\temp\file D:\file

just shows error message: MoveFile failed: The system cannot move the file to another drive.

I think the original MOVE and ERASE do not raise ERRORLEVEL when file is locked with another process and this ymove.exe to another drive can be fixed without any consequences for others

Were these the same version of ymove? There was a nasty bug introduced in 414c982 and fixed in 2b81159 which meant it didn't specify MOVEFILE_COPY_ALLOWED correctly, which is needed for cross drive moves.

Just done some tests with current source... now ymove.exe works with different drive letters.

And in a nutshell after CMD> notepad.exe > "C:\temp\raiser.txt":

CMD> ymove.exe "C:\temp\raiser.txt" "C:\temp\deraiser.txt"
CMD> ECHO %ERRORLEVEL%
1

works as expected!

CMD> yerase.exe "C:\temp\raiser.txt"
CMD> ECHO %ERRORLEVEL%
0

should be 1

Perfect!