How do I get package versions in c++? (linux) - c++

I've been writing a program that needs a wine version of 2.6 or later. I'd like to get it as a boolean, so I've been trying to use the code below:
#include <string>
#include <iostream>
#include "WineCheck.h"
#include <cstdlib>
using namespace std;
bool checkForWine()
{
// Create variables for checking wine state
bool wineIsThere = false;
bool wineIsVersion = false;
// Check dpkg if wine is there
if (string(system("dpkg -l | cut -c 4-9 | grep \\ wine\\ ")) == " wine ")
{
wineIsThere = true;
// Check version
if (double(system("wine --version | cut -c 6-8")) >= 2.6)
wineIsVersion = true;
}
// Return
if (wineIsThere && wineIsVersion)
return true;
else
return false;
}

First, it's my opinion you shouldn't bother with this. Wine 2.6 should just be included as a dependency in your configuration script, and/or your package file. Targeting a specific package management system in your program source code is not a good idea if you want to maintain portability to other GNU/Linux distributions that don't use that packager.
To answer your question though. There are two ways I found you can do this. You can check /var/lib/dpkg/status. Read through the file line by line until you get to this section. If you don't find the section, or the Status: ... line doesn't say installed then wine is not installed. The Version: ... line will tell you what version is installed. I verified this method works by installing and uninstalling Wine on Debian Wheezy. You didn't say what distro you're working with, but it's obvious you're using the Debian Packaging system, so this should work on Ubuntu and other Debian based distributions as well.
$cat /var/lib/dpkg/status
...
Package: wine
Status: install ok installed
Priority: optional
Section: otherosf
Installed-Size: 80
Maintainer: Debian Wine Party <pkg-wine-party#lists.alioth.debian.org>
Architecture: amd64
Version: 1.4.1-4
...
The other option is use libdpkg. I found an example that lists all installed packages.
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dpkg/dpkg.h>
#include <dpkg/dpkg-db.h>
#include <dpkg/pkg-array.h>
#include "filesdb.h"
const char thisname[] = "example1";
int
main(int argc, const char *const *argv)
{
struct pkg_array array;
struct pkginfo *pkg;
int i;
enum modstatdb_rw msdb_status;
standard_startup();
filesdbinit();
msdb_status = modstatdb_open(msdbrw_readonly);
pkg_infodb_init(msdb_status);
pkg_array_init_from_db(&array);
pkg_array_sort(&array, pkg_sorter_by_name);
for (i = 0; i < array.n_pkgs; i++) {
pkg = array.pkgs[i];
if (pkg->status == stat_notinstalled)
continue;
printf("Package --> %s\n", pkg->set->name);
}
pkg_array_destroy(&array);
modstatdb_shutdown();
standard_shutdown();
}

Related

log4cplus ConsoleAppender does not work in container

I'm trying to containerize my application but I'm having trouble getting log4cplus working. Bottom line up front, logging works when running on the host, but not in the container when I'm logging from long running loops. Its seems like a buffer somewhere is not getting flushed. A minimal example follows.
Additionally, removing the long lived loop removes the issue, presumably log4cplus flushes one last time before tearing down. Lengthening the sleep duration did not seem to help.
main.cpp
#include <iostream>
#include <unistd.h>
#include <log4cplus/logger.h>
#include <log4cplus/loggingmacros.h>
#include <log4cplus/configurator.h>
#include <log4cplus/initializer.h>
int main(int argc, char **argv)
{
std::cout << "Sanity Check" << std::endl;
auto log4cplus = ::log4cplus::Initializer();
std::string logconfig("log4cplus_configure.ini");
::log4cplus::PropertyConfigurator::doConfigure(logconfig);
auto logger = ::log4cplus::Logger::getInstance(LOG4CPLUS_TEXT("main"));
while (true) {
LOG4CPLUS_ERROR(logger, "Sleeping...");
// std::cout << "cout sleep..." << std::endl; // uncomment to get log messages working
sleep(1);
}
return 0;
}
log4cplus_configure.ini
log4cplus.rootLogger=INFO, MyConsoleAppender
log4cplus.appender.MyConsoleAppender=log4cplus::ConsoleAppender
log4cplus.appender.MyConsoleAppender.layout=log4cplus::PatternLayout
log4cplus.appender.MyConsoleAppender.layout.ConversionPattern=[%-5p][%d] %m%n
Dockerfile
FROM rockylinux:latest
RUN dnf install -y boost-system
COPY ./build/sandbox /
COPY ./log4cplus_configure.ini /
CMD ["/sandbox"]
CMakeLists.txt
cmake_minimum_required(VERSION 3.10)
set (CMAKE_CXX_STANDARD 17)
# Project executable and library
add_executable(sandbox main.cpp)
target_link_libraries(sandbox
PUBLIC liblog4cplus.a
PUBLIC pthread
PUBLIC boost_system
)
Not sure why, but adding log4cplus.appender.MyConsoleAppender.ImmediateFlush=true to log4cplus_configure.ini solved my issue.

There is not such a file called "SDL2.h"

I run KDE Neon 20.04 and whenever i try to run this command block in Sublime Text i get this error.
#include "SDL2.h"
#include "SDL2_image"
#include <iostream.h>
int main(int argc, char* args[])
{
std::cout << "Yay" << std::endl;
return 0;
}
SDL2.h there is no such file or directory
You have to install SDL development libraries first. You can install it using the command sudo apt-get install libsdl2-dev.
You are also including sdl headers wrong.
This is the correct way.
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>

Problems with building OpenCv with Xcode. Cannot find opencv2/opencv.hpp file

I have installed OpenCv with Homebrew on my MacOs. I have added libopencv 4.0.1.dylib in Xcode. When I try to build, Xcode cannot find the files. Any suggestions?
I changed my path but still have problems.
Main code:
#include <iostream>
#include <opencv4/opencv2/opencv.hpp>
int main(int argc, const char * argv[]) {
// insert code here...
std::cout << "Hello, World!\n";
return 0;
}
Build settings including path:
Error messages:

nVidia driver version from WMI is not what I want

I want to get driver version of nVidia video card.
So I used WMI and get data from "DriverVersion" obejct of "Win32_VideoController" class.
But it was like "9.18.13.1106"(file version) and what I wanted is something like "311.06"(treiber version).
Where can I get that information?
If it is impossible on WMI, I want to know other way to get that.
Thanks.
You can do this using NVML from nVidia's Tesla Deployment Kit. You can retrieve the internal driver version (the one you're accustomed to seeing for an nVidia driver) with code like this:
#include <iostream>
#include <string>
#include <stdlib.h>
#include <nvml.h>
#include <windows.h>
namespace {
typedef nvmlReturn_t (*init)();
typedef nvmlReturn_t (*shutdown)();
typedef nvmlReturn_t (*get_version)(char *, unsigned);
class NVML {
init nvmlInit;
shutdown nvmlShutdown;
get_version nvmlGetDriverVersion;
std::string find_dll() {
std::string loc(getenv("ProgramW6432"));
loc += "\\Nvidia Corporation\\nvsmi\\nvml.dll";
return loc;
}
public:
NVML() {
HMODULE lib = LoadLibrary(find_dll().c_str());
nvmlInit = (init)GetProcAddress(lib, "nvmlInit");
nvmlShutdown = (shutdown)GetProcAddress(lib, "nvmlShutdown");
nvmlGetDriverVersion = (get_version)GetProcAddress(lib, "nvmlSystemGetDriverVersion");
if (NVML_SUCCESS != nvmlInit())
throw(std::runtime_error("Unable to initialize NVML"));
}
std::string get_ver() {
char buffer[81];
nvmlGetDriverVersion(buffer, sizeof(buffer));
return std::string(buffer);
}
~NVML() {
if (NVML_SUCCESS != nvmlShutdown())
throw(std::runtime_error("Unable to shut down NVML"));
}
};
}
int main() {
std::cout << "nVidia Driver version: " << NVML().get_ver();
}
Note that if you're writing this purely for your own use on a machine where you're free to edit the PATH, you can simplify this quite a bit. Most of the code deals with the fact that this uses NVML.DLL, which is in a directory that's not normally on the path, so the code loads that dynamically, and uses GetProcAddress to find the functions in it that we need to use. In this case, we're only using three functions, so it's not all that difficult to deal with, but it still at drastically increases the length of the code.
If we could ignore all that nonsense, the real code would just come out to something on this general order:
nvmlInit();
nvmlSystemGetDriverVersion(result, sizeof(result));
std::cout << result;
nvmlShutdown();
Anyway, to build it, you'll need a command line something like:
cl -Ic:\tdk\nvml\include nv_driver_version.cpp
...assuming you've installed the Tesla Deployment Kit at c:\tdk.
In any case, yes, I've tested this to at least some degree. On my desktop it prints out:
nVidia Driver version: 314.22
...which matches what I have installed.
To get the Nvidia driver version through C++ on Win64:
Download NVAPI https://developer.nvidia.com/rtx/path-tracing/nvapi/get-started, a few MB
The main folder of the downloaded archive contains several header files, one of which is nvapi.h. Those headers are needed for compilation. The subfolder amd64 contains nvapi64.lib, which is needed for linking. The following code will now show the driver version:
#include <iostream>
extern "C" {
#include "nvapi.h"
}
int main() {
NvAPI_Status status = NVAPI_OK;
NvAPI_ShortString str;
status = NvAPI_Initialize();
if (status == NVAPI_LIBRARY_NOT_FOUND) {
//in this case NvAPI_GetErrorMessage() will only return an empty string
std::printf("error no nvidia driver found\n");
} else if (status != NVAPI_OK) {
NvAPI_GetErrorMessage(status, str);
std::printf("error initializing nvapi: %s\n", str);
}
NvU32 version = 0;
NvAPI_ShortString branch;
status = NvAPI_SYS_GetDriverAndBranchVersion(&version, branch);
if (status != NVAPI_OK) {
NvAPI_GetErrorMessage(status, str);
std::printf("error getting driver version: %s\n", str);
} else {
std::printf("driver version %d.%d", version / 100, version % 100);
}
}

Move application windows on desktop programmatically in Gnome or KDE

I want to reposition a application window on the desktop using a c++ program .
How should i go about doing that , i need solution for both situations .
When i have the source of the application which want to move .
Move windows of other application by Writing an external program.
External Bash script:
xdotool search --onlyvisible --class dolphin windowmove 13 37
# ^ ^ ^
# window class X & Y coordinates
For more information about this, use xdotool search, xdotool windowmove and man xdotool.
C++ example:
#include <cstdlib>
#include <string>
#include <sstream>
using namespace std;
int main()
{
string cls="dolphin";
int x=13, y=37;
stringstream s;
s<<"xdotool search --onlyvisible --class "<<cls<<" windowmove "<<x<<" "<<y;
system(s.str().c_str());
return 0;
}
And bare minimum example:
#include <stdlib.h>
int main()
{
system("xdotool search --onlyvisible --class dolphin windowmove 13 37");
return 0;
}