首页 > 解决方案 > 在 docker 容器中为 Win32 api 绑定目录

问题描述

背景:我目前正在开发一个 Windows 服务,用于监视 Windows 机器上文件系统的更改。

下一步是将这个应用程序放入一个容器中,以便它可以在每台机器上运行。为了“捕捉”目录更改,我使用 C++ 中的函数ReadDirectoryChangesExW。对给定目录的任何更改都将导致引发 Windows 事件。

为了启动我的容器并测试我的服务,我使用以下命令:

docker run --rm -it --workdir="c:\FileAgent" monitor

其中FileAgent是我放置.exe监视我的图像名称的目录。

通过运行该服务来监控容器的本地目录,该服务可以正常工作。但是当我尝试通过绑定监视主机上的文件夹时,该服务无法正常工作,因为ReadDirectoryChangesExW为 FALSE 并且应用程序正在崩溃。

代码示例:

string lpDir = "C:/tmp/";
FILE_NOTIFY_EXTENDED_INFORMATION strFileNotifyInfo[1024];

HANDLE fileH = CreateFileA
(
    lpDir.c_str(),
    FILE_LIST_DIRECTORY,
    FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
    NULL,
    OPEN_ALWAYS,
    FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED,
    NULL
);
if (!fileH) ErrorReporter(L"Error in creating file handler");

OVERLAPPED ovl = { 0 };
ovl.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if (!ovl.hEvent) {
    ErrorReporter(L"ERROR in creating event.");
    ExitProcess(GetLastError());
}

if (!ReadDirectoryChangesExW(
    fileH, (LPVOID)&strFileNotifyInfo, sizeof(strFileNotifyInfo),
    TRUE, //subtree watcher
    FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_DIR_NAME | FILE_NOTIFY_CHANGE_LAST_WRITE | FILE_NOTIFY_CHANGE_ATTRIBUTES,
    NULL, &ovl, NULL, ReadDirectoryNotifyExtendedInformation))
{
    ErrorReporter(L"Error in reading directory changes!");
    ExitProcess(GetLastError());
}

其中lpDir是目录的路径。为了重新生成该状态,在构建 docker 映像后,我使用以下命令启动容器:

docker run --rm -it --workdir="c:\FileAgent" -v c:\Users\john\Desktop\dataDir:c:\tmp\ monitor

正如我测试的那样,这是一种双向绑定。这意味着对dataDir的更改会影响容器内的tmp目录,反之亦然。当我启动服务时,它会崩溃,正如我前面提到的。

我尝试了什么:

  1. 使用标志以特定用户启动容器--user "NT AUTHORITY\SYSTEM"
  2. 在构建过程中通过 Dockerfile 定义用户

    RUN NET USER my_admin /add
    
    RUN NET LOCALGROUP Administrators /add
    
    my_admin USER my_admin
    
  3. 首先创建目录,然后绑定它。

在所有这些实验中,我注意到容器绑定文件夹上的用户是.... 此外,我无法删除此文件夹,因为真正的文件夹位于主机上,所以这是有道理的。

你能提供任何建议吗?

我是否遗漏了任何安全/访问权限问题?

标签: dockerwinapiwindows-servicescontainersc++17

解决方案


推荐阅读