파일 시스템 관리
Shell은 파일 시스템을 관리하는 다양한 방법을 제공합니다. Shell은 애플리케이션이 프로그래밍 방식으로 파일을 이동, 복사, 이름 바꾸기 및 삭제할 수 있도록 하는 SHFileOperation 함수를 제공합니다. 또한 셸은 몇 가지 추가 파일 관리 기능도 지원합니다.
- HTML 문서는 그래픽 파일 또는 스타일시트 같은 관련 파일에 연결할 수 있습니다. 문서를 이동하거나 복사하면 연결된 파일도 자동으로 이동되거나 복사됩니다.
- 둘 이상의 사용자가 사용할 수 있는 시스템의 경우 사용자 단위로 파일을 관리할 수 있습니다. 사용자는 데이터 파일에 쉽게 액세스할 수 있지만 다른 사용자에 속한 파일에는 액세스할 수 없습니다.
- 문서 파일이 추가되거나 수정되면 셸의 최근 문서 목록에 추가할 수 있습니다. 사용자가 시작 메뉴에서 문서 명령을 클릭하면 문서에 대한 링크 목록이 표시됩니다.
이 문서에서는 이러한 파일 관리 기술의 작동 방식을 설명합니다. 그런 다음 셸을 사용하여 파일을 이동, 복사, 이름 바꾸기 및 삭제하는 방법과 휴지통에서 개체를 관리하는 방법을 간략하게 설명합니다.
- 사용자별 파일 관리
- 내 문서 및 내 그림 폴더
- 연결된 파일
- 파일 이동, 복사, 이름 바꾸기 및 삭제
- SHFileOperation을 사용하여 파일 관리의 간단한 예
- 셸의 최근 문서 목록에 파일 추가
Windows 2000 셸을 사용하면 파일을 특정 사용자와 연결할 수 있으므로 파일이 다른 사용자로부터 숨겨집니다. 파일 시스템의 관점에서 파일은 일반적으로 Windows 2000 시스템의 C:\Documents 및 Settings\Username\ 사용자 프로필 폴더 아래에 저장됩니다. 이 기능을 사용하면 많은 개인이 동일한 컴퓨터를 사용하는 동시에 다른 사용자의 파일 개인 정보를 유지할 수 있습니다. 다른 사용자가 다른 프로그램을 사용할 수 있습니다. 또한 관리자와 애플리케이션이 초기화(.ini) 또는 링크(.lnk) 파일과 같은 항목을 저장할 수 있는 간단한 방법을 제공합니다. 따라서 애플리케이션은 각 사용자에 대해 다른 상태를 유지하고 필요할 때 해당 특정 상태를 쉽게 복구할 수 있습니다. 모든 사용자에게 공통적인 정보를 저장하기 위한 프로필 폴더도 있습니다.
로그인할 사용자와 해당 파일이 있는 위치를 결정하는 것은 불편하기 때문에 사용자별 표준 폴더는 특별한 폴더이며 CSIDL로 식별됩니다. instance 사용자별 Program Files 폴더에 대한 CSIDL은 CSIDL_PROGRAMS. 애플리케이션이 사용자별 CSIDL 중 하나를 사용하여 SHGetFolderLocation 또는 SHGetFolderPath 를 호출하는 경우 함수는 현재 로그인한 사용자에게 적합한 PIDL(항목 식별자 목록) 또는 경로에 대한 포인터를 반환합니다. 애플리케이션이 프로필 폴더의 경로 또는 PIDL을 검색해야 하는 경우 해당 CSIDL이 CSIDL_PROFILE.
바탕 화면에 있는 표준 아이콘 중 하나는 내 문서입니다. 이 폴더를 열면 현재 사용자의 문서 파일이 포함됩니다. 내 문서의 데스크톱 instance 가상 폴더이며, 사용자의 문서를 물리적으로 저장하는 데 사용되는 파일 시스템 위치에 대한 별칭이며 네임스페이스 계층 구조의 바탕 화면 바로 아래에 있습니다.
내 문서 및 내 사진 폴더의 목적은 사용자가 여러 사용자가 있을 수 있는 시스템에서 문서 및 그림 파일에 액세스할 수 있는 간단하고 안전한 방법을 제공하는 것입니다. 각 사용자에게는 파일에 대한 별도의 파일 시스템 폴더가 할당됩니다. 예를 들어 파일 시스템의 사용자 문서 폴더 위치는 일반적으로 C:\Documents 및 Settings\username\My Documents와 같습니다. 사용자가 파일 시스템 폴더의 물리적 위치에 대해 아무것도 알 필요가 없습니다. 단순히 내 문서 아이콘을 통해 파일에 액세스합니다.
참고
내 문서를 사용하면 사용자가 자신의 파일에 액세스할 수 있지만 다른 사용자의 파일에는 액세스할 수 없습니다. 여러 개인이 동일한 컴퓨터를 사용하는 경우 관리자는 실제 파일이 저장된 파일 시스템의 일부에서 사용자를 잠글 수 있습니다. 따라서 사용자는 내 문서 폴더를 통해 자신의 문서에서 작업할 수 있지만 다른 사용자에게 속한 문서에서는 작업할 수 없습니다.
일반적으로 애플리케이션에서 로그인한 사용자 또는 파일 시스템에서 사용자의 내 문서 폴더가 있는 위치를 알 필요가 없습니다. 대신 애플리케이션은 데스크톱의 IShellFolder::P arseDisplayName 메서드를 호출하여 내 문서 데스크톱 아이콘의 PIDL을 검색할 수 있습니다. 내 문서 폴더를 식별하는 데 사용되는 구문 분석 이름은 파일 경로가 아니라 ::{450d8fba-ad25-11d0-98a8-0800361b1103}입니다. 대괄호로 묶인 식은 내 문서 GUID의 텍스트 형식입니다. 예를 들어 내 문서의 PIDL을 검색하려면 애플리케이션에서 IShellFolder::P arseDisplayName 호출을 사용해야 합니다.
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"입니다. instance 경우 기본 문서의 이름이 MyDoc.htm 하위 폴더의 이름을 "MyDoc_files"로 지정하면 하위 폴더가 문서의 연결된 파일에 대한 컨테이너로 정의됩니다. 기본 문서를 이동하거나 복사하면 하위 폴더와 해당 파일도 이동되거나 복사됩니다.
일부 언어의 경우 지역화된 "_files"를 사용하여 연결된 파일에 대한 하위 폴더를 만들 수 있습니다. 다음 표에서는 문서 이름에 추가하여 연결된 파일 하위 폴더를 만들 수 있는 유효한 문자열을 나열합니다. 이러한 문자열 중 일부는 '_' 또는 '.'이 아닌 첫 번째 문자로 '-'가 있습니다.
"_archivos"
"_arquivos"
"_bestanden"
"_bylos"
"-Dateien"
"_datoteke"
"_dosyalar"
"_elemei"
"_failid"
"_fails"
"_fajlovi"
"_ficheiros"
"_fichiers"
"-filer"
".files"
"_files"
"_file"
"_fitxers"
"_fitxategiak"
"_pliki"
"_soubory"
"_tiedostot"
참고
이 기능은 확장의 경우에 중요합니다. instance 위의 예제에서는 "MyDoc_Files"이라는 하위 폴더가 MyDoc.htm 연결되지 않습니다.
파일 연결을 사용하도록 설정하거나 사용하지 않도록 설정할지 여부는 다음 레지스트리 키의 REG_DWORD 값인 NoFileFolderConnection에 의해 제어됩니다.
HKEY_CURRENT_USER
Software
Microsoft
Windows
CurrentVersion
Explorer
이 값은 일반적으로 정의되지 않으며 파일 연결을 사용하도록 설정됩니다. 필요한 경우 키에 이 값을 추가하고 1로 설정하여 파일 연결을 사용하지 않도록 설정할 수 있습니다. 파일 연결을 다시 사용하도록 설정하려면 NoFileFolderConnection을 0으로 설정합니다.
참고
다른 애플리케이션이 이에 의존할 수 있으므로 일반적으로 파일 연결을 사용하도록 설정해야 합니다. 반드시 필요한 경우에만 파일 연결을 사용하지 않도록 설정합니다.
네임스페이스는 정적이지 않으며 애플리케이션은 일반적으로 다음 작업 중 하나를 수행하여 파일 시스템을 관리해야 합니다.
- 개체를 다른 폴더에 복사합니다.
- 개체를 다른 폴더로 이동합니다.
- 개체를 삭제하는 중입니다.
- 개체 이름을 변경합니다.
이러한 작업은 모두 SHFileOperation을 사용하여 수행됩니다. 이 함수는 하나 이상의 원본 파일을 사용하고 해당 대상 파일을 생성합니다. 삭제 작업의 경우 시스템은 삭제된 파일을 휴지통에 넣으려고 시도합니다.
끌어서 놓기 기능을 사용하여 파일을 이동할 수도 있습니다.
함수를 사용하려면 SHFILEOPSTRUCT 구조체의 멤버를 채우고 SHFileOperation에 전달해야 합니다. 구조체의 핵심 멤버는 pFrom 및 pTo입니다.
pFrom 멤버는 하나 이상의 원본 파일 이름을 포함하는 이중 null로 끝나는 문자열입니다. 이러한 이름은 정규화된 경로 또는 표준 DOS 와일드카드(예: *.*)일 수 있습니다. 이 멤버는 null로 끝나는 문자열로 선언되지만 여러 파일 이름을 보유하는 버퍼로 사용됩니다. 각 파일 이름은 일반적인 단일 NULL 문자로 종료되어야 합니다. pFrom의 끝을 나타내려면 최종 이름의 끝에 추가 NULL 문자를 추가해야 합니다.
pTo 멤버는 pFrom과 마찬가지로 이중 null로 끝나는 문자열입니다. pTo 멤버에는 하나 이상의 정규화된 대상 이름의 이름이 포함됩니다. pFrom과 동일한 방식으로 pTo로 압축됩니다. pTo에 여러 이름이 포함된 경우 fFlags 멤버에서 FOF_MULTIDESTFILES 플래그도 설정해야 합니다. pTo 사용법은 여기에 설명된 작업에 따라 달라집니다.
- 복사 및 이동 작업의 경우 모든 파일이 단일 디렉터리로 이동하는 경우 pTo 에는 정규화된 디렉터리 이름이 포함됩니다. 파일이 다른 대상으로 가는 경우 pTo 는 각 원본 파일에 대해 하나의 정규화된 디렉터리 또는 파일 이름을 포함할 수도 있습니다. 디렉터리가 없으면 시스템에서 디렉터리를 만듭니다.
- 이름 바꾸기 작업의 경우 pTo 는 pFrom의 각 원본 파일에 대해 하나의 정규화된 경로를 포함합니다.
- 삭제 작업의 경우 pTo 는 사용되지 않습니다.
SHFileOperation을 사용하여 파일을 이동, 복사, 이름 바꾸기 또는 삭제하거나 네임스페이스에 영향을 주는 다른 작업을 수행한 후 셸에 변경 내용을 알립니다. 알림과 함께 제공되는 작업에는 다음이 포함됩니다.
- 파일 또는 폴더 추가 또는 삭제
- 파일 또는 폴더 이동, 복사 또는 이름 바꾸기
- 파일 연결 변경.
- 파일 특성 변경.
- 드라이브 또는 스토리지 미디어 추가 또는 제거
- 공유 폴더를 만들거나 사용하지 않도록 설정
- 시스템 이미지 목록 변경
애플리케이션은 변경된 내용에 대한 세부 정보와 함께 SHChangeNotify 를 호출하여 셸에 알 수 있습니다. 그런 다음 셸은 네임스페이스의 이미지를 업데이트하여 새 상태를 정확하게 반영할 수 있습니다.
다음 샘플 콘솔 애플리케이션에서는 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 인터페이스에 대한 포인터를 검색합니다. 그런 다음 IShellFolder::P arseDisplayName에 정규화된 경로를 전달하여 원본 디렉터리의 PIDL을 검색합니다. IShellFolder::P arseDisplayName을 사용하려면 디렉터리의 경로가 유니코드 문자열이어야 합니다. 그런 다음 애플리케이션은 원본 디렉터리에 바인딩하고 IShellFolder 인터페이스를 사용하여 열거자 개체의 IEnumIDList 인터페이스를 검색합니다.
원본 디렉터리의 각 파일이 열거되면 IShellFolder::GetDisplayNameOf 가 해당 이름을 검색하는 데 사용됩니다. SHGDN_FORPARSING 플래그가 설정되어 IShellFolder::GetDisplayNameOf 가 파일의 정규화된 경로를 반환합니다. 종료되는 NULL 문자를 포함한 파일 경로는 단일 배열 인 szSourceFiles로 연결됩니다. 배열을 올바르게 종료하려면 두 번째 NULL 문자가 최종 경로에 추가됩니다.
열거형이 완료되면 애플리케이션은 SHFILEOPSTRUCT 구조체에 값을 할당합니다. 대상을 지정하기 위해 pTo 에 할당된 배열도 이중 NULL로 종료되어야 합니다. 이 경우 pTo에 할당된 문자열에만 포함됩니다. 콘솔 애플리케이션이므로 FOF_SILENT, FOF_NOCONFIRMATION 및 FOF_NOCONFIRMMKDIR 플래그가 표시될 수 있는 대화 상자를 표시하지 않도록 설정됩니다. SHFileOperation이 반환되면 SHChangeNotify가 호출되어 셸에 변경 사항을 알립니다. 그런 다음, 애플리케이션은 일반적인 정리를 수행하고 를 반환합니다.
Shell은 각 사용자에 대해 최근에 추가되거나 수정된 문서 목록을 유지 관리합니다. 사용자는 시작 메뉴에서 문서를 클릭하여 이러한 파일에 대한 링크 목록을 표시할 수 있습니다. 내 문서와 마찬가지로 각 사용자에게는 실제 링크를 저장할 파일 시스템 디렉터리가 있습니다. 현재 사용자의 최근 디렉터리의 PIDL을 검색하기 위해 애플리케이션은 CSIDL_RECENT 사용하여 SHGetFolderLocation 을 호출하거나 SHGetFolderPath 를 호출하여 해당 경로를 검색할 수 있습니다.
애플리케이션은 이 문서의 앞부분에서 설명한 기술을 사용하여 최근 폴더의 내용을 열거할 수 있습니다. 그러나 애플리케이션은 일반 파일 시스템 폴더인 것처럼 폴더의 내용을 수정해서는 안 됩니다. 이렇게 하면 셸의 최근 문서 목록이 제대로 업데이트되지 않으며 변경 내용이 시작 메뉴에 반영되지 않습니다. 대신 사용자의 최근 폴더에 문서 링크를 추가하려면 애플리케이션에서 SHAddToRecentDocs를 호출할 수 있습니다. 셸은 적절한 파일 시스템 폴더에 대한 링크를 추가하고 최근 문서 목록과 시작 메뉴를 업데이트합니다. 이 함수를 사용하여 폴더를 지울 수도 있습니다.