4

My application is executing another process ("update.exe"), and I would like to pass large data (a Record maybe) from my app to the update program.

Using command line to pass the data parameter(s) is not an option, because the data is too big (also Data size may vary).

How to correctly create CreateFileMapping/MapViewOfFile/UnmapViewOfFile,
then Executing my update.exe,
finally Receiving the data in the update.exe program (OpenFileMapping),
and freeing all handles (from main app and update.exe) so I don't have memory/handle leaks?

Code would be nice (No JCL please). C++ is also fine. Thanks.


Edit: I think my main problem is how to "signal" the main app to UnmapViewOfFile and CloseHandle after update.exe done reading the data. (or maybe I need to use OpenFileMapping with bInheritHandle set to True in my child process?)
Here is an Example. How can the Second process read the data if the main process calls UnmapViewOfFile and CloseHandle?.

ZigiZ
  • 2,480
  • 4
  • 25
  • 41
  • 3
    But JCL is awesomeness defined... – Ignacio Vazquez-Abrams Feb 21 '12 at 16:51
  • 1
    A simple solution is to store the data in a file and pass the filename in the command line. – LU RD Feb 21 '12 at 18:10
  • 1
    @LURD, excatlly what I want to do, but pass FileMapping name as parameter and use `OpenFileMapping`... ;) – ZigiZ Feb 21 '12 at 18:24
  • 1
    Ok, I mean an ordinary file, but look here for an example of using windows file mapping, [Limiting multiple instances. Restoring last instance. The file mapping approach](http://delphi.about.com/od/windowsshellapi/l/aa100703c.htm). – LU RD Feb 21 '12 at 18:50

2 Answers2

2

You may find some good example at Inter-process communication. Right method depends on the size of your data and speed requirements.

Community
  • 1
  • 1
Adriano Repetti
  • 65,416
  • 20
  • 137
  • 208
1

Heres a code snippet from a memory mapped file we use to pass live video (uncompressed) between our applications, the SecurityDescriptor isn't needed but i've left it in and CreateWorldAccessDescriptor is one of our functions.

If you need to use this type of system to control messaging from services to application, or from applications running with different user credentials make sure you start your FileName with "Global\"

procedure TRawFeedImageQueue.CreateFileMap;
var
  SysInfo: TSystemInfo;
  sd: TSecurityDescriptor;
begin
  GetSystemInfo( SysInfo );
  MapGranularity := SysInfo.dwAllocationGranularity;
  MapSize := sizeof( TRawFeedImageQueueData );

  FSecObjOk := CreateWorldAccessDescriptor( sd, GENERIC_ALL );

  FileMappingHandle := CreateFileMapping( $FFFFFFFF, @sd, PAGE_READWRITE OR SEC_COMMIT, 0, MapSize and $FFFFFFFF, PChar(FFileName) );
  if FileMappingHandle <> 0 then
  begin
    MapView := MapViewOfFile( FileMappingHandle, FILE_MAP_ALL_ACCESS, 0, 0, MapSize );
  end
  else
  begin
    MapView := nil;
  end;
end;

procedure TRawFeedImageQueue.ReleaseFileMap;
begin
  if FileMappingHandle <> 0 then
  begin
    unMapViewOfFile( MapView );
    CloseHandle( FileMappingHandle );
  end;
end;

Hope that helps a bit.

Update

This code simply creates a MapView on the file of the whole file, and just a single view, you can of course create multiple smaller views on the same file if required.

Dampsquid
  • 2,456
  • 15
  • 14