IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 Delphi Discussion :

Thread ShellExecute PChar string transtypage


Sujet :

Delphi

  1. #1
    Membre expérimenté
    Avatar de ouiouioui
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Août 2006
    Messages
    984
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Août 2006
    Messages : 984
    Points : 1 419
    Points
    1 419
    Par défaut Thread ShellExecute PChar string transtypage
    bonjour, j'ai un thread pour vérifier si il y a une mise à jour et à la fin j'ai un shellexecute qui ne fonctionne pas, si je remplace PChar(UpdaterName) par 'wordpad.exe' c'est bon. Je trouve pas sa me dit transtypage incorrect or je pchar un string.

    Et aussi comment lancer close sans mettre use main; Afin de fermer l'application depuis le thread sa aussi je trouve pas

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    unit ThreadUpdater;
     
    interface
     
    uses
      Classes {$IFDEF MSWINDOWS} , Windows {$ENDIF}, SysUtils, MsgResource, Dialogs,
      Utils, IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient, IdHTTP,
      IniFiles, ShellApi;
     
    type
      TThreadUpdater = class(TThread)
      private
        NewVersionName,
        UpdaterName,
        Language,
        ApplicationExeName: String;
        UpdateAtStart,
        Skin,
        DownUpdate: Boolean;
        procedure SetName;
        procedure CheckUpdate;
        procedure SyncroMsgNew;
        procedure StartUpdate(ActualVer, FileToDown, FileSize, FileMD5, Author, Mail, WebPage, Comment: String);
      protected
        procedure Execute; override;
      public
      constructor Create(AUpdaterName, ALanguage, AApplicationExeName: String; AUpdateAtStart, ASkin: Boolean);
      end;
     
    implementation
     
    {$R fichiers.RES}
     
    {$IFDEF MSWINDOWS}
    type
      TThreadNameInfo = record
        FType: LongWord;     // doit être 0x1000
        FName: PChar;        // pointeur sur le nom (dans l'espace d'adresse de l'utilisateur)
        FThreadID: LongWord; // ID de thread (-1=thread de l'appelant)
        FFlags: LongWord;    // réservé pour une future utilisation, doit être zéro
      end;
    {$ENDIF}
     
    { uTUpdate }
     
    procedure TThreadUpdater.SetName;
    {$IFDEF MSWINDOWS}
    var
      ThreadNameInfo: TThreadNameInfo;
    {$ENDIF}
    begin
    {$IFDEF MSWINDOWS}
      ThreadNameInfo.FType := $1000;
      ThreadNameInfo.FName := 'ThreadUpdater';
      ThreadNameInfo.FThreadID := $FFFFFFFF;
      ThreadNameInfo.FFlags := 0;
     
      try
        RaiseException( $406D1388, 0, sizeof(ThreadNameInfo) div sizeof(LongWord), @ThreadNameInfo );
      except
      end;
    {$ENDIF}
    end;
     
    constructor TThreadUpdater.Create(AUpdaterName, ALanguage, AApplicationExeName: String; AUpdateAtStart, ASkin: Boolean);
    begin
      inherited Create(False);
      FreeOnTerminate := true;
      UpdaterName := AUpdaterName;
      Language := ALanguage;
      ApplicationExeName := AApplicationExeName;
      UpdateAtStart := AUpdateAtStart;
      Skin := ASkin;
      DownUpdate := false;
    end;
     
    procedure TThreadUpdater.Execute;
    begin
      SetName;
      Sleep(1500);
      if FileExists(UpdaterName) then
        DeleteFile(UpdaterName);
      if UpdateAtStart then
        CheckUpdate;
    end;
     
    procedure TThreadUpdater.CheckUpdate;
    var
      Version: array[0..3, 0..3] of SmallInt;
      ActualVer, FileToDown, FileSize, FileMD5, Author, Mail, WebPage, Comment: String;
      Search: TStringList;
      IdHTTP: TIdHTTP;
      I: SmallInt;
    begin
      Search := TStringList.Create;
      ActualVer := ApplicationVersion;
      try
        Search.Delimiter := '.';
        Search.QuoteChar := #0;
        Search.DelimitedText := ActualVer;
        if Search.Count < 4 then
          Exit;
        Version[0][0] := StrToInt(Search[0]);
        Version[0][1] := StrToInt(Search[1]);
        Version[0][2] := StrToInt(Search[2]);
        Version[0][3] := StrToInt(Search[3]);
      finally
        Search.Free;
      end;
      Search := TStringList.Create;
      try
        Search.Delimiter := '#';
        Search.QuoteChar := #0;
        IdHTTP := TIdHTTP.Create();
        Search.DelimitedText := IdHTTP.Get('http://www.tdgv.org/logiciels/version.php?program=cod4checker');
        IdHTTP.Free;
        if Search.Count < 16 then
          Exit;
        NewVersionName := Search[1];
        FileToDown := Search[3];
        FileSize := Search[5];
        FileMD5 := Search[7];
        Author := Search[9];
        Mail := Search[11];
        WebPage := Search[13];
        Comment := Search[15];
        if Search.Count > 15 then
        begin
          for I := 16 to Search.Count - 1 do
            Comment := Comment + sLineBreak + Search[i];
        end;
      finally
        Search.Free;
      end;
      Search := TStringList.Create;
      try
        Search.Delimiter := '.';
        Search.QuoteChar := #0;
        Search.DelimitedText := NewVersionName;    
        if Search.Count < 4 then
          Exit;
        Version[1][0] := StrToInt(Search[0]);
        Version[1][1] := StrToInt(Search[1]);
        Version[1][2] := StrToInt(Search[2]);
        Version[1][3] := StrToInt(Search[3]);
      finally
        Search.Free;
      end;
      if (Version[1][0] > Version[0][0]) or (Version[1][1] > Version[0][1]) or (Version[1][2] > Version[0][2]) or (((Version[0][0] + Version[0][1] + Version[0][2]) = (Version[1][0] + Version[1][1] + Version[1][2])) and (Version[1][3] > Version[0][3])) then
      begin
        Synchronize(SyncroMsgNew);
        if DownUpdate then
          StartUpdate(ActualVer, FileToDown, FileSize, FileMD5, Author, Mail, WebPage, Comment);
       end;
    end;
     
    procedure TThreadUpdater.SyncroMsgNew;
    begin
      if (MessageDlg(Format(MsgNew, [NewVersionName]), mtInformation, [mbYes, mbNo], 0) = 6) then
        DownUpdate := true;
    end;
     
    procedure TThreadUpdater.StartUpdate(ActualVer, FileToDown, FileSize, FileMD5, Author, Mail, WebPage, Comment: String);
    var
      iniSettings: TMemIniFile;
      CommentFile: textfile;
    begin
      ExtractOfRes('updater', UpdaterName);
      if Language <> 'FRA' then
        ExtractOfRes('updaterlng' + AnsiLowerCase(Language), ChangeFileExt(UpdaterName, '.' + Language));
      iniSettings := TMemIniFile.Create(ChangeFileExt(UpdaterName, '.ini'));
      iniSettings.WriteString('Main', 'ActualVer', ActualVer);
      iniSettings.WriteString('Main', 'NewVer', NewVersionName);
      iniSettings.WriteString('Main', 'FileToDown', FileToDown);
      iniSettings.WriteInteger('Main', 'FileSize', StrToInt(FileSize));
      iniSettings.WriteString('Main', 'FileMD5', FileMD5);
      iniSettings.WriteString('Main', 'Author', Author);
      iniSettings.WriteString('Main', 'Mail', Mail);
      iniSettings.WriteString('Main', 'WebPage', WebPage);
      iniSettings.WriteString('Main', 'OldFilePath', ApplicationExeName);
      iniSettings.WriteString('Main', 'Language', Language);
      iniSettings.WriteBool('Main', 'Skin', Skin);
      iniSettings.WriteBool('Main', 'UpdateAtRun', true);
      iniSettings.UpdateFile;
      iniSettings.Destroy;
      // ecrire commentaire
      assignfile(CommentFile, ChangeFileExt(UpdaterName, '.diz'));
      rewrite(CommentFile);
      writeln(CommentFile, Comment);
      closefile(CommentFile);
      // lancer updater, quitter
    //  ShellExecute(Handle, 'open', PChar(UpdaterName), nil, nil, SW_SHOWNORMAL);
    //  fmPrinc.Close;
    end;
     
    end.
    merci à celui qui trouvera
    Il existe 3 sortes de gens: ceux qui savent compter et ceux qui ne savent pas.

  2. #2
    Membre expérimenté Avatar de guillemouze
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    876
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Novembre 2004
    Messages : 876
    Points : 1 448
    Points
    1 448
    Par défaut
    effectivement c'est etrange.
    essaye de faire ton transtypage a l'exterieur, mais je ne pense pas que ca vienne de la
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    var 
      TmpPChar: PChar;
    begin
      ...
      TmpPChar := PChar(UpdaterName);
      ShellExecute(Handle, 'open', TmpPChar, nil, nil, SW_SHOWNORMAL);
    pour terminer sans mettre le main en uses, tu peux faire
    (uses Forms ou Classes il me semble)

  3. #3
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 744
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 744
    Points : 13 300
    Points
    13 300
    Par défaut
    Le message transtypage incorrect te dit également quel type est attendu, ça aiderait

    Je suspect un essai en D2009 et un mix entre PAnsiChar et PWideChar.

  4. #4
    Expert confirmé

    Profil pro
    Leader Technique
    Inscrit en
    Juin 2005
    Messages
    1 756
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Leader Technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2005
    Messages : 1 756
    Points : 4 173
    Points
    4 173
    Par défaut
    Vérifie tes options de compile.
    Si tu ne compiles pas ton projet avec l'option "Chaînes vastes" (ou $H+), le type string est équivalent au type shortString et ne peut pas être transtypé en PChar (il manque le 0 terminal).
    Sinon tu peux aussi essayer :

    @UpdaterName[1] à la place de PChar(UpdaterName). Ca devrait cours-circuiter les contrôles du compilateur. Mais bon, s'il n'est pas content, c'est qu'il y a sûrement une raison.

    Et aussi comment lancer close sans mettre use main
    Puisque tu es dans un context multi-thread, je posterais le message WM_CLOSE au handle de la fenêtre que tu veux fermer.
    Il suffirait de passer ce handle en paramètre à la création du thread.

  5. #5
    Membre expérimenté
    Avatar de ouiouioui
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Août 2006
    Messages
    984
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Août 2006
    Messages : 984
    Points : 1 419
    Points
    1 419
    Par défaut
    d'abord merci à vous trois,

    pour guillemouze j'avais essayé sans succès cette soluce

    pour Franck SORIANO j'avais décoché chaine vaste dans les options du compilateur maintenant sa fonctionne. Merci de l'explication

    sinon est-ce que
    Application.Terminate; est équivalent à poster le message WM_CLOSE au handle de la fenêtre main

    car dans le FormDestroy de ma form principal (main) j'ai des procédures executer enregistrement réglages, arret thread, etc

    merci.
    Il existe 3 sortes de gens: ceux qui savent compter et ceux qui ne savent pas.

  6. #6
    Expert confirmé

    Profil pro
    Leader Technique
    Inscrit en
    Juin 2005
    Messages
    1 756
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Leader Technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2005
    Messages : 1 756
    Points : 4 173
    Points
    4 173
    Par défaut
    Citation Envoyé par ouiouioui Voir le message
    Application.Terminate; est équivalent à poster le message WM_CLOSE au handle de la fenêtre main
    Pratiquement.
    Application.Terminate demandera à la fiche principale de se fermer.

    Sauf que si tu appelles Application.Terminate, tu vas appeler du code de la VCL depuis un thread secondaire. Hors la VCL n'est pas thread safe et ça se passera très mal... Pendant que tu fais le Application.Terminate, le code de la fiche principale continue son exécution, et il ne va pas aimer...

    Par contre, si tu postes un message, il sera dépilé et traité par le thread principal et là plus de problème (si ce n'est qu'il faudra qu'en même gérer la fermeture du thread secondaire... mais ça ne devrait pas être un problème dans ton cas).

  7. #7
    Membre expérimenté
    Avatar de ouiouioui
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Août 2006
    Messages
    984
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Août 2006
    Messages : 984
    Points : 1 419
    Points
    1 419
    Par défaut
    d'accord, à moins d'appeler Application.Terminate dans un Synchronize
    ou dans l'évènement onterminate du thread qui lui est Synchronizé, car mon thread se finit après mon shellexec

    je voulais utiliser ta méthode mais j'obtient
    [DCC Erreur] ThreadUpdater.pas(195): E2003 Identificateur non déclaré : 'WM_CLOSE'
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
      PostMessage(MainHandle, WM_CLOSE, 0, 0);
    MainHandle étant le handle de main reçu à la création du thread

    promis j'ai rien décoché dans les options du compilateur
    Il existe 3 sortes de gens: ceux qui savent compter et ceux qui ne savent pas.

  8. #8
    Expert éminent sénior
    Avatar de Cl@udius
    Homme Profil pro
    Développeur Web
    Inscrit en
    Février 2006
    Messages
    4 878
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Février 2006
    Messages : 4 878
    Points : 10 008
    Points
    10 008
    Par défaut
    Salut

    Tu as bien l'unité Messages parmi tes uses ?

  9. #9
    Membre expérimenté
    Avatar de ouiouioui
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Août 2006
    Messages
    984
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Août 2006
    Messages : 984
    Points : 1 419
    Points
    1 419
    Par défaut
    euh j'ai le droit de mentir et dire oui?

    merci c'est tout bon
    Il existe 3 sortes de gens: ceux qui savent compter et ceux qui ne savent pas.

  10. #10
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 744
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 744
    Points : 13 300
    Points
    13 300
    Par défaut
    A titre indicatif.

    Ces différentes possibilités sont identiques.

    Terminate appelle un PostQuitMessage, donc asynchrone et la gestion du WM_CLOSE appelle... Application.Terminate.

  11. #11
    Membre expérimenté
    Avatar de ouiouioui
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Août 2006
    Messages
    984
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Août 2006
    Messages : 984
    Points : 1 419
    Points
    1 419
    Par défaut
    par contre si je voulais utiliser directement
    Application.Terminate
    il me faudrais form dans les uses alors que la messages suffit
    Il existe 3 sortes de gens: ceux qui savent compter et ceux qui ne savent pas.

  12. #12
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 744
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 744
    Points : 13 300
    Points
    13 300
    Par défaut
    En effet, mais cela ne change rien.
    Le uses informe simplement le compilateur où trouver l'information. Ni la taille de ton exe, ni la vitesse de compilation ne seront augmentés.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. PChar, string, & Co
    Par juvamine dans le forum Langage
    Réponses: 9
    Dernier message: 02/07/2009, 16h00
  2. Transtypage String en Pchar impossible
    Par madfu dans le forum Delphi
    Réponses: 6
    Dernier message: 10/07/2006, 12h39
  3. [Raccourci]-Pchar ,String
    Par aityahia dans le forum Delphi
    Réponses: 3
    Dernier message: 14/05/2006, 16h21
  4. Pchar , string .. déclaration..
    Par petitcoucou31 dans le forum Langage
    Réponses: 8
    Dernier message: 01/05/2006, 16h59
  5. [transtypage]PChar et WideString
    Par rbag dans le forum Bases de données
    Réponses: 2
    Dernier message: 05/09/2002, 20h12

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo