21/02/2011
19/11/2010
Silverlight: Hoe refereer je een image, die in je XAP-file staat?
Af en toe is het nodig om een resource uit je eigen XAP-file te refereren. Er zijn veel voorbeelden te vinden op internet hoe je dat met WPF doet. Maar die werken vaak niet omdat de Assembly.GetName() functie in Silverlight niet werkt (zie referentie hieronder). In Silverlight werkt de volgende methode het beste:
// Get the simple name of the application
string appName = Application.Current.GetType().Assembly.FullName.Split (',') [0];
// Get the string that points to the image file in the subfolder Images
string uriStr = "/" + appName + ";component/Images/" + imageFilename;
// Get the relative URI
Uri uri = new Uri(uriStr, UriKind.Relative);
// Create the ImageSource for the image
ImageSource imgSource = new BitmapImage(uri);
Let op de “/”, waarmee de uriString start.
Referenties:
16/11/2010
MVVM en MEF: Verdere verdieping
Hieronder een lijstje met artikel, die mij meer inzicht gaven in het werken met MEF en MVVM:
- MVVM – Bad practice to reference a viewmodel from another viewmodel? Een artikel, waarin duidelijk wordt dat het aanroepen van ViewModels vanuit een “Master ViewModel” een van de best pratices van MVVM is.
- MVVM ViewModel linking to Model Een artikel, waarin duidelijk wordt dat volgens MVVM in principe de gehele interface van het Model herhaald wordt in het ViewModel. Bij een grote interface van misschien wel 50 properties, lijkt dat wel vreemd. Sommigen kiezen er dan ook voor om dan het Model in zijn geheel als property als een Property in het ViewModel te zetten. Volgens wordt dan in de View een binding gemaakt met de individuele property van het Model via Model.Property.
- Building Composable Apps in .NET 4 with the Managed Extensibility Framework Een artikel, waarin zeer helder de MEF architectuur stap-voor-stap wordt uitgelegd.
- MEF and an issue with ViewModels communicating with each other Een artikel, waarin een mooie discussie staat over hoe je ViewModels in ViewModels via MEF het beste kan aanroepen.
Verder een mooie serie van Glenn Block over het gebruik van MEF in Silverlight 4:
- Part I – Building the Hello MEF Dashboard in Silverlight 4
- Part II – Why being lazy is a good thing
- Part III – XAP partioning with the host’s permission and the sweetness of recomposition
En later nog een mooie serie van Jeremy Likeness over het gebruik van PRISM, MEF en MVVM:
12/11/2010
Encryptie met Silverlight en Decryptie met PHP
Ik had behoefte aan een manier om strings van Silverlight te encrypten en die met PHP te decrypten. Mijn vraag was hoe doe je dat?
In eerste instantie dacht ik dat het nodig was om een encryptie/decryptie algoritme te kiezen en daarvan een versie te hebben voor Silverlight en voor PHP. Daarbij kwam ik op een elegant algoritme uit, dat niet te veel processorkracht nodig had het TEA-algoritme. Maar daarmee was het probleem niet direct lekker opgelost. Want je moet dan ook een implementatie hebben. In ons geval aan de server kant een PHP-versie. En aan de client kant het liefst een C# versie. Maar bij het zoeken naar zo’n implementatie is het erg oppassen geblazen. Want er blijken verschillende varianten van het TEA algoritme te zijn. Een originele versie (TEA), een verbeterde versie (XTEA) en een nogmaals verbeterde versie (XXTEA). Soms is het duidelijk om welke versie het gaat, maar soms moet je het uit de code zelf halen. Bovendien geven sommige implementaties slechts een interface naar ruwe encryptie / decryptie methodes, waarbij je byte-arrays van een lengte van 8 bytes converteert. Om dan strings te kunnen converteren, moet je nog wat extra code maken, die string pad met spaties.
Al met al had ik op basis van een aantal artikelen een C# versie geproduceerd, die compatibel was met een PHP en Javascript implementatie van Babelfish.nl. Maar na verschillende mislukte pogingen om de Silverlight zijde met de PHP-zijde te laten praten, heb ik het maar opgegeven om op deze weg verder te gaan.
Volgende stap was om gebruik te maken van algoritmes, die al standaard in Silverlight en PHP zitten. En dan maar hopen dat die algoritmes ook met elkaar willen praten. Dat bleek nog een hele klus. Maar uiteindelijk is het me gelukt om een goed werkend encryptie / decryptie mechanisme te bewerkstelligen tussen Silverlight en PHP. Het algoritme dat ik daarvoor heb gebruikt is het AES algoritme. Het artikel, waar ik uiteindelijk de code aan te danken heb was: The PHP-silverlight Cryptography Challenge (hoewel in dat artikel nog een foutje zat met verkeerde lengtes van de key en de initialization vector en, naar zeggen van de auteur, de MD5 hash over het password). Verder heb ik veel hulp gehad van een artikel van Chilkat Software, Inc.:Understanding PHP AES Encryption
Uiteindelijk ziet mijn code er nu als volgt uit:
AesCryptographer.cs
using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;
namespace Aduba.Cryptography
{
public class AesCryptographer
{
private byte[] mKey = null;
private byte[] mIV = null;
public string Key { set { mKey = Encoding.UTF8.GetBytes(value); } }
public string IV { set { mIV = Encoding.UTF8.GetBytes(value); } }
public string EncryptAes128(string plainText)
{
byte[] data;
byte[] encryptedData;
// convert the plain text to a byte array
data = Encoding.UTF8.GetBytes(plainText);
// encrypt the plain text
encryptedData = EncryptAes128(data);
// convert to Base64 in order to transfer over internet.
return Convert.ToBase64String(encryptedData);
}
public byte[] EncryptAes128(byte[] plainData)
{
MemoryStream MStream = new MemoryStream(); // Memory stream to write encrypted data to.
CryptoStream CryptoStream = null;
AesManaged A128 = new AesManaged();
try
{
//Create aes128 Encryptor from this instance.
ICryptoTransform A128Encrypt = A128.CreateEncryptor(mKey, mIV);
//Create Crypto Stream that transforms memory stream using aes encryption.
using (CryptoStream = new CryptoStream(MStream, A128Encrypt, CryptoStreamMode.Write))
{
//Write out and flush AES encrypted data to memory stream.
CryptoStream.Write(plainData, 0, plainData.Length);
CryptoStream.FlushFinalBlock();
}
// Return encrypted data.
return MStream.ToArray();
}
catch (Exception ex)
{
return null;
}
finally
{
if (CryptoStream != null) { CryptoStream.Close(); };
if (MStream != null) { MStream.Close(); }
}
}
public byte[] DecryptAes128(byte[] EncryptedByteData)
{
MemoryStream MStream = null; // Memory stream to write encrypted data to.
CryptoStream CryptoStreamDecr = null;
AesManaged A128 = new AesManaged();
try
{
//Create aes128 instance and Decryptor.
ICryptoTransform A128Decrypt = A128.CreateDecryptor(mKey, mIV);
//Create crypto stream set to read and do a AES decryption transform on incoming bytes.
MStream = new MemoryStream(EncryptedByteData);
CryptoStreamDecr = new CryptoStream(MStream, A128Decrypt, CryptoStreamMode.Read);
//Get the decrypted bytes.
byte[] DestArray = new BinaryReader(CryptoStreamDecr).ReadBytes((int)MStream.Length * 2);
//Return decrypted data.
return DestArray;
}
catch (Exception ex)
{
return null;
}
finally
{
if (MStream != null) { MStream.Close(); }
}
}
}
}
En de PHP-code voor de decryptie:
function aes128cbcDecrypt($key, $encrypted_text, $iv) {
$td = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_CBC, '');
mcrypt_generic_init($td, $key, $iv);
$decrypted = mdecrypt_generic($td, $encrypted_text);
$decrypted = removePadding($decrypted);
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
return trim($decrypted);
}
function removePadding($text) {
$block = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
$packing = ord($text{strlen($text) - 1});
if ($packing and ($packing < $block)) {
for ($P = strlen($text) - 1; $P >= strlen($text) - $packing; $P--) {
if (ord($text{$P}) != $packing) {
$packing = 0;
}
}
}
return substr($text, 0, strlen($text) - $packing);
}
Deze decryptie functie wordt aangeroepen door:
$encryptedData = $_REQUEST['Cipher']; $data = base64_decode($encryptedData); $plainText = aes128cbcDecrypt($key, $data, $iv);
Een volledige PHP AES Klasse is te vinden via de volgende link:
http://www.phpclasses.org/browse/file/23124.html
11/11/2010
iTunes opstarten met het Logitech Internet 350 Keyboard
Ik wilde vandaag eens iTunes opstarten met de op de Logitech Internet 350 Keyboard aanwezige Multimedia knop. Dit bleek toch meteen weer een echte zoektocht. Uiteindelijk erachter gekomen dat het wel te doen is en dat er een aantal leuke mogelijkheden zijn als je ook nog sciprts gebruikt voor de iTunes Application.
In het kort komt het op het volgende neer.
Het keyboard stuur bij het indrukken van een knop een code naar de PC. Deze code kan de Windows Explorer dan interpreteren naar een op te starten programma of associëren met een filetype. Welke codes met programma of filetype is geassocieerd staat in het Register onder de volgende Key:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\AppKey\[KeyName]
Onder de Key [KeyName] staat een nummer, dat is geassocieerd met een actie. In de volgende tabel staan de nummers met hun vertaling:
| KeyName | Commando | Keyboard Button |
|---|---|---|
| 16 | APPCOMMAND_LAUNCH_MEDIA_SELECT | Media player |
| 15 | APPCOMMAND_LAUNCH_MAIL | |
| 8 | APPCOMMAND_BROWSER_HOME | Browser |
| 18 | APPCOMMAND_LAUNCH_APP2 | Calculator |
| 14 | APPCOMMAND_MEDIA_PLAY_PAUSE | Play/Pause |
| 9 | APPCOMMAND_VOLUME_DOWN | Volume down |
| 10 | APPCOMMAND_VOLUME_UP | Volume down |
| 8 | APPCOMMAND_VOLUME_MUTE | Mute |
Vervolgens kun je onder een Key ofwel een Association of een ShellExecute script aanmaken. In principe kan je om iTunes dan onder de MediaPlayer knop te stoppen, gewoon een ShellExecute key maken, die de iTunes applicatie gewoon opstart. Maar het is leuker als iTunes dan direct gaat spelen. Daarvoor zijn er scripts te vinden, die je dat makkelijker maken. Met die scripts kan je trouwens nog veel meer leuke dingen vanaf een commando line (of met de ShellExecutor) doen. Al met al krijg je dan een aantal Register Keys, die je tezamen in een Registration File (met de standaard extensie .reg)
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\explorer\AppKey]
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\explorer\AppKey\15]
"Association"="mailto"
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\explorer\AppKey\16]
"ShellExecute"="\"C:\\Program Files (x86)\\iTunes\\Scripts\\Play.vbs\""
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\explorer\AppKey\17]
"ShellExecute"="::{20D04FE0-3AEA-1069-A2D8-08002B30309D}"
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\explorer\AppKey\18]
"ShellExecute"="calc.exe"
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\explorer\AppKey\7]
"Association"="http"
Referenties, die ik bij dit artikel heb gebruikt:
- Customizing the Internet Keyboard 350 multimedia player key
- Control iTunes for Windows with this collection of scripts!
- List of keys for the …\Explorer\AppKey registry keys?
- http://groups.google.com/group/microsoft.public.fr.windowsxp/msg/ef076bdbd86f12b1?pli=1
Een meer volledige lijst van KeyName / Commando paren staat hieronder. Let op: het Logitech Internet 350 Keyboard heeft echter slechts de bovengenoemde 8 knoppen, dus de andere Commando’s kunnen op dat keyboard niet met 1 knop worden uitgevoerd.
| KeyName | Commando |
|---|---|
| 1 | Back (Internet browser) |
| 2 | Forward (Internet browser) |
| 3 | Refresh (Internet browser) |
| 4 | Stop (Internet browser) |
| 5 | Search |
| 6 | Favorites |
| 7 | WebHome |
| 8 | Mute volume |
| 15 | |
| 16 | Media |
| 17 | My Computer |
| 18 | Calculato |
| 24 | Mute microphone |
| 25 | Lower microphone volume |
| 26 | Raise microphone volume |
| 27 | Help |
| 28 | Find |
| 29 | New |
| 30 | Open |
| 31 | Close |
| 32 | Save |
| 33 | |
| 34 | Undo |
| 35 | Redo |
| 36 | Copy |
| 37 | Cut |
| 38 | Paste |
| 39 | Reply |
| 40 | Forward (mail) |
| 41 | Send |
| 42 | Spelling checker |
| 43 | Toggle dictation and command/control |
| 44 | Toggle microphone |
| 45 | Corrections |
09/11/2010
Cursus MVVM / MEF / SOLID voor Silverlight
Op mijn zoektocht naar hoe je goed kan omgaan met de INotifyChanged interface, kwam ik een heel interessant artikel met de titel tegen waarin MVVM en MEF werden uitgelegd. Dat gaf mij aanleiding om hier verder op in te gaan en er mee te experimenteren. Daarbij kwam ik nog een aantal interessante artikelen tegen. Al met al ben ik hierdoor steeds meer enthousiast geworden om hiermee verder te gaan. En daarom wil ik dat in dit artikel een beetje vastleggen als een soort referentie voor in de toekomst.
Allereerst een aantal definities:
| Afkorting | Definitie | Uitleg |
|---|---|---|
| MVVM | Model View ViewModel | Een architectuur, waarin het model, de view en een zogenaamde ViewModel van elkaar gescheiden zijn |
| MEF | Managed Extensibility Framework | Dit raamwerk verzorgt het detecteren van componenten en het vervolgens samenstellen van die componenten |
| SOLID | Single responsibility, Open-closed, Liskov substitution, Interface segregation and Dependency inversion | Een samenstelsel van een vijftal basis principe voor een goed OO design en goede OO programmeertechnieken |
- “How to refractor and build better Microsoft Silverlight applications” van Jag Reehal. Een artikel, dat aan de hand van een Calculator voorbeeld stap-voor-stap deze applicatie langs de lijnen van MVVM, MEF en SOLID opbreekt in componenten. Zeer helder beschreven en uitgelegd.
- First experiments using MEF, MVVM and Silverlight 4 Beta van Davide Zordan. Een artikel, waarin de Silverlight MVVM en MEF architectuur ook stap-voor-stap worden toegepast. Iets minder duidelijk beschreven, maar wel met een aantal extra details zoals over de CreationPolicy.
- MEF community site op CodePlex.
- WPF Apps With The Model-View-ViewModel Design Pattern. Een zeer helder en uitgebreide handleiding over het gebruik van de MVVM architectuur in WFP applicaties.
08/11/2010
Veilige login: hoe doe je dat?
Nu ik zover ben dat ik een inlog-scherm heb, wil ik ook graag een veilige manier om de login te laten plaatsvinden. En dat over een “gewone” HTTP verbinding, want ons huidig serverabonnement bij CSV-networks biedt geen mogelijkheid voor SSL (en dus ok niet voor HTTPS-certificaten). Daarvoor zouden we een eigen IP-adres moeten krijgen. En die kost (op dit moment) 14.50 euro per jaar extra. Gaan we nu even niet doen.
Simpele login voorbeelden
Daarom gekeken of er een andere manier is om veilig te kunnen inloggen. Nou, dat is toch nog best wel lastig. Er zijn wel allerlei login voorbeelden op internet te vinden, maar de meeste voorbeelden sturen of “plain-text” passwords van de client naar de server of (als er iets meer aan veiligheid wordt gedacht) MD5-gehashde passwords. Dat zijn toch geen veilige manieren om in te loggen, want iedereen, die kan sniffen, kan op die manier gewoon op het systeem komen. Een lijstje van deze oplossingen:
- PHP Login script tutorial. Een simpele oplossing met ver sturen van passwords in plain text
- Creating a Secure PHP Login Page. Een iets veiligere oplossing met een randomword als een Salt
- Create a Login Window in WPF. Een voorbeeld van een vrij leuke layout van een loginscherm
- PHP Login Script with Remember Me Feature. Een geheel uitgewerkt PHP login-script met een Remember Me functie
Veilige manier van inloggen
Na wat extra zoekwerk stuitte ik op de volgende pagina: PHP – Implementing Secure Login with PHP, JavaScript, and Sessions (without SSL). Een pagina, die vrij helder een Challenge-Response Authenticatie mechanisme beschrijft met PHP. Alleen wordt er ook een Javascript meegestuurd en dat wil ik natuurlijk niet. Dat zal door de Silverlight client moeten gebeuren. Maar goed, het principe zou ik wel kunnen gebruiken. Maar het grootste probleem met dit voorbeeld was dat dit voorbeeld alleen werkt als de passwords als “plain-text” in de database staan. Dat is wat ik ook niet wil. Maar daar is ook nog een oplossing voor. Die staat vermeldt in 1 van de commentaren. En is ook erg goed verwoordt in een artikel, waarin in dat commentaar naar wordt verwezen: You Want Salt With That?. Hierin wordt een Challenge-Response with Salt mechanisme besproken. Dat lijkt mij voor onze login de mooiste oplossing. Natuurlijk kan het altijd veiliger, maar deze methode is voor ons veilig genoeg. Dus nu aan de slag.
05/10/2009
Onze nieuwe website is live!
Vandaag hebben we onze nieuwe website live gezet. Een mooi nieuw design van onze vormgever: Rellebel Reclame. En we hebben ook flink aan de teksten geschreven. Ik ben er wel trots op. Maar een website is natuurlijk nooit af. Dus wie weet hoe onze site er over pakweg een maand of een jaar eruit ziet? In ieder geval kunnen we nu weer een tijdje vooruit nu we ook onze website in de nieuwe huisstijl hebben gezet.
Trouwens. De foto’s van mij en Rogier op onze “over ons” pagina zijn gemaakt door Jacqueline Louter van jaXpiX. Ook erg professioneel gedaan.
04/10/2009
NCSI – Sociale Innovatie werkt!
Afgelopen week contact gehad met het NCSI, het Nederlands Centrum voor Sociale Innovatie. Een erg inspirerend gesprek. Eindelijk een organisatie, die inziet dat innovatie niet alleen om technologie gaat. Maar dat mensen/ het personeel de motor achter vernieuwingen zijn. Ze ondersteunen een aantal leuke projecten, zoals een project waarbij medewerkers worden gestimuleerd om zelf roosters te maken. Dit in plaats van dat het roosters “van bovenaf” worden opgelegd. Daarmee is het voor de medewerkers veel makkelijker om hun rooster af te stemmen op hun eigen privé-leven. En het blijkt dat het ook nog eens tot een hogere productiviteit leidt. Prachtig om te merken dat het stimuleren van individuele verantwoordelijkheid van medewerkers daadwerkelijk tot betere prestaties van het personeel leidt.
Dit past tot heel erg in wat wij voorstaan met onze workshops. Laat medewerkers vooral zelf ontdekken hoe ze hun taak het beste kunnen uitvoeren. Er is zoveel kennis en ervaring op de werkvloer aanwezig. Het is echt zonde om die niet te benutten. En uiteindelijk zal dat toch de manier moeten zijn om de arbeidsproductiviteit in Nederland te verhogen. Naast alle technologische verbeteringen, die natuurlijk ook voor een hogere productiviteit kunnen zorgen. Maar laten we wel beide kanten, de techniek en de mens, in de innovatie meenemen. Fijn dat het NCSI hier een stimulans aan wil geven!
Google Wave – Echt samenwerken?
Vandaag Google Wave ontdekt via DutchCowboys. Wat een mooie omgeving lijkt dit te zijn als je de instructie-video bekijkt. Ik kan mij voorstellen dat je op deze manier met een team medewerkers, heel eenvoudig samen kan. Zeker als je niet allemaal vanuit dezelfde locatie werkt. Maar zelfs ook als dat wel zo is, maar je bijvoorbeeld gezamenlijk een document wilt maken. Of je in een creatief proces wil bijhouden hoe een werkstuk tot stand komt. Ieder kan zijn eigen moment uitkiezen om dat stuk te bewerken. Of opmerkingen plaatsen.
Probleem op dit moment is wel dat het allemaal nog maar te zien is vanuit een marketing-perspectief. Het platform is nog niet openbaar toegankelijk, dus ik heb nog geen “hands-on” experience. En ja, dat is toch de lakmoes test. Er zelf mee gaan werken en kijken of het echt nuttig is. Maar op het eerste gezicht spreekt het mij erg aan. Dus even wacht tot half december 2009, de datum die op dit moment rondzingt als datum van de openbare release.