none
Conversion fichier texte en encodage Utf-8 et difficulté avec sendkeys RRS feed

  • Question

  • Bonjour à tous

    Question de débutant.

    Mon objectif est de transformer un fichier texte dont je ne connais pas l'encodage en un fichier texte encodé Utf-8.

    Faute d'avoir trouvé une fonction faisant ce travail, j'imagine une solution pas très élégante consistant à ouvrir mon fichier avec un NotePad et forcer son enregistrement dans l'encodage désiré.

    Depuis le code VB je voudrais donc ouvrir un programme externe (notepad++) et lui envoyer un sendkeys qui modifie le fichier.

    Quand je lance ma Sub depuis la fenêtre exécution de Visual Studio, le programme s'ouvre avec mon fichier mais le sendkeys ne donne aucun résultat.

    Merci de votre aide!

    Voici le code:

    --------------------------------

    Sub Utf8_Encodage(ByVal MonPath As String)
            ' ouvre un fichier dont l'application par défaut est Notepad++
            ' Lance une macro Notepad++ qui convertira le fichier en codage Utf-8 et le sauvegardera sous cet encodage
            Dim NotepadUtf8 As New Process
            Dim NotePadHandle As System.IntPtr
            NotepadUtf8.StartInfo.UseShellExecute = False
            NotepadUtf8.StartInfo.RedirectStandardInput = True
            NotepadUtf8.StartInfo.FileName = MonPath
            NotepadUtf8.StartInfo.WindowStyle = ProcessWindowStyle.Maximized
            'Démarrage de l'application
            Process.Start(MonPath)
            '----------------------ici tout va bien, le fichier s'ouvre dans Notepad++
            NotePadHandle = Process.GetCurrentProcess.Handle
            SetActiveWindow(NotePadHandle)
            ' lancer la macro en envoyant "Ctrl + F8" à Notepad++
            System.Windows.Forms.SendKeys.SendWait("^({F8})") ' ici, rien ne se passe dans Notepad++
        End Sub

    -----------------------------------------------------

    Encore merci pour l'aide!

    Gilles

    vendredi 7 mars 2014 23:05

Réponses

Toutes les réponses

  • Bonjour,

    Mon objectif est de transformer un fichier texte dont je ne connais pas l'encodage en un fichier texte encodé Utf-8.
    Pour information, aucun logiciel à ce jour ne peut détecter de manière fiable l'encodage d'un fichier...

    Essayez :

    System.Windows.Forms.SendKeys.SendWait("^{F8}") ' ici, rien ne se passe dans Notepad++

    Cordialement


    Gilles TOURREAU - MVP C#
    Architecte logiciel/Consultant/Formateur Freelance - P.O.S Informatique
    Blog : http://gilles.tourreau.fr - Suivez-moi sur Twitter
    - MCPD : Enterprise Developper / Windows Developper 3.5 / ASP .NET 3.5/4.0
    - MCSA : SQL Server 2012
    - MCITP : SQL Server 2008 Developper
    - MCTS : ADO .NET 3.5 / SQL Server 2008 Developper / Windows Forms 3.5 / ASP .NET 3.5/4.0 / TFS 2010 / Windows Azure

    samedi 8 mars 2014 06:47
    Modérateur
  • Merci Gilles de vous intéresser à mon cas.

    Malgré tout le

    System.Windows.Forms.SendKeys.SendWait("^{F8}")

    ne fonctionne pas mieux.

    Je me demande si cela ne vient pas du fait que je suis en mode debug avec lancement via la fenêtre execution car la fenêtre notepad++ reste au second plan malgré l'instruction

    SetActiveWindow(NotePadHandle)

    qui précède le sendkeys

    Cordialement

    Gilles T


    samedi 8 mars 2014 23:26
  • Bonjour

    C'est très simple de convertir un string en UTF8 - voir ici :
    http://social.msdn.microsoft.com/Forums/en-US/aa5b2e9c-c4cd-4f45-a9f0-a906542c5e49/text-convert-to-utf8
    Par contre, Process.GetCurrentProcess ne fait pas ce que vous voulez:
    http://msdn.microsoft.com/fr-fr/library/system.diagnostics.process.getcurrentprocess(v=vs.110).aspx
    Essayez avec les solutions proposes dans l'exemple.

    Cordialement, 


    Aurel BERA, MSFT
    MSDN Community Support. LE CONTENU EST FOURNI "TEL QUEL" SANS GARANTIE D'AUCUNE SORTE, EXPLICITE OU IMPLICITE.
    S'il vous plaît n'oubliez pas de "Marquer comme réponse" les réponses qui ont résolu votre problème. C'est une voie commune pour reconnaître ceux qui vous ont aidé, et rend plus facile pour les autres visiteurs de trouver plus tard la résolution.

    lundi 10 mars 2014 07:55
  • Bonjour

    Un petit retour SVP?

    Merci!

    Cordialement,


    Aurel BERA, MSFT
    MSDN Community Support. LE CONTENU EST FOURNI "TEL QUEL" SANS GARANTIE D'AUCUNE SORTE, EXPLICITE OU IMPLICITE.
    S'il vous plaît n'oubliez pas de "Marquer comme réponse" les réponses qui ont résolu votre problème. C'est une voie commune pour reconnaître ceux qui vous ont aidé, et rend plus facile pour les autres visiteurs de trouver plus tard la résolution.

    mardi 11 mars 2014 10:11
  • Bonjour Aurel

    J'ai tardé à reprendre contact car j'ai passé du temps à chercher par moi-même.

    Je ne m'en sort toujours pas.

    1) solution senkeys()

    Sur votre conseil j'ai modifié mon appel a getcurrentprocess() pour récupérer le bon Handle avec Process.GetProcessesByName("notepad++"). Cette erreur est corrigée, mais cela n'a pas suffit.

    J'ai écumé les forums et j'ai trouvé une piste qui dit qu'il faut faire un threadattachinput().

    http://www.tek-tips.com/faqs.cfm?fid=4262

    Ce que j'ai essayé de retranscrire dans mon code, mais j'ai certainement une erreur quelque-part car le sendkeys() ne fonctionne pas mieux.

    ---------------------------------------

        Private Declare Function AttachThreadInput Lib "user32" (ByVal idAttach As IntPtr, idAttachTo As IntPtr, fAttach As Boolean) As IntPtr
        Private Declare Function GetCurrentThreadId Lib "kernel32" Alias "GetCurrentThreadId" () As IntPtr
        Private Declare Function ShowWindow Lib "user32" (ByVal h As Long, Int As Long) As IntPtr
        Public Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hwnd As Long, ProcId As Long) As Long

       Public Declare Function BringWindowToTop Lib "user32" (ByVal hwnd As Long) As Long

    '---------------------------

        Sub Utf8_Encodage(ByVal MonPath As String)
            ' ouvre un fichier dont l'application par défaut est Notepad++
            ' Lance une macro Notepad++ qui convertira le fichier en Utf-8 et le sauvegardera sous cet encodage
            Dim NotepadUtf8 As New Process
            Dim NotePadHandle As Long
            Dim TestForm As New Form
            Dim ThreadID1, ThreadID2 As IntPtr
            Dim nRet As Integer
            Dim ProcId As Long
            NotepadUtf8.StartInfo.UseShellExecute = False
            NotepadUtf8.StartInfo.RedirectStandardInput = True
            NotepadUtf8.StartInfo.FileName = MonPath
            NotepadUtf8.StartInfo.WindowStyle = ProcessWindowStyle.Maximized
            'Démarrage de l'application
            Process.Start(MonPath)
            Dim remoteByName As Process() =
            NotePadHandle = remoteByName(0).Handle
            '----------------------ici tout va bien, le fichier s'ouvre dans Notepad++
            ThreadID1 = GetWindowThreadProcessId(GetForegroundWindow(), ProcId)
            ThreadID2 = GetCurrentThreadId()
            If ThreadID1 <> ThreadID2 Then
                AttachThreadInput(ThreadID1, ThreadID2, True)
                nRet = BringWindowToTop(NotePadHandle)
                ShowWindow(NotePadHandle, 1)
                System.Windows.Forms.SendKeys.SendWait("^({F8})")
                Debug.Print("sendkeys envoyé au formulaire: ")
                AttachThreadInput(ThreadID1, ThreadID2, False)
            Else
                nRet = BringWindowToTop(NotePadHandle)
                ShowWindow(NotePadHandle, 1)
                System.Windows.Forms.SendKeys.SendWait("^({F8})")
            End If
        End Sub

    ---------------------------------------

    2) solution directe via les fonctions d'encodage décodage fournies.

    Je n'ai pas fait de test pour l'instant.

    Ce que j'ai compris des données de l'aide en ligne c'est qu'il est facile de lire un texte avec un encodage donné et de le transformer en encodage Utf-8.

    Mon interrogation sur cette solution est que je ne connais pas l'encodage du fichier que l'on me soumet, cela va de MicrosoftANSI, Utf-8, Utf-16, MacRoman, WindowsLatin1 ASII voire ANSEL.

    J'ai donc besoin d'identifier l'encodage avant de faire la traduction et comme le dit Gilles Toureau ci-dessus "Pour information, aucun logiciel à ce jour ne peut détecter de manière fiable l'encodage d'un fichier..."

    Dans mon cas, Notepad++ présente l'avantage de détecter les principaux encodages automatiquement et de sauvegarder en Utf-8 en 2 clics.

    Je suis preneur de toute autre idée car là je patauge :-)

    Bonne journée

    Gilles T

    mardi 11 mars 2014 15:36
  • Bonjour,

    Dans mon cas, Notepad++ présente l'avantage de détecter les principaux
    encodages automatiquement et de sauvegarder en Utf-8 en 2 clics.
    Comme je l'ai dit, ce n'est pas fiable. Notepad++ comme certains logiciels de traitement de texte analyse le début du texte afin de trouver des caractères spéciaux (accents frenchy, caractères chinois, arabe,....) afin de détecter l'encodage du fichier. Pour un texte en anglais c'est quasiment impossible...

    En revanche il existe une norme présente dans les documents UTF qui consiste à placer 3 octets au début du fichier (ou dans flux de manière générale) afin de spécifier l'encodage UTF utilisé (8, 16, 24 ou 32). Ce préambule est appelé le "BOM". Mais ce préambule n'est pas obligatoire, certains éditeurs ne l'écrivent pas même si vous écrivez un fichier au format UTF. Le .NET Framework peut utiliser ce BOM pour détecter l'encodage à utiliser lorsque vous lisez ce fichier, mais sans cette information le .NET Framework (ou les autres logiciels) ne peuvent pas savoir l'encodage de votre fichier...

    Pour confirmer mes dires (que je n'arrête pas d'expliquer et à démontrer sans cesse) car cela choque les gens, mais c'est la réalité de l'informatique sur l'encodage des fichiers :

    • Dans Visual Studio, créer un fichier texte, saisissez le texte "UTF8".
    • Dans le menu Fichier et sélectionnez les "options d'enregistrements avancés" et sélectionnez "Unicode (UTF-8) sans signature". En choisissant cette option vous indiquez à Visual Studio d'enregistrer le fichier au format UTF-8 sans BOM (sans indicateur). Cela veut dire qu'aucun éditeur ne pourra savoir l'encodage de votre fichier.
    • Ouvrez maintenant Notepad++ et regardez dans le menu Encodage vous verrez que l'option "Encoder en ANSI" est sélectionné. Cela signifie que Notepad++ ne reconnaît pas l'encodage (normal il y a rien qui lui indique l'encodage réel du fichier...).
    • Maintenant, dans Visual Studio avec le même fichier, ajouté un "é" après le mot "UTF" et ouvrez à nouveau le fichier dans Notepad++. Vous verrez que Notepad++ considère le fichier cette fois-ci en UTF8...

    Pour quelle raison Notepad++ en déduit que votre fichier est en UTF-8 ? Parceque après une petite analyse Notepad++, en déduit que la suite hexa "C3 A9" présente à la fin de votre fichier représente le caractère "é" en UTF-8... Mais cette déduction de Notepad++ n'est pas tellement "fiable", car il se peut que le suite hexa "C3 A9" représente réellement les caractères "é" qui serait mis volontairement dans votre document car votre document est codé en ANSI.

    Voilà pourquoi la détection de l'encodage d'un fichier "n'est pas fiable". Il faut toujours spécifier l'encodage d'un fichier que l'on traite (soit via le BOM, soit via des specs...). D'après vous, pourquoi dans les documents XML qui sont échangés informatiquement partout dans le monde, la première ligne est : "<?xml version="1.0" encoding="utf-8"?>" ???

    Cordialement

     

    Gilles TOURREAU - MVP C#
    Architecte logiciel/Consultant/Formateur Freelance - P.O.S Informatique
    Blog : http://gilles.tourreau.fr - Suivez-moi sur Twitter
    - MCPD : Enterprise Developper / Windows Developper 3.5 / ASP .NET 3.5/4.0
    - MCSA : SQL Server 2012
    - MCITP : SQL Server 2008 Developper
    - MCTS : ADO .NET 3.5 / SQL Server 2008 Developper / Windows Forms 3.5 / ASP .NET 3.5/4.0 / TFS 2010 / Windows Azure

    mardi 11 mars 2014 19:08
    Modérateur
  • Bonsoir Gilles.

    Merci de compléter ma culture sur l'encodage.

    J'ai compris depuis quelque temps que ce sujet est très difficile et si j'en crois votre avis, l'appel à notepad++ n'étant pas la solution,  que dois-je faire?

    Je rappelle que je ne connais pas l'encodage du fichier d'entrée.

    Dois-je lire séquentiellement tous les caractères du fichier, intercepter tout caractère non conforme et le transformer?

    Cordialement

    Gilles T

    mardi 11 mars 2014 22:27
  • Bonjour

    Voir la solution proposée ici :

    http://www.codeproject.com/Articles/17201/Detect-Encoding-for-In-and-Outgoing-Text

    Cordialement,


    Aurel BERA, MSFT
    MSDN Community Support. LE CONTENU EST FOURNI "TEL QUEL" SANS GARANTIE D'AUCUNE SORTE, EXPLICITE OU IMPLICITE.
    S'il vous plaît n'oubliez pas de "Marquer comme réponse" les réponses qui ont résolu votre problème. C'est une voie commune pour reconnaître ceux qui vous ont aidé, et rend plus facile pour les autres visiteurs de trouver plus tard la résolution.


    • Modifié Aurel Bera mercredi 12 mars 2014 08:52
    • Marqué comme réponse mahastian mercredi 12 mars 2014 18:45
    • Non marqué comme réponse mahastian mercredi 12 mars 2014 18:45
    • Marqué comme réponse mahastian mercredi 12 mars 2014 18:46
    mercredi 12 mars 2014 08:52