Windows 8 introduced WinRT(Windows Runtime) that allows us to develop applications based on C++, C#, Vb and JavaScript by allowing access to its Api and by allowing communication between different programming languages. Communication between languages is possible through Windows Runtime Component that creates WinMD Assembly. WinMD Assembly is a Assembly that contains metadata but can also contain types.
When you try to create Windows 8.1 store app you cannot add usual Class Library, you have to add Windows Runtime Component and there you can write your usual code.
Trying to add Class library to your Store App will result in “Unable to add a reference to project” error.
WinMD limitations (copied from https://www.microsoftpressstore.com/articles/article.aspx?p=2199428&seqNum=3):
- The fields, parameters, and return values of all the public types and members in your component must be WinRT types.
- Public structures may not have any members other than public fields, and those fields must be value types or strings.
- Public classes must be sealed. If your programming model requires polymorphism, you can create a public interface and implement that interface on the classes that must be polymorphic. The only exceptions are XAML controls.
- All public types must have a root namespace that matches the assembly name, and the assembly name must not begin with “Windows.”
Why would I need to create WinMD class library?
Lets explore it through Windows store app example.
Create new Solution and there add two Blank App.s for Windows 8.1 (one for C# and another for JS).
Both of these apps should have:
2x Textbox
1x Label
2x Button
Goal of this Application is to create Application where you can input data inside two different TextBoxes and combine their values inside Label after clicking button. Second goal is to copy some text value in your clipboard(simply copy some text with Ctrl+C) and display value in Label after clicking second button.
All this code can be easily achieved by writing it in backend of MainPage.xaml.cs file or inside JavaScript function, but we want our Application to share code, and that is here WinMD steps in. You can create methods that perform that actions and reuse it across different applications and different languages. Yup, even JavaScript can use WinMD classes written in C#.
Example of WinMD / Windows Runtime Component Assembly
MainPage.xaml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
<Page x:Class="XamlApp.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:XamlApp" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"> <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> <TextBox x:Name="TextBox1" HorizontalAlignment="Left" Margin="50,50,0,0" TextWrapping="Wrap" Text="First Word" VerticalAlignment="Top" Width="306"/> <TextBox x:Name="TextBox2" HorizontalAlignment="Left" Margin="50,100,0,0" TextWrapping="Wrap" Text="Second Word" VerticalAlignment="Top" Width="306"/> <TextBox x:Name="TextBox3" HorizontalAlignment="Left" Margin="50,150,0,0" TextWrapping="Wrap" Text="Result" VerticalAlignment="Top" Width="306"/> <Button x:Name="Button1" Content="Combine Text" HorizontalAlignment="Left" Margin="47,200,0,0" VerticalAlignment="Top" Click="Button1_Click"/> <Button x:Name="Butonn2" Content="Get Clipboard data" HorizontalAlignment="Left" Margin="47,250,0,0" VerticalAlignment="Top" Click="Butonn2_Click"/> </Grid> </Page> |
default.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>JsApp.Windows</title> <!-- Style --> <style> body { display: block; } #txtBox1, #txtBox2, #result, .button { display: inherit; margin: 20px; } </style> <!-- WinJS references --> <link href="//Microsoft.WinJS.2.0/css/ui-dark.css" rel="stylesheet" /> <script src="//Microsoft.WinJS.2.0/js/base.js"></script> <script src="//Microsoft.WinJS.2.0/js/ui.js"></script> <!-- JsApp.Windows references --> <link href="/css/default.css" rel="stylesheet"/> <!-- Functions --> <script type="text/javascript"> function combineText() { var hlpClass = new WindowsRuntimeComponentTest.HelperClass(); document.getElementById('result').innerText = hlpClass.combineTwoStrings(window.txtBox1.value, window.txtBox1.value); } // JavaScript has already function to get clipboard data so there is no need to use GetTextFromClipboard method function getClipboard() { document.getElementById('result').innerText = window.clipboardData.getData('Text'); } </script> </head> <body> <input type="text" id="txtBox1" value="First Word"/> <input type="text" id="txtBox2" value="Second Word"/> <label id="result">Result</label> <button class="button" onclick="combineText()">Combine Text</button> <button class="button" onclick="getClipboard()">Get Clipboard data</button> </body> </html> |
MainPage.xaml.cs – Buttons
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
private void Button1_Click(object sender, RoutedEventArgs e) { HelperClass hlpClass = new HelperClass(); TextBox3.Text = ""; TextBox3.Text = hlpClass.CombineTwoStrings(TextBox1.Text, TextBox2.Text); } private async void Butonn2_Click(object sender, RoutedEventArgs e) { HelperClass hlpClass = new HelperClass(); TextBox3.Text = ""; TextBox3.Text = await hlpClass.GetTextFromClipboard(Clipboard.GetContent()); } |
Windows Runtime Component – Helper class
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
public sealed class HelperClass { public string CombineTwoStrings(string v1, string v2) { return v1 + " " + v2; } public IAsyncOperation<string> GetTextFromClipboard(DataPackageView clipboard) { var result = ReturnStringFromClipboardData(clipboard).AsAsyncOperation(); return result; } internal async Task<string> ReturnStringFromClipboardData(DataPackageView value) { string cliboardStringValue = await value.GetTextAsync(); return cliboardStringValue; } } |
If you wish to inspect entire solution , download it from this link.
Please do not use code from solution for your projects because no checks were implemented what so ever.