Open sindresorhus opened 9 years ago
This is what I found out at StackOverflow:
http://stackoverflow.com/a/27847797
Let's try to pass an NSURL to resultingItemURL
.
Yeah, I've tried that too and lots of other things. Nothing. Debugged this for hours...
Have you tried adding a sleep between two consecutive calls? Maybe something in the background can't follow the trash procedure and gets confused...
Yup, also tried doing some other NSFileManager
between, and also tried making the calls in different threads.
@pornel Sorry for mentioning you, but you're the only the Obj-C person I know of. Any idea what's going on?
Any particular reason why you allocate two file managers instead of using the same instance? (Not sure if it affects the problem, but worth trying).
@thomassnielsen Just to make sure the problem is not with reusing the defaultManager
. That's not the problem, though.
@fcanas: After a deep 🐇 hole: Looks like a NSFileManager 🐛. Can workaround by having Finder delete via ScriptingBridge. - https://twitter.com/fcanas/status/654817376790167552
Deleting via scriptingbridge is... messy. Let my try to repro and play with it a bit.
I can't even repro it working for the first file; nothing can be put back. Calling trash
with a single file doesn't even work. Confirmed it's not even the directory that matters; it's any directory.
I tried figuring out where it's storing the original location of the file, but I can't find a PList or anything.
The answer seems to lay within the .DS_Store
file (~/.Trash/.DS_Store
). Legend has it Apple has deprecated their use, but it seems to be the key here.
$ pwd
/src/sindresorhus.osx-trash
$ touch foo bar
$ <use finder to manually Move To Trash `foo`>
$ ./trash bar
$ xxd ~/.Trash/.DS_Store
. . . snip . . .
00001570: 0069 006e 0064 0072 0065 0073 006f 0072 .i.n.d.r.e.s.o.r
00001580: 0068 0075 0073 002e 006f 0073 0078 002d .h.u.s...o.s.x.-
00001590: 0074 0072 0061 0073 0068 002f 0000 0003 .t.r.a.s.h./....
000015a0: 0066 006f 006f 7074 624e 7573 7472 0000 .f.o.optbNustr..
000015b0: 0003 0066 006f 006f 0000 0026 0047 006f ...f.o.o
. . . snip . . .
ptbNustr
is some sort of separator token
Upon further look, as I suspected, bar
was nowhere to be seen in the .DS_Store
, which means Trash doesn't know where the file came from; this is definitely a bug in [NSFileManager trashItemAtURL: resultingItemURL:error:]
. Our workaround could be to edit the .DS_Store
file manually, though there isn't a cocoa interface to do this; we'd have to manually do it ourselves.
I filed a bug with Apple; bug 23153124. Don't think it's publicly viewable. I'll update here as I hear anything.
Probably want to work on a workaround for now.
Oh, very interesting. Thanks for looking into this @Qix- and for filing the bug. Would you mind also filing it on https://openradar.appspot.com and pasting a link to it here?
Will do; also, it looks like Put Back isn't the most polished feature to begin with.
Opened radar rdar://23153124.
@gchriswill Why not Objective-C? ;)
As well, @sindresorhus has been doing a bit of C lately, not just for OS X. That's probably why.
I initally wrote this in Swift, but had to rewrite it in Objective-C as the binary was several megabytes (because before Swift 2 the whole interpreter was embedded in the binary). Doesn't really matter anyways, though, as it's so little code.
@sindresorhus Sorry I couldn't check that earlier. ImageOptim suffers from the same problem, and I'm pretty sure Put Back used to work for all files when I first wrote it, so it's a regression in OS X.
sleep(10)
between the calls "fixes" it, so there may be some kind of delayed flush in Finder. The problem still happens when I try to delete 1 file per process, by launching 2 processes, so it's a system-wide bug, not something limited to NSFileManager instance.
@pornel could you write a quick POC for that? I'll add it to the bug report.
The code at the top of the thread already shows the bug very well.
@pornel with the sleep()
call I mean.
@pornel Oh, interesting. Thanks for chiming in.
sleep(2);
is the shortest sleep that makes it work for me. sleep(1)
and [NSThread sleepForTimeInterval:1.9]
does not. So it seems there some kind of flush after 2 seconds.
Still an issue in macOS Sierra...
Let me check on the radar...
EDIT: Nothing. I've added information re: Sierra.
Should we resort to creating a .DS_Store
editor? There's a Perl implementation that we could port.
Still nothing on the radar.
I just stumbled upon this while debugging https://github.com/IngmarStein/Monolingual/ which suffers from the same bug. Thanks for your analysis and please keep us in the loop when (or if) the radar status changes.
There's a Swift implementation of this function, maybe that has better chance of working on Sierra?
@h0d I doubt that will make any difference. That Swift call uses the same Objective-C API underneath.
^ Correct.
Still having problem in 10.13.5. No "Put back" option appears on deleted files in Trash. Any news?
Thanks for the reminder @leanne63 - just checked bugreport.apple.com on the radar (23153124) and they have not responded in almost three years (Oct 16, 2015). There's not even an assigned status.
I added another comment requesting a response, but don't hold your breath.
FWIW, I've filed two other issues through Apple's bug report system and both received responses rather quickly. Not sure why this one is falling through the cracks.
Feel free to ping me again in another year :trollface:
I've reproduced it in macOS 10.14 beta 3 too and I've filed a duplicate radar: https://openradar.appspot.com/radar?id=5063396789583872
I'm testing trash
and "Put Back" is not an option, even if you delete just one file
Using Finder to delete the file is how other utils have worked around this issue (though not elegant, I agree)... but it seems to have some side issues on files on networked shares that you've side-stepped (see https://github.com/ali-rantakari/trash/issues/32)
Testing a similar utility (https://github.com/sindresorhus/macos-trash), they implement an elegant workaround for the Networked/mapped folder issue:
When trying to delete a file on an network share, the utility fails with a message that the volume doesn't have a Trash folder:
jjarava$ trash-swift Safari\ -\ 6\ feb\ 2018\ 22\:35\ copy.pdf
“Safari - 6 feb 2018 22/35 copy.pdf” couldn’t be moved to the trash because the volume “DRIVE” doesn’t have one
(trash-swift
is the name I've given to the binary complied from https://github.com/sindresorhus/macos-trash on my system)
Just as an FYI I lost access to the original report, so I cannot check/update the original radar. @sindresorhus's radar should serve as most up-to-date version.
any progress?
@tjx666
This shell script works with full Put Back support.
Also, ali-rantakari/trash with the -F
flag works with full put-back support.
Continued from https://github.com/sindresorhus/trash/issues/24. This is a really weird issue.
Only the first file trashed with
trashItemAtURL
in a process will have the ability toPut back
from the trash. I've narrowed down the code and the below still only addsPut back
for the first filefoo
:I'm starting to think this is a OS X bug. Would appriciate being proved wrong, though. Gonna open an issue on radar when I get a chance, unless someone can figure this out.