将内存映射与服务一起使用

2024-03-02

我构建了一个也可以作为服务运行的应用程序(使用-service) 转变。当我从命令提示符运行服务时,这可以完美地工作,没有任何问题(我设置了一些设置,可以让我在不作为真正的服务运行时从控制台调试它)。但是,当我尝试将其作为真正的服务运行然后使用我的应用程序打开现有的内存映射时,我收到错误...

无法找到指定的文件。

我如何将其作为服务或在控制台中运行:

[STAThread]
static void Main(string[] args)
{
    //Convert all arguments to lower
    args = Array.ConvertAll(args, e => e.ToLower());

    //Create the container object for the settings to be stored
    Settings.Bag = new SettingsBag();

    //Check if we want to run this as a service
    bool runAsService = args.Contains("-service");

    //Check if debugging
    bool debug = Environment.UserInteractive;

    //Catch all unhandled exceptions as well
    if (!debug || debug)
    {
        Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
        AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
    }

    if (runAsService)
    {
        //Create service array
        ServiceBase[] ServicesToRun;
        ServicesToRun = new ServiceBase[]
        {
            new CRSService()
        };

        //Run services in interactive mode if needed
        if (debug)
            RunInteractive(ServicesToRun);
        else
            ServiceBase.Run(ServicesToRun);
    }
    else
    {
        //Start the main gui
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new MainGUI());
    }
}

在我的应用程序中,我有一个服务端和一个应用程序端。应用程序的目的只是控制服务。我使用内存映射文件进行所有控制,它似乎工作得很好并且适合我的需求。但是,当我将应用程序作为真正的服务运行时,我从调试日志中看到它正在创建具有正确名称和访问设置的内存映射文件。我还可以看到文件在应有的位置创建。服务中的一切似乎与我通过控制台调试时完全相同。但是,我的应用程序(当作为应用程序而不是服务运行时)告诉我它找不到内存映射文件。我也将文件名路径放入错误中,这样我就知道它正在寻找正确的位置。

我如何打开内存映射(抛出错误的地方):

m_mmf = MemoryMappedFile.OpenExisting(
    m_sMapName,
    MemoryMappedFileRights.ReadWrite
);

注意:该服务以与我运行 Visual Studio 相同的帐户运行。作为示例,下图显示了我的任务管理器、services.msc gui 和我当前识别的帐户。

在服务创建内存映射文件后,如何让客户端应用程序查看该文件?为什么当我将其作为控制台服务运行时它可以工作,而不是当我将它作为真正的服务运行时它可以工作?


Windows 服务在会话中独立运行0,而您的控制台应用程序在用户会话中运行,因此为了使它们能够相互通信,必须在Global\命名空间,以使其可供其他会话访问。例如

var file = MemoryMappedFile.CreateOrOpen(@"Global\MyMemoryMappedFile", ...

您还应该为该文件设置适当的权限,以确保所有用户都可以访问它。

我建议阅读这篇文章实现非持久内存映射文件,公开与 Windows 服务的 IPC 样式通信 http://web.archive.org/web/20180221131343/http://blogs.networkingfutures.co.uk/post/2015/12/28/Windows-Services-Implementing-Non-Persisted-Memory-Mapped-Files-Exposing-IPC-Style-Communications.aspx,它更详细地解释了上述内容,并提供了有关设置权限等的示例。


从上面链接的帖子复制的源代码:

互斥体、互斥体安全和 MMF 安全策略创建

bool mutexCreated;
Mutex mutex;
MutexSecurity mutexSecurity = new MutexSecurity();
MemoryMappedFileSecurity mmfSecurity = new MemoryMappedFileSecurity();

mutexSecurity.AddAccessRule(new MutexAccessRule(new SecurityIdentifier(WellKnownSidType.WorldSid, null), 
MutexRights.Synchronize | MutexRights.Modify, AccessControlType.Allow));
mmfSecurity.AddAccessRule(new AccessRule<MemoryMappedFileRights>("everyone", MemoryMappedFileRights.FullControl, 
AccessControlType.Allow));

mutex = new Mutex(false, @"Global\MyMutex", out mutexCreated, mutexSecurity);
if (mutexCreated == false) log.DebugFormat("There has been an error creating the mutex"); 
else log.DebugFormat("mutex created successfully");

创建并写入 MMF

MemoryMappedFile file = MemoryMappedFile.CreateOrOpen(@"Global\MyMemoryMappedFile", 4096, 
MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.DelayAllocatePages, mmfSecurity, 
HandleInheritability.Inheritable);

using (MemoryMappedViewAccessor accessor = file.CreateViewAccessor()) {
   string xmlData = SerializeToXml(CurrentJobQueue) + "\0"; // \0 terminates the XML to stop badly formed 
issues when the next string written is shorter than the current

    byte[] buffer = ConvertStringToByteArray(xmlData);
    mutex.WaitOne();
    accessor.WriteArray<byte>(0, buffer, 0, buffer.Length);
    mutex.ReleaseMutex();
    }

从 MMF 读取

using (MemoryMappedFile file = MemoryMappedFile.OpenExisting(
   @"Global\MyMemoryMappedFile", MemoryMappedFileRights.Read)) {

     using (MemoryMappedViewAccessor accessor =
         file.CreateViewAccessor(0, 0, MemoryMappedFileAccess.Read)) {
         byte[] buffer = new byte[accessor.Capacity];

         Mutex mutex = Mutex.OpenExisting(@"Global\MyMutex");
         mutex.WaitOne();
         accessor.ReadArray<byte>(0, buffer, 0, buffer.Length);
         mutex.ReleaseMutex();

         string xmlData = ConvertByteArrayToString(buffer);
         data = DeserializeFromXML(xmlData);
       }
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

将内存映射与服务一起使用 的相关文章

随机推荐

  • 用于一对多查找的 Cassandra 数据建模

    考虑存储用户及其联系人的问题 大约有一亿用户 每个用户有几百个联系人 平均联系人大小为 1kb 可能有些用户拥有太多联系人 gt 5000 并且可能有一些联系人比平均 1kb 大得多 例如 10 倍 用户会主动添加联系人 但很少会删除联系人
  • 使用 Ansible 配置 Jenkins 2.0

    我使用 Ansible 来配置我们的服务器 我安装了 Jenkins 2 0 但当我打开 Web UI 时 它变成了启动配置 我如何使用 Ansible 或 shell 或 jenkins cli 来做到这一点 CentOS 7 Ansib
  • 登录时从用户集合中获取用户数据

    我目前正在开发一个在客户端初始化了 firebase 的应用程序 当用户通过 firebase 登录时 我想从 firestore 获取用户的数据 我目前正在这样做onAuthStateChanged侦听器并成功获取用户 我想知道这是否是获
  • 套接字连接超时:规范在哪里?

    我的工作环境是我的局域网 下面的代码示例是用 Java 语言编写的 但我的问题是关于 TCP 而不是编程 我遇到过以下连接超时的情况 2 ms when connection established 当主机处于活动状态但未侦听指定套接字端口
  • emacs lisp 中的 let 和 flet

    我不知道你是否会称其为规范公式 但为了绑定本地函数 GNU 手册建议我使用 flet defun adder with flet x flet f x x 3 f x 然而 我偶然尝试了 在玩了一会儿Scheme之后 下面的表达式 其中我使
  • 将给定字符串转换为具有给定子字符串的回文

    给定字符串 S1 和字符串 S2 将字符串 S1 转换为回文字符串 例如 S2 是该回文字符串的子字符串 S1 上允许的唯一操作是将任何字符替换为任何其他字符 找出所需的最少操作次数 我已经编写了这段代码 可以计算需要使用常规字符串进行多少
  • AngularJS CORS 问题

    我已经搜索了 200 多个网站 也许有点夸张 但也不是很多 来了解如何使用 angularjs 处理 cors 我们有一台运行 Web API 服务器的本地计算机 我们正在开发一个调用 API 获取数据的客户端 当从服务器运行客户端时 我们
  • 计算多维数组中的元素数量

    我有这个代码 loadData function jsonArray var id this attr id for var i in jsonArray id tbody append tr class entry details pag
  • 声音匹配/搜索

    实际上声音匹配 搜索的当前技术水平如何 我目前正在远程参与规划一个 Web 应用程序 该应用程序将包含并公开录制的短音频剪辑 最多 3 5 秒 人名 的数据库 有人提出了是否有可能实现基于用户语音输入的搜索的问题 我的直觉告诉我 从计算和算
  • 如何在同一服务器环境下运行PHP和Tomcat?

    不久前在 AskUbuntu 上问过这个问题 https askubuntu com questions 630897 apache httpd backed by both tomcat and php https askubuntu c
  • TypeScript:类型“EventTarget & Element”上不存在属性“checked”。为什么它不存在?

    我收到此错误 错误 17 35 TS2339 类型 EventTarget Element 上不存在属性 checked 但这绝对是不可能的错误 因为 React 文档说checked确实存在于target的复选框 https reactj
  • 对复合对象数组以及日期范围进行 Elasticsearch 查询

    您好 我有一个问题 如何为具有日期范围和附加字段参数的嵌套复合对象创建弹性搜索查询 如下所示 name A availability partial true dates gte 2020 12 01 lte 2020 12 02
  • 在 Java 8 中使用 lambda 出现意外错误

    我正在使用 Java 8 Update 20 32 位 Maven 3 2 3 Eclipse Luna Build id 20140612 0600 32 位 开始使用 lambda 后 我的项目中的一些类开始在 Maven 中报告编译错
  • Javascript 前进后退按钮

    我在我正在开发的网站的主页上使用 s3Slider javascript 幻灯片 http alexisparkinn com http alexisparkinn com 我真的很喜欢这张幻灯片 但它无法让用户转到下一张或上一张图像 我怎
  • 有没有办法对VBA中的代码施加时间限制?

    我想知道是否有人有对代码段施加时间限制的经验 我已经用 VBA 将搜索引擎编程到 Excel 电子表格中 并且有一段代码可以删除重复的结果 现在 如果给出最模糊的搜索条件 这部分有时可能会持续相当长的时间 所以我想对这个操作施加一个时间限制
  • 使用滑块更改 QTimer 的间隔超时

    timer new QTimer this timer gt setInterval 50 QPushButton start new QPushButton Start Stop this start gt setText Start S
  • 使用 Core Data(在 SwiftUI 中)提供的数据并与另一个视图共享

    我在这里遇到了一些麻烦Core Data and SwiftUI 我的主视图可以访问来自实体的一些信息Core Data 我想使用某种绑定将其传递给子视图 以便它也可以访问该数据并可能更新它 这是我尝试过的代码的一个版本 在主视图一侧 En
  • 如何在此 React 18 应用程序中即时验证表单字段?

    我正在使用 React 18 和 Firebase 开发一个聊天应用程序 In the src pages Register jsx组件 我有一个可以验证的表单简单的身体验证器 https github com jadKhoury1 sim
  • 如何在组织模式下使用其他标题样式,例如 twiki ---+ 或 mediawiki == h2 == ?

    我真的很想使用组织模式 但是 我想使用 org mode 来理解已经使用不同标题语法编写的结构化文档 例如使用 twiki 的 H1 Top level H2 Nested H1 2 Second top level 或者类似媒体维基 H1
  • 将内存映射与服务一起使用

    我构建了一个也可以作为服务运行的应用程序 使用 service 转变 当我从命令提示符运行服务时 这可以完美地工作 没有任何问题 我设置了一些设置 可以让我在不作为真正的服务运行时从控制台调试它 但是 当我尝试将其作为真正的服务运行然后使用