Tag Archives: interop

Always on top window

Un petit bout d’interop pour créer des TopMost window. Les flags permettent d’éviter a la fenêtre de se resizer et de bouger après l’appel de la fonction. (Sinon, avec les arguments {x,y,cx,cy} à 0, la fenêtre fera 0*0 à la coordonnée 0:0).
Ensuite le placement de la fenêtre se fait avec le IntPtr HWND_x.

        private static readonly IntPtr HWND_TOPMOST = new IntPtr(-1);
        private static readonly IntPtr HWND_NOTOPMOST = new IntPtr(-2);
        private const UInt32 SWP_NOSIZE = 0x0001;
        private const UInt32 SWP_NOMOVE = 0x0002;
        private const UInt32 FLAGS = SWP_NOMOVE | SWP_NOSIZE;

        [DllImport("user32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);

        public void SetOnTop()
        {
            SetWindowPos(this.Handle, HWND_TOPMOST, 0, 0, 0, 0, FLAGS);
        }

        public void UnSetOnTop()
        {
            SetWindowPos(this.Handle, HWND_NOTOPMOST, 0, 0, 0, 0, FLAGS);
        }

Ref. : msdn

Events fantôme et interop office


Je développe actuellement une application ou j’ai besoin d’intégrer l’éditeur de dessin Visio et, entre autre, m’abonner a certains événements. Seul soucis, l’évènement survient de manière aléatoire. Après quelques heures de recherche et l’écriture d’un wrapper de COM event qui a donné le même résultat, j’ai trouvé ceci sur un forum concernant un problème d’event dans outlook.

The reason is: “GC collect the .NET object, whichc wrapps COM object from Outlook )”. The solution is hold reference to this .NET object.

La solution, simplement garder une référence sur l’objet. Dans mon cas, ma page Visio dans un attribut privé 😀

Convertisseur Word vers PDF en ligne de commande


J’ai besoin de convertir de documents docx en pdf afin d’intégrer la génération de documentations dans mes build TFS2010. Malheureusement, les outils de « conversion » word->pdf sont la plupart du temp des drivers d’impression ou nécessitent une action manuel. Voici donc deux bout de code. Le premier avec uniquement le code de sauvegarde en pdf et le second pour une application avec deux arguments in: et out:, une vérification de la validité des arguments et l’émission de logs d’erreur dans l’event log windows. (L’application allant tourner en background lors des build, c’est le seul moyen propre de savoir ou ca à merdé)
Donc on commence par ouvrir une instance Word et un document de manière classique. (Classique a l’interop office). Ensuite, il suffit de définir quelques variables, mais le principal se joue sur le WdSaveFormat à définir en temp que wdFormatPDF. Voici le code :

    object inputFilePath = @"C:\teste.docx";
    object outputFilePath = @"C:\teste.pdf";

    object typeMissing = Type.Missing;

    // Création d'une instance
    _Application application = new Microsoft.Office.Interop.Word.Application();

    // La rendre invisible
    application.Application.Visible = false;

    // Ouvrir le fichier word
    Documents documents = application.Documents;
    _Document document = documents.Open
                        (ref inputFilePath, ref typeMissing, ref typeMissing, ref typeMissing,
                        ref typeMissing, ref typeMissing, ref typeMissing, ref typeMissing,
                        ref typeMissing, ref typeMissing, ref typeMissing, ref typeMissing,
                        ref typeMissing, ref typeMissing, ref typeMissing, ref typeMissing);

    // Définition des arguments de sauvegarde
    object FileFormat = WdSaveFormat.wdFormatPDF;
    object LockComments = false;
    object AddToRecentFiles = false;
    object ReadOnlyRecommended = false;
    object EmbedTrueTypeFonts = true;
    object SaveNativePictureFormat = false;
    object SaveFormsData = false;
    object SaveAsAOCELetter = false;
    object InsertLineBreaks = false;
    object AllowSubstitutions = false;
    object LineEnding = WdLineEndingType.wdCRLF;
    object AddBiDiMarks = false;

    // Saauvegarde
    document.SaveAs2(ref outputFilePath,
                    ref FileFormat,
                    ref LockComments,
                    ref typeMissing,
                    ref AddToRecentFiles,
                    ref typeMissing,
                    ref ReadOnlyRecommended,
                    ref EmbedTrueTypeFonts,
                    ref SaveNativePictureFormat,
                    ref SaveFormsData,
                    ref SaveAsAOCELetter,
                    ref typeMissing,
                    ref InsertLineBreaks,
                    ref AllowSubstitutions,
                    ref LineEnding,
                    ref AddBiDiMarks);

    // Fermerture
    application.Quit();
}
catch (Exception ex)
{
    WriteLog(String.Format("Application Excepetion for files : " +
                            "\nInput : {0}\nOutput : {1}\nError : {2}",
                            inputFilePath, outputFilePath, ex.Message));
}

Et la version « directement utilisable » :

static void Main(string[] args)
{
    Program p = new Program();
    if (p.CheckInput(args))
        p.Convert();
}

private object inputFilePath = null;
private object outputFilePath = null;

// Quelques vérifications basique.
public bool CheckInput(string[] args)
{
    // Check nombre d'arguments
    if (args.Length != 2) 
       { WriteLog("Nombre d'arguments invalide"); return false; }

    // Récupèration
    foreach (string a in args)
    {
        if (a.StartsWith("in:")) inputFilePath = a.Substring(3);
        if (a.StartsWith("out:")) outputFilePath = a.Substring(4);
    }

    // Verification non null
    if (inputFilePath == null) 
        { WriteLog("Fichier d'entré non spécifié"); return false; }
    if (outputFilePath == null) 
        { WriteLog("Fichier de sortie non spécifié"); return false; }

    // Verification existence input
    if(!(File.Exists(inputFilePath.ToString()))) 
        { WriteLog("Fichier d'entré n'existe pas"); return false; }
           
    return true;
}

public void Convert()
{
    try
    {
        object typeMissing = Type.Missing;

        // Création d'une instance
        _Application application = new Microsoft.Office.Interop.Word.Application();

        // La rendre invisible
        application.Application.Visible = false;

        // Ouvrir le fichier word
        Documents documents = application.Documents;
        _Document document = documents.Open
                         (ref inputFilePath, ref typeMissing, ref typeMissing, ref typeMissing,
                            ref typeMissing, ref typeMissing, ref typeMissing, ref typeMissing,
                            ref typeMissing, ref typeMissing, ref typeMissing, ref typeMissing,
                            ref typeMissing, ref typeMissing, ref typeMissing, ref typeMissing);

        // Définition des arguments de sauvegarde
        object FileFormat = WdSaveFormat.wdFormatPDF;
        object LockComments = false;
        object AddToRecentFiles = false;
        object ReadOnlyRecommended = false;
        object EmbedTrueTypeFonts = true;
        object SaveNativePictureFormat = false;
        object SaveFormsData = false;
        object SaveAsAOCELetter = false;
        object InsertLineBreaks = false;
        object AllowSubstitutions = false;
        object LineEnding = WdLineEndingType.wdCRLF;
        object AddBiDiMarks = false;

        // Saauvegarde
        document.SaveAs2(ref outputFilePath,
                        ref FileFormat,
                        ref LockComments,
                        ref typeMissing,
                        ref AddToRecentFiles,
                        ref typeMissing,
                        ref ReadOnlyRecommended,
                        ref EmbedTrueTypeFonts,
                        ref SaveNativePictureFormat,
                        ref SaveFormsData,
                        ref SaveAsAOCELetter,
                        ref typeMissing,
                        ref InsertLineBreaks,
                        ref AllowSubstitutions,
                        ref LineEnding,
                        ref AddBiDiMarks);

        // Fermerture
        application.Quit();
    }
    catch (Exception ex)
    {
        WriteLog(String.Format("Application Excepetion for files : " +
                                "\nInput : {0}\nOutput : {1}\nError : {2}",
                                inputFilePath, outputFilePath, ex.Message));
    }
}

void WriteLog(string message)
{
        // Ecriture dans l'event log
        string sSource = "Word To Pdf Tool";
        string sLog = "Application";
        string sEvent = message;

        // Vérification de la source, != création
        if (!EventLog.SourceExists(sSource)) EventLog.CreateEventSource(sSource, sLog);

        // Enregitrement du log
        EventLog.WriteEntry(sSource, sEvent, EventLogEntryType.Error, 234);
        Console.WriteLine(sEvent);
}

MCI Wrapper : Basic Audio Player C#

Salut, comme promis voici ma classe permettant de wrapper les mci pour obtenir un player audio simple en dotnet avec un peu d’interop. Je vous fournis le code ainsi que la dll, le code étant documenté et assez simple je ne rentrerai pas dans de longues explications.

Voici cependant un exemple pour charger un morceau, le lancer, changer son volume le mettre en pause, reprendre puis stopper :

MyBasicAudioPlayer bad = new MyBasicAudioPlayer();
bad.Open(@”C:\music.mp3″);
bad.Play(false);
bad.SetVolume(798);
bad.Pause();
bad.Resume();
bad.Stop();

Bref, un jeux d’enfant ^^ Cette librairie est aussi ultra legere, 3Ko, donc ne vous en privez pas 😉

Voici les liens :
:- Code source  -:
:- DLL -: 

Pour plus d”infos sur les MCI : http://msdn.microsoft.com/en-us/library/ms704979%28v=vs.85%29.aspx

Inform@tiquement
Manu404