C переместить файл в корзину
Я ищу способ поместить папку (с подпапками) в корзину с этими условиями:
Это должно быть сделано молча — без всяких Пользовательский интерфейс Windows.
Папка никогда не должен быть навсегда удаленным. Если это не может быть помещено в корзину, я ожидаю, что API потерпит неудачу.
Получить процедуру обратного вызова для процесса, как CopyFileEx делает.
Пока я смог придумать это:
Который ужасно терпит неудачу на папке, расположенной на флеш-накопителе USB, то есть это постоянно удаляется несмотря на FOF_ALLOWUNDO флаг.
Так ли я не делаю что-то правильно, или SHFileOperation API очень неправильно!
Любая идея, как сделать то, что я изложил выше?
РЕДАКТИРОВАТЬ: Я реализовал IRecycleBinManager::WillRecycle метод, как было предложено @Denis Anisimov, но, очевидно, это еще не все. Вот моя версия C ++. Первое определение интерфейса для метода, который мне нужен:
а потом сам звонок:
К сожалению, я получаю эту ошибку на линии, где я должен позвонить WillRecycle метод:
Другие решения
Мне удалось найти решение для всех 3 моих первоначальных пунктов / запросов.
В двух словах, нужно использовать IFileOperation интерфейс и реализовать IFileOperationProgressSink в этом.
РЕДАКТИРОВАТЬ: Хорошо, это еще не все. Метод, который я разместил выше, не охватывает все основы 🙁
Но как я могу использовать эту функцию для отправки файла в корзину вместо того, чтобы просто удалить его сразу?
ПРИМЕЧАНИЕ. Это также не работает с интерактивными приложениями без пользовательского интерфейса, такими как службы Windows.
Эта оболочка может предоставить вам необходимую функциональность:
Хотя это будет работать с интерактивными приложениями пользовательского интерфейса, это не будет работать с интерактивными приложениями без пользовательского интерфейса, такими как приложение службы Windows.
Добавьте ссылку на сборку Microsoft.VisualBasic. Нужный класс находится в этой библиотеке.
Добавьте этот оператор using в начало файла using Microsoft.VisualBasic.FileIO ;
Используйте FileSystem.DeleteFile для удаления файла, есть возможность указать корзину или нет.
Используйте FileSystem.DeleteDirectory для удаления каталога с возможностью указать, отправлять его в корзину или нет.
Следующее решение проще других:
Вы можете использовать другие функции корзины с помощью этой библиотеки.
Во-первых, не забудьте добавить библиотеку «Microsoft Shell Controls And Automation» (из меню COM), чтобы иметь возможность использовать пространство имен Shell32 . Он будет динамически связан с вашим проектом, а не компилироваться вместе с вашей программой.
К сожалению, вам нужно прибегнуть к Win32 API, чтобы удалить файл в корзину. Попробуйте следующий код на основе этот пост. Он использует общую функцию SHFileOperation для операций с файловой системой через оболочку Windows.
Определите следующее (в классе утилит, вероятно, лучше всего).
И чтобы использовать его для удаления файла, отправив его в корзину, вам нужно что-то вроде:
Вы можете DllImport SHFileOperation в сделай это.
Я использую этот метод расширения, тогда я могу просто использовать DirectoryInfo или FileInfo и удалить его.
Образец того, как это назвать, может быть таким:
Для этого есть встроенная библиотека .
Сначала добавьте ссылку Microsoft.VisualBasic Затем добавьте этот код:
Есть ли функция Qt для перемещения файлов в корзину вместо их полного удаления для ОС, которые ее поддерживают, или мне нужно использовать код, специфичный для ОС?
Начиная с Qt 5.15.0 Alpha , этот метод был добавлен, что должно быть именно тем, что вы искали.
Соответствующие изменения кода можно найти здесь.
Qt не предоставляет MoveToTrash. Вот часть моего кода
Проблема закрыта, и версия исправления: Некоторый будущий выпуск
Редактировать По-видимому, теперь это сделано в версии 5.15.0 Alpha bool QFile::moveToTrash()
Я считаю, что кроссплатформенного способа не существует. Простое перемещение файлов в «корзину» не даст эффекта, так как пользователь может отключить эту возможность.
Я относительно уверен, что не существует Qt API, который бы обертывал это для всех поддерживаемых платформ. К сожалению, это означает, что вам придется писать код для конкретной платформы.
Я ничего не знаю о том, где и как дистрибутивы Linux хранят удаленные файлы, и полагаю, что это, вероятно, зависит от того, какой файловый менеджер вы используете. Я считаю, что перемещение файлов в папку ~/.Trash - это стандартный способ сделать это, но я не уверен, что это надежно. Например, в случае файлов, хранящихся на внешних томах.
В Mac OS X все немного проще, где для этого есть поддерживаемый API: FSMoveObjectToTrashSync , предоставляемый Core Services. По крайней мере, я так помню, что ты должен это делать. SHFileOperation функция:
Также есть флаги, которые можно установить для настройки подтверждения, отчетов об ошибках и другого поведения. Связанная документация содержит все детали, необходимые для построения этого базового примера.
В Windows Vista и более поздних версиях функция SHFileOperation заменена методами, предоставляемыми IFileOperation интерфейс. Если вы ориентируетесь только на эти более поздние версии Windows, вам следует предпочесть этот интерфейс. В противном случае SHFileOperation продолжит нормально работать.
Файлы мусора в Linux существуют в каталоге /home/user_name/.local/share/Trash/files/ , но для них также требуется информационный файл для каждого файла мусора, который существует в каталоге /home/user_name/.local/share/Trash/info/ . когда мы хотим переместить файл в корзину, фактически переместите файл в каталог /home/user_name/.local/share/Trash/files/ и создайте информационный файл в каталоге /home/user_name/.local/share/Trash/info/ . внутри формата .trashinfo используйте схему процентного декодирования для указания пути к файлу, в котором файл существовал, информационный файл также содержит время и дату удаления.
Нельзя сказать, что это просто.
Это очень просто.
Надо переместить файл в карзину, как в обычную папку.
BOOL MoveFile(
LPCTSTR lpExistingFileName, // путь + имя перемещаемого файла
LPCTSTR lpNewFileName // путь + имя конечного файла (для тебя - путь в карзину)
);
if(!MoveFile("c:/myfile.txt","c:/Recycled/myfile.txt"))MessageBox(NULL,"Can't delete myfile.txt","My application",MB_OK);
Originally posted by lord Kelvin
Нельзя сказать, что это просто.
Это очень просто.
Надо переместить файл в карзину, как в обычную папку.
BOOL MoveFile(
LPCTSTR lpExistingFileName, // путь + имя перемещаемого файла
LPCTSTR lpNewFileName // путь + имя конечного файла (для тебя - путь в карзину)
);
if(!MoveFile("c:/myfile.txt","c:/Recycled/myfile.txt"))MessageBox(NULL,"Can't delete myfile.txt","My application",MB_OK);
Увы, это просто, если у тебя система Win98 и ты гарантированно работаешь на диске С:. Если у тебя XP с несколькими учетными записями и неизвестен рабочий диск, то все не так радужно :(
Originally posted by GDragon
Увы, это просто, если у тебя система Win98 и ты гарантированно работаешь на диске С:. Если у тебя XP с несколькими учетными записями и неизвестен рабочий диск, то все не так радужно :(
Диск C: есть всегда, это раз. Корзина находиться не в ../Dobuments and settings/. а прямо на диске, это два.
P.S. Папка Recycled есть на каждом диске.
Это сущее вранье! У меня установлена Windows XP, и там нет никаких дисков С:! Их вообще-то переименовать можно.
А вот узнать имя хотя бы системной папки, для этого есть API'шные команды, чё-то типа GetWindowsDirectory, а там выделить букву диска как нечего делать
Это сущее вранье! У меня установлена Windows XP, и там нет никаких дисков С:! Их вообще-то переименовать можно.
А вот узнать имя хотя бы системной папки, для этого есть API'шные команды, чё-то типа GetWindowsDirectory, а там выделить букву диска как нечего делать
Оффтоп:
Ну и как же ты убрал диск Це? Вытащил винт наверно.
Originally posted by lord Kelvin
Диск C: есть всегда, это раз. Корзина находиться не в ../Dobuments and settings/. а прямо на диске, это два.
P.S. Папка Recycled есть на каждом диске.
Ну, начнем с того, что С: есть не всегда, но даже если есть, а файл удаляется на диске D:, то не лучшая идея - грузить удаляемое файло на другой диск.
Папка называется не RECYCLED, а RECYCLER и содержит в себе еще несколько папок (по количеству учетных записей в системе) с именем типа GUID - по одному уникальному имени для каждой записи. К стати, файло в них хранится не под собственными именами, а под каким-то образом перекодированными. GUID, соответствующий текущему юзеру можно выцепить из HKCU\Software\Microsoft\Protected Storage System Provider.
Но что-то мне подсказывает, что удаление в корзину можно сделать гораздо легче.
Originally posted by GDragon
Всем привет.
Народ, подскажите, как из программы удалить файл в корзину?
Выяснил, что энто делается с помощью SHFileOperation(). Теперь другая проблема - файл не хочет удаляться. Удалился только с диска С:, из папки - ни в какую.
Originally posted by GDragon
Выяснил, что энто делается с помощью SHFileOperation(). Теперь другая проблема - файл не хочет удаляться. Удалился только с диска С:, из папки - ни в какую.
Бббылин! Строка с именем удаляемого файла, оказывается, должна завершаться не одним, а двумя нулями! Идиотизьм какой-то.
Кому тоже интересно, вот код рабочей функции:
BOOL SafeDeleteFile(LPCTSTR lpFileName)
TCHAR lpPath[MAX_PATH];
ZeroMemory(lpPath, sizeof(TCHAR) * MAX_PATH);
CopyMemory(lpPath, lpFileName, sizeof(TCHAR) * strlen(lpFileName));
SHFILEOPSTRUCT shfoStruct = ;
shfoStruct.wFunc = FO_DELETE;
shfoStruct.pFrom = lpPath;
shfoStruct.fFlags = FOF_ALLOWUNDO | FOF_NOCONFIRMATION | FOF_SILENT;
if(!SHFileOperation(&shfoStruct))
return TRUE;
return FALSE;
>
Originally posted by GDragon
Бббылин! Строка с именем удаляемого файла, оказывается, должна завершаться не одним, а двумя нулями! Идиотизьм какой-то.
Не думаю. Кажется, потому, что можно передать сразу несколько файлов функции. Надо внимательнее прочитать доку.
Есть ли функция Qt для перемещения файлов в корзину вместо того, чтобы действительно удалять их, для ОС, которые его поддерживают, или мне нужно использовать специфичный для ОС код?
Решение
Каждый диск имеет свою собственную корзину. А когда вы удаляете файл с диска С: он должен быть перемещен в корзину на диске С :. Когда вы удаляете файл с USB-накопителя, его следует переместить в корзину на USB-накопителе. Но когда на USB-накопителе нет корзины, файл удаляется без возможности восстановления. Это поведение Windows по умолчанию.
Флаг FOF_ALLOWUNDO — только РЕКОМЕНДАЦИЯ. MSDN говорит о флаге FOF_ALLOWUNDO:
Сохранять отмененную информацию, если возможно.
Поэтому нет никаких ошибок, когда Windows окончательно удаляет файлы, даже если вы используете флаг FOF_ALLOWUNDO.
Единственный способ, которым я вижу, — это проверить наличие корзины на диске с помощью функции SHQueryRecycleBin (как указал Алекс Фарбер в комментарии) перед операцией удаления. Но даже если Recycle Bin представляет, это не полная гарантия, что файл будет удален в корзину. Корзина имеет максимальный размер и может быть уже заполнена.
ОБНОВИТЬ
Вы можете использовать взломать. Вы можете эмулировать удаление файла в корзину с вашим собственным кодом, который создаст все необходимые системные записи в папке C: \ $ Recycle.Bin \ UserSID. Я протестировал этот метод на Windows 7, и он работает правильно. Это позволяет игнорировать ограничение максимального размера корзины. Также это позволяет перемещать файлы с USB в корзину на любом диске.
ОБНОВЛЕНИЕ 2
Вы можете проверить возможность удаления файла в корзину с помощью следующего кода:
ОБНОВЛЕНИЕ 3
Также вы можете попробовать следующий код для удаления объекта в корзину:
Решение
Проблема закрыта, и версия исправления: Некоторый будущий выпуск
Другие решения
Qt не предоставляет MoveToTrash. Вот часть моего кода
Я думаю, что нет кроссплатформенного пути. Простое перемещение файлов в «мусорную корзину» не даст эффекта, потому что пользователь может отключить эту возможность.
Я относительно уверен, что не существует API Qt, который оборачивает это для всех поддерживаемых платформ. К сожалению, это означает, что вам придется писать код для конкретной платформы.
Я ничего не знаю о том, где и как дистрибутивы Linux хранят удаленные файлы, и я предполагаю, что это, вероятно, зависит от того, какой файловый менеджер вы используете. Я считаю, что перемещение файлов в ~/.Trash папка является стандартным способом сделать это, но я не уверен, что это надежно. Например, в случае файлов, хранящихся на внешних томах.
В Mac OS X все немного проще, и для этого есть поддерживаемый API: FSMoveObjectToTrashSync , предоставляемых Core Services. По крайней мере, я так помню, ты должен это делать. Документация утверждает, что этот метод в настоящее время устарел в OS X 10.8. Я понятия не имею, что является рекомендуемой альтернативой.
Как программист Windows, я думаю, что эта платформа намного проще. 🙂 Основным решением является вызов SHFileOperation функция:
Есть также флаги, которые вы можете установить, чтобы настроить подтверждение, отчеты об ошибках и другое поведение. Связанная документация содержит все детали, необходимые для построения этого базового примера.
В Windows Vista и более поздних SHFileOperation функция была заменена методами, предоставленными IFileOperation интерфейс. Если вы ориентируетесь только на эти более поздние версии Windows, вам следует использовать этот интерфейс. Иначе, SHFileOperation продолжит работать нормально.
Мусорные файлы в Linux существуют /home/user_name/.local/share/Trash/files/ каталог, но он также требует информационный файл для каждого файла корзины, которые существуют в /home/user_name/.local/share/Trash/info/ каталог. когда мы хотим переместить файл в корзину, на самом деле переместить файл в /home/user_name/.local/share/Trash/files/ каталог и создать информационный файл в /home/user_name/.local/share/Trash/info/ каталог. внутри .trashinfo Формат использует процентную схему декодирования для задания пути к файлу, в котором файл существует, в информационном файле также указывается время и дата удаления.
Читайте также: