Yesterday we discussed on Silverlight 5 RC Feature called PInvoke. Hope that was informative for you. We learned how to call system APIs from Silverlight application. We demonstrated this using In-Browser application, but you can use that for Out-Of-Browser too easily.
In Silverlight 4, if we wanted to access system drive or any files, we had to use the COM APIs and this was only applicable from Out-Of-Browser applications. In this article, we will show you the way to access system resources using PInvoke in Silverlight 5. You can call this directly from Browser applications as well as Out-Of-Browser applications. Read to know more.
Prerequisite
This article is based on Silverlight 5 RC. If you didn't install the latest RC bits, download them from "Download Silverlight 5 RC". Before downloading and installing the bits, make sure that, you removed the previous Beta version of Silverlight 5 completely.
You also need to know about the changes in Elevated Trust Settings in Silverlight 5 RC. Read it from the blog post: “Elevated Trust Settings for Out-of-Browser and In-Browser”.
Once you are done with the above prerequisite, let’s jump into the actual post where we will discuss about PInvoke with a small and simple demo.
Overview
Platform Invoke has been added newly to Silverlight 5 Release Candidate. It’s not a class or method. It’s just a way to communicate with system resources. If you are a .Net developer, you must be aware of the [DllImport(“”)] attribute to include system assemblies in your project and call those APIs.
To demonstrate it, we will import the “kernel32.dll” of the Windows System and we will call the CreateDirectory() method present in the assembly as exposed APIs.This method takes path and attributes as parameters and creates the directory. Windows uses the same API to create directories.
Designing the UI
It’s time for us to design the UI. We will use a TextBox and a Button control in the UI. User will be able to enter the name of the directory that he wants to create. Once he hits the button, the Silverlight application will create the folder in ‘C’ drive (for example). This is the UI that we will develop now:
Let’s open the XAML page and split the Grid with some Rows and Columns according to the UI that we need. Place a TextBox and a Button control at appropriate location of the Grid. Register a click event to the button.
Here is the complete XAML code for your reference:
<UserControl x:Class="PInvokeDemo.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Height="300" Width="400">
<Grid x:Name="LayoutRoot" Background="White" Margin="20">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="36"/>
<RowDefinition Height="8"/>
<RowDefinition Height="26"/>
<RowDefinition Height="8"/>
<RowDefinition Height="26"/>
</Grid.RowDefinitions>
<TextBlock Text="PInvoke Demo using Silverlight 5"
FontSize="20" Grid.Column="0" Grid.Row="0" Grid.ColumnSpan="2"/>
<TextBlock Grid.Column="0" Grid.Row="2" Grid.RowSpan="3" TextWrapping="Wrap">
<Run Text="Enter Folder Name: "/>
<LineBreak/>
<Run Text="Folder will be created at c:\"/>
</TextBlock>
<TextBox x:Name="txtFolderName" Grid.Column="1" Grid.Row="2"/>
<Button Content="Create Folder" Grid.Column="1" Grid.Row="4"
Click="CreateFolder"/>
</Grid>
</UserControl>
I have decorated the UI for clear visibility. You may not need all the things as shown above.
Playing with the Code
It’s time to play with the code. Open the MainPage.xaml.cs and inside the class, declare the API from the kernel32.dll. Before declaration, import the DLL using DllImport attribute. Then declare the APIs that you want to use. For our example, we will use only the CreateDirectory() method. So, we will declare only that API. Here is the declaration:
[DllImport("kernel32.dll")]
static extern bool CreateDirectory(string lpPathName, IntPtr lpSecurityAttributes);
Once the declaration is done, we will implement the button click event. Inside the button click event, write the following code:
private void CreateFolder(object sender, RoutedEventArgs e)
{
var folderName = txtFolderName.Text;
if (!string.IsNullOrWhiteSpace(folderName))
{
MessageBox.Show(CreateDirectory("C:\\" + folderName, IntPtr.Zero)
? string.Format("Folder named \"{0}\" created at \"C:\\\"", folderName)
: string.Format("Unable to create folder: {0}", folderName));
}
else
{
MessageBox.Show("Enter a Name");
}
}
This code will check the name of the folder that user specified. If it is not null, it will call the API with specified attributes. If it succeeds to create the directory, it will show directory created message. If it fails (possible reason may be, directory already exists), it will show proper message to the user.
Download Source
Need the complete project source code for reference? You can download it from here: PInvoke Demo (32 KB)
Demo
Let’s see a demo of what we implemented just now. Let us open the ‘C’ drive in Windows Explorer. Now we will run the application that we developed just now. Enter a name of the directory that we want to create. Make sure that, we are not specifying any name that already exists. Click “Create Folder” button.
This will create the folder in ‘C’ drive as shown below:
Wao! We are now able to create the folder from browser window itself and without using any COM operation. We are directly invoking the system APIs to do system specific operations.
Now, we will again hit the button with the same name mentioned in the TextBox and this will popup a message box stating that it was unable to create the folder in the specified location because, the folder is already present there.
Hope, this information was helpful for you to understand the basic development feature of PInvoke. If you understood this simple demonstration, we will be able to develop complex applications using the same. You can get directory structures, you can get drive information, you can get any other system specific information or can do some system operations.
End Note
Again, make sure that, you marked the application as trusted one before building the project else you will get some security exception. By default, the “localhost” domain is trusted for development purpose. You need to change a registry value for development. To put it to the production environment, you need to sign the XAP for trusting.
Finally, here are some good articles on the same topic that you may want to read:
Stay tuned to my coming articles on Silverlight 5 Release Candidate in my blog.