Forum: PC-Programmierung [C++] Personal Folder + Verzeichnis erstellen


von Tobi (Gast)


Lesenswert?

Hallo,

ich möchte gerne unter Windows mit C++ in dem Dokumenteordner des 
aktuellen Benutzers ein Verzeichnis anlegen. Den Ordner auslesen habe 
ich bereits geschafft mit:
1
LPWSTR basePath;
2
3
SHGetFolderPath(NULL, CSIDL_PERSONAL, NULL, SHGFP_TYPE_DEFAULT, basePath);

Um dann zu testen ob es das Verzeichnis schon gibt habe ich die Funktion 
GetFileAttributesA gefunden. Problem dabei ist, dass die Funktion einen 
LPCSTR erwartet, ich aber nur einen LPWSTR habe. Ich habe weder Ahnung 
was das überhaupt seien soll, noch wie ich LPWSTR in LPCSTR konvertiere.


Hier einmal ein C# Code für das was ich genau will:
1
string basePath = Environment.GetFolderPath(Environment.SpecialFolder.Personal).ToString() + @"\<SoftwareName>";
2
3
if (!Directory.Exists(basePath))
4
{
5
    Directory.CreateDirectory(basePath);
6
}

~Tobi

von Sven P. (Gast)


Lesenswert?

Das ist feinster Windows-Schwachsinn, angefangen bei der total falsch 
verstandenen ungarischen Notation bis hin zum Ansi/Wchar-Clusterf***.

SHGetFolderPath erwartet keinen LPWSTR, sondern einen LPTSTR, das ist 
ein kleiner, aber sehr wichtiger Unterschied.

Du hast folgende Möglichkeiten:
. GetFileAttributesW und SHGetFolderPathW benutzen mit LPWSTR,
. GetFileAttributesA und SHGetFolderPathA benutzen mit LPSTR oder
. GetFileAttributes und SHGetFolderPath benutzen mit LPTSTR.

von Tobi (Gast)


Lesenswert?

Danke für die schnelle Antwort. Würde das jetzt gerne Testen aber QT hat 
soeben beschlossen keine moc_xxxx.cpp Datei mehr zu erstellen und somit 
kann ich mein Projekt nicht mehr übersetzen.

Ich bin froh, wenn ich wieder C# programmieren darf. Seitdem ich C++ 
benutzen muss ärgere ich mich fast täglich mit irgendwelchen 
Bibliotheken rum...

von Sven P. (Gast)


Lesenswert?

Wegen Qt: Mit fast absoluter Sicherheit hast du irgendwo eine 
Abhängigkeit verbockt. Also von QObject abgeleitet und das 
Q_OBJECT-Makro vergessen oder das Projekt verändert und vergessen, qmake 
aufzurufen.

Aber wenn du doch schon Qt verwendest, weshalb zum Teufel schlägst du 
dich dann noch mit dem Windows-API-Murks herum?!

QDir::mkdir erzeugt ein Verzeichnis und über QDesktopServices kommst du 
an die benutzerspezifischen Verzeichnisse heran.

von Tobi (Gast)


Lesenswert?

Sven P. schrieb:
> Wegen Qt: Mit fast absoluter Sicherheit hast du irgendwo eine
> Abhängigkeit verbockt. Also von QObject abgeleitet und das
> Q_OBJECT-Makro vergessen oder das Projekt verändert und vergessen, qmake
> aufzurufen.

Zwischen "läuft" und "läuft nicht" lagen nur Änderungen an der GUI 
mittels Designer und ein paar Zeilen im Konstruktor der GUI Klasse, die 
mittlerweile wieder auskommentiert sind. qmake rufe ich garnicht auf. 
Ich click in Visual Studio auf "erstellen".

Sven P. schrieb:
> Aber wenn du doch schon Qt verwendest, weshalb zum Teufel schlägst du
> dich dann noch mit dem Windows-API-Murks herum?!

Weil ich keine Ahnung von QT, WinAPI usw. habe. Generell hab ich noch 
nicht viel mit C++ gemacht.

Sven P. schrieb:
> QDir::mkdir erzeugt ein Verzeichnis und über QDesktopServices kommst du
> an die benutzerspezifischen Verzeichnisse heran.

Danke für den Tip. Ich werds mir angucken, sobald ich das Projekt wieder 
übersetzen darf.


Wenn ich "Projektmappe neu erstellen" ausführe, dann bekomme ich den 
Fehler mit der fehlenden moc-Datei. Wenn ich nur "Projektmappe 
erstellen" ausführe, bekomme ich:
>> Fehler  1  error MSB6006: "cmd.exe" wurde mit dem Code 1 beendet.
>> C:\Program Files\MSBuild\Microsoft.Cpp\v4.0\Microsoft.CppCommon.targets

von Sven P. (Gast)


Lesenswert?

Du betreibst ernsthaft Qt im Visual Studio? Na denn wundert mich nicht 
mehr viel.

Sorry, den Support für solch nen Käse kann ich nicht leisten :-)
Ich nutze weder Visual Studio noch Windows.

von Rolf Magnus (Gast)


Lesenswert?

Sven P. schrieb:
> QDir::mkdir erzeugt ein Verzeichnis und über QDesktopServices kommst du
> an die benutzerspezifischen Verzeichnisse heran.

Das Benutzerverzeichnis bekommt man als QDir per QDir::home() oder als 
QString per QDir::homePath().

von Sven P. (Gast)


Lesenswert?

Ja. Aber das Benutzerverzeichnis ist nicht das Verzeichnis, welches du 
mit SHGetFolderPath und CSIDL_PERSONAL bekommst.

von Rolf Magnus (Gast)


Lesenswert?

Ach so, dann hatte ich das wohl falsh verstanden.

von Tobi (Gast)


Lesenswert?

Das mit dem verzeichnis habe ich jetzt so gelöst:
1
QDir *basePath;
2
QString basePathStr = QDesktopServices::storageLocation(QDesktopServices::DocumentsLocation) + "\\<SoftwareName>;
3
  
4
basePath = new QDir(basePathStr);
5
6
if(!basePath->exists())
7
{
8
  if(!basePath->mkpath(basePath->path()))
9
  {
10
    // Verzeichniss konnte nicht erstellt werden
11
  }
12
}

Um das Projekt zu erstellen habe ich es leider neu anlegen müssen. Den 
Fehler mit der moc-Datei kann ich mir immer noch nicht erklären, aber 
der andere wird wohl verursacht, wenn ich eine Headerdatei aus dem 
Projekt hinzufüge. Ich hab keine Ahnung warum, vor allem da es sich um 
eine Klasse handelt die aus dem Projekt eines Kollegen (welches für mich 
als Grundlage dient) kopiert ist. Wenn ich diese aus dem alten Projekt 
rausnehme wird auch dort wieder die moc-Datei erstellt.

Ich finde es auch verwirrend dass ich bei der Autovervollständigung jede 
eigene Headerdatei doppelt angezeigt bekomme. Irgendwas muss da doch 
faul sein...

von Rolf Magnus (Gast)


Lesenswert?

Tobi schrieb:
> basePath = new QDir(basePathStr);

Warum legst du das mit new an? Das ist bei QDir nicht nötig und lädt nur 
dazu ein, zu vergessen, es wieder freizugeben.

von Tobi (Gast)


Lesenswert?

Stimmt. Ich kann den Path ja auch einfach später mit setPath hinzufügen. 
basePath ist bei mir ein Attribut der Klasse und der Rest des Codes 
steht im Konstruktor. Aber geht ja auch mit normalen Objekten.

Ich bin es nicht gewöhnt echte Objekte zu haben. In anderen Sprachen 
benutzt man ja ausschließlich Pointer und nennt sie Referenzen (und 
verbietet Arithmetik auf den Pointern).

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.