Background
In Silverlight 4, Out Of Browser with elevated permission is significantly improved, now the OOB application has more privileges in accessing system resources such as the ability of accessing Isolated Storage, manipulating COM objects, access local registry entries, or even invoke Microsoft Speech API to phonate.
Essentially, to achieve this, the main improvements are:
- Microsoft gives Silverlight 4 OOB applications ability to request elevated trust.
From Trusted Applications
You can configure out-of-browser applications to require elevated trust. After installation, these trusted applications can bypass some of the restrictions of the security sandbox. For example, trusted applications can access user files and use full-screen mode without keyboard restrictions.
- A new concept coming from .NET 4.0 called “late binding”, the C# keyword:
dynamic
could be used to declare an undetermined type at build time, during runtime, Microsoft.CSharp.RuntimeBinder will do dynamically building.
Introduction
My post is going to concentrate on discussing about elevated trust, so read the articles below if you have any issues about creating OOB and request elevated permission.
I developed a simple Silverlight OOB demo, it will access local system resources including:
Screenshot
After installing on the system, its UI is shown below (I know it is really poor… Sorry):
Implementation
The elevated permission is ONLY enabled in Out Of Brower scenario, so in our Silverlight application we need to check whether currently it is running out of browser:
if(Application.Current.IsRunningOutOfBrowser)
In addition, to invoke COM objects, we need to check whether AutomationFactory
is available:
if (AutomationFactory.IsAvailable)
OK, here we go to see the code behind to implement elevated permission.
- Clicks on Button – “Copy File to Isolated Storage access”, a File open dialog will popup, screenshot below:
Code behind to open file dialog:
OpenFileDialog dlg = new OpenFileDialog { Filter = "All files (*.*)|*.*", Multiselect = true };
var dlgResult = dlg.ShowDialog();
Read selected file(s) and copy them to isolated storage:
IsolatedStorageFile iso = IsolatedStorageFile.GetUserStoreForApplication();
foreach (FileInfo file in dlg.Files)
{
using (Stream fileStream = file.OpenRead())
{
using (IsolatedStorageFileStream isoStream =
new IsolatedStorageFileStream(file.Name, FileMode.Create, iso))
{
while (true)
{
byte[] buffer = new byte[100001];
int count = fileStream.Read(buffer, 0, buffer.Length);
if (count > 0)
{
isoStream.Write(buffer, 0, count);
}
else
{
break;
}
}
}
}
}
Code behind for “Load file from isolated storage”:
var isoFiles = from files in IsolatedStorageFile.GetUserStoreForApplication().GetFileNames()
select files;
- Create a text file at “C:\WayneTestSL4Fso\WayneTest.txt”, please note: if you use
System.IO.File
to do such operation, you won’t succeed, I guess it is because elevated trust is still not directly implemented in a lot of managed assemblies. Here in my demo, I used Scripting.FileSystemObject
:
private String folderPath = "C:\\WayneTestSL4FSO";
private String filePath = "C:\\WayneTestSL4Fso\\WayneTest.txt";
using (dynamic fso = AutomationFactory.CreateObject("Scripting.FileSystemObject"))
{
if (!fso.FolderExists(folderPath)) fso.CreateFolder(folderPath);
dynamic txtFile = fso.CreateTextFile(filePath);
txtFile.WriteLine("Some text...");
txtFile.close();
}
P.S. While I used “dynamic
” keyword for the first time within a using
statement, I was a little bit surprised, I can simply tried to dispose a dynamic object without checking whether it has implemented IDisposible
, hence I tried run using (dynamic x = 8 )
, then I got this:
OK, let’s back to the code implementation for reading the text file I just created:
var fileContent = String.Empty;
using (dynamic fso = AutomationFactory.CreateObject("Scripting.FileSystemObject"))
{
dynamic file = fso.OpenTextFile(filePath);
fileContent = file.ReadAll();
file.Close();
}
- Registry write/read, please note: we can only have registry write permission to HKCU NOT HKLM, we have read permission to HKLM entries.
using (dynamic wScript = AutomationFactory.CreateObject("WScript.Shell"))
{
wScript.RegWrite(@"HKCU\Software\WayneTestRegValue",
"SomeStrValue", "REG_SZ");
}
using (dynamic wScript = AutomationFactory.CreateObject("WScript.Shell"))
{
string dotNetRoot =
wScript.RegRead(@"HKLM\SOFTWARE\Microsoft\.NETFramework\InstallRoot");
}
- Run another local application:
using (dynamic wScript = AutomationFactory.CreateObject("WScript.Shell"))
{
wScript.Run("iexplore http://wayneye.com", 1, true);
}
Note 1: WScript.Shell.Run
method can accept not only executable files, but also accepts *.bat, Windows Script Host files (*.vbs, *.js) or PowerShell script files, etc.
Note 2: Intention to elevate more permission by running another EXE or script file definitely won’t success, for example, if I try to invoke AccessKHLM.js below from my OOB application, I will get a 80070005 error code that indicates access denied:
var WshShell = WScript.CreateObject("WScript.Shell");
WshShell.RegWrite("HKLM\\Software\\WayneTestValue\\", 1, "REG_BINARY");
WshShell.Close();
If you double click the Demo.js, you will succeed since you are a Windows Administrator, while “Silverlight-based applications run in partial trust, which means they run within a security sandbox“. For more information, please refer to Trusted Application.
- Phonate a sentence:
using (dynamic speechApi = AutomationFactory.CreateObject("Sapi.SpVoice"))
{
speechApi.Speak(this.txtPhonateSource.Text);
}
- Code to implement close button “X” appears on the upper-top corner.
using (var wScript = AutomationFactory.CreateObject("WScript.Shell"))
{
wScript.Run(@"cmd /k taskkill /IM sllauncher.exe & exit", 0);
}
This is a little bit tricky, I searched a while on Google and found a great article Programmatically exit Silverlight 4 Out-of-browser application. Essentially, the code invokes WScript.Shell
and runs cmd and terminates sllauncher.exe, so that our OOB process got killed.
Conclusion
With elevated trust for Silverlight OOB applications, we can do much more than ever, it gives more confidence to develop Enterprise business applications using Silverlight technology, yesterday I saw Scott Guthrie posted a blog talking about Silverlight, he mentioned Microsoft will absolutely continue work hard on Silverlight for Enterprise Business Applications (both online and OOB).
References
Filed under: Silverlight Development
Tagged: C#, CodeProject, COM, IsolatedStorage, Out Of Browser, Silverlight