简体   繁体   中英

How to tell if a folder is a subfolder of a special Windows folder?

If I have a CSIDL (or its newer alternative KNOWNFOLDERID ) for a special folder (for the sake of this example, let's assume My Documents folder) and a DOS folder path , is there any way to tell that the path refers to a subfolder within the special folder?

EDIT 1: I implemented the following method after @RemyLebeau's suggestion , but it always sets my nIsParent to 0, or not a parent . What am I missing there?

int nCSIDL = CSIDL_PERSONAL;
LPCTSTR pDosPath = L"C:\\Users\\UserName\\Documents\\Subfolder1\\File.txt";

int nIsParent = -1; //-1=error, 0=no, 1=yes

LPITEMIDLIST pidlDocuments = NULL;
if(SUCCEEDED(SHGetFolderLocation(NULL, nCSIDL, NULL, 0, &pidlDocuments)))
{
    LPITEMIDLIST pidl = ILCreateFromPath(pDosPath);
    if(pidl)
    {
        nIsParent = ILIsParent(pidlDocuments, pidl, FALSE) ? 1 : 0;

        ILFree(pidl);
    }

    ILFree(pidlDocuments);
}

EDIT 2: As for his 2nd suggestion to use SHGetPathFromIDList and then PathRelativePathTo on both DOS paths, it won't work for the following: My Documents on my computer is redirected to "\\\\SRVR-A\\Home\\UserName\\Documents" , which is also the "R:\\Documents" folder with drive R: mapped to that Home share. PathRelativePathTo fails on those paths.

EDIT 3: If I had a folder Test folder in My Documents I could do this using my mapped drive R: :

subst S: "R:\Documents\Test folder"

Which will technically make folder "S:\\Test folder" a parent of My Documents as well, which is "\\\\SRVR-A\\Home\\UserName\\Documents\\Test folder" .

That is why I was looking for a Shell-only, or a single API solution.

Everything in the Shell is represented by the ITEMIDLIST structure, even file system paths. Retrieve the ITEMIDLIST of the special folder using SHGetFolderLocation() or SHGetKnownFolderIDList() , then retrieve the ITEMIDLIST of the DOS path using SHParseDisplayName() or ILCreateFromPath() , then use ILIsParent() to check if the special folder's ITEMIDLIST is a parent of the DOS path's ITEMIDLIST .

Alternatively, retrieve the special folder's path using SHGetFolderPath() or SHGetKnownFolderPath() , then use PathRelativePathTo to check if the DOS path can be represented as a relative subfolder of the special folder's path without using any ".." components.

Create a function that gets a full path, name of the special folder, and just call strstr on the full path with the name of the special folder and if it does not return NULL then it is a subfolder.

As for an API for it, I'm not aware of something like that but it could be possible.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM