22 mai 2007 • 10h54 • 103 mots
Simplement en utilisant la méthode System.Windows.Forms.SendKeys.Flush(). Evidemment ça vide complètement le buffer clavier, mais c'est efficace pour traiter le cas suivant : une fenêtre parent, avec une TextBox réagissant à l'évènement "Enter", et une fenêtre enfant, qui a ce que j'appelle un OKButton (un AcceptButton avec son DialogResult à OK). Si l'on appuie sur Enter dans la fenêtre enfant, celle-ci se ferme (courtesy of the OKButton), mais si dans la fenêtre parent le focus se trouve dans la TextBox sensible au Enter, l'évènement idoine est déclenché. Donc, pour empêcher ce déclenchement précoce, il suffit d'insérer la petite fonction ci-dessus à l'endroit approprié.
Over.
12 avril 2007 • 14h23 • 154 mots
Juste un petit post-it pour vous rappeler la procédure à suivre pour activer DatabaseMail sous SQL Server 2005. En réalité, il s'agit plus d'un rappel pour moi puisque j'ai eu une période de doute cet après-midi...
Donc :
- paramétrer Database Mail (créer un profil et un compte avec les coordonnées du serveur SMTP (ou autre) approprié
- créer un Opérateur en indiquant son adresse mail
- ne pas oublier d'activer Database Mail dans l'agent SQL Server (c'est la partie que j'ai oublié tout à l'heure donc), car il est inactif par défaut
- redémarrer l'agent SQL Server
- enfin paramétrer les alerts et notifications idoines en utilisant l'Opérateur crée précedemment
Encore une fois, le plus important est de bien activer Database Mail dans l'agent SQL Server. D'autant que si on teste l'envoi de mail via le petit menu idoine de Database Mail, ça fonctionne...
Sur ce bonne soirée, et à la prochaine fois.
29 mars 2007 • 16h09 • 254 mots
Voilà, vous êtes sur un site flambant neuf. Si si. Bon, effectivement, esthétiquement rien n'a changé. Mais en fait, tout est nouveau. Tout. L'hébergeur d'abord : bye bye TextDrive, et bonjour HostingRails. Pas de raison précise ou de mécontentement particulier à l'égard du plus hype des hébergeurs Rails, simplement une envie de changement. Et puis il faut dire que les tutoriaux de mon nouvel hôte sont vraiment bien foutus.
Mais le site aussi a changé, puisque je l'ai redéveloppé "from sratch" comme disent nos amis anglo-saxons. Encore une fois, pas de raison majeure, juste une lubie et l'envie de me replonger dans Ruby avant (j'espère) de plus gros travaux. Donc voilà, un blog powered by Rails 1.2, avec tentative d'implémentation du RESTful way. Quelques nouvelles features ont également fait leur apparition, côté utilisateurs (\o/ on peut maintenant voir la liste des posts rattachés à un tag \o/ deux ans après le reste de la planète \o/) mais surtout côté admin. Et puis, grâce à l'extrême vélocité du support d'HostingRails, le site est maintenant propulsé par Mongrel, le serveur http préféré des railers (on dit ça dans les milieurs autorisés).
Donc pas d'inquiétude, normalement je suis revenu pour rester, je vais continuer à poster (bientôt sur la PS3, mais aussi sur .NET je pense), so stay tuned !
UPDATE : et toujours plus fort, le déploiement s'effectue maintenant via Capistrano, ex-SwitchTower, apparemment renommé pour des raisons légales. Mais ça marche toujours aussi bien.
24 mars 2007 • 20h52 • 653 mots
Première étape pour notre test de MonoRail (normalement il n'y a plus rien à installer à ce stade), la création d'une arborescence adéquate. Voici ce que j'ai utilisé :
MonoWebApp/
bin/
Controllers/
Models/
Views/
Home/
Ensuite, il faut copier le fichier Manufacturer.cs que nous avons crée à l'étape précédente dans le répertoire Models. Je ne recopie pas le code, mais il ne faut pas oublier de renommer le namespace en MonoWebApp.Models. Ensuite, je vais créer le contrôleur, qui s'appellera HomeController.cs, et qui sera placé dans le répertoire Controllers/. Là, encore, quelque chose de très simple :
using Castle.MonoRail.Framework;
using MonoWebApp.Models;
namespace MonoWebApp.Controllers
{
public class HomeController: Controller
{
public void Index()
{
Manufacturer[] manufacturers = Manufacturer.FindAll();
PropertyBag.Add("Manufacturers", manufacturers);
}
}
}
On passe maintenant aux trois fichiers plus amusants, qui m'ont demandé un peu plus de tâtonnements. Il nous faut d'abord un fichier de config, non seulement pour passer à l'appli les paramètres de la base de données mais aussi pour initialiser MonoRail. A la racine de l'arborescence il faut donc créer un fichier web.config qui a cette tête là :
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section
name="monoRail"
type="Castle.MonoRail.Framework.Configuration\
.MonoRailSectionHandler, Castle.MonoRail.Framework"
/>
<section
name="activerecord"
type="Castle.ActiveRecord.Framework.Config\
.ActiveRecordSectionHandler,Castle.ActiveRecord"
/>
</configSections>
<activerecord isWeb="true">
<config>
<add
key="hibernate.connection.driver_class"
value="NHibernate.Driver.MySqlDataDriver"
/>
<add
key="hibernate.dialect"
value="NHibernate.Dialect.MySQLDialect"
/>
<add
key="hibernate.connection.provider"
value="NHibernate.Connection.DriverConnectionProvider"
/>
<add
key="hibernate.connection.connection_string"
value="Database=test;Data Source=localhost;
User Id=root;Password="
/>
</config>
</activerecord>
<monoRail>
<controllers>
<assembly>MonoWebApp</assembly>
</controllers>
<viewEngine
viewPathRoot="Views"
customEngine="Castle.MonoRail.Views.Brail.BooViewEngine,
Castle.MonoRail.Views.Brail"
/>
</monoRail>
<system.web>
<httpHandlers>
<add
verb="*"
path="*.rails"
type="Castle.MonoRail.Framework\
.MonoRailHttpHandlerFactory,
Castle.MonoRail.Framework"
/>
</httpHandlers>
<httpModules>
<add
name="monorail"
type="Castle.MonoRail.Framework\
.EngineContextModule,
Castle.MonoRail.Framework"
/>
</httpModules>
</system.web>
</configuration>
Ouf, fini ! Ne soyez pas intimidé par ce fichier, il est en réalité très simple : une section pour déclarer les sections, puis les sections de config détaillés (ici monorail et activerecord, et l'obligatoire system.web), le tout modifié à la sauce MonoRail pour que tout fonctionne bien. Notez d'ailleurs quand dans la section monorail, j'ai déclaré le moteur de rendu comme étant du type Brail (basé sur le langage Boo), mais on aurait pu tout aussi bien utiliser le moteur de rendu "par défaut" de Castle, NVelocity.
Il ne reste plus qu'une chose à faire : initialiser ActiveRecord. Mais ici, nous sommes en mode Web, donc, pas de fonctions Main bien pratique. Il faut donc initialiser ActiveRecord via le fichier global.asax. Mais pour cela, il faut d'abord créer à la racine de notre arborescence un fichier GlobalApplication.cs, histoire d'éviter les problèmes de dll introuvables. Le code est juste celui du Program.cs de l'étape précédente, mis à la sauce web.
using System.Configuration;
using System.Web;
using Castle.ActiveRecord;
using Castle.ActiveRecord.Framework;
using MonoWebApp.Models;
namespace MonoWebApp
{
public class GlobalApplication : HttpApplication
{
public void Application_OnStart()
{
IConfigurationSource source =
ConfigurationManager.GetSection("activerecord")
as IConfigurationSource;
ActiveRecordStarter.Initialize(
typeof(Manufacturer).Assembly,
source
);
}
public void Application_OnEnd()
{
}
}
}
Une fois ce fichier crée, il suffit de créer (toujours à l'arboresence) le fichier global.asax qui contiendra une seule ligne :
<%@ Application Inherits="MonoWebApp.GlobalApplication" %>
Voilà, fini, c'est prêt. Ha non, avant de tester, j'allais oublier de créer la vue... Donc, dans le répertoire Views/Home, il faut créer un fichier Index.boo, avec le bout de code suivant :
<p>Manufacturers:</p>
<ul>
<%
for manufacturer in Manufacturers:
output "<li>${manufacturer.Designation}</li>"
end
%>
</il>
Voilà, tout le code est prêt, il ne reste plus qu'à compiler et à tester. La compilation d'abord : gmcs GlobalApplication.cs Controllers/HomeController.cs Models/Manufacturer.cs -target:library -out:bin/MonoWebApp.dll -r:Castle.ActiveRecord -r:Castle.MonoRail.Framework -r:System.Web -r:System.Configuration (oui, ça change d'appuyer sur F5 dans Visual Studio, mais ce n'est pas forcément un mal).
Il suffit maintenant de lancer le serveur de test intégré à MonoRail xsp2 (le 2 est important) en ligne de commande, et de lancer son browser favori en pointant sur l'adresse http://localhost:8080/Home/Index.rails . Si tout est ok, vous devriez maintenant voir apparaître la liste des constructeurs présents dans votre table Manufacturers. Félicitations ! Et en cas de souci, un petit commentaire et j'essaierais de vous filer un coup de main pour débugguer tout ça.
24 mars 2007 • 20h51 • 751 mots
Tout d'abord, direction le Project Château et sa rubrique Downloads. Ensuite, il suffit de télécharger la Release Candidate 2, en sélectionnant la version .NET 2.0 (toujours pour le support des génériques, qui évitent quand même beaucoup d'overload et de cast inutiles). On se retrouve avec un très beau zip, qu'on s'empresse de décompresser. Dans le répertoire Castle-net-2.0-rc2/bin, il vaut mieux dézipper également external-depencies.zip, qui contient notamment les dll de NHibernate, de NUnit, de NVelocity et de Boo. A noter que ces dll sont déjà présentes dans le répertoire bin/ de la version de Castle pour .NET 1.1, donc peut être que dans une prochaine release cette petite étape ne sera plus nécessaire. Ensuite, j'ai rangé ce répertoire Castle dans le répertoire /Library/Frameworks/Mono.framework/Libraries/ (parce que ça me semblait logique, mais je suppose qu'il n'y a pas de règles). Il est l'heure de tester tout ça. D'abord, je vais créer une simple table dans une simple base. Il est possible de laisser ActiveRecord s'occuper de la création du schéma, mais je suis un maniaque de l'intégrité de données, alors je préfère de loin le faire à la main.
create database Test;
use Test;
create table Manufacturers (
Id int auto_increment primary key,
Designation varchar(255) not null unique
);
insert into Manufacturers ( Designation ) values ( 'Intel' );
insert into Manufacturers ( Designation ) values ( 'nVidia' );
insert into Manufacturers ( Designation ) values ( 'Asus' );
On colle ça dans un fichier create.sql, et ensuite un petit
mysql -u root < create.sql en ligne de commande, et c'est fini.
Ensuite, il faut créer la classe ActiveRecord qui correspond à ce schéma.
using System;
using Castle.ActiveRecord;
namespace MonoActiveRecord
{
[ActiveRecord("Manufacturers")]
public class Manufacturer : ActiveRecordBase<Manufacturer>
{
private int _id;
private string _designation;
[PrimaryKey]
public int Id
{
get { return _id; }
set { _id = value; }
}
[Property]
public string Designation
{
get { return _designation; }
set { _designation = value; }
}
}
}
Je sais, c'est très mal d'utiliser un setter sur la clé primaire, mais là il s'agit de tester ActiveRecord, pas de faire quelque chose de vraiment solide. Evidemment, ce fichier s'appelle Manufacturer.cs, parce que chaque fichier devrait être nommé à partir de la classe qu'il contient. Heureusement que chaque fichier ne contient qu'une seule classe. Simple rappel.
Bon, par contre, pour qu'ActiveRecord soit capable de faire quelque chose, il faut l'initialiser. On commence donc par lui indiquer où et comment se connecter à la base de données. Pour cela, il suffit de créer un fichier, disons activeRecord.xml, que l'on mettra dans le répertoire de l'exécutable.
<activerecord>
<config>
<add
key="hibernate.connection.driver_class"
value="NHibernate.Driver.MySqlDataDriver"
/>
<add
key="hibernate.dialect"
value="NHibernate.Dialect.MySQLDialect"
/>
<add
key="hibernate.connection.provider"
value="NHibernate.Connection.DriverConnectionProvider"
/>
<add
key="hibernate.connection.connection_string"
value="
Database=test;
Data Source=localhost;
User Id=root;
Password="
/>
</config>
</activerecord>
Dans la chaîne de connexion, il faut bien sûr mettre les bons paramètres pour la base de données. Quelques exemples de fichiers de config sont dispos à cette adresse.
Mais créer le fichier de config ne suffit pas, il faut aussi dire à ActiveRecord de s'initialiser proprement dans notre application. Et comme de toute façon il nous manquait une méthode Main... Voici donc le corps du fichier Program.cs :
using System;
using Castle.ActiveRecord;
using Castle.ActiveRecord.Framework.Config;
namespace MonoActiveRecord
{
public class Program
{
public static void Main()
{
ActiveRecordStarter.Initialize(
new XmlConfigurationSource("activeRecord.xml"),
typeof(Manufacturer)
);
foreach (Manufacturer m in Manufacturer.FindAll())
{
Console.WriteLine(m.Designation);
}
}
}
}
Dernière étape, la compilation, mais avant, histoire de ne pas retaper le chemin jusqu'aux DLL nécessaires, on va créer une variable globale qui contiendra le chemin d'accès aux différentes librairies que Mono peut utiliser. Il faut donc modifier (ou le créer au besoin) son fichier .bash_login à la racine de son compte et rajouter la ligne export MONO_PATH="/Library/Frameworks/Mono.framework/Libraries/Castle-net-2.0-rc2/
bin:$MONO_PATH". Quitter et relancer le terminal, et ça devrait être bon. Au besoin, vérifiez que la variable d'environnement est correctement paramétrée. Et sans plus attendre, la ligne magique de compilation :
gmcs Program.cs Manufacturer.cs -r:Castle.ActiveRecord.dll
A noter que le fichier généré sera nommé à partir du premier fichier de la liste (ici Program.cs). pour indiquer un autre nom de fichier, il faut utiliser l'option -out:Blabla.exe. A ce stade là, tout devrait être OK, et on devrait récupérer le fichier Program.exe dans le répertoire de travail. Dernière étape, l'exécution, avec un petit coup de mono Program.exe. Ce qui nous donne à l'écran
Intel
nVidia
Asus
Magnifique ! Comme toujours, si vous avez le moindre souci, n'hésitez pas à laisser un commentaire, on réfléchit mieux à plusieurs.
24 mars 2007 • 20h49 • 209 mots
Première chose à faire : aller récupérer le framework Mono sur le site officiel. Dans la rubrique Downloads, il faut choisir la dernière version stable (c'est plus prudent au début) pour Mac OS X. Après le téléchargement des 50 et quelques Mo, il ne reste qu'à installer le package, qui va créer un répertoire Mono.framework dans /Library/Frameworks. Bon, par contre, il faut tester ça. Créons donc un fichier HelloWorld.cs (soyons fous). Mettons un peu de code dedans :
using System;
namespace MonoHello
{
public class HelloWorld
{
static void Main()
{
Console.WriteLine("Hello, World !");
}
}
}
Maintenant il faut compiler le fichier. Là, deux choix sont possibles : utiliser mcs ou gmcs. Pour résumer, mcs est la version du compilateur pour .NET 1.1, et gmcs est la version pour .NET 2.0 (avec support des génériques). Pianotons donc un joli gmcs HelloWorld.cs. Avec un peu de chance, pas de message d'erreur bizarre, et on obtient un fichier HelloWorld.exe en sortie. Et pour exécuter ce fichier soooo Windows, un simple mono HelloWorld.exe suffit. Si tout s'est bien passé, un splendide "Hello World !" s'affiche maintenant sur la ligne de commande. Félicitations ! Sinon, n'hésitez pas à laisser un petit commentaire ici même, histoire que l'on cherche ensemble la solution.
11 mars 2007 • 22h08 • 188 mots
Aujourd'hui j'ai décidé d'écrire un petit tutorial pour décrire l'installation et la mise en oeuvre de Mono, MonoRail et ActiveRecord sous Mac OS X. Rien de très difficile, mais j'ai été obligé de fouiner un peu partout sur le Net pour tout faire fonctionner, donc autant tout regrouper dans un même endroit. Je ne prétend pas non plus que ce soit la méthode la plus efficace ou la plus propre pour faire prendre cette sauce là. C'est juste ce que j'ai fait.
Attention : je pars de la supposition que MySQL est installé sur le système (version 5.0.27 pour moi). Je ne décris pas l'install, il n'y a rien à faire de plus que d'aller chercher le package sur le site officiel.
Attention (bis) : le système sur lequel je réalise cette install est en version 10.4.8, avec XCode 2.4.1. Je ne sais pas si ça a de l'importance, mais autant être au courant.
UPDATE : j'ai finalement préféré diviser ce post en trois parties (Mono 101, ActiveRecord 101 et MonoRail 101), histoire que ce soit un peu plus digeste.
10 mars 2007 • 00h31 • 221 mots
Et apparement, ce n'est pas une blague. Captain America se serait fait descendre comme un bleu par un (sniper ?) en pleine rue, dans le n° 25 de cette semaine. Salaud de Brubaker ! Comment, pourquoi, y a-t-il un rapport avec la fin de Civil War, perso je n'aurais des débuts de réponse qu'en lisant le comics (vivement mardi). Par contre, le retentissement au niveau des médias est assez étonnant, même si les comics ne sont plus aussi "has-been" qu'il y a quelques années. Bref, un passage chez Colbert (l'extrait est dispo sur CBR), un papier dans Le Monde, un sur CNN, un dans le New-York Times : ça nous donne presque autant de battage que pour la mort de Superman tout ça. Il faut dire que l'allégorie est belle : dans Civil War, Cap' était devenu le porte-étendard d'une "certaine" Amérique, celle de de la Liberté (oui, avec un L majuscule), opposée à celle plus protectionniste et sécuritaire d'Iron Man, le vilain marchand d'armes Tony Stark. Et même si l'écho qui en est fait dans les médias est un peu trop "caricatural", encore une fois, le symbole est beau.
So long, Steve, et à la prochaine fois.
5 mars 2007 • 22h23 • 316 mots
Comme je l'ai dit il y a quelques mois, je vais essayer de me remettre à poster un peu plus régulièrement. Donc voilà, aujourd'hui une petite bafouille sur un album relativement mésestimé, l'excellent Fireworks des brésiliens d'Angra. La formation d'origine hein, pas la pâle copie qui survit actuellement. Si on demande aux fans d'Angra leur album préféré, la réponse est en général Holy Land, si l'on oublie les quelques illuminés qui vous citeront Angels Cry, "parce que le premier album c'est toujours le meilleur". Voire les ultras qui répondront sans hésiter Rebirth uniquement pour faire chier les fans d'Andre Matos. Mais pour moi, le meilleur album d'Angra reste sans conteste Fireworks.
Il faut dire que cet album est moins purement "heavy speed mélodique mais progressif quand même" que le reste de la disco du groupe. Il correspond sans doute plus à ma sensibilité parfois un tantinet bourrine. En une petite heure et dix chansons, la messe est dite. Un seul titre dépasse les 7 minutes (Paradise, un mid-tempo parfois un peu longuet), donc clairement, les fans qui attendaient un nouveau Carolina IV en ont été pour leurs frais. Le reste de l'album est remarquablement équilibré, entre chansons bien catchy (Wings of Reality), petits brûlots speed à la Helloween (attention, site buggué sous Safari), et expérimentations à la limite de la bossa nova (Gentle Change). On a bien affaire à un recueil de chansons rock, parfois heavy, sans concept bien lourd à se farcir derrière, une galette à l'ancienne, qu'on peut mettre sur sa platine juste pour le plaisir de gueuler les refrains sous sa douche. Toutes proportions gardées, on est plus proche d'Appetite for Destruction ou de Machine Head que de leur précédent effort. Ce qui explique pourquoi Fireworks reste mon préféré après toutes ces années.
6 février 2007 • 00h23 • 16 mots
Et aussi, apparemment les named routes version REST merdoient quand le modèle contient le mot serie.