简体   繁体   English

在没有注册表的情况下存储应用程序数据/设置的方法?

[英]Methods of storing application data/settings without the registry?

I need some methods of storing and getting data from a file (in WIN32 api c++ application, not MFC or .NET) 我需要一些从文件存储和获取数据的方法(在WIN32 API C ++应用程序中,而不是MFC或.NET)

eg saving the x, y, width and height of the window when you close it, and loading the data when you open the window. 例如,在关闭窗口时保存其x,y,宽度和高度,并在打开窗口时加载数据。

I have tried .ini files, with the functions -- WritePrivateProfileString and ReadPrivateProfileString/Int, but on MSDN it says 我已经尝试过.ini文件,其功能为WritePrivateProfileString和ReadPrivateProfileString / Int,但是在MSDN上它说

"This function is provided only for compatibility with 16-bit Windows-based applications. Applications should store initialization information in the registry." “提供此功能仅是为了与基于16位Windows的应用程序兼容。应用程序应在注册表中存储初始化信息。”

and when i tried on my Windows7 64bit machine to read a ini file, i got blue screen! 当我在Windows7 64位计算机上尝试读取ini文件时,出现蓝屏! (in debug mode with visual studio) OO (在Visual Studio的调试模式下)OO

I notice that most other application use XML to store data, but I don't have a clue how to read/write xml data in c++, are there any libraries or windows functions which will allow me to use xml data? 我注意到大多数其他应用程序都使用XML来存储数据,但是我不知道如何在c ++中读取/写入xml数据,是否有任何库或Windows函数可以使用xml数据?

Any other suggestions would be good too, thanks. 任何其他建议也将很好,谢谢。

There is nothing wrong with .ini files, the only problem with them is where to write them. .ini文件没有任何问题,它们的唯一问题是在哪里编写它们。 CIniFile from CodeProject is good enough class. CodeProject的CIniFile类足够好。 Ini file should be placed in %APPDATA%/<Name Of Your Application> (or %LOCALAPPDATA%\\<Same Name Here> , as described below). Ini文件应放置在%APPDATA%/<Name Of Your Application> (或%LOCALAPPDATA%\\<Same Name Here> ,如下所述。

EDIT: If we are talking about Windows family of operating systems from Windows 2000 onward then function SHGetFolderPath is portable way to retrieve user specific folder where application configuration files should be stored. 编辑:如果我们正在谈论从Windows 2000开始的Windows操作系统家族,那么函数SHGetFolderPath是可移植的方式,用于检索应存储应用程序配置文件的用户特定文件夹。 To store data in romaing folder use CSIDL_APPDATA with SHGetFolderPath . 要将数据存储在罗马文件夹中,请使用CSIDL_APPDATA和SHGetFolderPath To store data to local folder use CSIDL_LOCAL_APPDATA. 要将数据存储到本地文件夹,请使用CSIDL_LOCAL_APPDATA。

The difference between local and roaming folder is in the nature of the data to be stored. 本地文件夹和漫游文件夹之间的区别在于要存储的数据的性质。 If data is too large or machine specific then store it in local folder. 如果数据太大或计算机专用,则将其存储在本地文件夹中。 Your data (coordinates and size of the window) are local in nature (on other machine you may have different resolution), so you should actually use CSIDL_LOCAL_APPDATA. 您的数据(坐标和窗口大小)本质上是本地的(在其他计算机上您可能具有不同的分辨率),因此您实际上应该使用CSIDL_LOCAL_APPDATA。

Windows Vista and later have extended function SHGetKnownFolderPath with its own set of constants, but if you seek compatibility stick to the former SHGetFolderPath . Windows Vista和更高版本已经使用其自己的常量集扩展了功能SHGetKnownFolderPath ,但是如果您寻求兼容性,请坚持使用以前的SHGetFolderPath

TinyXML is a popular and simple XML parser for C++. TinyXML是用于C ++的流行且简单的XML解析器。

Apart from that, you can really use any format you want to store your settings, though it's considered good practice to keep settings in text format so that they can be hand-edited if necessary. 除此之外,您实际上可以使用任何想要存储设置的格式,尽管将设置保持为文本格式是一种很好的做法,以便在必要时可以对其进行手动编辑。

It's fairly simple to write your own functions for reading/writing a file in INI or similar format. 编写自己的函数以INI或类似格式读取/写入文件非常简单。 The format is entirely up to you, as long as it's easily comprehensible to humans. 格式完全取决于您,只要它对人类来说很容易理解即可。 Some possibilities are: 一些可能性是:

; Comment
# Comment
Key = Value (standard INI format)
Key Value
Key: Value

You could use Boost.PropertyTree for this. 您可以为此使用Boost.PropertyTree

Property trees are versatile data structures, but are particularly suited for holding configuration data. 属性树是通用的数据结构,但是特别适合保存配置数据。 The tree provides its own, tree-specific interface, and each node is also an STL-compatible Sequence for its child nodes. 该树提供了自己的,特定于树的接口,并且每个节点的子节点也是与STL兼容的Sequence。

It supports serialization, and so is well-suited to managing and persisting changeable configuration data. 它支持序列化,因此非常适合管理和持久保存可更改的配置数据。 There is an example here on how to load and save using the XML data format that this library supports. 此处有一个示例,说明如何使用此库支持的XML数据格式进行加载和保存。

The library uses RapidXML internally but hides the parsing and encoding details, which would save you some implementation time (XML libraries all have their idiosyncracies), while still allowing you to use XML as the data representation on disk. 该库在内部使用RapidXML,但是隐藏了解析和编码细节,这将节省您一些实现时间(XML库都具有其特质),同时仍允许您将XML用作磁盘上的数据表示。

Libconfig is the best solution in C++ as far as I have tried. 据我所试, Libconfig是C ++中最好的解决方案。 Works multi platform with minimum coding. 适用于具有最少编码的多平台。 You must try that! 您必须尝试一下!

libxml2 . libxml2 I have seen quite a lot places where it is used. 我已经看到很多使用它的地方。 Easy to use and loads of examples to get you started and not a vast library as such. 易于使用和大量示例来帮助您入门,而不是一个庞大的库。 And in C, take it wherever you want. 在C语言中,将其随心所欲。

pugixml is another good (and well documented) XML parser library. pugixml是另一个好的(且有据可查的)XML解析器库。 And If you like portability XML is a better option. 如果您喜欢可移植性,那么XML是更好的选择。

While INI files may not be the best format, I think you can safely ignore the warning MSDN puts on WritePrivateProfileString and ReadPrivateProfileString. 尽管INI文件可能不是最佳格式,但我认为您可以放心地忽略MSDN上对WritePrivateProfileString和ReadPrivateProfileString的警告。

Those two functions are NEVER going away. 这两个功能永远不会消失。 It would break THOUSANDS of applications. 它将破坏成千上万的应用程序。

That warning has been there for years and I suspect was added when the registry was all the rage and someone naively thought it would one day completely replace INI files. 该警告已经存在多年了,我怀疑当注册表风行一时时又添加了这个警告,有人天真地认为它会在一天之内完全替换INI文件。

I might be wrong but it would be very unlike Microsoft to break so many existing apps like this for no good reasons. 我可能是错的,但与Microsoft完全无缘无故地破坏这么多现有的应用程序完全不同。 (Not that they do not occasionally break backwards compatibility, but this would cause huge problems for zero benefit.) (并不是说它们偶尔不会破坏向后兼容性,但这会导致零收益的巨大问题。)

Ohhh My GOD? 哦,我的天哪? Have you ever thought of stright-forward solution rather then thinking of Super-Duper-all-can-do framework way? 您是否曾经想过直截了当的解决方案,而不是想着超级Duper-All-can-do框架方式?

Sorry... 抱歉...

You want to store two numbers between restarts??? 您想在两次重启之间存储两个数字???

Save: Open a file, write these two numbers, close the file: 保存:打开文件,输入这两个数字,然后关闭文件:

std::ifstream out(file_name);
out << x << ' ' << y;
out.close();

Load: Open a file, read these two numbers, close the file: 加载:打开文件,读取这两个数字,然后关闭文件:

std::ifstream in(file_name);
if(!in) return error...
in >> x >> y;
if(!in) return error...
in.close();

Come on, just save the data you need in a text file. 来吧,只需将所需的数据保存在文本文件中。 You can also write a thin wrapper API for that functionality. 您也可以为该功能编写瘦包装API。 What's the problem? 有什么问题?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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