Hypercell ein ] Hypercell aus ] Zeige Navigation ] Verstecke Navigation ]
c++.de  
   

Die mobilen Seiten von c++.de:
http://m.c-plusplus.de
Infos hier [BETA]

  
c++.de :: WinAPI ::  .ini Dateien unter Win7     Zeige alle Beiträge auf einer Seite Auf Beitrag antworten
Autor Nachricht
Alberich
Mitglied

Benutzerprofil
Anmeldungsdatum: 28.01.2011
Beiträge: 56
Beitrag Alberich Mitglied 17:55:34 29.07.2012   Titel:   .ini Dateien unter Win7            Zitieren

Hallo zusammen! Hoffe meine Frage ist hier im richtigen Subforum gelandet...

Ich habe ein kleines Programm geschrieben welches beim Start eine .ini Datei zeilenweise einliest und so ein paar Parameter für den Programmstart bekommt. Das sieht ungefähr so aus:

C++:
1
2
3
4
5
6
7
8
9
10
11
            std::ifstream CONF;
            CONF.open("startup.ini");
            if(CONF)
            {
               //Inhalt der Datei startup.ini einlesen
               CONF.close();
            }
            else
            {
               MessageBox(NULL, "Error!\n\nstartup.ini not found\nloading default values", "Testprogram", MB_OK);
            }


Die Datei startup.ini liegt natürlich im gleichen Verzeichnis wie das Programm. Das funktioniert soweit auch ganz gut (WinXP), jedoch berichtet mir ein Freund dass dieses Programm unter Win7 die .ini Datei nicht öffnen kann (die Messagebox erscheint). Dieser Freund berichtet mir auch dass er die .ini Datei nicht mit einem Doppelklick öffnen kann, Win7 sagt ihm dann dass er dafür nicht die nötige Berechtigung (oder so ähnlich) hat. Öfnnen der Datei aus einem Texteditor heraus funktioniert zwar, zum schnellen Editieren der Startwerte aber schon unpraktisch.
Kann es sein dass Win7 .ini Dateien besonders schützt? Ist im Grunde ja doch nur eine Text-Datei...

Alberich
..........
Unregistrierter




Beitrag .......... Unregistrierter 18:07:19 29.07.2012   Titel:              Zitieren

Stickwort UAC.
ehauser
Unregistrierter




Beitrag ehauser Unregistrierter 19:02:44 29.07.2012   Titel:              Zitieren

Nein es ist egal ob die Datei .ini oder sonstwas ist.Aber seit Windows Vista können Programme ohne Adminrechte nicht mehr in C:\Programme schreiben.
Alberich
Mitglied

Benutzerprofil
Anmeldungsdatum: 28.01.2011
Beiträge: 56
Beitrag Alberich Mitglied 20:56:16 29.07.2012   Titel:              Zitieren

OK, sowas hatte ich mir auch schon fast gedacht. Aber das Programm schreibt gar nicht in die .ini sondern soll sie nur beim Start lesen.
Das Programm also mit Adminrechten starten und nicht in die Programme-Ordner packen.

Vielen Dank!
Patrickssj6
Mitglied

Benutzerprofil
Anmeldungsdatum: 08.01.2012
Beiträge: 100
Beitrag Patrickssj6 Mitglied 00:03:36 30.07.2012   Titel:              Zitieren

Lass auch gleich am Besten das Programm Administrationsrechte anfordern :D
Martin Richter
Moderator

Benutzerprofil
Anmeldungsdatum: 18.04.2006
Beiträge: 14217
Beitrag Martin Richter Moderator 08:13:44 30.07.2012   Titel:              Zitieren

Ich würde mal sagen, dass Du nicht davon ausgehen, dass das aktuelle Verzeichnis Dein Programmverzeichnis ist. Deshalb wird die Datei nicht gefunden.

Verwende einen vollen Pfad und ermittle das Programmverzeihcnis mit GetModuleFilename

_________________
Martin Richter (MVP für C++) WWJD http://blog.m-ri.de
"A well-written program is its own heaven; a poorly written program is its own hell!" The Tao of Programming
Scorcher24
Mitglied

Benutzerprofil
Anmeldungsdatum: 29.12.2004
Beiträge: 2361
Beitrag Scorcher24 Mitglied 12:08:25 30.07.2012   Titel:              Zitieren

Alberich schrieb:
OK, sowas hatte ich mir auch schon fast gedacht. Aber das Programm schreibt gar nicht in die .ini sondern soll sie nur beim Start lesen.
Das Programm also mit Adminrechten starten und nicht in die Programme-Ordner packen.


NEIN!
Machs richtig.
Lass dir von der WinAPI den %apppath% Ordner geben und erstelle dort einen eigenen Ordner mit deinen Einstellungsdateien.
Beispielcode aus einem Programm von mir:

C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
namespace fs = boost::filesystem;

#ifdef WIN32

#   include <direct.h>
#   include <shlobj.h>
#   include <winerror.h>
#endif /* WIN32 */

#ifdef WIN32

    static const char NLPathSep = '\\';
#else
    static const char NLPathSep = '/';
#endif /* WIN32 */
 
void SystemController::findUserDataDir()
{
   #ifdef WIN32    
        char dir[MAX_PATH];
        HRESULT hr = SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, SHGFP_TYPE_CURRENT, dir); // <- Hier wird nach %apppath% gefragt, wo Einstellungen hinsollten
        if ( hr == S_FALSE )
        {
            NLError("[SystemController] Critical Exception: Cannot find your Path to Application Data");
            throw Exception("[SystemController] Critical Exception: Cannot find your Path to Application Data", true);
        }
   #else
        char* dir = getenv("%home%");
   #endif // WIN32
 
    std::string r;
    if ( m_vendor.empty() )
    {
        r = std::string(dir) + NLPathSep + std::string(".") + this->getAppName() + NLPathSep;
    }
    else
    {
        r = std::string(dir) + NLPathSep + std::string(".") + this->getVendorName() + NLPathSep + this->getAppName() + NLPathSep;
    }
    m_userpath = r;
}
 
 
bool SystemController::createUserDataDir()
{
    if ( !fs::is_directory(this->getUserDataDir()) )
    {
        fs::create_directories(this->getUserDataDir());
        if ( fs::is_directory(this->getUserDataDir()))
        {
            NLTrace(std::string("UserData-Directory created on path '") + this->getUserDataDir() + "'");
            return true;
        }
        else
        {
            NLError(std::string("Could not create UserData-Directory on path '") + this->getUserDataDir() + "'");
            return false;
        }
    }
    return true; // Dir exists already
 
}
 
bool SystemController::userDataDirExists() const
{
    return fs::is_directory(this->getUserDataDir());
}


Ich finde es eine sehr schlechte Gewohnheit wenn man wegen fehlender Rechte einfach nach diesen fragt obwohl man sie nicht braucht. Dateien die vom Nutzer modifiziert werden, gehören nach My Documents oder in den AppPath.

_________________
Sometimes it pays to stay in bed in Monday, rather than spending the rest of the week debugging Monday's code. ~Dan Salomon
Meine Projekte


Zuletzt bearbeitet von Scorcher24 am 12:10:38 30.07.2012, insgesamt 1-mal bearbeitet
hustbaer
Mitglied

Benutzerprofil
Anmeldungsdatum: 27.10.2006
Beiträge: 16252
Beitrag hustbaer Mitglied 13:18:21 30.07.2012   Titel:              Zitieren

Scorcher24 schrieb:
Ich finde es eine sehr schlechte Gewohnheit wenn man wegen fehlender Rechte einfach nach diesen fragt obwohl man sie nicht braucht. Dateien die vom Nutzer modifiziert werden, gehören nach My Documents oder in den AppPath.

:live:
Danke

_________________
"Let there be Licht..." http://lichttools.sourceforge.net/
Sehr cooles ASCII Spiel (leider nicht von mir): ASCII-Scramble - http://www.roskakori.at/ascii/
-guest-
Unregistrierter




Beitrag -guest- Unregistrierter 14:31:14 30.07.2012   Titel:              Zitieren

@Scorcher24 und hustbaer
Grundsätzlich vollkommen korrekt ;)

Nur:
Zitat:
Aber das Programm schreibt gar nicht in die .ini sondern soll sie nur beim Start lesen.
Laut dieser Aussage könnte es sich z.B. um eine Konfigurationsdatei handeln, die vom Installer erstellt wird und Grundeinstellungen zum Start beinhaltet.

Auf programmspezifische Dateien ohne Pfadangabe zuzugreifen, wie Martin Richter es schon sagte, geht meistens in die Hose.
hustbaer
Mitglied

Benutzerprofil
Anmeldungsdatum: 27.10.2006
Beiträge: 16252
Beitrag hustbaer Mitglied 16:28:03 30.07.2012   Titel:              Zitieren

-guest- schrieb:
Nur:
Zitat:
Aber das Programm schreibt gar nicht in die .ini sondern soll sie nur beim Start lesen.
Laut dieser Aussage könnte es sich z.B. um eine Konfigurationsdatei handeln, die vom Installer erstellt wird und Grundeinstellungen zum Start beinhaltet.

Stimmt, ja. Dann gibt es erst recht keinen Grund Admin-Rechte zu verlangen.
Einfach den korrekten Pfad ermitteln (GetModuleFilename, hat Martin Richter ja schon geschrieben), und aufmachen.

Die mMn. wichtigen Punkte hier sind:
* Keine Admin-Rechte verlangen wenn nicht nötig
* Wenn man Einstellungen/... schreiben will, dann im passenden Verzeichnis (-> AppData)

_________________
"Let there be Licht..." http://lichttools.sourceforge.net/
Sehr cooles ASCII Spiel (leider nicht von mir): ASCII-Scramble - http://www.roskakori.at/ascii/
Alberich
Mitglied

Benutzerprofil
Anmeldungsdatum: 28.01.2011
Beiträge: 56
Beitrag Alberich Mitglied 19:44:24 30.07.2012   Titel:              Zitieren

Vielen Dank für die vielen hilfreichen Antworten!

Es ist also, wenn ich das jetzt richtig verstanden habe, nicht notwendig (und "unschön") nach Adminrechten für das Programm zu verlangen. OK.

Jetzt muss ich mir also beim Programmstart den Pfad ins aktuelle Verzeichnis besorgen. Das Testprogramm sieht jetzt so aus:

C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
TCHAR EXEPath[MAX_PATH + 1];
DWORD nChars = GetModuleFileName( NULL, EXEPath, MAX_PATH + 1 );
//EXEPath enthält jetzt den Pfad inklusive Dateiname der exe
 
 
//hier mache ich nen std::string draus um auf die Konsole auszugeben
std::string strPath;
strPath.assign(&EXEPath[0], &EXEPath[nChars]);
std::cout<<"\n"<<strPath;
 
std::ifstream CONF;
CONF.open("startup.ini");
if(CONF)
{
    //Inhalt der Datei startup.ini einlesen
    CONF.close();
}
else
{
    std::cout<<"\nstartup.ini not found";
}


Die Ausgabe auf der Konsole ist jetzt wie erwartet

D:\EigeneProgramme\Test\bin\Debug\Testprogramm.exe

Hier muss ja nun noch der Dateiname entfernt und statt dessen der Name der .ini Datei (startup.ini) angefügt werden.
Gibt es für char-Arrays so etwas wie substring(pos_begin, pos_end) und find_last_of() für strings um den Dateinamen der exe abschneiden zu können?

Alberich
-guest-
Unregistrierter




Beitrag -guest- Unregistrierter 20:12:22 30.07.2012   Titel:              Zitieren

Das geht u.a. mit GetFullPathName (http://msdn.microsoft.com/en-us/library/windows/desktop/aa364963%28v=vs.85%29.aspx)
geeky
Mitglied

Benutzerprofil
Anmeldungsdatum: 04.05.2001
Beiträge: 6204
Beitrag geeky Mitglied 21:32:15 30.07.2012   Titel:              Zitieren

Mit PathRemoveFileSpec kann man den Dateinamen entfernen ;D
hustbaer
Mitglied

Benutzerprofil
Anmeldungsdatum: 27.10.2006
Beiträge: 16252
Beitrag hustbaer Mitglied 21:38:28 30.07.2012   Titel:              Zitieren

Alberich schrieb:
Hier muss ja nun noch der Dateiname entfernt und statt dessen der Name der .ini Datei (startup.ini) angefügt werden.

Japp.
Zitat:
Gibt es für char-Arrays so etwas wie substring(pos_begin, pos_end) und find_last_of() für strings um den Dateinamen der exe abschneiden zu können?

Nö. Aber es gibt ja std::string. Willst du std::string aus irgend einem Grund dafür nicht verwenden?

Ansonsten...
PathRemoveFileSpec EDIT: zu langsam *grmpf* /EDIT

C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <windows.h>
#include <shlwapi.h> // für PathRemoveFileSpec

#pragma comment(lib, "shlwapi.lib") // für PathRemoveFileSpec

 
// ...
 
    // TODO: check for errors
 
    TCHAR exeDirectory[MAX_PATH] = {}; // + 1 brauch ma nicht. Das = {} auch nicht, aber naja... hab's mir irgendwann angewöhnt so-gut-wie immer alles zu initialisieren.
                                       // Da hier nicht Performance-kritisch schadet es auch nicht.
    GetModuleFileName(NULL, exeDirectory, MAX_PATH);
    PathRemoveFileSpec(exeDirectory);  // Macht Filenamen inklusive dem letzten "\" weg (modifiziert direkt den übergebenen Puffer)
 
    // Wenn schon TCHAR dann auch bei std::basic_string, sonst kompiliert das ja nichtmal mit UNICODE
    // (ggf. irgendwo in nem .h File ein nettes  typedef std::basic_string<TCHAR> tstring;  machen)
    std::basic_string<TCHAR> configFilePath = std::basic_string<TCHAR>(exeDirectory) + _T("\\startup.ini");
 
    std::ifstream configFile(configFilePath.c_str()); // geht auch ohne extra .open() Zeile
    if (configFile)
    {
        // Inhalt der Datei startup.ini einlesen
        // configFile.close(); // kümmert sich der Destruktor drum, und bei ausschliesslich lesenden Zugriffen ist das auch vollkommen OK
    }
    else
    {
        std::cout<<"\nstartup.ini not found";
    }


Bitte die ganzen zusätzlichen Anmerkungen nicht falsch verstehen. Wenns dich nicht interessiert überlies es einfach, falls doch hast du ein paar Tips was du besser/anders machen kannst.

_________________
"Let there be Licht..." http://lichttools.sourceforge.net/
Sehr cooles ASCII Spiel (leider nicht von mir): ASCII-Scramble - http://www.roskakori.at/ascii/


Zuletzt bearbeitet von hustbaer am 21:40:41 30.07.2012, insgesamt 1-mal bearbeitet
Alberich
Mitglied

Benutzerprofil
Anmeldungsdatum: 28.01.2011
Beiträge: 56
Beitrag Alberich Mitglied 10:04:48 31.07.2012   Titel:              Zitieren

hustbaer schrieb:
Bitte die ganzen zusätzlichen Anmerkungen nicht falsch verstehen. Wenns dich nicht interessiert überlies es einfach, falls doch hast du ein paar Tips was du besser/anders machen kannst.
Ganz im Gegenteil! Ich bin dankbar für jede Hilfe und Anmerkung! Dein Codebeispiel finde ich sehr lehrreich, leider spielt der Compiler/Linker nicht mit:

Zeile 4: warning: ignoring #pragma comment
Zeile 13: undefined reference to `_imp__PathRemoveFileSpecA@4'


Ich verwende Code::Blocks (10.05).
Oberon_0
Mitglied

Benutzerprofil
Anmeldungsdatum: 08.04.2010
Beiträge: 86
Beitrag Oberon_0 Mitglied 10:30:49 31.07.2012   Titel:              Zitieren

#pragma comment(lib, "shlwapi.lib") führt bei MS Visual C++ dazu, dass die "shlwapi.lib", die PathRemoveFileSpec enthält automatisch zu deinem Programm gelinkt wird. Bei CodeBlocks musst du sie wohl in den (Projekt-)Einstellungen eintragen.
Scorcher24
Mitglied

Benutzerprofil
Anmeldungsdatum: 29.12.2004
Beiträge: 2361
Beitrag Scorcher24 Mitglied 10:33:04 31.07.2012   Titel:              Zitieren

gcc kann mittlerweile afaik das #pragma :).

_________________
Sometimes it pays to stay in bed in Monday, rather than spending the rest of the week debugging Monday's code. ~Dan Salomon
Meine Projekte
Alberich
Mitglied

Benutzerprofil
Anmeldungsdatum: 28.01.2011
Beiträge: 56
Beitrag Alberich Mitglied 10:55:36 31.07.2012   Titel:              Zitieren

OK, werd ich mir anschauen. Danke!

Habe noch ein bischen über das "Problem" nachgedacht und dieser Satz von hustbaer hat mich in die (hoffentlich :) ) richtige Richtung geschubst:

hustbaer schrieb:
[...] Aber es gibt ja std::string. Willst du std::string aus irgend einem Grund dafür nicht verwenden?
Es ist ja eigentlich schon alles da was ich brauche...

C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
TCHAR EXEPath[ MAX_PATH ];
DWORD nChars = GetModuleFileName( NULL, EXEPath, MAX_PATH );
 
//in einen string schreiben
std::basic_string<TCHAR> strPath;
strPath.assign( &EXEPath[0], &EXEPath[nChars] );
//den Namen der .exe abschneiden
strPath=strPath.substr( 0, strPath.find_last_of(_T("/\\")) );
//den Namen der .ini stattdessen anfügen
strPath=strPath + _T("\\startup.ini");
 
//und wieder einen C-string draus machen
std::ifstream configFile( strPath.c_str() );
if(configFile)
{
    //lesen
    //configFile.close(); //Aber schaden würde das explizite schliessen auch nicht, oder doch?
}


Gibt es gegen diese Lösung Einwände?


Alberich


Zuletzt bearbeitet von Alberich am 11:03:41 31.07.2012, insgesamt 1-mal bearbeitet
Swordfish
Mitglied

Benutzerprofil
Anmeldungsdatum: 27.03.2005
Beiträge: 4335
Beitrag Swordfish Mitglied 10:59:52 31.07.2012   Titel:              Zitieren

//edit: Chupa Chups, LLLLösch mich!


Zuletzt bearbeitet von Swordfish am 11:04:49 31.07.2012, insgesamt 2-mal bearbeitet
Swordfish
Mitglied

Benutzerprofil
Anmeldungsdatum: 27.03.2005
Beiträge: 4335
Beitrag Swordfish Mitglied 11:03:40 31.07.2012   Titel:              Zitieren

Alberich schrieb:
C++:
std::basic_string<TCHAR> strPath;
strPath.assign( &EXEPath[0], &EXEPath[nChars] );

Warum nicht gleich

C++:
[cpp]std::basic_string<TCHAR> strPath( EXEPath );

?
Alberich
Mitglied

Benutzerprofil
Anmeldungsdatum: 28.01.2011
Beiträge: 56
Beitrag Alberich Mitglied 11:08:51 31.07.2012   Titel:              Zitieren

In der Kürze liegt die Würze! :)
Danke für den Hinweis, ich wusste nicht dass man das auch so zuweisen kann!
c++.de :: WinAPI ::  .ini Dateien unter Win7   Auf Beitrag antworten

Zeige alle Beiträge auf einer Seite




Nächstes Thema anzeigen
Vorheriges Thema anzeigen
Sie können Beiträge in dieses Forum schreiben.
Sie können auf Beiträge in diesem Forum antworten.
Sie können Ihre Beiträge in diesem Forum nicht bearbeiten.
Sie können Ihre Beiträge in diesem Forum nicht löschen.
Sie können an Umfragen in diesem Forum nicht mitmachen.

Powered by phpBB © 2001, 2002 phpBB Group :: FI Theme

c++.de ist Teilnehmer des Partnerprogramms von Amazon Europe S.à.r.l. und Partner des Werbeprogramms, das zur Bereitstellung eines Mediums für Websites konzipiert wurde, mittels dessen durch die Platzierung von Werbeanzeigen und Links zu amazon.de Werbekostenerstattung verdient werden kann.

Die Vervielfältigung der auf den Seiten www.c-plusplus.de, www.c-plusplus.info und www.c-plusplus.net enthaltenen Informationen ohne eine schriftliche Genehmigung des Seitenbetreibers ist untersagt (vgl. §4 Urheberrechtsgesetz). Die Nutzung und Änderung der vorgestellten Strukturen und Verfahren in privaten und kommerziellen Softwareanwendungen ist ausdrücklich erlaubt, soweit keine Rechte Dritter verletzt werden. Der Seitenbetreiber übernimmt keine Gewähr für die Funktion einzelner Beiträge oder Programmfragmente, insbesondere übernimmt er keine Haftung für eventuelle aus dem Gebrauch entstehenden Folgeschäden.