Fehler bei CreateDirectory

gabifi

Mitglied
Kann es sein, dass man mit der Funktiopn CreateDirectory nur Ordner erstellen kann, die sich schon in inem existierenden befinden.

Will sagen,
Code:
CreateDirectory("c:\\neu",NULL)
funktioniert, da es ja den Ordner c:\ schon gibt.

Möchte ich jedoch
Code:
CreateDirectory("c:\\neu\\Unterordner",NULL)
dann tut sich nichts.

Weiß dann jemand, wie ich einen beliebeigen Ordner erstellen kann, ganz egal wo er liegen soll.
Danke
Gabriel
 
Du kannst immer nur einen Ordner auf einmal anlegen. Willst du mehrere auf einmal anlegen, musst du das Ordner für Ordner machen.

Hier ein Bleistift aus meinen Utility-Sourcen:

Code:
bool CWinUtils::CreateSubDir( const std::string& strSubDir )
{

  int             i;

  std::string     strDest,
                  strTempPath;


  strDest = strSubDir;

  char            szOldPath[MAX_PATH];

  GetCurrentDirectory( MAX_PATH, szOldPath );

  i = 0;
  strTempPath = "";
  while ( strDest[i] )
  {
    strTempPath += strDest[i];

    if ( ( i >= 3 )       // Sonst gibt´s Probleme mit dem Laufwerk
    &&   ( ( strDest[i + 1] == 92 )
    ||     ( i + 1 == strDest.length() ) ) )
    {
      // Wir haben ein weiteres Unterverzeichnis entdeckt
      if ( ( strTempPath.length() )
      &&   ( strTempPath[0] == '\"' ) )
      {
        strTempPath = strTempPath.substr( 1 );
      }
      if ( ( strTempPath.length() )
      &&   ( strTempPath[strTempPath.length() - 1] == '\"' ) )
      {
        strTempPath = strTempPath.substr( 0, strTempPath.length() - 1 );
      }
      if ( !SetCurrentDirectory( strTempPath.c_str() ) )
      {
        // Verzeichnis existiert also noch nicht
        if ( !CreateDirectory( strTempPath.c_str(), NULL ) )
        {
          // Konnte Verzeichnis nicht anlegen, Hurra
          dh::Log( "CWinUtils::CreateSubDir  Failed to create directory %s (%x)", strTempPath.c_str(), GetLastError() );

          SetCurrentDirectory( szOldPath );
          // BAUSTELLE
          // Angelegte Verzeichnisse wieder killen
          return false;
        }
      }
      else
      {
        // Mitloggen, falls wir abbrechen müssen
      }
    }
    i++;
  }

  SetCurrentDirectory( szOldPath );
  return true;

}
 
Sowas hatte ich schon befürchtet.

Würde deinen Code ganz gern benutzen, kannst du mir dafür verraten wir ich einen CString in std::string bekommen, den Pfad hab ich nämlich nur in einem CString-Objekt.
Wär ein Traum.
Gabriel
 
Ich hab' hier ne MFC-Version davon, da ich das auch öfter brauche:
Code:
//CreateDirectoryTree

DWORD CreateDirectoryTree(CString cstrNewDir, LPSECURITY_ATTRIBUTES lpSecurityAttributes)
{
	DWORD dwRetVal = 0;
	int iIndex, iStart = 0;
	CString cstrActPath, cstrLastExisting, cstrFirstCreated;

	cstrNewDir.TrimRight('\\');

	iIndex = cstrNewDir.Find('\\');
	while(iIndex != -1)
	{
		cstrActPath = cstrNewDir.Left(iIndex);
		if(!PathFileExists(cstrActPath))
		{
			if(!CreateDirectory(cstrActPath, lpSecurityAttributes))
			{
				dwRetVal = GetLastError();
				if(!cstrFirstCreated.IsEmpty())
				{
					RemoveDirectoryTree(cstrLastExisting, cstrFirstCreated);
				}
				break;
			}
			else if(cstrFirstCreated.IsEmpty())
				cstrFirstCreated = cstrActPath.Mid(cstrActPath.ReverseFind('\\'));
		}
		else
			cstrLastExisting = cstrActPath;
		iStart = iIndex + 1;
		iIndex = cstrNewDir.Find('\\', iIndex + 1);
	}
	if(dwRetVal == 0)
	{
		cstrActPath = cstrNewDir;
		if(!PathFileExists(cstrActPath))
		{
			if(!CreateDirectory(cstrActPath, lpSecurityAttributes))
			{
				dwRetVal = GetLastError();
				if(!cstrFirstCreated.IsEmpty())
				{
					RemoveDirectoryTree(cstrLastExisting, cstrFirstCreated);
				}
			}
		}
		else
			cstrLastExisting = cstrActPath;
	}
	return dwRetVal;
}

//RemoveDirectoryTree
DWORD RemoveDirectoryTree(CString cstrBaseDir, CString cstrRemoveDir)
{
	DWORD dwRetVal = 0;
	BOOL bOK;
	CString cstrActPath, cstrSearch, cstrFileName;
	WIN32_FIND_DATA FindFileData;
	HANDLE hFind;

	if(cstrBaseDir.Right(1) != "\\")
		cstrBaseDir += '\\';

	cstrRemoveDir.TrimRight('\\');
	cstrRemoveDir.TrimLeft('\\');

	cstrActPath = cstrBaseDir + cstrRemoveDir;
	if(!PathFileExists(cstrActPath))
	{
		return ERROR_PATH_NOT_FOUND;
	}

	cstrSearch = cstrActPath + "\\*";
	hFind = FindFirstFile(cstrSearch, &FindFileData);
	if(hFind != INVALID_HANDLE_VALUE)
	{
		cstrFileName = FindFileData.cFileName;
		if((cstrFileName != ".") && (cstrFileName != ".."))
		{
			if(FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
			{
				RemoveDirectoryTree(cstrActPath, FindFileData.cFileName);
			}
			else
			{
				::DeleteFile(FindFileData.cFileName);
			}
		}
		while(FindNextFile(hFind, &FindFileData))
		{
			cstrFileName = FindFileData.cFileName;
			if((cstrFileName != ".") && (cstrFileName != ".."))
			{
				if(FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
				{
					RemoveDirectoryTree(cstrActPath, FindFileData.cFileName);
				}
				else
				{
					::DeleteFile(FindFileData.cFileName);
				}
			}
		}
		FindClose(hFind);
	}
	bOK = RemoveDirectory(cstrActPath);
	if(!bOK)
	{
		dwRetVal = GetLastError();
	}

	return dwRetVal;
}
 
Vielen Herzlichen Dank, hat mir einiges an Arbeit erspart.
Wieso gibts da eigentlich keine vorgefertigten Funktionen dafür, immerhin gibts ja schon die CreateDirectory.
 
Ja, ja. Fragen über Fragen über die Mysterien dieser Welt.... Und keine Antworten!
[MECKERMODE ON]
Aber ehrlich, ich hab' mich genauso geärgert und dann die 2 Funktionen geschrieben. Ich dachte auch erst, für eine solche Allerweltsanwendung müßte es schon was geben, aber Pustekuchen. Was mich ähnlich ärgert ist, daß es in der CString-Klasse keine Methoden zur Behandlung von Dateinamen gibt. Auch das ist eine Sache, die man ziemlich häufig machen muß (Erweiterung extrahieren oder ersetzen, Pfadd extrahieren, und und und...)
Bei der Erstellung der MFC haben sie halt nur stur das SDK in Klassen gekapselt, ohne darüber nachzudenken, ob man vielleicht was besser machen könnte.
[MECKERMODE OFF]
 
Zurück