跨程序实现数据传递之FileMapping实现

一、传递数据结构定义及公共单元代码:

需要引入单元:winapi.windows;

1、声明部分

//用户库及主程序间数据共享相关
TAuthOnlineInfo = record
  IsDLL: Boolean;
  IsOnline: Boolean;
  IsAuth: Boolean;
  IsToDB: Boolean;
  CurDBID: Integer;
  UserName: string[255];
end;
PAuthOnlineInfo = ^TAuthOnlineInfo;
TAuthOnlineHelp = class
private
  const KeyName = ‘{89B70110-BC0A-426F-B097-3FC0271744AE}‘;

  class var FMapFile: THandle;
  class var FBuf: Pointer;
  class var FExist: Boolean;

  class function IsNT: Boolean;
public
  class function Exist: Boolean;
  //创建映射
  class function CreateMap(AInfo: PAuthOnlineInfo): Boolean;
  //更新映射
  class function UpdateMap(AInfo: PAuthOnlineInfo): Boolean;
  //关闭映射
  class procedure CloseMap;
  //获取映射数据
  class function GetAuthOnlineInfo(AInfo: PAuthOnlineInfo): Boolean;
end;

2、实现部分

{ TAuthOnlineHelp }

class procedure TAuthOnlineHelp.CloseMap;
begin
  if FBuf <> nil then
    UnMapViewOfFile(FBuf);
  if FMapFile <> 0 then
    CloseHandle(FMapFile);
  FBuf := nil;
  FMapFile := 0;
end;

class function TAuthOnlineHelp.CreateMap(AInfo: PAuthOnlineInfo): Boolean;
var
  SecurityDescriptor: TSecurityDescriptor;
  SecurityAttr: TSecurityAttributes;
begin
  //需要加安全设置,才能跨用户进程访问
  if IsNT then
  begin
    SecurityAttr.nLength := SizeOf(SECURITY_ATTRIBUTES);
    SecurityAttr.bInheritHandle := True;
    SecurityAttr.lpSecurityDescriptor := @SecurityDescriptor;

    if not InitializeSecurityDescriptor(@SecurityDescriptor, 1) then
      raise Exception.CreateFmt(‘初始化安全设置失败(%d)‘, [GetLastError]);
    if not SetSecurityDescriptorDacl(@SecurityDescriptor, TRUE, nil, FALSE) then
      raise Exception.CreateFmt(‘安全设置错误(%d)‘, [GetLastError]);
    if not SetKernelObjectSecurity(GetCurrentProcess, DACL_SECURITY_INFORMATION,
      @SecurityDescriptor) then
      raise Exception.CreateFmt(‘安全设置失败(%d)‘, [GetLastError]);

    FMapFile := CreateFileMapping($FFFFFFFF, @SecurityAttr, PAGE_READWRITE,
      0, SizeOf(TAuthOnlineInfo), PChar(KeyName));
  end
  else
    FMapFile := CreateFileMapping($FFFFFFFF, nil, PAGE_READWRITE,
      0, SizeOf(TAuthOnlineInfo), PChar(KeyName));
  if (FMapFile = 0) or (GetLastError() = ERROR_ALREADY_EXISTS) then
  begin
    Result := False;
    Exit;
  end
  else
    Result := True;
  FBuf := MapViewOfFile(FMapFile, FILE_MAP_ALL_ACCESS, 0, 0, 0);
  if (FBuf = nil) then
  begin

    raise Exception.CreateFmt(‘映射内存空间失败 (%d).‘, [GetLastError]);
      CloseHandle(FMapFile);

    Result := False;
    Exit;
  end
  else if AInfo <> nil then
   CopyMemory(FBuf, AInfo, SizeOf(TAuthOnlineInfo));
  FExist := True;
end;

class function TAuthOnlineHelp.Exist: Boolean;
begin
  Result := FExist;
end;

class function TAuthOnlineHelp.GetAuthOnlineInfo(AInfo: PAuthOnlineInfo): Boolean;
var
  hMapFile: THandle;
  pBuf: Pointer;
begin
  Result := False;
  if (AInfo= nil) then Exit;

  hMapFile := OpenFileMapping(FILE_MAP_READ, FALSE, PChar(KeyName));
  if hMapFile = 0 then
  begin
    Result := False;
    Exit;
  end;

  pBuf := MapViewOfFile(hMapFile, FILE_MAP_READ, 0, 0, SizeOf(TAuthOnlineInfo));
  if (pBuf = nil) then
  begin
    CloseHandle(hMapFile);
    Result := False;
    Exit;
  end;
  CopyMemory(AInfo, pBuf, SizeOf(TAuthOnlineInfo));
  UnmapViewOfFile(pBuf);
  CloseHandle(hMapFile);

  Result := True;
end;

class function TAuthOnlineHelp.IsNT: Boolean;
var
  OS: TOSVERSIONINFO;
begin
  OS.dwOSVersionInfoSize := SizeOf(TOSVERSIONINFO);
  GetVersionEx(OS);
  Result := (OS.dwMajorVersion >= 5) or (OS.dwPlatformId = VER_PLATFORM_WIN32_NT);
end;

class function TAuthOnlineHelp.UpdateMap(AInfo: PAuthOnlineInfo): Boolean;
begin
  Result := False;
  if (AInfo= nil) then Exit;

  if FMapFile = 0 then
    Exit
  else
  begin
    CopyMemory(FBuf, AInfo, SizeOf(TAuthOnlineInfo));
    Result := True;
  end;
end;

二、创建映射的进程代码 

New(pInfo);  //pInfo 类型PAuthOnlineInfo 
pInfo.IsDLL := False;
pInfo.CurDBID := ASheet.App.BaseData.CurUserDBID;
if TAuthOnlineHelp.Exist then
  TAuthOnlineHelp.UpdateMap(pInfo)
else
  TAuthOnlineHelp.CreateMap(pInfo);
Dispose(pInfo);
ShellExecute(0, ‘Open‘, PWideChar(sFileName), nil, nil, SW_SHOWMAXIMIZED);  //sFileName是第二个进程名称

三、读取映射文件的进程代码

New(pInfo);   //pInfo 类型PAuthOnlineInfo 
TAuthOnlineHelp.GetAuthOnlineInfo(pInfo);

时间: 2025-01-10 03:25:16

跨程序实现数据传递之FileMapping实现的相关文章

Android 跨程序共享数据,探究内容提供器

内容提供器(Content Provider)主要用于在不同的应用程序之间实现数据共享的功能,它提供了一套完整的机制,允许一个程序访问另一个程序中的数据,同时还能保证被访问数据的安全性.目前,使用内容提供器是 Android 实现跨程序共享数据的标准方式. 不同于文件存储和 SharePreferences 存储中的两种全局可读写操作模式,内容提供器可以选择只对哪一部分数据进行共享,从而保证我们程序中的隐私数据不会有泄露的风险. 访问其他程序中的数据: 对于每一个应用程序来说,如果想要访问内容提

内容提供者(Content Provider)--跨程序共享数据

内容提供者简介 访问其他应用中的数据 ContentResolver 的基本用法 实例读取系统联系人 创建自己的内容提供器 创建内容提供器的步骤 创建新类继承ContentProvider并且重写其中6个方法 内容URI参数 使用UriMatcher实现匹配内容URI的功能 getType函数介绍 实现跨程序数据共享 内容提供者 访问自己创建的内容提供者数据 遇到的问题 内容提供者简介 使用场景: 比如:电话薄,短信,媒体库 简介 主要用于在不同的应用程序之间实现数据共享的功能,它提供了一套完整

跨程序共享数据

一.内容提供器 内容提供器(Content Provider)主要用于在不同的应用程序之间实现数据共享的功能,它提供了一套完整的机制,允许一个程序访问另一个程序中的数据,同时还能保证被访数据的安全性. 内容提供器的用法一般有两种,一种是使用现有的内容提供器来读取和操作相应程序中的数据,另一种是创建自己的内容提供器给我们程序的数据提供外部访问接口. 二.ContentResolver 的基本用法 对于每一个应用程序来说,如果想要访问内容提供器中共享的数据,就一定要借助ContentResolve

android——实现跨程序访问数据

使用之前的SQLite存储的应用程序.首先需要在这个应用程序中创建内容提供器,右击com.example.administrator.exp7包→New→Other→Content Provider,会弹出这样的对话框, 其中Class name 是内容提供器的名字,Authorities是包名com.example.administrator.exp7,Exported表示是否允许外部程序访问内容提供器,Enabled表示是否启用这个内容提供器. 然后修改MyContentProvider中的

内容提供者(Content Provider)——跨程序共享数据

内容提供者 Content Provider 应用的数据库是不允许其他应用访问的 内容提供者的作用就是让别的应用访问到你的数据库 自定义内容提供者,继承ContentProvider类,重写增删改查方法, 如果想要访问ContentProvider中的共享的数据,就一定要借助ContentResolver类 进行CRUD操作 insert() 添加数据 update() 更新数据 delete() 删除数据 query() 查询数据 getContentResolver().query(uri,

android: 实现跨程序数据共享

简单起见,我们还是在上一章中 DatabaseTest 项目的基础上继续开发,通过内容提供器 来给它加入外部访问接口. 打开 DatabaseTest 项目,首先将 MyDatabaseHelper 中使用 Toast 弹出创建数据库成功的提示去除掉,因为跨程序访问时我们不能直接使用 Toast.然后添加 一个 DatabaseProvider 类,代码如下所示: public class DatabaseProvider extends ContentProvider { public sta

从控制器到视图的数据传递

一.ViewData 1.ViewData是一种字典集合数据(即键值对类型),是“视图基类”和“控制器基类”的属性 2.常见用法是在控制器中写入数据,在视图中读取数据 3.ViewData的values可以存放任意数据类型的数据,因此使用时需要强制类型转换 二.ViewBag动态对象 1.ViewBag是dynamic类型对象,同样也是“视图基类”和“控制器基类”的属性 2.ViewBag使用更加灵活方便(可以直接使用,编写的时候不会进行错误检查,但是运行的时候没有就会报错) 3.ViewBag

小程序跨页面数据传递与事件响应

在实际工作中有很多场景需要在第二个页面中将用户操作之后的将数据回传到上一页面.接下来将我的方案分享给小伙伴. 本次示例采用 uni-app 框架和 weui 样式库 实现思路 创建一个 Emitter,用于事件处理 创建一个 ... 在实际工作中有很多场景需要在第二个页面中将用户操作之后的将数据回传到上一页面.接下来将我的方案分享给小伙伴. 本次示例采用 uni-app 框架和 weui 样式库 实现思路 创建一个 Emitter,用于事件处理 创建一个全局的 Storage 在第一个页面创建一

html5跨域数据传递(postMessage)

在html5中有个支持跨域传递的方法postMessage,可是实现iframe之间的数据传递! 代码如下:数据发送页面 <!DOCTYPE HTML> <html lang="en"> <head> <meta charset="utf-8"/> <meta name="copyright" content=""/> <meta name="keyw