1. Silverlight 4, есть ли жизнь на
десктопе?
Евгений Жарков
Silverlight MVP/MCTS
2. Silverlight
Windows
ПК
Phone 7
Вне
Браузер
браузера
3. Out of browser (OOB)
• Управление окном
• Настройка внешнего вида окна
• Размещения HTML внутри приложения
• Окна уведомлений
• Digital Rights Management (DRM)
• Расширенные права
• Доступ к файловой системе
• COM
• Интегрированная возможность обновления
10. Тихая установка XAP
Инсталляция
/install:"xapFile" – where xapFile is the file name/file path to the .xap file., E.g.
/install:"c:tempsample.xap"
/origin:"xapURI" – where xapURI is the URI where the .xap file would've come from if not
installed at the commandline
e.g. /origin:"http://example.com/sample.xap" . This URI will be used as the site of
origin for security purposes. For example, for sandboxed applications, Silverlight
networking requires a policy file check when making network requests to domains
other than the site of origin. The origin also serves as a unique ID for the
application. The xapURI must be an absolute URI not a relative URI, and must start
with http:, https:, or file:.
/overwrite -- (optional) Overwrites any previously installed .xap with that xapURI.
Деинсталляция
/uninstall – Uninstalls the application specified in /origin. This is the same /origin value
that was used to install the app originally.
/origin:"xapURI" – same as /origin for the install case
11. Тихая установка XAP
Установка
sllauncher.exe
/install:"{LocalPathToXapFile}Yourfile.xap"
/origin:"{urltoxapfile}/Yourfile.xap"
/shortcut:desktop+startmenu
Автозапуск
"%ProgramFiles%Microsoft Silverlightsllauncher.exe"
/emulate:"Yourfile.xap"
/origin:"http://blabla.com/Yourfile.xap"
Деинсталляция
"%ProgramFiles%Microsoft Silverlightsllauncher.exe"
/uninstall
/origin:"http://blabla.com/Yourfile.xap"
12. Тихая установка Silverlight
/q - quiet install or upgrade. This installs or upgrades Silverlight
without seeing the GUI. When Silverlight is installed quietly, by default
privacy related features such as DRM protected media playback and
the Silverlight auto-update feature will be configured to prompt the
user for permission on 1st use of the respective features. The
Silverlight auto-update feature requires administrative rights so non-
admin users will not be prompted.
/doNotRequireDRMPrompt - turns off the 1st use prompt allowing
content protected by Digital Rights Management (DRM) to play
without requiring any end-user intervention. When Silverlight is
installed quietly, DRM Playback is set to prompt on 1st use by default.
/ignorewarnings - non-fatal warnings will not be reflected in the quiet
installer return code but will instead return zero indicating success.
/noupdate - disables the Silverlight internal auto-updater.
/qu - quiet uninstall. This uninstalls Silverlight without seeing the GUI.
14. NSIS Script Example
Name “Test Out of Browser Installer"
OutFile “TextOOBInstaller.exe"
InstallDir "$PROGRAMFILESTestOOB"
XPStyle on
Section
SetOutPath "$INSTDIR"
SetOverwrite ifnewer
File "Silverlight.exe"
ExecWait "$INSTDIRSilverlight.exe /q /doNotRequireDRMPrompt"
File “TestOOB.xap"
ExecWait '"$PROGRAMFILESMicrosoft Silverlightsllauncher.exe"
/install:"$INSTDIRTestOOB.xap"
/origin:"http://blabla.com/TestOOB.xap"
/shortcut:desktop+startmenu'
SectionEnd
15. Batch Script
:: Is this a 64-bit machine?
@echo off
if exist "%ProgramFiles(x86)%" (
:: We're on 64-bit
set sllauncherlocation="%ProgramFiles(x86)%Microsoft
Silverlightsllauncher.exe"
) else (
::We're on 32-bit
set sllauncherlocation="%ProgramFiles%Microsoft
Silverlightsllauncher.exe"
)
:: run SL
%sllauncherlocation% /overwrite /emulate:“TestOOB.xap"
/origin:"http://blabla/TestOOB.xap"
16. Мои документы
我的文件
My Eigene
Documents Dateien
Mes docum
ents Documents
Мои Τα
документы έγγραφά
μου
17. Batch Script User Folder
Извлекаем правильный адрес директории “Мои документы” из
реестра
FOR /F "tokens=3 delims= " %%G IN ('REG QUERY
"HKCUSoftwareMicrosoftWindowsCurrentVersionExp
lorerShell Folders" /v "Personal"') DO (SET docsdir=%%G)
22. Многоязычный интерфейс
Регистрация ресурса
public class LocalizationResource : INotifyPropertyChanged
{
private static Localization.Strings resource = new Localization.Strings();
public Localization.Strings Strings
{
get { return resource; }
set { OnPropertyChanged("Strings"); }
}
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
#endregion
}
23. Многоязычный интерфейс
Переключение языка UI
Thread.CurrentThread.CurrentUICulture = new CultureInfo("uk-UA");
((LocalizationResource)Application.Current.Resources["Localizatio
n"]).Strings = new MyApplication.Localization.Strings();
24. COM
Подключаем пространство имен
using System.Runtime.InteropServices.Automation;
Создаем файлы в любом месте на ПК
using (dynamic fsoCom =
AutomationFactory.CreateObject("Scripting.FileSystemObject"))
{
dynamic file = fsoCom.CreateTextFile(@"c:test.txt", true);
file.WriteLine("Bloody Hell!");
file.WriteLine("Silverlight is writing to C:");
file.Close();
}
25. COM
Пиним приложение на панель задач
using (dynamic ShellApplication =
ComAutomationFactory.CreateObject("Shell.Application"))
{
dynamic commonPrograms = ShellApplication.NameSpace(23);
string allUsersPath = commonPrograms.Self.Path;
dynamic directory = ShellApplication.NameSpace(allUsersPath +
@"Accessories");
dynamic link = directory.ParseName("Calculator.lnk");
dynamic verbs = link.Verbs();
for (int i = 0; i < verbs.Count(); i++)
{
dynamic verb = verbs.Item(i);
if (verb.Name.Replace(@"&", string.Empty).ToLower() == "pin
to taskbar")
{
verb.DoIt();
}
}
}
26. COM
Добавляем OOB-приложение в автозагрузку
using (dynamic ShellApplication =
ComAutomationFactory.CreateObject("Shell.Application"))
{
dynamic commonPrograms = ShellApplication.NameSpace(11);
string allUsersPath = commonPrograms.Self.Path;
dynamic directory = ShellApplication.NameSpace(allUsersPath +
@"Programs");
dynamic link =
directory.ParseName(Deployment.Current.OutOfBrowserSettings.ShortName +
".lnk");
string OOBLink = link.Path;
using (dynamic WShell =
ComAutomationFactory.CreateObject("WScript.Shell"))
{
WShell.RegWrite(@"HKLMSoftwareMicrosoftWindowsCurrentVersionRun"
+
Deployment.Current.OutOfBrowserSettings.ShortName,
OOBLink);
MessageBox.Show("Please restart your machine and this application will
load on startup.");
}
27. COM
Работа с ODBC
using (dynamic IDbConnection =
ComAutomationFactory.CreateObject("ADODB.Connection"))
using (dynamic IDbCommand =
ComAutomationFactory.CreateObject("ADODB.Command"))
{
IDbConnection.ConnectionString = "driver={SQL Server};" +
"server=.;uid=sa;pwd=password;database=Northwind";
IDbConnection.Open();
IDbCommand.ActiveConnection = IDbConnection;
IDbCommand.CommandText =
@"INSERT INTO [Northwind].[dbo].[Region]
([RegionID], [RegionDescription]) VALUES (10, 'BLa')";
IDbCommand.Execute();
}
31. Silverlight COM Toolkit
ComToolkit.Data
string connectionString = @"Provider=SQLOLEDB;Data
Source=servernamesqlexpress;Initial Catalog=databasename;User ID=username;
Password=password";
using (var connection = new ComToolkit.Data.AdoConnection(connectionString)) {
connection.Open();
var command = connection.CreateCommand();
command.CommandText = "SELECT MyColumn FROM MyTable";
var reader = command.ExecuteReader();
while (reader.Read()) {
object byindex = reader[0];
object bystring = reader["MyColumn"];
// для работы с динамическими свойства reader должен быть объявлен
как dynamic
//object bydynamic = reader.MyColumn;
}}
http://silverlightcom.codeplex.com/
32. Silverlight COM Toolkit
Асинхронный ComToolkit.Data
private ComToolkit.Data.AdoConnection connection;
private void ExecuteReaderAsyncSample() {
connection = new ComToolkit.Data.AdoConnection(connectionString);
connection.Open();
var command = connection.CreateCommand();
command.CommandText = "SELECT MyColumn FROM MyTable";
command.ExecuteReaderCompleted += new
EventHandler<ComToolkit.Data.ExecuteReaderCompletedEventArgs>(command_Ex
ecuteReaderCompleted);
command.ExecuteReaderAsync(); }
void command_ExecuteReaderCompleted(object
sender, ComToolkit.Data.ExecuteReaderCompletedEventArgs e) {
//TODO: обрабатываем результат
}
http://silverlightcom.codeplex.com/
34. XML Paper Specification (XPS)
Позитивные факторы
• В основе лежит ZIP, XML, XAML. Разработан Microsoft и Ecma
International, 2006 год
• Возможность относительно легкой конвертации в XAML
• Родная поддержка в Windows Vista/7
Негативные факторы
• Windows XP SP2 требует наличие .NET Framework 3 и XPS
Document Viewer
35. PDF
Позитивные факторы
• Бесплатные компоненты для обработки PDF-документа
• Возможность разместить документ в WebBrowser при наличии
Adobe Acrobat плагина
Негативные факторы
• Платные компоненты для обработки и отображения в
Silverlight-приложении
36. HTML
Позитивные факторы
• Возможно разместить внутри элемента управления
WebBrowser
Негативные факторы
• Невозможно открывать локальные файлы внутри WebBrowser
• Невозможно задать заголовочную информацию в WebBrowser
• Невозможно открыть MHT-файлы
• Следует собирать все ресурсы в единый HTML-файл, включая
изображения, используя Data URI, который имеет ограничение
в 32КБ
37. Microsoft Office (Word, Excel, PowerPoint)
Позитивные факторы
• Работа с документами через COM
Негативные факторы
• Отсутствует родная поддержка в Silverlight
38. Microsoft Office (Word, Excel, PowerPoint)
Пример обработки Word документа
using (dynamic word =
AutomationFactory.CreateObject("Word.Application"))
{
int wdFormatWebArchive = 9; // MHT fileformat
int wdDoNotSaveChanges = 0; // WdSaveOptions do not
save value
using (dynamic document = word.Documents.Open(tempDoc))
{
document.SaveAs("C:t.doc", ref wdFormatWebArchive);
}
word.Quit(ref wdDoNotSaveChanges);
}
39. События Office
Пример обработки Word документа
dynamic word = AutomationFactory.CreateObject("Word.Application");
word.Visible = true;
AutomationEvent searchEvent = AutomationFactory.GetEvent(word, "Quit");
searchEvent.EventRaised += (s, a) =>
{
MessageBox.Show("Quit");
};
dynamic document = word.Documents.Open("C:test.doc");
40. Потоки и BackgroundWorker
var bw = new BackgroundWorker();
bw.WorkerReportsProgress = true;
bw.DoWork += (s, a) => {
var worker = sender as BackgroundWorker;
worker.ReportProgress(0, "Сейчас начнем");
MessageBox.Show("Работаем");
worker.ReportProgress(100, «Закончили");
};
bw.ProgressChanged += (s, a) => {
MessageBox.Show("Current state" + a.ProgressPercentage.ToString());
// сложные объекты могут передаваться в e.UserState
};
bw.RunWorkerCompleted += (s, a) => {
MessageBox.Show("Done");
};
bw.RunWorkerAsync(new Dictionary<string, object> {
{ "file", "test.doc" },
{ "region", "Ukraine"}
});
41. Navigation Framework
Подключение пространства имен в XAML
<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:navigation="clr-
namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigatio
n"
xmlns:uriMapper="clr-
namespace:System.Windows.Navigation;assembly=System.Windows.Controls.Navigat
ion">
42. Navigation Framework
Добавление Frame
<navigation:Frame x:Name="ContentFrame" Source="/Action">
<navigation:Frame.UriMapper>
<uriMapper:UriMapper>
<uriMapper:UriMapping Uri="" MappedUri="/Pages/Action.xaml"/>
<uriMapper:UriMapping Uri="/{pageName}"
MappedUri="/Pages/{pageName}.xaml"/>
</uriMapper:UriMapper>
</navigation:Frame.UriMapper>
</navigation:Frame>
Переход на другую страницу
NavigationService.Navigate(new Uri("/INeedThisPage", UriKind.Relative));