Windows 8 Applications (formerly Metro) run inside a sandbox, making communicating with other application difficult at best. There is no easy way to do it, and for good reason, too. When one app is running, all other may be suspended, so what’s the point of communicating anyway? Furthermore, there is no guarantee that the other app even exists on the machine.
Still, suppose we wanted to share some information (I’m not talking about the standard share contract) via (say) shared memory. Can we achieve that?
Flipping to the documentation of the CreateFileMapping Win32 API shows that unfortunately this is only available for desktop apps. A new function exists, however, called CreateFileMappingFromApps that works only in Windows 8 apps. Great! Can we use that? Let’s try.
I’ve created two simple C++ Windows 8 Applications (Metro or Store apps) that have a simple UI consisting of a TextBox with two buttons, one for writing to the shared memory, the other for reading. The XAML looks something like this:
<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}"> <Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<TextBlock Grid.ColumnSpan="2" HorizontalAlignment="Center" FontSize="40" Text="Application 2" Margin="10"/>
<TextBox Grid.Row="1" Margin="20" AcceptsReturn="True" BorderThickness="2" Grid.ColumnSpan="2" x:Name="_text" FontSize="20"/>
<Button FontSize="40" Content="Write" HorizontalAlignment="Center" Grid.Row="2" Margin="10" Click="OnWrite"/>
<Button FontSize="40" Content="Read" HorizontalAlignment="Center" Grid.Row="2" Margin="10" Grid.Column="1" Click="OnRead"/>
</Grid>
In the MainPage constructor, we can create the file mapping (section) object and save it in a member handler:
m_hMemFile = ::CreateFileMappingFromApp(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 1 << 20, L"MySharedMem");
This creates a 1MB shared memory section named “MySharedMem” backed up by the system paging file.
To write some text into that memory, we can use the following code:
void * p = ::MapViewOfFileFromApp(m_hMemFile, FILE_MAP_WRITE, 0, 0);
::wcscpy((WCHAR*)p, _text->Text->Data());
::UnmapViewOfFile(p);
MapViewOfFileFromApp is the equivalent of MapViewOfFile API that is forbidden in Windows 8 apps. _text is the name of the TextBox created in XAML. Reading can be similarly achieved:
void * p = ::MapViewOfFileFromApp(m_hMemFile, FILE_MAP_READ, 0, 0);
_text->Text = ref new String((PWSTR)p);
::UnmapViewOfFile(p);
Running a single application has the desired effect – the memory is written and read from correctly, which may not be surprising.
If two similar application are running, that use the same code, i.e. – the same file mapping object name – sharing is possible.
However, trying this simply fails. The handles are created successfully, the writing and reading succeed as well. So, what’s wrong?
Opening Process Explorer reveals the unpleasant truth. Here’s the handle view for the first app, concentrating on the section object in question:

It seems that the name of the section is not really MySharedMem, but something that consists of some SID-looking string. Running another application shows the following in Process Explorer:

That’s a completely different name! That’s why the sharing wasn’t working.
Communicating between a desktop app and a Windows 8 app is problematic for exactly the same reason; desktop apps names are under the BasedNamedObjects logical directory (and not AppContainerNamedObjects).
One option that we can try is prefixing the object name with “Global\”, such as “Global\\MySharedMem”. This should create the object in session 0, allowing easy sharing. This, unfortunately, fails, because of a missing privilege that a Windows 8 app does not (and cannot) have.
The above is not specific to section objects, but to any kernel object created from a Windows 8 app process, such as a mutex, semaphore, file, etc. Another option we may consider is using the DuplicateHandle API, and although this is permitted, we first need a handle to the other process, which requires a call to OpenProcess, which, unfortunately cannot be used in Windows 8 apps.
So, there you have it. Windows 8 apps are really in a tight box.