Управление файловой системой
Оболочка предоставляет ряд способов управления файловыми системами. Оболочка предоставляет функцию, SHFileOperation, которая позволяет приложению программно перемещать, копировать, переименовать и удалять файлы. Оболочка также поддерживает некоторые дополнительные возможности управления файлами.
- HTML-документы могут быть подключены к связанным файлам, таким как графические файлы или таблицы стилей. При перемещении или копировании документа подключенные файлы автоматически перемещаются или копируются.
- Для систем, доступных нескольким пользователям, управление файлами может осуществляться для каждого пользователя. Пользователи имеют простой доступ к файлам данных, но не к файлам, принадлежащим другим пользователям.
- Если файлы документов добавляются или изменяются, их можно добавить в список последних документов оболочки. Когда пользователь щелкает команду "Документы" в меню "Пуск", появится список ссылок на документы.
В этом документе описывается, как работают эти технологии управления файлами. Затем в нем описывается, как использовать оболочку для перемещения, копирования, переименования и удаления файлов, а также управления объектами в корзине.
- Per-User Управление файлами
- Мои документы и папки "Мои рисунки"
- Связанные файлы
- Перемещение, копирование, переименование и удаление файлов
- простой пример управления файлами с помощью shFileOperation
- Добавление файлов в список недавних документов оболочки
управление файлами Per-User
Оболочка Windows 2000 позволяет связывать файлы с определенным пользователем, чтобы файлы оставались скрытыми от других пользователей. С точки зрения файловой системы файлы хранятся в папке профиля пользователя, как правило, C:\Documents and Settings\имя пользователя\ в системах Windows 2000. Эта функция позволяет многим пользователям использовать тот же компьютер, сохраняя конфиденциальность своих файлов от других пользователей. Разные пользователи могут иметь различные программы. Он также предоставляет простой способ для администраторов и приложений хранить такие вещи, как инициализация (.ini) или ссылки (.lnk) файлов. Таким образом, приложения могут сохранять разные состояния для каждого пользователя и легко восстанавливать это конкретное состояние при необходимости. Существует также папка профиля для хранения сведений, общих для всех пользователей.
Поскольку неудобно определить, какой пользователь вошел в систему и где находятся его файлы, стандартные папки пользователей являются специальными и определяются с помощью CSIDL. Например, CSIDL для папки Program Files для каждого пользователя — CSIDL_PROGRAMS. Если приложение вызывает SHGetFolderLocation или SHGetFolderPath с одним из CSID-адресов для каждого пользователя, функция возвращает указатель на список идентификаторов элементов (PIDL) или путь, соответствующий пользователю, вошедшим в систему. Если вашему приложению необходимо получить путь или PIDL папки профиля, ее CSIDL — CSIDL_PROFILE.
Мои документы и папки "Мои рисунки"
Одним из стандартных значков, найденных на рабочем столе, является "Мои документы". При открытии этой папки он содержит файлы документов текущего пользователя. Десктопный экземпляр "Мои документы" — это виртуальная папка, являющаяся псевдонимом для расположения в файловой системе, используемого для физического хранения документов пользователя, которое находится прямо под рабочим столом в иерархии пространства имен.
Цель папок "Мои документы" и "Мои рисунки" — обеспечить простой и безопасный способ доступа пользователей к файлам документов и рисунков в системе с несколькими пользователями. Каждому пользователю назначены отдельные папки файловой системы для его файлов. Например, расположение папки документов пользователя в файловой системе обычно похоже на C:\Documents and Settings\имя пользователя\Мои документы. Пользователям не нужно знать ничего о физическом расположении папок файловой системы. Они просто получают доступ к своим файлам с помощью значка "Мои документы".
Заметка
Мои документы позволяют пользователю получать доступ к своим файлам, но не к другим пользователям. Если несколько пользователей используют один и тот же компьютер, администратор может заблокировать пользователей из части файловой системы, в которой хранятся фактические файлы. Таким образом, пользователи смогут работать над собственными документами в папке "Мои документы", но не на документах, принадлежащих любым другим пользователям.
Обычно приложению не нужно знать, в какой пользователь вошел в систему или где находится папка "Мои документы" пользователя. Вместо этого приложение может получить PIDL значка "Мои документы" на рабочем столе, вызвав метод IShellFolder::ParseDisplayName. Имя синтаксического анализа, используемое для идентификации папки "Мои документы", — это не путь к файлу, а :{450d8fba-ad25-11d0-98a8-0800361b1103}. Выражение с скобками — это текстовая форма GUID "Мои документы". Например, чтобы получить PIDL Моих документов, приложение должно использовать этот вызов для IShellFolder::ParseDisplayName.
hr = psfDeskTop->ParseDisplayName(NULL,
NULL,
L"::{450d8fba-ad25-11d0-98a8-0800361b1103}",
&chEaten,
&pidlDocFiles,
NULL);
После того как приложение имеет PIDL "Мои документы", оно может обрабатывать папку так же, как и обычную папку файловой системы— перечисление элементов, синтаксический анализ, привязку и выполнение любых других допустимых операций папок. Оболочка автоматически отслеживает изменения в Моих документах или их вложенных папках и направляет их в соответствующие папки файловой системы.
Если приложению требуется доступ к фактической папке файловой системы, содержащей документы текущего пользователя, передайте CSIDL_PERSONAL в SHGetFolderLocation. Функция возвращает PIDL папки файловой системы, отображаемой в папке "Мои документы" текущего пользователя.
Подключенные файлы
HTML-документы часто имеют ряд связанных графических файлов, файл таблицы стилей, несколько файлов Microsoft JScript (совместимых с спецификацией языка ECMA 262) и т. д. При перемещении или копировании основного HTML-документа обычно также нужно перемещать или копировать связанные файлы, чтобы избежать нарушения ссылок. К сожалению, до сих пор не было простого способа определить, какие файлы связаны с любым документом HTML, кроме анализа их содержимого. Чтобы устранить эту проблему, Windows 2000 предоставляет простой способ подключить основной HTML-документ к группе связанных файлов. Если подключение к файлу включено, при перемещении или копировании документа все его подключенные файлы перемещаются вместе с ним.
Чтобы создать группу подключенных файлов, основной документ должен иметь расширение .htm или .html имени файла. Создайте вложенную папку родительской папки первичного документа. Имя вложенной папки должно быть именем основного документа, минус расширение .htm или .html, за которым следует одно из расширений, перечисленных ниже. Наиболее часто используются расширения :files или "_files". Например, если основной документ называется MyDoc.htm, именование вложенной папки "MyDoc_files" определяет вложенную папку в качестве контейнера для подключенных файлов документа. Если основной документ перемещается или копируется, вложенные папки и его файлы также перемещаются или копируются.
Для некоторых языков можно использовать локализованный эквивалент "_files", чтобы создать вложенную папку для подключенных файлов. В следующей таблице перечислены допустимые строки, которые можно добавить в имя документа для создания вложенных папок подключенных файлов. Обратите внимание, что некоторые из этих строк имеют "-" в качестве первого символа, а не "_" или ".".
"_archivos"
"_arquivos"
"_bestanden"
"_bylos"
"-Файлы"
"_datoteke"
_файлы
"_elemei"
"_failid"
_не удается
_файлы
"_ficheiros"
_файлы
-файлер
.files
_файлы
_файл
"_fitxers"
"_fitxategiak"
_файлы
"_soubory"
_файлы
Заметка
Эта функция учитывается в случае расширения. Например, например, вложенная папка с именем "MyDoc_Files" не будет подключена к MyDoc.htm.
Включение или отключение подключения к каталогам или файлам контролируется значением NoFileFolderConnection типа REG_DWORD из следующего раздела реестра.
HKEY_CURRENT_USER
Software
Microsoft
Windows
CurrentVersion
Explorer
Обычно это значение не определено, а подключение к файлу включено. При необходимости можно отключить подключение к файлу, добавив это значение в ключ и задав его значение 1. Чтобы снова включить подключение к файлу, установите значение NoFileFolderConnection равным нулю.
Заметка
Обычно подключение к файлам должно быть включено, так как другие приложения могут зависеть от него. Отключите подключение к файлу только при необходимости.
Перемещение, копирование, переименование и удаление файлов
Пространство имен не является статическим, и приложения обычно должны управлять файловой системой, выполняя одну из следующих операций.
- Копирование объекта в другую папку.
- Перемещение объекта в другую папку.
- Удаление объекта.
- Переименование объекта.
Эти операции выполняются с SHFileOperation. Эта функция принимает один или несколько исходных файлов и создает соответствующие целевые файлы. В случае операции удаления система пытается поместить удаленные файлы в корзину.
Также можно переместить файлы с помощью функции перетаскивания.
Чтобы использовать функцию, необходимо заполнить элементы структуры SHFILEOPSTRUCT и передать ее в SHFileOperation. Ключевые элементы структуры — pFrom и pTo.
Элемент pFrom — это строка с двойным завершением нулями , содержащая одно или несколько имен исходных файлов. Эти имена могут быть либо полностью определенными путями, либо стандартными символами подстановки DOS, такими как *.*. Хотя этот элемент объявляется как строка null-terminated, он используется в качестве буфера для хранения нескольких имен файлов. Каждое имя файла должно быть завершено обычным символом NULL. Для указания конца последовательности pFrom, в конец окончательного имени необходимо добавить дополнительный символ NULL.
Элемент pTo — это двойная строка null-terminated string, как pFrom. Элемент pTo содержит одно или несколько полностью квалифицированных имен назначения. Они упакованы в pTo так же, как для pFrom. Если pTo содержит несколько имен, необходимо также задать флаг FOF_MULTIDESTFILES в элементе fFlags. Использование pTo зависит от операции, как описано здесь.
- Для операций копирования и перемещения, если все файлы собираются в один каталог, pTo содержит полное имя каталога. Если файлы направляются в различные места назначения, pTo также может содержать один полный путь к каталогу или полное имя файла для каждого исходного файла. Если каталог не существует, система создает его.
- Для операций переименования pTo содержит один полный путь для каждого исходного файла в pFrom.
- Для операций удаления pTo не используется.
Уведомление Shell
Уведомите оболочку об изменении после использования SHFileOperation для перемещения, копирования, переименования или удаления файлов или выполнения других действий, влияющих на пространство имен. Действия, которые должны сопровождаться уведомлением, включают следующее:
- Добавление или удаление файлов или папок.
- Перемещение, копирование или переименование файлов или папок.
- Изменение сопоставления файлов.
- Изменение атрибутов файла.
- Добавление или удаление дисков или носителей хранилища.
- Создание или отключение общей папки.
- Изменение списка системных образов.
Приложение уведомляет оболочку, вызвав SHChangeNotify с подробными сведениями о том, что изменилось. Затем оболочка может обновить своё представление пространства имен, чтобы точно отразить его новое состояние.
Простой пример управления файлами с помощью SHFileOperation
В следующем примере консольного приложения показано использование SHFileOperation для копирования файлов из одного каталога в другой. Исходные и конечные каталоги C:\My_Docs и C:\My_Docs2 жестко закодируются в приложении для простоты.
#include <shlobj.h>
#include <shlwapi.h>
#include <strsafe.h>
int main(void)
{
IShellFolder *psfDeskTop = NULL;
IShellFolder *psfDocFiles = NULL;
LPITEMIDLIST pidlDocFiles = NULL;
LPITEMIDLIST pidlItems = NULL;
IEnumIDList *ppenum = NULL;
SHFILEOPSTRUCT sfo;
STRRET strDispName;
TCHAR szParseName[MAX_PATH];
TCHAR szSourceFiles[256];
int i;
int iBufPos = 0;
ULONG chEaten;
ULONG celtFetched;
size_t ParseNameSize = 0;
HRESULT hr;
szSourceFiles[0] = '\0';
hr = SHGetDesktopFolder(&psfDeskTop);
hr = psfDeskTop->ParseDisplayName(NULL, NULL, L"c:\\My_Docs",
&chEaten, &pidlDocFiles, NULL);
hr = psfDeskTop->BindToObject(pidlDocFiles, NULL, IID_IShellFolder,
(LPVOID *) &psfDocFiles);
hr = psfDeskTop->Release();
hr = psfDocFiles->EnumObjects(NULL,SHCONTF_FOLDERS | SHCONTF_NONFOLDERS,
&ppenum);
while( (hr = ppenum->Next(1,&pidlItems, &celtFetched)) == S_OK
&& (celtFetched) == 1)
{
psfDocFiles->GetDisplayNameOf(pidlItems, SHGDN_FORPARSING,
&strDispName);
StrRetToBuf(&strDispName, pidlItems, szParseName, MAX_PATH);
hr = StringCchLength(szParseName, MAX_PATH, &ParseNameSize);
if (SUCCEEDED(hr))
{
for(i=0; i<=ParseNameSize; i++)
{
szSourceFiles[iBufPos++] = szParseName[i];
}
CoTaskMemFree(pidlItems);
}
}
ppenum->Release();
szSourceFiles[iBufPos] = '\0';
sfo.hwnd = NULL;
sfo.wFunc = FO_COPY;
sfo.pFrom = szSourceFiles;
sfo.pTo = "c:\\My_Docs2\0";
sfo.fFlags = FOF_SILENT | FOF_NOCONFIRMATION | FOF_NOCONFIRMMKDIR;
hr = SHFileOperation(&sfo);
SHChangeNotify(SHCNE_UPDATEDIR, SHCNF_PATH, (LPCVOID) "c:\\My_Docs2", 0);
CoTaskMemFree(pidlDocFiles);
psfDocFiles->Release();
return 0;
}
Приложение сначала получает указатель на интерфейс IShellFolder рабочего стола. Затем он извлекает PIDL исходного каталога, передав полный путь к IShellFolder::P arseDisplayName. Обратите внимание, что IShellFolder::ParseDisplayName требует, чтобы путь каталога был строкой Юникода. Затем приложение привязывается к исходному каталогу и использует его интерфейс IShellFolder для получения интерфейса объекта перечислителя IEnumIDList.
По мере перечисления каждого файла в исходном каталоге IShellFolder::GetDisplayNameOf используется для получения его имени. Установлен флаг SHGDN_FORPARSING, который приводит к возвращению функцией IShellFolder::GetDisplayNameOf полного пути к файлу. Пути к файлам, включая конечные символы NULL, объединяются в один массив, szSourceFiles. Второй символ NULL добавляется к окончательному пути для правильного завершения массива.
После завершения перечисления приложение назначает значения структуре SHFILEOPSTRUCT. Обратите внимание, что массив, присвоенный pTo для указания назначения, также должен быть завершен двойным NULL. В этом случае она просто включена в строку, назначенную pTo. Так как это консольное приложение, FOF_SILENT, FOF_NOCONFIRMATION и флаги FOF_NOCONFIRMMKDIR задаются для подавления всех диалоговых окон, которые могут появиться. После того как SHFileOperation возвращается, вызывается SHChangeNotify, чтобы уведомить оболочку об изменении. Затем приложение выполняет обычную очистку и возвращается.
Добавление файлов в список последних документов оболочки
Интерфейс оболочки поддерживает список недавно добавленных или измененных документов для каждого пользователя. Пользователь может отобразить список ссылок на эти файлы, щелкнув "Документы" в меню "Пуск". Как и в случае с моими документами, каждый пользователь имеет каталог файловой системы для хранения фактических ссылок. Чтобы получить PIDL текущего каталога текущего пользователя, приложение может вызывать SHGetFolderLocation с CSIDL_RECENT или вызывать SHGetFolderPath, чтобы получить путь.
Приложение может перечислить содержимое папки "Последние", используя методы, описанные ранее в этом документе. Однако приложение не должно изменять содержимое папки, как если бы это была обычная папка файловой системы. Если это произойдет, список последних документов оболочки не будет обновляться должным образом, и изменения не будут отображаться в меню "Пуск". Вместо этого, чтобы добавить ссылку на документ в папку "Последние", приложение может вызывать SHAddToRecentDocs. Оболочка добавит ссылку на соответствующую папку файловой системы, а также обновит список последних документов и меню "Пуск". Эту функцию можно также использовать для очистки папки.