Je doit régulièrement effacer une clef de registre* dans les profils itinérants de certain de nos utilisateurs, étant donné que je suis un tantinet fainéant et que je trouve cela fastidieux de devoir charger/decharger les ruches, chercher ensuite dans le registre, il ma semblé utile de créer ce petit prog.
- Pour ma part la clef Resiliency de Outlook, qui nous pose quelques problèmes en ce moment. Mais il est très facile de modifier la source pour l'adapter à ses besoins.
Je me suis appliqué au niveau des commentaires... :o) (le plus galère de tout)
Le programme permet de donner le chemin vers le serveur de profil dans un fichier, ce qui évite de reprendre le code quand celui-ci change.
De charger une ruche (fichier NTUSER.DAT) dans le registre local afin de pouvoir modifier/ajouter/supprimer des valeurs.
Source / Exemple :
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Microsoft.Win32; //Contient les fonctions permettants l'accès au registre
using System.IO; //Contient les fonctions permettant les actions sur les fichiers
using System.Diagnostics; //Contient les fonctions permettant de lancer d'autres procesus
namespace ResiliencyCleaner
{
public partial class frfMainResiliencyCleaner : Form
{
//******************************
//* Déclaration des constantes *
//******************************
//RCNL n'est pas reellement constante mais pris je la vois comme telle.
//Permet de connaitre la sequence d'echapement retour chariot nouvelle ligne,
//sur le systeme d'exploitation actuel.
string RCNL = Environment.NewLine;
//Constante servant pour la fonction de charge/decharge des ruches
const string cstLoad = "Load";
const string cstUnload = "Unload";
public frfMainResiliencyCleaner()
{
InitializeComponent();
}
private void btnCancel_Click(object sender, EventArgs e)
{
this.Close();
}
private void btnOk_Click(object sender, EventArgs e)
{
//on verifie qu'un login a bien été saisie
if (this.txtLogin.Text == "")
{
MessageBox.Show("Veuillez saisir un Login" , "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
return;
}
//On vide le textbox
this.txtInfos.Clear();
if (ResiliencyCleaner(this.txtLogin.Text, this.txtInfos) == false)
{
this.txtInfos.Text = this.txtInfos.Text+ RCNL + "Une erreur c'est produite.";
}
else
{
this.txtInfos.Text = this.txtInfos.Text + RCNL + "Toutes les opérations ce sont déroulées avec succès.";
}
}
public bool ResiliencyCleaner(string NomDeRuche, TextBox txtInformation)
{
//*****************************
//* Déclaration des variables *
//*****************************
//Contient le chemin complet vers le profile, on le lit dans le fichier "constante.cst"
string[] strCheminCompletVersProfile;
strCheminCompletVersProfile = new string[2];
//Nom que l'on donne a la ruche lors de l'import dans le registre, dans ce cas le nom
//du dossier contenant le profile
string strNomDeRuche = NomDeRuche;
//Chaine pointant vers la clef Resiliency que l'on veut supprimer dans le registre du Profile
string strResiliencyKey = strNomDeRuche + @"\Software\Microsoft\Office\11.0\Outlook\Resiliency";
try
{
//on recupere le chemin vers le profile en verifiant si la fonction c'est bien deroulé
strCheminCompletVersProfile = LireFichier("ProfilePath");
//Si la fonction ne c'est pas bien déroulée on affiche un message d'erreur
if (strCheminCompletVersProfile[0] == "0")
{
txtInformation.Text = txtInformation.Text + strCheminCompletVersProfile[1] + RCNL;
return false;
}
//Si la fonction c'est bien déroulée on complete le chemin avec le nom de dossier(Login)
strCheminCompletVersProfile[1] = strCheminCompletVersProfile[1] + @"\" + NomDeRuche;
//On informe l'utilisateur de l'étape suivante du programme
txtInformation.Text = txtInformation.Text + "Chargement de la ruche : " + RCNL +
strCheminCompletVersProfile[1] + RCNL + " dans le registre local." + RCNL;
// On charge la ruche avec Reg.exe avec la fonction OperationSurRuche, on verifie en mênme temps que
//celle si c'est bien déroulée
if(OperationSurRuche(strNomDeRuche, strCheminCompletVersProfile[1], cstLoad)!="")
{
//on informe l'utilisateur que le chargement c'est bien déroulée
txtInformation.Text = txtInformation.Text + RCNL + "L'opération s'est terminé avec succes" + RCNL;
//On efface la clef Resiliency de la ruche charger
Registry.Users.DeleteSubKeyTree(strResiliencyKey);
txtInformation.Text = txtInformation.Text + RCNL + "La clef Resiliency a été supprimée avec succès"
+ RCNL;
//On informe l'utilisateur de l'étape suivante du programme, soit le dechargement de la ruche
txtInformation.Text = txtInformation.Text + RCNL + "Dechargement de la ruche : " + strNomDeRuche +
" du registre local." + RCNL;
// On decharge la ruche et on affiche le resultat de Reg.exe
txtInformation.Text = txtInformation.Text + RCNL + "Dechargement de la ruche : " +
OperationSurRuche(strNomDeRuche, strCheminCompletVersProfile[1], cstUnload) + RCNL;
//Si tout c'est bien deroulé la fonction retourne True.
return true;
}
//Sinon on informe l'utilisateur qu'une erreur c'est produite lors du chargement de la ruche
else
{
txtInformation.Text = txtInformation.Text + RCNL +
"Une erreur c'est produite lors du chargement de la ruche." + RCNL +
"Cause possible l'utilisateur n'existe pas." + RCNL;
return false;
}
}
catch (Exception objErreurRegistre)
{
//On informe l'utilisateur q'une erreur c'est produite lors de l'opération dans le registre
txtInformation.Text = txtInformation.Text + RCNL + "Dechargement de la ruche : " + strNomDeRuche +
" du registre local suite à l'erreur:" + RCNL + objErreurRegistre.Message + RCNL;
// On decharge la ruche et on affiche le resultat de Reg.exe
txtInformation.Text = txtInformation.Text +
OperationSurRuche(strNomDeRuche, strCheminCompletVersProfile[1], cstUnload) + RCNL;
return false;
}
}
public string[] LireFichier(string parametre)
{
//fonction permettant de lire le fichier de configuration et de renvoyer le chemin vers les Profils
//et vers les journaux. Parametre attendu: ProfilePath ou ProtocolPath.
//Valeur retournées sous forme d'un tableau, le 1er element indique l'état d'achevement de la fonction
//(0 si il y a eu une erreur, 1 si ok) et le 2eme element la valeur a retourner.
//*****************************
//* Déclaration des variables *
//*****************************
// Contient la ligne actuelle lu par la fonction
string strLigneDuFichier;
//Contient les valeurs de retour de la fonction
string[] strValeur = new string[2];
try
{
//on crée un nouvel objet de type Streamreader
//AppDomain.CurrentDomain.BaseDirectory represente le repertoire de l'application
StreamReader objFichier = new StreamReader(AppDomain.CurrentDomain.BaseDirectory + @"\constante.cst");
//On lit la premiere ligne du fichier afin de determiner si le fichier n'est pas vide avant la boucle Wihle
strLigneDuFichier = objFichier.ReadLine();
// on va lire le fichier jusqu'a sa fin pour etre sur de ne pas sauter un parametre...
//on pourrait ne pas lire le fichier en entier et quitter la boucle une fois le parametre
//rechercher trouver.
while (strLigneDuFichier != null)
{
//on determine quel parametre est demandé
switch (parametre)
{
case "ProfilePath":
//Si strLigneDuFichier est égal a [ProfilePath], la prochaine ligne contient le chemin
//vers le serveur de profil
if (strLigneDuFichier == "[ProfilePath]")
{
strValeur[0] = "1";
//on lit la ligne (suivante) et on place la valeur dans strValeur
strValeur[1] = objFichier.ReadLine();
//on assigne strLigneDuFichier a NULL afin de sortir de la boucle.
//strLigneDuFichier = null;
}
break;
case "ProtocolPath":
//Si strLigneDuFichier est égal a [ProtocolPath], la prochaine ligne contient le chemin
//vers le serveur de protocol
if (strLigneDuFichier == "[ProtocolPath]")
{
strValeur[0] = "1";
//on lit la ligne (suivante) et on place la valeur dans strValeur
strValeur[1] = objFichier.ReadLine();
//on assigne strLigneDuFichier a NULL afin de sortir de la boucle.
//strLigneDuFichier = null;
}
break;
//Ici on peut rajouter autant de case que souhaité
//case n:
//
//
//
// V
//Si le parametre donné ne correspond a aucun de ceux connus (peu probable mais bon...)
default:
MessageBox.Show("Parametre inconnu : " + parametre + " dans le fichier de configuration.", "Erreur");
break;
}
//lecture de la ligne suivante permettant a la boucle d'avancer dans le fichier
strLigneDuFichier = objFichier.ReadLine();
}
//on ferme le fichier
objFichier.Close();
//on libere les ressources utilisés par l'objet
objFichier.Dispose();
//on retourne la valeur
return strValeur;
}
catch
{
//Si une erreur se produit lors de l'ouverture du fichier ou tout autre erreur
MessageBox.Show("Une erreur c'est produite lors de l'ouverture ou de la lecture du fichier de configuration.", "Erreur");
strValeur[0]="0";
strValeur[1]="Erreur de Fichier";
return strValeur;
}
}
public string OperationSurRuche(string NomDeRuche, string CheminVersRuche, string Operation)
{
//Fonction permettant la charge ou la decharge d'une ruche de registre.
//Revois True si l'operation demandee c'est bien passee ou False le cas contraire.
//Parametre attendus:
// - NomDeRuche, est le nom avec laquel la ruche apparait dans le registre local.
// - CheminVersRuche, est le chemin complet qui pointe vers le fichier NTUSER.DAT.
// - Operation, peut prendre les valeurs Load ou Unload selon l'operation que l'on veut faire.
//**************************************
//* Déclaration des variables et objet *
//**************************************
//Va contenir le chemin vers le repertoire systeme(System32)
string strSystem32Path;
//contien le parametre Operation
string strOperation= Operation;
//contien le parametre NomDeRuche
string strNomDeRuche = NomDeRuche;
//contien le parametre CheminVersRuche
string strCheminVersRuche = CheminVersRuche;
//contient la command complette pour charger une Ruche
string strCommand = "";
//contient la reponse renvoyer par la fonction
string strReponse = "";
//Creation d'un nouvel objet Process
Process MyProcess = new Process();
//on determine l'opération à effectuer et on affecte les arguments adequat a strCommande
if (strOperation == "Load")
{
strCommand = "load HKU\\" + strNomDeRuche + " " + strCheminVersRuche + @"\\NTUSER.DAT";
}
else
{
strCommand = "unload HKU\\" + strNomDeRuche;
}
//On affecte a "strPath" le chemin vers system32(la ou se trouve reg.exe)
strSystem32Path = Environment.GetFolderPath(Environment.SpecialFolder.System);
//Si l'on ne veut pas que la fenetre du programme invoqué s'affiche
//on met la propriete a true, sinon on la met a false ou on omet de
//specifié la propriete
MyProcess.StartInfo.CreateNoWindow = true;
//Si CreateNoWindows est a false on peut definir le style
//d'affichage de la fenetre du programme invoque.
//MyProcess.StartInfo.WindowStyle=ProcessWindowStyle.Hidden;
//Pour pouvoir rediriger la sortie standart il faut placer UseShell_
//Execute a false.
MyProcess.StartInfo.UseShellExecute = false;
//On redirige la sortie standart vers la sortie que l'on desire
MyProcess.StartInfo.RedirectStandardOutput = true;
//On specifie le programme ou le fichier a executer
//dans ce cas on a ajoute le chemin complet vers le fichier
MyProcess.StartInfo.FileName = strSystem32Path + "\\reg.exe";
MyProcess.StartInfo.Arguments = strCommand;
//On invoque le programme
MyProcess.Start();
//On lit la reponse que le programme retournerait vers la sortie
//standard et on la place dans strReponse
strReponse = MyProcess.StandardOutput.ReadToEnd();
//On attend la fin du programme
MyProcess.WaitForExit();
//On libere les ressources utilisees
//MyProcess = null; ou:
MyProcess.Dispose();
//On retourne la reponse
return strReponse;
}
}
}
Conclusion :
Ce n?est surement rien d?extraordinaire mais je suis plutôt fier du résultat, sachant que c?est mon premier code en C#...
Je suis ouvert a tout commentaire ou amélioration.