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

时间:2010-11-25 17:22:37

标签: c++ c windows winapi

我需要一些存储和从文件中获取数据的方法(在WIN32 api c ++应用程序中,而不是MFC或.NET)

e.g。关闭窗口时保存窗口的x,y,宽度和高度,并在打开窗口时加载数据。

我尝试过.ini文件,包含函数 - WritePrivateProfileString和ReadPrivateProfileString / Int,但在MSDN上它说

“此功能仅用于与16位基于Windows的应用程序兼容。应用程序应将初始化信息存储在注册表中。”

当我尝试在我的Windows7 64位机器上读取ini文件时,我得到了蓝屏! (在Visual Studio的调试模式下)O.O

我注意到大多数其他应用程序使用XML来存储数据,但我不知道如何在c ++中读/写xml数据,是否有任何库或窗口函数可以让我使用xml数据? / p>

任何其他建议都会很好,谢谢。

9 个答案:

答案 0 :(得分:3)

.ini文件没有任何问题,它们唯一的问题是在哪里编写它们。来自CodeProject的CIniFile足够好了。 Ini文件应放在%APPDATA%/<Name Of Your Application>(或%LOCALAPPDATA%\<Same Name Here>中,如下所述。)

编辑:如果我们从Windows 2000开始讨论Windows系列操作系统,那么函数SHGetFolderPath是可移植的方式来检索应存储应用程序配置文件的用户特定文件夹。要将数据存储在romaing文件夹中,请使用带有SHGetFolderPath的CSIDL_APPDATA。要将数据存储到本地文件夹,请使用CSIDL_LOCAL_APPDATA。

本地和漫游文件夹之间的区别在于要存储的数据的性质。如果数据太大或特定于机器,则将其存储在本地文件夹中。您的数据(窗口的坐标和大小)本质上是本地的(在其他计算机上可能有不同的分辨率),因此您应该实际使用CSIDL_LOCAL_APPDATA。

Windows Vista及更高版本扩展了函数SHGetKnownFolderPath并使用了自己的一组常量,但是如果你寻求兼容性坚持前者SHGetFolderPath

答案 1 :(得分:2)

TinyXML是一种流行且简单的C ++ XML解析器。

除此之外,您可以使用任何您想要存储设置的格式,但将文本格式设置保留为良好做法,以便必要时可以手动编辑。

编写自己的函数来读取/写入INI或类似格式的文件相当简单。格式完全取决于您,只要它易于人类理解。一些可能性是:

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

答案 2 :(得分:1)

您可以使用Boost.PropertyTree

  

属性树是通用数据   结构,但特别是   适合保存配置数据。   树提供了自己的,   树特定的接口和每个节点   也是STL兼容的序列   它的子节点。

它支持序列化,因此非常适合管理和保存可更改的配置数据。关于如何使用此库支持的XML数据格式加载和保存,有一个示例here

uses RapidXML internally但隐藏了解析和编码细节,这可以节省一些实现时间(XML库都有它们的特性),同时仍允许您使用XML作为磁盘上的数据表示。

答案 3 :(得分:0)

libxml2。我已经看到了很多使用它的地方。易于使用和大量示例可以帮助您入门,而不是一个庞大的库。在C中,随身携带它。

答案 4 :(得分:0)

pugixml是另一个优秀(并且记录良好)的XML解析器库。如果你喜欢可移植性,XML是一个更好的选择。

答案 5 :(得分:0)

虽然INI文件可能不是最佳格式,但我认为您可以放心地忽略MSDN对WritePrivateProfileString和ReadPrivateProfileString的警告。

这两个功能永远不会消失。它会破坏数千个应用程序。

这个警告已经存在多年了,我怀疑是在注册表风靡一时并且有人天真地认为它有一天会完全取代INI文件时添加的。

我可能错了,但与微软打破这么多现有的应用程序是完全不同的。 (并不是说它们偶尔不会破坏向后兼容性,但这会导致零利益的巨大问题。)

答案 6 :(得分:0)

哦,我的上帝?你有没有想过直截了当的解决方案,而不是想到Super-Duper-all-can-do框架方式?

...对不起

你想在重启之间存储两个数字???

保存:打开文件,写下这两个数字,关闭文件:

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

加载:打开文件,读取这两个数字,关闭文件:

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

答案 7 :(得分:0)

就我的尝试而言,

Libconfig是C ++中最好的解决方案。 以最少的编码工作多平台。 你必须试试!

答案 8 :(得分:-1)

来吧,只需将您需要的数据保存在文本文件中即可。您还可以为该功能编写一个瘦包装API。有什么问题?