How do I use the registry? - c++

In the simplest possible terms (I'm an occasional programmer who lacks up-to-date detailed programming knowledge) can someone explain the simplest way to make use of the registry in codegear C++ (2007).
I have a line of code in an old (OLD!) program I wrote which is causing a significant delay in startup...
DLB->Directory=pIniFile->ReadString("Options","Last Directory","no key!");
The code is making use of an ini file. I would like to be able to use the registry instead (to write variables such as the last directory the application was using)
But the specifics are not important. I'd just like a generic how-to about using the registry that's specific to codegear c++ builder.
I've googled this, but as usual with this type of thing I get lots of pages about c++ builder and a few pages about the windows registry, but no pages that explain how to use one with the other.

Use the TRegistry class... (include registry.hpp)
//Untested, but something like...
TRegistry *reg = new TRegistry;
reg->RootKey = HKEY_CURRENT_USER; // Or whatever root you want to use
reg->OpenKey("theKey",true);
reg->ReadString("theParam",defaultValue);
reg->CloseKey();
Note, opening and reading a ini file is usually pretty fast, so maybe you need to test your assumption that the reading of the ini is actually your problem, I don't think that just grabbing your directory name from the registry instead is going to fix your problem.

Include the Registry.hpp file:
#include <Registry.hpp>
Then in any function you have, you can write the following to read the value:
String __fastcall ReadRegistryString(const String &key, const String &name,
const String &def)
{
TRegistry *reg = new TRegistry();
String result;
try {
reg->RootKey = HKEY_CURRENT_USER;
if (reg->OpenKeyReadOnly(key)) {
result = reg->ReadString(name, def);
reg->CloseKey();
}
}
__finally {
delete reg;
}
return result;
}
So reading the value should be as easy as:
ShowMessage(ReadRegistryString("Options", "Last Directory", "none"));
You can use the following to write the value:
void __fastcall WriteRegistryString(const String &key, const String &name,
const String &value)
{
TRegistry *reg = new TRegistry();
try {
reg->RootKey = HKEY_CURRENT_USER;
if (reg->OpenKey(key, true)) {
reg->WriteString(name, value);
reg->CloseKey();
}
}
__finally {
delete reg;
}
}
Should be self explaining, remembering the try ... finally is actually really helpful when using the VCL TRegistry class.
Edit
I've heard that .ini files are stored in the registry in Windows, so if you want the speed advantage of ini files you should call them something else - like .cfg
This is something I've heard from an although reliable source, I haven't tested it myself.

Tim is right but an even simpler class to use is TIniRegFile but it is also more limited in what you can do.

Please see the documentation for the QSettings class from the Qt 4.5 library. It will allow you to load and store your program's configuration settings easily and in a cross-platform manner. The Windows implementation uses the Windows registry for loading and storing your program's configuration data. On other platforms, the platform's preferred, native mechanism for storing configuration data will be used. This is far better than interacting with the Windows registry directly, as you will not be tied to a specific platform.

Related

C++ - Using a variable without knowing what it is called

I have a program that uses plug-ins. As I'm in development, these plug-ins are currently just .h and .cpp files that I add or remove from my project before re-compiling, but eventually they will be libraries.
Each plug-in contains lists of data in vectors, and I need to dynamically load data from the plug-ins without knowing which plug-ins are present. For instance:
// plugin1.h
extern vector<int> plugin1Data;
// plugin2.h
extern vector<int> plugin2Data;
// main.cpp
vector<vector<int>> pluginDataList;
int CountPlugins () {
// Some function that counts how many plug-ins are present, got this bit covered ;)
}
int main() {
int numPlugins = CountPlugins();
for (int i = 0; i < numPlugins; i++) {
vector<int> newPluginData = /***WAY TO ADD PLUGIN DATA!!!***/;
pluginDataList.push_back(newPluginData);
}
}
I already access the names of each plugin present during my CountPlugins() function, and have a list of names, so my first gut feeling was to use the name from each plugin to create a variable name like:
vector<string> pluginNames = /*filled by CountPlugins*/;
string pluginDataName = pluginNames.at(i) + "Data";
// Use pluginDataName to locate plugin1Data or plugin2Data
That's something I've done before in c# when I used to mess around with unity, but I've read a few stackoverflow posts clearly stating that it's not possible in c++. It's also a fairly messy solution in C# anyway as far as I remember.
If each plugin was a class instead of just a group of vectors, I could access the specific data doing something like plugin2.data... but then I still need to be able to reference the object stored within each plugin, and that'll mean that when I get round to compiling the plugins as libraries, I'll always have to link to class declaration and definition, which isn't ideal (though not out of the question if it'll give a nicer solution over all).
I'm all out of ideas after that, any help you can offer will be most welcome!
Thanks! Pete
Why dont you save the data as JSON between the application and the plugins ? That way you will also allow other types of tech to plug-into your app, like javascript based plugins via an embedded version of v8 or c#/.net plugins via mono.'

How to get list of files opened by a process in Windows? [duplicate]

How do I get the list of open file handles by process id in C#?
I'm interested in digging down and getting the file names as well.
Looking for the programmatic equivalent of what process explorer does.
Most likely this will require interop.
Considering adding a bounty on this, the implementation is nasty complicated.
Ouch this is going to be hard to do from managed code.
There is a sample on codeproject
Most of the stuff can be done in interop, but you need a driver to get the filename cause it lives in the kernel's address space. Process Explorer embeds the driver in its resources. Getting this all hooked up from C# and supporting 64bit as well as 32, is going to be a major headache.
You can also run the command line app, Handle, by Mark Rusinovich, and parse the output.
Have a look at this file :
http://vmccontroller.codeplex.com/SourceControl/changeset/view/47386#195318
And use:
DetectOpenFiles.GetOpenFilesEnumerator(processID);
Demo:
using System;
using System.Diagnostics;
namespace OpenFiles
{
class Program
{
static void Main(string[] args)
{
using (var openFiles = VmcController.Services.DetectOpenFiles.GetOpenFilesEnumerator(Process.GetCurrentProcess().Id))
{
while (openFiles.MoveNext())
{
Console.WriteLine(openFiles.Current);
}
}
Console.WriteLine();
Console.ReadKey();
}
}
}
It has dependency over assembly System.EnterpriseServices
You can P/INVOKE into the NtQuerySystemInformation function to query for all handles and then go from there. This Google groups discussion has details.
Take a look at wj32's Process Hacker version 1, which can do what you asked, and more.
Handle is great program, and the link to codeproject is good.
#Brian
The reason for the code is that handle.exe is NOT redistributable. Nor do they release their source.
It looks as if .Net will not easily do this since it appears that an embedded device drive is requried to access the information. This cannot be done in .net without an unmanged DLL. It's relatviely deep kernel code when compared to typical .net coding. I'm surprised that WMI does not expose this.
Perhaps using command line tool:
OpenedFilesView v1.50 - View opened/locked files in your system (sharing violation issues)
http://www.nirsoft.net/utils/opened_files_view.html

What's the standard approach for configuration in Qt console apps?

In .Net you typically have an app.config file and built in ways to access the configuration.
Is there an equivalent standard approach to configuration using Qt?
For example, lets say my application connects to an online server, I want the ability to store the connection details (user defined).
Is this a case of "roll your own", or is there a way to store and read these configurations using XML, or any other format with easy read/write methods provided by Qt?
Edit: To add some complication to the question. This is a Linux console app, so looking specifically for file based and transparent config please.
You could use QSettings for this. Please refer to the documentation for details:
http://qt-project.org/doc/qt-5.1/qtcore/qsettings.html
You could always use other formats as well like XML, Json, and so forth, but generically speaking, QSettings is the way, or if you are writing a KDE application, then probably KConfig.
These are the two important methods you need to be aware of when dealing with QSettings for reading and writing:
Reading
QVariant QSettings::value(const QString & key,
const QVariant & defaultValue = QVariant()) const
Writing
void QSettings::setValue(const QString & key, const QVariant & value)
Then, you can simply stick to the native format (or even ini on your Linux if you prefer):
QSettings::NativeFormat 0 Store the settings using the most
appropriate storage format for the platform. On Windows, this means
the system registry; on Mac OS X, this means the CFPreferences API; on
Unix, this means textual configuration files in INI format.
Here you can find an example for your convenience:
#include <QSettings>
int main()
{
....
QSettings settings("Foo", "Bar");
// settings.beginGroup("application");
QString string = settings.value("foo", "bar");
// settings.endGroup();
....
}
Note, the groups are optional, and it depends on your exact purpose. You can group settings that way to keep certain ones encapsulated.
This may also be important for you to know as per documentation:
On Unix systems, if the file format is NativeFormat, the following files are used by default:
$HOME/.config/MySoft/Star Runner.conf (Qt for Embedded Linux: $HOME/Settings/MySoft/Star Runner.conf)
$HOME/.config/MySoft.conf (Qt for Embedded Linux: $HOME/Settings/MySoft.conf)
/etc/xdg/MySoft/Star Runner.conf
/etc/xdg/MySoft.conf

Can you use multiple message domains in boost::locale?

I have a number of applications that share a number of general libraries. I am trying to internationalize my applications using boost::locale. It will be easy for me to create a separate .mo file for each general library and for each specific application. I was wandering if it is possible to simultaneously use multiple message domains like this:
boost::locale::generator gen;
gen.add_messages_path(".");
gen.add_messages_domain("lib1");
gen.add_messages_domain("lib2");
std::locale::global(gen("zh_CN.UTF-8"));
.
.
.
boost::locale::gettext("Show image");
I was expecting boost::locale to search in both lib1.mo and lib2.mo, however this doesn't seem to work. Only messages from the first domain added are found, in this case from lib1.mo. If I add lib2 before lib1, then only messages from lib2 are found.
I know you can use a domain explicitly in the call like this:
boost::locale::dgettext("lib2", "Show image");
This does work, but I would like to avoid specifying the domain for every call. I am also not sure that this will work well with extracting the strings with xgettext.
Is it possible what I am trying to do? Am I missing something?
Please suggest any alternative if you know one.
I use msvc 9.0 (2008) and boost 1.48.
Since there were no answers posted to this question I assume that this is not possible with boost::locale. I will shortly therefore outline what I did to achieve my required functionality:
I created a singleton class with the following interface
class MY_GETTEXT
{
public:
void SetPath(const std::string& i_path);
void AddDomain(const std::string& i_domain);
void ChangeLocale(const std::string& i_locale);
std::string gettext(const std::string i_msg_id);
};
AddDomain is called for each domain you want to use, and adds it to a member set m_language_domains_a. ChangeLocale does some locale manipulation and stores a locale in the member m_locale, I will ignore its implementation here.
To translate you should simply call MY_GETTEXT::gettext. Its implementation looks like this:
std::string MY_GETTEXT::gettext(const std::string i_msg_id)
{
BOOST_FOREACH(const std::string& domain , m_language_domains_a)
{
if (boost::locale::translate(i_msg_id).str(m_locale, domain) != i_msg_id)
{
return boost::locale::translate(i_msg_id).str(m_locale, domain);
}
}
return i_msg_id;
}

Monitoring a folder for new files in Windows

What is the best way to go about monitoring a folder to see when an image file has been added to it? Files are added approximately once a minute and the naming goes like this... image0001.jpg, image0002.jpg, image0003.jpg etc. I need to know when a file has been written to the folder so that my app can access and use it.
Look into directory change notifications.
As per previously mentioned, the directory change notifications is what you want.
I have looked into them as well, and the caveat I have seen is that windows will fire off the notification when the file starts to be written to the folder. If the file is large enough then you will receive the notification before the file has finished being written.
Check out this google search for various solutions for waiting until the file is completely written
Edit: I just saw that the question was tagged with c++, and I linked to a .Net search. Although what I provided may not be the correct language, I would think that you will still have the same issues on Windows no matter what system you are coding with.
FileSystemWatcher should be able to do that for you.
Change notifactions may cause some overhead, if you've NTFS, consider NTFS change journals.
You can use a polling method to monitor the folder. The loop will execute every 5 seconds, for example.
This method returns a list of new files:
List<string> files = new List<string>();
string path = #"C:\test\"; // whatever the path is
public List<string> GetNewFiles(string path)
{
// store all the filenames (only .jpg files) in a list
List<string> currentFiles = System.IO.Directory.GetFiles(path, "*.jpg");
if ( currentFiles.Count() > files.Count() )
{
count = newFiles.Length - files.Length;
List<string> newFiles = new List<string>();
foreach ( string file in currentFiles )
{
if ( !files.Contains(file) )
{
newFiles.Add(file);
}
}
}
files = currentFiles;
return newFiles;
}
This is the method that will poll every 5 seconds and call the previous method.
public void MonitorFolder()
{
while (true)
{
List<string> newFiles = GetNewFiles(path);
System.Threading.Thread.Sleep(5000); // 5000 milliseconds
}
}
Synch.variant FindFirstChangeNotification
Asynch.variant ReadDirectoryChangesW
This was the top google result for my search so I'll add this as an answer.
If you're using Qt, there's QFileSystemWatcher. I didn't know this existed and we happened to be using Qt, so I wasted more than a few hours using FindFirstChangeNotification to rewrite what was readily available to me until a colleague showed me the light.
Good learning experience though.
inotify might be your thing