我正在为 Linux 操作系统开发一个小型服务。我有一个问题。尽管我以根用户身份运行它,但我无法从我的服务访问显示。如果我将相同的代码传输到控制台应用程序,则一切正常。我怀疑 Linux 服务无法与 Xorg 一起使用。我的怀疑正确吗?你能给我建议吗!
对于没有提供我的代码,我深表歉意。请看一下我的代码。
namespace tasks::window {
using namespace storage::entities;
WindowTask::WindowTask(Poco::Logger &logger, sdk::events::AbstractCollector& events)
:Poco::Task("WindowTask"),
logger_(logger),
event_(events)
{
}
WindowTask::~WindowTask()
{
}
void WindowTask::runTask() {
while (!isCancelled()) {
auto wi = getWindowInfo();
std::cout<<"window name = "<< wi->name << std::endl;
std::cout<<"window pid = "<< wi->pid << std::endl;
// отправим dlp событие на сервер
dlp::events::WindowEventData eventData;
eventData.setTitle(wi->name);
eventData.setPid(wi->pid);
this->sendDlpEvent(eventData);
//задержка перед повторной отправкой события об активном окне пользователя
this->sleep(sleep_period_); // каждый некоторый промежуток времени повторить действия в цикле
}
}
Window WindowTask::getActiveWindow() {
Window activeWindow = None;
unsigned char* property = getProperty(::XDefaultRootWindow(xDisplay_), XA_WINDOW,
"_NET_ACTIVE_WINDOW");
if (property != nullptr)
{
activeWindow = *(reinterpret_cast<Window*>(property));
}
return activeWindow;
}
Poco::SharedPtr<WindowInfo> WindowTask::getWindowInfo() {
xDisplay_ = ::XOpenDisplay(NULL);
Window activeWindow = getActiveWindow();
if (activeWindow == None){
logger_.information("не удалось получить активное окно");
return nullptr;
}
unsigned char* netwmName = getProperty(activeWindow,
::XInternAtom(xDisplay_, "UTF8_STRING", False),
"_NET_WM_NAME");
if (netwmName == nullptr)
netwmName = getProperty(activeWindow,
::XInternAtom(xDisplay_, "UTF8_STRING", False),
"WM_NAME");
unsigned char* wmPid = getProperty(activeWindow,
AnyPropertyType,
"_NET_WM_PID");
::XCloseDisplay(xDisplay_);
if (netwmName != nullptr && wmPid != nullptr)
{
Poco::SharedPtr<WindowInfo> windowInfo = Poco::makeShared<WindowInfo>();
windowInfo->name = std::string((char*)netwmName);
unsigned long long_property = static_cast<unsigned long>(wmPid[0] + (wmPid[1] << 8) + (wmPid[2] << 16) +
(wmPid[3] << 24));
windowInfo->pid = (int)long_property;
return windowInfo;
}
return nullptr;
}
// метод получающий некоторое свойство окна
unsigned char* WindowTask::getProperty(Window xWindow, Atom xPropertyType, const char* propertyName){
Atom xProperty = ::XInternAtom(xDisplay_,propertyName,False);
if (xProperty == None)
{
logger_.information("не удалось получить следующее свойство окна - %s",propertyName);
return nullptr;
}
Atom xActualType = None;
int actualFormat = 0;
unsigned long itemsNumber = 0;
unsigned long RemainigBytes = 0;
unsigned char *pProperty = NULL;
const long maxPropertySize = 4096;
int result = ::XGetWindowProperty(xDisplay_,xWindow,xProperty,0,maxPropertySize/4,False,xPropertyType,
&xActualType,&actualFormat,&itemsNumber,&RemainigBytes,&pProperty);
if (result != Success) {
logger_.information("не удалось получить следующее свойство окна - %s",propertyName);
return nullptr;
}
return pProperty;
}
void WindowTask::sendDlpEvent(dlp::events::WindowEventData& eventData) {
auto event = std::make_shared<sdk::events::UserEvent>(TypeTaskString.at(TypeTask::ACTIVE_WINDOW));
event->setStatus("NOTIFY");
event->setAttack(sdk::events::Attack::BENIGN);
event->setLogin("test");
auto data_object = Poco::makeShared<Poco::JSON::Object>(Poco::JSON_PRESERVE_KEY_ORDER);
eventData.serialize(*data_object);
event->setData(std::move(data_object));
event_.push(std::move(event));
}
}
在这行代码中我的应用程序崩溃了。我怀疑我无法接收显示:
unsigned char* property = getProperty(::XDefaultRootWindow(xDisplay_), XA_WINDOW,"_NET_ACTIVE_WINDOW");
我的服务并与当前用户一起使用。我只需要登录 X 服务器即可接收屏幕截图。我发现一些代码可以帮助我让 xLib 库在我的服务中工作。 为此,我在代码中编写以下行:
setenv("XAUTHORITY", "/run/user/1000/.mutter-Xwaylandauth.AL7MK2", 1);
我使用命令从控制台获取变量的值
echo $XAUTHORITY
但我怎样才能在代码中做到这一点?这样我就不需要从控制台获取信息并手动输入。
请告诉我如何在代码中正确执行此操作?如果我们使用函数 getuid() 获取用户 ID
或者谁能告诉我如何在知道用户 ID 的情况下登录 X 服务器?