Vendredi 30 Juin 2006
Récupérer le chemin courant de votre application avec VB.NET /s .NETCF
Les espaces de noms nécessaires sont:
• System.Reflection
• System.IO
Par dotnet, Vendredi 30 Juin 2006 à 13:50 GMT+2 dans PDA
Vendredi 30 Juin 2006
Par dotnet, Vendredi 30 Juin 2006 à 13:50 GMT+2 dans PDA
Vendredi 31 Mars 2006
Une petite histoire
Un jour mon boss entre dans mon bureau et me demande si c’est facile de faire communiquer deux applications GRC distantes (Gestion de la Relation Client) développées sous .NET sachant qu’on n’avait pas la main sur l’une d’elles. J’ai répondu qu’il suffit de passer par .NET Remoting (trop lourd) ou utiliser un WebService (inadapté) car on n’avait besoin que d’une méthode (celle qui retourne les infos concernant le nouveau client). Mauvaise réponse !
L’idée :
La première application avais pour rôle de créer de nouveaux clients et d’effectuer un minimum de vérifications (adresse postale, mail, âge, …) et la seconde devait récupérer ces informations pour géocoder les adresses postales afin de les placer sur une carte.
Le principe:
Le principe serait d’avoir un répertoire commun aux deux applications dans lequel l’application 1 pourra déposer la description du nouveau client et l’application 2 devra vérifier à intervalle régulier si un nouveau client a été créé.
L’architecture :
Les deux applications appartenant au même réseau local (et domaine) nous avons créé un répertoire partagé nommé Spy contenant un fichier nommée Customers.xml.
L’application 1 devait créer un client puis le rajouté dans le fichier xml et l’application 2 vérifier à intervalle régulier si le fichier avait été modifié pour le lire.
Cette technique est très utilisée dans les applications EAI pour faire communiquer plusieurs applications hétérogènes.
La solution :
Après un peu de recherche sur le web j’ai vu que je n’avais pas à développer des containers ni de connecteurs comme dans les EAI puisque .NET offre une classe très particulière et peu utilisé qui permet de le faire : FileSystemWatcher.
Pour le faire :
using System;
using System.IO;
namespace ConsoleApplicationTests
{
/// <summary>
/// Description résumée de Class1.
/// </summary>
class
Class1
{
/// <summary>
/// Point d'entrée
principal de l'application.
/// </summary>
[STAThread]
static void
{
// Création de l’objet FileSystemWatcher
FileSystemWatcher
MyWatcher = new FileSystemWatcher();
// Répertoire à surveiller
\\par-madiop\Spy
MyWatcher.Path =
@"\\MaMachine\Spy";
// Ne pas surveiller les répertoires
fils
MyWatcher.IncludeSubdirectories = false;
// Filtre pour les notifications
MyWatcher.NotifyFilter = NotifyFilters.LastAccess |
NotifyFilters.LastWrite
|
NotifyFilters.FileName
|
NotifyFilters.DirectoryName;
// Superviser uniquement le fichier Customers.xml
MyWatcher.Filter
= "Customers.xml";
//En cas de changement de
Customer.xml -> appeler la méthode OnChange
MyWatcher.Changed += new FileSystemEventHandler(OnChanged);
//En cas de création de Customer.xml
-> appeler la méthode OnChange
MyWatcher.Created += new FileSystemEventHandler(OnChanged);
// Permettre le composant de
commencer à superviser nles changements
MyWatcher.EnableRaisingEvents = true;
//Maintenir la console afficher pour voir défiler les
changements
Console.WriteLine("Press \'q\' to
quit.");
while(Console.Read()!='q');
}
public static void OnChanged(object source, FileSystemEventArgs
e)
{
Console.WriteLine("{0}
: Changed", System.DateTime.Now);
}
}
}
Par dotnet, Vendredi 31 Mars 2006 à 15:04 GMT+2 dans Astuces du Mois
Lundi 20 Mars 2006
Dans cet article je vais expliquer en quelques étapes comment faire une application distribué avec la technologie .NET Remoting.
IDE : Visual studio 2003 avec le .NET Framework 1.1
Langage : C#
.NET Remoting est une technologie offerte avec le Framework .NET et permet de faire de la programmation distribuée. La programmation distribuée permet par principe d’exécuter un processus sur plusieurs machines. Le but étant d’exécuter des parties du processus sur des machines qui sont le plus disposées à l’effectuer (gros calculs, traitement métier, …).
Voici notre scenario :
Nous disposons d’une application de gestion de compte bancaire qui est composée de trois applications reparties dans toute la France.

Pour visualiser le schéma vous devez avoir un web browser IE
Il est utile de comprendre l’architecture du .NET remoting.
En gros : vous avez d’un côté un serveur puis de l’autre un ou plusieurs client comme ci-dessous.

Pour visualiser le schéma vous devez avoir un web browser IE
L’échange de données peut se faire via HTTP ou TCP (dans notre cas nous utiliserons le protocole TCP). HTTP est plus adapté pour des communications distantes nécessitants le réseau web et TCP pour des communications en réseaux locaux (format binaire, plus performant). Le format d’échange peut être du Xml ou du binaire.
Important :
Dans notre cas les applications 1 et 2 sont des serveurs et l’application 3 le
client
Il est intéressant de savoir que le client ne manipule jamais les objets hébergé par le serveur mais passe par se qu’on appelle des proxies.
En effet, les proxies sont
les représentants locaux des objets distants. Pour communiquer avec un objet
distant, on instancie un proxy qui sera la représentation locale de cet objet.
On manipule le proxy comme si c’était notre objet distant.
Dans notre cas nous allons avoir deux proxies
(un pour l’application 1 et l’autre pour l’application 2). Un proxy étant un
objet, il est donc représentable par une classe ou une interface.
A ce stade nous avons toutes les entités nécessaires, reste plus qu’à les meubler.
Projet Lib_App2
Son rôle est de calculer un agio à partir d’un montant représentant le découvert bancaire
Renommer class1 en LibApp2 ainsi que le fichier (LibApp2.cs)
La classe LibApp2 doit
forcément dériver de MarshalByRefObject
Ajouter au projet une méthode nommée float getAgio(float fDec)
Le projet Lib_App1
Son rôle est de récupérer le montant du découvert de la base de données puis d’interroger l’application 2 pour avoir le montant de l’agio.
Renommer class1 en LibApp1 ainsi que le fichier (LibApp1.cs)
La classe LibApp1 doit
forcément dériver de MarshalByRefObject
Ajouter une méthode nommée void getAgioAndDec(long lIDClient, ref float fDec, ref float fAgio)
Ajouter une interface nommée IApp2 (proxy de Lib_App2) –fichier IApp2.cs-
Le projet Svr_App2
Renommer Class2 en App2 ainsi que le fichier (App2.cs au lieu de Class1.cs)
Ajouter une référence du projet Lib_App2
Le projet Svr_App1
Renommer Class1 en App1 ainsi que le fichier (App1.cs au lieu de Class1.cs)
Ajouter une référence du projet Lib_App1
Le projet clt_App3
Ajouter un bouton, une textbox, et un label
Dans le textbox vous saisirez l’ID du client et l’appui sur le bouton invoquera les méthodes distantes puis le résultat sera affiché dans le label.
Ajouter une interface nommée IApp1 (proxy de Lib_App1) –fichier IApp1.cs-
Au niveau des deux
serveurs
Ajouter
les références suivantes (fichier App1.cs et App2.cs) :
using
System;
using System.Collections;
using System.Runtime.Remoting;
using MyTcpChannel = System.Runtime.Remoting.Channels.Tcp.TcpChannel;
using System.Runtime.Remoting.Channels.Tcp;
using System.Runtime.Remoting.Channels;
Attention: Vous devez ajouter la référence
de l’assembly System.Runtime.Remoting
à vos projets (Click droit sur le projet puis ajouter référence)
Pour “servir un objet” on doit:
Et tout ça dans la méthode main
Au niveau du client
(clt_App3)
using
System;
using System.Collections;
using System.Runtime.Remoting;
using MyTcpChannel = System.Runtime.Remoting.Channels.Tcp.TcpChannel;
using System.Runtime.Remoting.Channels.Tcp;
using System.Runtime.Remoting.Channels;
Attention: Vous devez ajouter la référence
de l’assembly System.Runtime.Remoting
à vos projets (Click droit sur le projet puis ajouter référence)

Pour visualiser le schéma vous devez avoir un web browser IE
Si vous voulez les codes complets envoyez moi un mail à l’@ suivante :bossiel@yahoo.fr
Svr_App1 :App1.cs
using System;
using System.Collections;
using System.Runtime.Remoting;
using MyTcpChannel
= System.Runtime.Remoting.Channels.Tcp.TcpChannel;
using System.Runtime.Remoting.Channels.Tcp;
using System.Runtime.Remoting.Channels;
namespace
Svr_App1
{
/// <summary>
/// Description résumée de Class1.
/// </summary>
class
App1
{
/// <summary>
/// Point d'entrée
principal de l'application.
/// </summary>
[STAThread]
static void
{
BinaryServerFormatterSinkProvider
serverProv = new BinaryServerFormatterSinkProvider();
serverProv.TypeFilterLevel
= System.Runtime.Serialization.Formatters.TypeFilterLevel.Full;
BinaryClientFormatterSinkProvider
clientProv = new BinaryClientFormatterSinkProvider();
IDictionary
props = new Hashtable();
props["port"] = 1234;//port
//(1): Ouvrir un canal selon le protocole tcp et sur un port 1234
// Enregistrer le canal ouvert précédemment
MyTcpChannel _tcpChannel = new MyTcpChannel(props,clientProv,serverProv);
ChannelServices.RegisterChannel(_tcpChannel);
//(2): Publier son type avec l’URI et le mode pour y
accéder
RemotingConfiguration.RegisterWellKnownServiceType(typeof(Lib_App1.LibApp1),"Svr_App1",WellKnownObjectMode.SingleCall);
Console.Write("**********************************************\n");
Console.Write("
MON SERVEUR Svr_App1 \n");
Console.Write("***********************************************\n");
Console.Write("Moi
je suis un serveur d'application conçu pour Lib_App1 distant\nqui sera utilisé par un client autonome (App3) via tcp/http au format binaire ou soap\n");
Console.Write("\n\n");
Console.Write("-Je
viens de me lancer sur tcp:1234\n\n");
Console.Write("-Je
viens de demarrer l'objet distant ok\n\n");
Console.Write("[Entree] pour quitter");
Console.ReadLine();
ChannelServices.UnregisterChannel(_tcpChannel);
}
}
}
Lib_App1 :LibApp1.cs
using System;
using System.Collections;
using System.Runtime.Remoting;
using MyTcpChannel
= System.Runtime.Remoting.Channels.Tcp.TcpChannel;
using System.Runtime.Remoting.Channels.Tcp;
using System.Runtime.Remoting.Channels;
namespace
Lib_App1
{
/// <summary>
/// Description résumée de Class1.
/// </summary>
public
class LibApp1 :MarshalByRefObject
{
public LibApp1()
{ }
public void getAgioAndDec(long lIDClient, ref float fDec, ref float fAgio)
{
//les calcul sont fictifs: ajouter du code pour acceder à une DB
if(lIDClient
> 0)
{
fDec = -152;//toujours
fAgio = getAgio2(fDec);
}
}
/// <summary>
/// Cette methode
appel l'objet distant Lib_App2 pour avoir le montant de l'agio
/// sachant
à combien s'éleve le découvert.
/// Pour que cette méthode
marche il faut que le serveur Svr_App2 soit démarré
/// </summary>
/// <returns></returns>
private float
getAgio2(float fDec)
{
//(1): Ouverture du canal selon le protocole Tcp
MyTcpChannel _tcpChannel = new MyTcpChannel(1);
//(2): Enregistrement du canal ouvert précédemment
ChannelServices.RegisterChannel(_tcpChannel);
// (3): Récupération d'une référence de l'objet distant
Lib_App2 hebergé par Svr_App2
Lib_App2.LibApp2 pxy_App2 = (Lib_App2.LibApp2)RemotingServices.Connect(typeof(Lib_App2.LibApp2),
"tcp://localhost:5678/Svr_App2");
try
{
return pxy_App2.getAgio(fDec);
}
catch(Exception ex)
{
return -1;
}
finally
{
// (4):
Fermeture et deréférencement du canal
ChannelServices.UnregisterChannel(_tcpChannel);
}
}
}
}
ctl_App3 :IApp1.cs
/*C'est le proxy de l'objet
Lib_App1*/
using System;
namespace
Lib_App1
{
public
interface LibApp1
{
void getAgioAndDec(long lIDClient, ref float fDec, ref float fAgio);
int test();
}
}
clt_App3 :
Form1.cs
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Runtime.Remoting;
using MyTcpChannel
= System.Runtime.Remoting.Channels.Tcp.TcpChannel;
using System.Runtime.Remoting.Channels.Tcp;
using System.Runtime.Remoting.Channels;
namespace
clt_App3
{
/// <summary>
/// Description résumée de Form1.
/// </summary>
public
class Form1 : System.Windows.Forms.Form
{
private System.Windows.Forms.TextBox
textBox1;
private System.Windows.Forms.Button
button1;
private System.Windows.Forms.Label
label1;
/// <summary>
/// Variable nécessaire au
concepteur.
/// </summary>
private System.ComponentModel.Container
components = null;
public Form1()
{
//
// Requis pour la prise en charge du Concepteur Windows Forms
//
InitializeComponent();
//
// TODO : ajoutez le code du constructeur après l'appel à InitializeComponent
//
}
/// <summary>
/// Nettoyage des
ressources utilisées.
/// </summary>
protected override
void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
#region Code généré par le Concepteur Windows Form
/// <summary>
/// Méthode requise pour la
prise en charge du concepteur - ne modifiez pas
/// le
contenu de cette méthode avec l'éditeur de code.
/// </summary>
private void InitializeComponent()
{
this.textBox1
= new System.Windows.Forms.TextBox();
this.button1
= new System.Windows.Forms.Button();
this.label1
= new System.Windows.Forms.Label();
this.SuspendLayout();
//
//
textBox1
//
this.textBox1.Location
= new System.Drawing.Point(16, 16);
this.textBox1.Name
= "textBox1";
this.textBox1.TabIndex
= 0;
this.textBox1.Text
= "45286";
//
//
button1
//
this.button1.Location
= new System.Drawing.Point(144, 16);
this.button1.Name
= "button1";
this.button1.Size
= new System.Drawing.Size(88, 23);
this.button1.TabIndex
= 1;
this.button1.Text
= "Go";
this.button1.Click
+= new System.EventHandler(this.button1_Click);
//
// label1
//
this.label1.Location
= new System.Drawing.Point(24, 48);
this.label1.Name
= "label1";
this.label1.Size
= new System.Drawing.Size(528, 376);
this.label1.TabIndex
= 2;
this.label1.Text
= "Result";
//
//
Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new
System.Drawing.Size(584, 446);
this.Controls.Add(this.label1);
this.Controls.Add(this.button1);
this.Controls.Add(this.textBox1);
this.Name = "Form1";
this.Text = "Form1";
this.ResumeLayout(false);
}
#endregion
/// <summary>
/// Point d'entrée principal de
l'application.
/// </summary>
[STAThread]
static void
{
Application.Run(new Form1());
}
/// <summary>
/// Cette methode
appel l'objet distant Lib_App1 pour avoir le montant de l'agio et du découvert
/// en
se basant sur l'ID du client
/// Pour que cette méthode
marche il faut que le serveur Svr_App1 soit démarré
/// </summary>
/// <param
name="sender"></param>
/// <param
name="e"></param>
private void
button1_Click(object sender, System.EventArgs e)
{
long lIDClient = long.Parse(textBox1.Text);
float fAgio = 0;
float fDec = 0;
//(1): Ouverture du canal selon
le protocole Tcp
MyTcpChannel _tcpChannel = new MyTcpChannel(0);
//(2): Enregistrement du canal ouvert précédemment
ChannelServices.RegisterChannel(_tcpChannel);
// (3): Récupération d'une référence de l'objet distant
Lib_App1 hebergé par Svr_App1
Lib_App1.LibApp1 pxy_App1 = (Lib_App1.LibApp1)RemotingServices.Connect(typeof(Lib_App1.LibApp1),
"tcp://localhost:1234/Svr_App1");
try
{
pxy_App1.getAgioAndDec(lIDClient,ref fDec,ref fAgio);
label1.Text = "Agio = "+fDec+" et Dec ="+ fAgio;
if(fAgio > 15)
label1.Text
+= "\n Un courrier sera transmis!";
else
label1.Text += "\n Aucun courrier ne sera transmis!";
}
catch(Exception ex)
{
label1.Text = ex.ToString();
}
finally
{
// (4): Fermeture et deréférencement
du canal
ChannelServices.UnregisterChannel(_tcpChannel);
}
}
}
}
Bien entendu si vous voulez tester l’application cliente (clt_App3) vous devez d’abord lancer les deux serveurs (Svr_App1 et Svr_App2). Le client utilise uniquement le serveur Svr_App1 (calcul découvert) et ce dernier utilisera le serveur des agios (Svr_App2).

Par dotnet, Lundi 20 Mars 2006 à 11:55 GMT+2 dans .NET
Mercredi 8 Mars 2006
Comme vous le savez très bien il peut être très utile de pouvoir faire des énumérateurs de string (par défaut les enumérateurs contiennent des entiers).
Avec .NET on peut facilement faire cela en ajoutant des descriptions à vos enumérateurs.
Pour cela procédez comme suit :
using System.ComponentModel;
using System.Reflection;
Créer
votre enumérateur (dans mon cas j’ai un énumérateur « Voitures »)
enum Voitures{
[Description("Une Renault 12 année 75
-Française-")]R12,
[Description("Une Renault 5 année 60
-Française-")]R5,
[Description("Une Peugeot 607 année 2001
-Française-")]P607
};
private string _GetDesc(Voitures enumConst)
{
FieldInfo finfo = enumConst.GetType().GetField(enumConst.ToString());
object [] descAttr = finfo.GetCustomAttributes(typeof(DescriptionAttribute),false);
if(descAttr.Length > 0)
return ((DescriptionAttribute)descAttr[0]).Description;
else
return
enumConst.ToString();
}
Voitures
v_f = Voitures.P607;
string desc = _GetDesc(v_f);//='Une Peugeot 607 année
2001 -Française-'
Par dotnet, Mercredi 8 Mars 2006 à 09:16 GMT+2 dans .NET
Lundi 6 Mars 2006
Malheureusement
aucunes commandes T-SQL ne permettent d’exécuter un dts,
mais il existe cependant deux « solutions de contournement » :
Dans
cette première partie nous allons utiliser la première méthode car plus facile
à mettre en œuvre bien que plus contraignante en terme de gestion de sécurité
DTSRUN
est un utilitaire qui vous permet d’exécuter un lot, ou le planifier sans
utiliser le fameux Microsoft Management Console (MMC). Pour exécuter cette
commande vous devez bien sûr avoir MS SQL Server sur votre machine.
Lancer
l’invite de commande (démarrer->exécuté puis tapez « cmd ») puis
tapez dtsrun pour avoir l’aide concernant
l’utilisation de celle-ci.
Syntaxe
dtsrun
[/?] |
[
[
/[~]S server_name[\instance_name]
{ {/[~]U user_name [/[~]P password]} | /E }
]
{
{/[~]N package_name }
| {/[~]G package_guid_string}
| {/[~]V package_version_guid_string}
}
[/[~]M package_password]
[/[~]F filename]
[/[~]R repository_database_name]
[/A global_variable_name:typeid=value]
[/L log_file_name]
[/W NT_event_log_completion_status]
[/Z] [/!X] [/!D] [/!Y] [/!C]
]
Utilitaire d’aide à la génération de la
commande
Il
existe un utilitaire qui permet de générer graphiquement la commande nécessaire
pour l’exécution d’un lot donnée.
Supposons
que nous avons besoin de générer la commande d’exécution du lot suivant
Nom : abcdTest
Server : MyServer
User name = sa
Pwd = pwd
Variable globale : NBLigne avec comme valeur
780
Fichier journal : C:\Temp\log.txt
Se qu’il faut faire :
NB : cet utilitaire vous donne aussi la
possibilité de planifier l’exécution de votre lot.
Le résultat doit être semblable à quelque chose
comme :
DTSRun /S "MyServer " /U "sa" /P "pwd" /N "abcdTest " /G
"{5360FD4D-5326-4640-B06C-31E8652F48B3}" /L "C:\Temp\log.txt" /A
"NBLignes":"780"="78" /W
"0"
Vous
pouvez tester votre commande en l’exécutant en ligne de commande
La
seconde étape consiste à exécuter cette commande dans MS SQL Server.
MS SQL Server offre la possibilité d’exécuter des lignes de commande grâce à la procédure stockée xp_cmdshell (à utiliser avec prudence et parcimonie) qui se trouve dans la base master.
Ouvrez l’analyseur de requêtes puis tapez exec master..xp_cmdshell ‘dir’. Cela aura pour effet de lister les fichiers situés sur le disque dur de la machine sur laquelle SQL Server est installé.
Pour exécuter votre commande créez une procédure stockée contenant le code suivant :
DECLARE @CMD varchar(1000)
SET @CMD = ‘DTSRun /S "MyServer " /U
"sa" /P "pwd"
/N "abcdTest " /G "{5360FD4D-5326-4640-B06C-31E8652F48B3}"
/L "C:\Temp\log.txt" /A
"NBLignes":"780"="78" /W "0"’
exec master..xp_cmdshell @CMD
Et voilà, c’est partiiiiiiii
Par dotnet, Lundi 6 Mars 2006 à 13:32 GMT+2 dans Astuces du Mois
Jeudi 2 Mars 2006
Ouvrer l’analyser de requête et tapez ceci
SELECT ServerProperty('PRODUCTVERSION') AS
VERSION_NUMBER,
ServerProperty ('PRODUCTLEVEL') AS SERVICE_PACK,
ServerProperty ('EDITION') AS EDITION
Par dotnet, Jeudi 2 Mars 2006 à 11:25 GMT+2 dans SQL Server - TSQL - DAL
Jeudi 22 Decembre 2005
Pouvoir définir un style à la volée (suivant un utilisateur) en ASP.NET peut être très utile.
J’ai eu à faire cela dans une application web où chaque utilisateur avait son propre style définie dans une base de données (le chemin du fichier CSS).
Si les utilisateurs sont habitués aux styles CSS ils peuvent même écrire leurs propres feuilles de styles en se basant sur un Template prédéfini.
Vous devez procéder en 3 étapes
<HEAD>
…..
<LINK id="stPageStyle"
type="text/css" rel="stylesheet" runat="server"></LINK>
…..
</HEAD>
protected HtmlGenericControl
stPageStyle;
/* strCssFile doit contenir le path complet de votre feuille de style.
* Si votre feuille de style
s'appel MyStyle.css et est située dans
* un répertoire de votre
site web alors vous pouvez faire un Mapping
* pour retrouver le chemin
complet. Sinon mettez le en dure ou récupérez
* d'une DB ou d'un fichier
.ini.
* */
string strCssFile = Server.MapPath("MyStyle.css");//Mapping
stPageStyle.Attributes.Add("href",strCssFile);
Par dotnet, Jeudi 22 Decembre 2005 à 10:25 GMT+2 dans .NET
Mardi 13 Decembre 2005
InetAddress est une classe java fort intéressant car elle permet de retrouver une adresse IP d’un poste à partir de son nom de domaine (DNS). Pour cela java passe par la couche réseau de l’OS pour que celui-ci interroge ces serveurs pour obtenir, soit le nom, soit l’IP.
Voici un exemple qui permet d’avoir une adresse IP à partir d’un nom.
package dotnet.mabulle.java;
import java.net.* ;
public class NomToIp {
public static void
main(String[] args){
String m_Name = args[0];
if(m_Name.length()==0){
System.out.println("Saisissez un nom");
}
try{
InetAddress address = InetAddress.getByName(m_Name);
System.out.println("Name: "+ address.getHostName());
System.out.println("Address: "+ address.getHostAddress());
}catch(UnknownHostException Unex){
Unex.printStackTrace();
}
}//fin main
}//fin class
Si vous donnez google.fr en entrée, vous obtenez:
Name: google.fr
Address: 216.239.57.104
Si vous donnez dotnet.mabulle.com en entrée, vous obtenez:
Name: dotnet.mabulle.com
Address: 213.251.133.165
Dans le prochain article je vous expliquerai comment faire un pseudo ping avec java.
A+
Par dotnet, Mardi 13 Decembre 2005 à 16:42 GMT+2 dans J2EE
Vendredi 9 Decembre 2005
Sous .NET il est important de savoir par exemple comment ouvrir un panneau de configuration avec C#.Net car il arrive très souvent qu’on souhaite offrir à l’utilisateur la possibilité de configurer sa machine à la suite d’une levée d’exception (par exemple).
Pour ouvrir un panneau de configuration particulier, il faut savoir ou se trouve le fichier d’extension de ce dernier (*.cpl). Pour les panneaux concernant Windows, la plupart sont dans c:\windows\system32\.
System.Diagnostics.Process.Start(Environment.
GetEnvironmentVariable("windir") + "\\system32\\inetcpl.cpl");
System.Diagnostics.Process.Start(Environment.
GetEnvironmentVariable("windir") + "\\system32\\ncpa.cpl");
NB: Vous
pouvez faire la même chose pour toutes les applications installées sur votre
poste possédant un fichier .cpl.
Voici quelques fichiers cpl utiles
|
Accessibilité |
access.cpl |
|
Mots de passe |
password.cpl |
|
Affichage |
desk.cpl |
|
Thèmes du bureau |
themes.cpl |
|
Paramètres régionaux |
intl.cpl |
|
Internet |
inet.cpl |
|
Modem |
modem.cpl |
|
Système |
sysdm.cpl |
|
Réseau |
netcpl.cpl |
|
Profils Microsoft Exchange |
mlcfg32.cpl |
|
Logiciels |
appwiz.cpl |
|
Souris |
main.cpl |
|
Multimédia |
mmsys.cpl |
|
Manette de jeu |
joy.cpl |
|
Date/heure |
timedate.cpl |
Par dotnet, Vendredi 9 Decembre 2005 à 17:18 GMT+2 dans .NET
Mardi 6 Decembre 2005
L’objectif de ce document est d’expliquer dans un premier temps comment lancer une application externe (ou processus) à partir d’une application .NET, puis dans un second temps montrer comment lancer ce processus avec un utilisateur particulier.
1. Lancer l’application
avec l’utilisateur par défaut
//pour
lancer IE vous pouvez initialiser appPath à
"C:\Program Files\Internet //Explorer\iexplore.exe"
string appPath =
System.IO.Path.Combine(Environment.SystemDirectory,
"cmd.exe");
System.Diagnostics.Process.Start(appPath);
2. Lancer
l’application avec un utilisateur défini
Cette option peut être intéressante
dans le cas ou vous souhaitez lancer une application avez un utilisateur
privilégié ou contrer l’utilisateur par défaut ASPNET (empreint d’identité ou « impersonalisation »).
Si vous essayer par exemple de
faire System.Diagnostics.Process.Start(« une
application sécurisée »); sous ASP .NET, alors vous aurez une exception car
l’utilisateur qui sera utilisé est APSNET (droits réduits).
Vous-vous dites surement que la
solution serait donc d’utiliser la méthode « LogonUser »
de l’API « advapi32 » (cf. http://dotnet.mabulle.com/index.php/2005/12/02/24858-empreint-didentite-avec-cnet).
Si c’est le cas, alors c’est loupé, car la méthode « Process.Start »
utilise toujours le contexte de sécurité du processus parent ASP.NET. Pour résoudre cela il faudra
chercher du coté de la méthode « CreateProcessWithLogonW »
de la même API (advapi32).
using System;
using System.Runtime.InteropServices;
namespace WindowsApplication1
{
/// <summary>
///
Description résumée de DLLClass.
/// </summary>
public class DLLClass
{
[Flags]
public enum LogonFlags
{
LOGON_WITH_PROFILE = 0x00000001,
LOGON_NETCREDENTIALS_ONLY =
0x00000002
}
[Flags]
public enum CreationFlags
{
CREATE_SUSPENDED = 0x00000004,
CREATE_NEW_CONSOLE = 0x00000010,
CREATE_NEW_PROCESS_GROUP = 0x00000200,
CREATE_UNICODE_ENVIRONMENT
= 0x00000400,
CREATE_SEPARATE_WOW_VDM = 0x00000800,
CREATE_DEFAULT_ERROR_MODE = 0x04000000,
}
[StructLayout(LayoutKind.Sequential)]
public struct ProcessInfo
{
public IntPtr
hProcess;
public IntPtr
hThread;
public uint dwProcessId;
public uint dwThreadId;
}
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
public struct StartupInfo
{
public int cb;
public string
reserved1;
public string
desktop;
public string title;
public uint dwX;
public uint dwY;
public uint dwXSize;
public uint dwYSize;
public uint dwXCountChars;
public uint dwYCountChars;
public uint dwFillAttribute;
public uint dwFlags;
public ushort wShowWindow;
public short
reserved2;
public int
reserved3;
public IntPtr hStdInput;
public IntPtr hStdOutput;
public IntPtr hStdError;
}
[DllImport("advapi32.dll",
CharSet=CharSet.Unicode, ExactSpelling=true, SetLastError=true)]
public static extern bool CreateProcessWithLogonW(
string principal,
string authority,
string password,
LogonFlags logonFlags,
string appName,
string cmdLine,
CreationFlags creationFlags,
IntPtr environmentBlock,
string currentDirectory,
ref StartupInfo
startupInfo,
out ProcessInfo
processInfo);
[DllImport("kernel32.dll")]
public static extern bool CloseHandle(IntPtr h);
public DLLClass()
{
//
//
TODO : ajoutez ici la logique du constructeur
//
}
}
}
string strError =
"";
//DLLClass représente la class que vous avez ajoutez
DLLClass.StartupInfo _StartupInfo
= new DLLClass.StartupInfo();
DLLClass.ProcessInfo _ProcessInfo
= new DLLClass.ProcessInfo();
string strAppPath
= @"C:\Program Files\Internet Explorer\iexplore.exe";
if (DLLClass.CreateProcessWithLogonW("login",
"domain", "password",
DLLClass.LogonFlags.LOGON_WITH_PROFILE,
strAppPath, null,
0,
IntPtr.Zero, null,
ref _StartupInfo,
out _ProcessInfo))
{
DLLClass.CloseHandle(_ProcessInfo.hProcess);
DLLClass.CloseHandle(_ProcessInfo.hThread);
}
else strError
= string.Format("Code
error: {0}", Marshal.GetLastWin32Error());
/*/libre à vous d'afficher l'erreur
Console.WriteLine(strError);
//ou
label1.Text = strError;
//ou
MessageBox.Show(strError);
*/
Vous pouvez savoir qu’elle utilisateur a lancé l’application en faisant ceci :
string strUserName
= System.Security.Principal.WindowsIdentity.GetCurrent().Name;
Par dotnet, Mardi 6 Decembre 2005 à 17:01 GMT+2 dans .NET
Lundi 5 Decembre 2005
package blog.tecnoJava.serialization;
import java.beans.XMLDecoder;
import java.beans.XMLEncoder;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
public class Serialize {
//Cette
méthode permet d’écrire (sérialiser) un objet java dans un fichier
//Binaire:*.dat,*.bin,...
public void
WriteInBinaryFormat(Object oToSerialize,String
strDestinationPath) throws IOException{
//Create
output streams.
FileOutputStream
fos = new FileOutputStream(strDestinationPath);
ObjectOutputStream
oos = new ObjectOutputStream(fos);
//Write
object
oos.writeObject(oToSerialize);
}
// Cette Methode Permet de lire un objet sérialiser à partir d’un
fichier binaire
public Object ReadFromBinaryFile(String
strSourceFilePath) throws IOException,
ClassNotFoundException{
//Create
input streams.
FileInputStream
fis = new FileInputStream(strSourceFilePath);
ObjectInputStream
ois = new ObjectInputStream(fis);
//Read
object
return
ois.readObject();
}
//Cette
méthode permet d’écrire (archiver) un objet java dans une archive
//XML comme ci-dessous
public void
WriteInXMLArchiveFormat(Object oToSerialize,String
strDestinationPath) throws FileNotFoundException{
// Create output stream.
FileOutputStream
fos = new FileOutputStream(strDestinationPath);
//Create
XML encoder
XMLEncoder
Xmlenc = new XMLEncoder(fos);
//Write
object.
Xmlenc.writeObject(oToSerialize);
}
public
Object ReadFromXMLArchive(String strSourceFilePath)
throws FileNotFoundException{
// Create input stream.
FileInputStream
fis = new FileInputStream(strSourceFilePath);
//Create
XML decoder
XMLDecoder
Xmldec = new XMLDecoder(fis);
//Read
object.
return
Xmldec.readObject();
}
}
Par dotnet, Lundi 5 Decembre 2005 à 12:05 GMT+2 dans J2EE
VS .NET offre un environnement robuste pour
créer des applications basées sur le NETCF. Ces applications peuvent tourner
sur Pocket PC, Pocket PC 2002(et plus) et Windows CE .NET 4.1 (et plus). L’environnement
permet d’inclure facilement des Windows Forms et composants ADO.NET dans les
programmes en plus de tout ce qui a attrait au web ( consommer des services web).
a)
Design : VS .NET :1 /
eVC++ :0
A la différence
d’eVC++ VS .NET offre un environnement
très simple d’utilisation pour tout ce qui concerne le
« design » de forms. VS .NET a reprit toutes les bonnes idées de VB
concernant le design notamment la notion de form (fichiers *.ebf en VB).
b)
Sécurité : VS .NET :2 /
eVC++ :0
Un autre avantage d’utiliser des assemblies
plutôt que des DLLs est que les premiers sont plus sécurisés (chargés dans le
runtime avec un niveau de confiance), permettent d’éviter le chainage (système
de versionning), gèrent les dépendances, … En un mot, les assemblies permettent
de se passer de ce que certains appellent « l’enfer des DLLs ».
c)
Performances
d’exécution : VS .NET :2 / eVC++ :1
L’inconvénient qui résulte de cela (b) est que
les assemblies ne peuvent s’exécuter que dans le Runtime .NET (ce qui fait
qu’il faut avoir le NETCF installé à la fois sur le PC et le PPC) qui est
lui-même est chargé par l’OS ; les DLLs C++ sont directement
« consommable » par l’OS (win32) d’une façon native. C’est en partie
à cause de se « problème » (et d’autres aussi) que les applications
C++/C sont beaucoup plus performant que celles développées avec C# .NET/VB
.NET/C++ .NET/Java, …
d)
Intégration de
composants natifs type ocx : VS .NET :2 / eVC++ :2
Annoncé
pour la version 2 du NETCF, il n’est toujours pas possible
d’ « héberger » des composants ActiveX sous NETCF. Sous eVC++ il
suffit d’un clic deux mouvements pour intégrer son contrôle ActiveX dans son
programme. Cependant, il est possible de développer une couche supplémentaire
au NETCF permettant de résoudre cet handicap. Sinon, la seule alternative est
de redévelopper son composant pour le NETCF (paradoxalement, il permet de le
faire). Le développement et la mise en place de cette couche est assez complexe
mais ils existent des bases (librairies de classes) offertes « gratuitement »
par la firme OpenNETCT.
Pour que cela fonctionne on doit disposer du
proxy sous forme d’Assemby et d’un Wrapper dans un fichier C# (c’est le seul
langage dans lequel le Wrapper peut être généré). L’Assembly et le Wrapper sont
générés par l’utilitaire de ligne de commande offert avec le FrameWork .NET
(Aximp, pour ActiveX IMPort). Cet utilitaire n’étant pas adapté pour le NETCF, il pourrait être
nécessaire de modifier la Wrapper à la main dans certain cas (c’est le cas du
composant MapX50.dll).
Cependant, sous NETCF il existe toutes les
classes nécessaires pour faire du Marshling de type et du Wrapping.
e)
Automation OLE : VS .NET :3 /
eVC++ :2
C# permet beaucoup plus aisément de faire de l’automation (accès aux routines d’un processus) que le C++. On peut très facilement contrôler un processus Word en exécutant ces routines (créer un document, faire des mises en page ou tout simplement générer des rapports Word ou Excel) à partir d’un code managé. Faire ce type de programme en C++ est possible mais pas facile d’accès. o:p>
f)
C# (sous VS .NET) vs C++
(sous eVC++) : VS .NET :3 / eVC++ :2
Il n’est tout simplement pas possible de
comparer ces deux langages du fait que leurs objectifs ne sont pas les mêmes.
Si j’avais à le faire je dirais qu’un programme C# offre très certainement plus
de lisibilité (il suffit juste
de voir le nombre de ligne de code généré automatique par eVC++ avant même
d’avoir écrit une ligne), de productivité
(le système de séparation du « code design (interface) » et du
« code code (implementation) » - utilisation de Classes partielles-
améliore grandement la productivité avec C#) et de facilités de management (gestion du code au
sens large) du fait tout simplement que
ces concepteurs ont retenu les leçons tirer du C++, Java, Delphi et autres
langages.
Cela fait que dans notre cas (programmation PPC)
C# est sans aucun doute le langage le plus approprié.
g)
Ouverture : VS .NET :4 /
eVC++ :2
Pour faire des applications mobiles cloisonnées
eVC++ pourrait rivaliser avec VS .NET mais du moment que ces applications ont
vocation à s’ouvrir sur le web ou interopérer avec d’autres applications (processus,
SGBD, supports hybrides, …) on peut dire que VS.NET prend largement le dessus
(à savoir qu’à l’origine .NET était définie par Microsoft comme étant une
technologie qui permet de « communiquer », le mot –communiquer- souligne
l’importance donner au web et à l’interopérabilité).
Il convient ainsi de bien
étudier les possibles évolutions de notre application avant de choisir à le
développer sous eVC++.
h)
Design patterns (ou
réutilisation de code) : VS .NET :4 / eVC++ :2
Il est bien dommage de remarquer qu’au cours des
développements les développeurs sont
amenés à créer plusieurs fois les mêmes classes (types), d’exécuter les même
procédures, de manipuler les mêmes objets pour accéder aux DB, etc. … tout ça
pour dire : réinventer la roue. Une parade à cela est certainement la
définition de motifs de conception (design patterns) réutilisable. Le C# et le
C++ étant tous les deux très orientés Objet (l’objet étant la base des design
patterns) on ne pourrait choisir l’un plutôt que l’autre.
VS
.NET remporte 4 points contre 2 pour eVC++. L’avantage donné à VS .NET peut
être dut au fait que je maitrise plus celui-ci.
L’élément le plus
important à prendre en compte est l’évolution de l’application.
Merci
de me signaler les âneries.
Par dotnet, Lundi 5 Decembre 2005 à 10:38 GMT+2 dans PDA
Dimanche 4 Decembre 2005
Dans ce document je vais expliquer comment lister toutes les tables d’une base de données SQL Server.
Ce bout de code TSQL (à exécuter dans une procédure stockée par exemple) vous permettra de lister l’ensemble des tables (table_name) de votre DB avec les colonnes (column_name) de chaque table et son type (data_type).
--afficher toutes les tables de la db avec les colonnes et leurs type
SELECT
table_name,
data_type FROM information_schema.columns
WHERE table_name in
(select table_name
FROM Information_Schema.Tables
WHERE Table_Type='Base
Table'
)
ORDER BY table_name
Ce bout de code spécialisé vous permettra de ne lister que les propriétés d’une table entrée en paramètre (@TableName).
DECLARE @TableName as varchar(255)
SET @TableName
= 'T_MaTable'
--afficher toutes les tables de la db avec les colonnes et leurs type
SELECT
table_name,
column_name,
data_type
FROM information_schema.columns
WHERE table_name
in (select table_name
FROM Information_Schema.Tables
WHERE Table_Type='Base
Table'
and Table_Name = @TableName
)
ORDER BY table_name
Par dotnet, Dimanche 4 Decembre 2005 à 18:33 GMT+2 dans SQL Server - TSQL - DAL
Vendredi 2 Decembre 2005
Pour la programmation en code manage pour le Framework et
des Assemblies (cela a la couleur et l’odeur d’une DLL mais ça n’a rien à
voir).
Par dotnet, Vendredi 2 Decembre 2005 à 15:08 GMT+2 dans PDA
Par dotnet, Vendredi 2 Decembre 2005 à 14:22 GMT+2 dans .NET
Jeudi 1 Decembre 2005
Par dotnet, Jeudi 1 Decembre 2005 à 14:58 GMT+2 dans Divers
Mercredi 30 Novembre 2005
Il faut juste savoir que le Newton, lancé par Apple en 1993, est le pionnier des assistants
personnels. Puis deux modèles se sont imposés grâce aux fonctions de
synchronisation avec un ordinateur de bureau: le Palm Pilot, commercialisé dès
1996 par US Robotics, et le Psion. Aujourd'hui de nombreuses marques proposent
des assistants personnels très sophistiqués, pouvant allier multimédia et accès
Internet sans fil : Compaq, Hewlett-Packard, Toshiba, Sagem, etc.
La différence majeure entre ces différents
modèles est l’OS : les uns utilisent Microsoft
Mobile et les autres PalmOS.
Pour faire simple nous dirons que ceux fonctionnant sous Microsoft mobile sont
des PPC (Pocket PC) et les autres des Palms.
Comme dans
le monde des Postes de travail (pour ne pas dire PC) il existe deux
camps : Microsoft et les autres.
Pour faire simple et claire on dira que PPC ~=
PC et Palm ~= Mac car PalmOS et Windows Mobile sont deux systèmes
d’exploitation bien différents. PalmOS semble toute fois être supérieur à WM en
se qui concerne le choix des logicielles, la rapidité d’exécution, le prix, …
(pour aller loin : ZDNET).
Par dotnet, Mercredi 30 Novembre 2005 à 15:06 GMT+2 dans PDA



