Linux。是否可以在服务应用程序中使用 Xorg 库?

问题描述 投票:0回答:1

我正在为 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");

linux display xorg
1个回答
0
投票

我的服务并与当前用户一起使用。我只需要登录 X 服务器即可接收屏幕截图。我发现一些代码可以帮助我让 xLib 库在我的服务中工作。 为此,我在代码中编写以下行:

setenv("XAUTHORITY", "/run/user/1000/.mutter-Xwaylandauth.AL7MK2", 1);
我使用命令从控制台获取变量的值
echo $XAUTHORITY
但我怎样才能在代码中做到这一点?这样我就不需要从控制台获取信息并手动输入。

请告诉我如何在代码中正确执行此操作?如果我们使用函数 getuid() 获取用户 ID

或者谁能告诉我如何在知道用户 ID 的情况下登录 X 服务器?

© www.soinside.com 2019 - 2024. All rights reserved.