How to check if Directory already Exists in MFC(VC++)? - visual-c++

How to check if Directory already Exists in MFC(VC++) ?
I am using below code to get current application Path and there i am creating NDSLog folder
so that all my Logfiles should place there , now i want to check the condition if NDSLog folder already exists dont create it .How to do that ?
Thanks.
char strPathName[_MAX_PATH];
::GetModuleFileName(NULL, strPathName, _MAX_PATH);
// The following code will allow you to get the path.
CString newPath(strPathName);
int fpos = newPath.ReverseFind('\\');
if (fpos != -1)
newPath = newPath.Left(fpos+1);
newPath += "NDSLog\\" ;
CreateDirectory(newPath,NULL);

The simplest way to check if a file/directory exists is to use GetFileAttributes:
if (GetFileAttributes(newPath) == INVALID_FILE_ATTRIBUTES) {
CreateDirectory(newPath,NULL);
}
Note that the function will return INVALID_FILE_ATTRIBUTES even if it fails due to some other reason, such as not having permissions to access the file, so you should check the return value of CreateDirectory to make sure that it succeeded.
Actually, you don't need to check whether the directory already exists; CreateDirectory will set an error code if the directory already exists:
if (!CreateDirectory(newPath,NULL)) {
if (GetLastError() == ERROR_ALREADY_EXISTS) {
// directory already exists
} else {
// creation failed due to some other reason
}
}

How about PathIsDirectory()? In the original example, you can use PathRemoveFilespec() followed by PathCombine() to add a new filename/extension. In the unlikely case that your target is only Windows 8 or later, there are safer PathCch...() flavors of these functions.

I use PathFileExists.

FindFirstFile. Despite the "File" in the name, it'll find directories perfectly well.

You can use _accees or _waccess from C runtime.
This is the msdn page and you can see sample usage
And also you don't have to wory about if directory already exist because CreateDirectory checks and returns ERROR_ALREADY_EXISTS if exists. You can see from here (Return Codes).

I must note, that GetFileAttributes work slow when file is a network path.
Actually, it works slow for the first time, and fast afterwards.

Related

Create directory under local app data

I have application written in C/C++ and it needs to create a folder and file under the local app directory. When I call CreateDirectory the result is False and the directory is never created. What am I missing?
TCHAR szPath[MAX_PATH];
if (SUCCEEDED(SHGetFolderPath(NULL,CSIDL_LOCAL_APPDATA|CSIDL_FLAG_CREATE, NULL, 0, szPath)))
{
PathAppend(szPath,_T("\\FredDir\\backupfirmware\\"));
bool result = CreateDirectory(szPath, NULL);
}
As near as I can tell this should work.
CreateDirectory can't create several levels worth of directories at once. You need to create them one by one - first FredDir, then backupfirmware under that.

How to go back three steps from the path recieved by GetExecutingAssembly().Location

I want to go back three steps from the current Executing assembly so that I get the name of the folder present there. My requirement is not fulfilled by using ..\..\..\.
so suggest.
Thanks
Get path of executing assembly
Uri path = (new System.Uri(Assembly.GetExecutingAssembly().CodeBase));
Then you can do youre stuff (possible look at segment property) or add ......\ after the path
// get path and transform into FileInfo
FileInfo fi = new FileInfo(path.LocalPath);
// now you can go up with property Parent
var directory = fi.Directory.Parent;

UnauthorizedAccessException while scanning directory 'User\Documents\My Music'

Question: Why do I get this error while scanning a users 'My Documents' folder, but not when I scan the 'My Music/My Pictures/My Videos' directory?
Secondary, less important question: Is there a way to avoid this without having to specifically filter these folders out, or using a try/catch block?
I prefer answers that teach me how to fish, instead of just giving me fish. Just at this point I am not sure where I need to look to specifically answer this question. I've read through documents about elevating permissions and iterating through the file system, and spent a good week looking for why I can set DirectoryInfo on 'User\My Music' but not 'User\Documents\My Music'(link) and just would enjoy a little boost in a different direction in regards to learning more.
I catch the initial 'UnauthorizedAccessException' that is thrown initially when attempting Directory.GetFiles('path', "*", SearchOption.AllDirectories) where path is the users 'My Documents'. To handle the exception I know that I need to walk the directory manually. Which works, returning the files from the sub-directories.
The code for the initial GetFiles function:
public static string[] GetFiles(string path)
{
string[] files;
try
{
files = Directory.GetFiles(path, "*", SearchOption.AllDirectories);
}
catch(UnauthorizedAccessException ex)
{ files = WalkDirectory(path); }
return files;
}
public static string[] WalkDirectory(string path)
{
List<string> files = new List<string>();
DirectoryInfo dir = new DirectoryInfo(path);
foreach (DirectoryInfo subDir in dir.GetDirectories())
{
try
{
files.AddRange(WalkDirectory(subDir.FullName));
}
catch(UnauthorizedAccessException ex)
{
// complete fail to walk directory listed
throw ex;
}
}
foreach (FileInfo file in dir.GetFiles())
{
files.Add(file.FullName);
}
}
This works out perfectly, until the code attempts to walk the hidden folders: My Music, My Pictures, or My Videos. No matter how I try and re-code to walk the hidden files, I keep receiving the UnauthorizedAccessException.
I understand completely that I am going to code around this. Mainly what I am curious to know, is why is the exception happening under a users folder?
An asssumption I am making is that the folder is a symlink to another directory, because I can make the path ?:\users directory\user\My (Music, Pictures, or Videos) and the code walks those directories then without any issues. This only happens when trying to scan the directory files after setting them from within the users My Documents.
OS: Windows 7
User Privliages: Administrator
Application Elevated to run as administrator
I was speaking about this with a friend, who is not technical, but knows enough tech to hold a conversation and he helped me narrow this question down further. This is actually a duplicate question and was answered at Check if a file is real or a symbolic link.
The folder is a symbolic link that was placed there for backwards compatibility purposes according to this article on TechRepublic: Answers to some common questions about symbolic links under the section Windows Vista and Windows 7 have built-in symbolic links paragraph 2.
In order to specifically avoid attempting to scan this directory without a Try/Catch block on an UnauthorizedAccessException the folder attributes need to be checked to determine if the folder or file in question is a symbolic link. Which again was answered in the above listed stackoverflow question.

Jake: directory-tasks function not working?

Jake's documentation states that directory-tasks create a directory for use with for file-tasks. Jake checks for the existence of the directory, and only creates it if needed.
Example:
desc('This creates the bar directory for use with the foo-minified.js file-task.');
directory('bar');
I have not been able to get this to work inside or outside of a file-task. Anyone know what I'm doing wrong?
I was running Node v0.5.0-pre and updated to v0.6.6. Still no luck. I've filed an official ticket, but see if anyone knows if I've just been using it wrong.
In the meantime I just wrote and am using:
/* Checks if directory exists, creates if needed with optional created callback. */
function directory(dir, callback){
if (!path.existsSync(dir)){
console.log(dir + " folder doesn't exist. Creating...");
fs.mkdirSync(dir);
if (callback){
callback(dir);
}
}
}

While parsing into a root folder how can I distinguish the upcoming is whether a file or a folder in C language?

I want to parse through a root folder which is entered by the user by using multi threading and multi processing at different versions.But how can I distinguish while I am parsing through a root folder whether the next is a folder or a file?To summarize I want to learn how I can distinguish the upcoming is a file or a folder.I wanna learn this because if it is a folder then I let opening this folder to a dynamically thread and/or process.If it is a file the existing thread or process can continue its work without any necessarity to create any different thread and/or process.I hope I can express my problem.I am waiting your answers.Thank you.
You can check whether a path refers to a file or directory using the stat() function, and checking the st_mode field on the returned structure (see http://pubs.opengroup.org/onlinepubs/009695399/basedefs/sys/stat.h.html).
On Windows, you can use GetFileAttributesEx to get the file attributes, which you can check to see if it is a file or a directory.
Note that whatever you use may be subject to a race condition if the file system is being updated by another thread or process at the same time, as the file/directory may be deleted and/or changed after you checked it and before you access it.
Here are some quick samples. It will be up to you to thread from multiple root locations, call these recursively, and sync all the data.
Under *nix systems;
struct dirent *entry;
while ((entry = readdir("/root")) != NULL)
{
if (entry->d_type == DT_DIR)
{
// do something
}
}
closedir(dir);
Under Windows:
WIN32_FIND_DATA findData;
HANDLE hFind = FindFirstFile(("C:\\root" + "*.*").c_str(), &findData);
do
{
if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
// do something
}
} while (FindNextFile(hFind, &findData));
FindClose(hFind);

Resources