2010-06-15 6 views
2

Je souhaite créer et ouvrir un fichier txt à l'aide de la commande ShellExecute.ShellExecute ne fonctionne pas à partir d'IDE mais fonctionne différemment

J'ai utilisé ce code depuis des années avec Delphi 7 et cela a fonctionné:

function Executa(CONST ExeName, Parameters: string): Boolean; 
begin 
if Parameters= '' 
then Result:= ShellExecute(0, 'open', PChar(ExeName), NIL    , nil, SW_SHOWNORMAL)> 32 
else Result:= ShellExecute(0, 'open', PChar(ExeName), PChar(Parameters), nil, SW_SHOWNORMAL)> 32; 
end; 

Maintenant, je passe à Windows 7 et le code ne fonctionne plus quand il va de l'IDE. Delphi affiche la fenêtre CPU avec la légende "CPU-Process unknown (2352)". Je ferme les fenêtres CU et tout fonctionne bien jusqu'à ce que je ferme l'application, quand Delphi montre la fenêtre CPU une fois de plus. Si j'exécute l'application depuis l'extérieur d'IDE, cela fonctionne très bien.

On dirait que le débogueur a quelque chose à me dire, mais je ne sais pas quoi.

Répondre

6

Cela me semble que l'option "debug spawned processes" est activée. Lorsque cela est activé, le débogueur interrompt le nouveau processus le plus tôt possible. Appuyez sur le bouton "Exécuter" pour le laisser continuer à fonctionner.

Vous pouvez confirmer cette hypothèse la prochaine fois que vous déboguez votre programme. Comparez l'ID de processus (2352, dans votre exemple) avec la liste des processus affichés par le Gestionnaire des tâches. Quel processus dans cette liste correspond à l'ID de processus signalé par le débogueur?

+0

C'était tout! Mais j'ai eu cette option vérifiée pendant des années! Avec travaillé avec Win 98 et Win XP! Ne vaut-il pas mieux laisser ceci sur ON? 1+ et marqué comme "accepté". Merci beaucoup. – Ampere

+0

Évidemment, il est préférable de le laisser sur si vous allez déboguer le processus engendré. Est-ce que c'est ce que tu veux faire? Si vous n'avez pas le code source ou les informations de débogage, il n'y a probablement pas grand-chose que vous puissiez faire, vous pouvez donc le laisser éteint pour ne pas être interrompu à chaque nouveau processus. –

1

J'ai eu un problème hier avec le débogueur qui plante mon application, mais en l'exécutant en dehors de l'EDI cela fonctionnerait bien. J'utilisais des paquets dans mon développement.

J'ai utilisé process explorer pour vérifier que je chargeais une copie d'un autre emplacement que prévu. J'avais deux copies du même BPL flottant autour. Une fois que j'ai enlevé celui que je ne compilais pas, ça allait.

En appliquant cela à ce problème, je vérifierais pour vous assurer que vous n'avez aucune copie du code compilé qui inclut: .DCU, .DCP, .BPL, .EXE autour. Ensuite, je voudrais également vous assurer que vous pouvez Ctrl-cliquez sur "ShellExecute" pour voir la déclaration. Vous pouvez configurer votre chemin de bibliothèque de manière à ce qu'il ne trouve pas la source.

+0

Ceci peut être mon cas. Je vérifierai. Merci! – Ampere

1

Photographié dans l'obscurité ici, mais essayez d'exécuter l'EDI en tant qu'administrateur, et non en tant qu'administrateur. Cela peut être un facteur. Certains utilisateurs créent un raccourci avec l'option d'administrateur, de sorte que la mise à jour automatique s'exécute correctement. Vous pouvez donc exécuter l'EDI en tant qu'administrateur, si vous l'avez fait.

2

Ce n'est pas la réponse à votre question (je vote pour Rob Kennedy & Chris Thornton), mais vous pouvez écrire votre routine d'une manière plus compacte:

function Executa(const ExeName, Parameters: string): Boolean; 
begin 
    Result := 
    (ShellExecute(0, 'open', PChar(ExeName), Pointer(Parameters), nil, SW_SHOWNORMAL) > 32); 
end; 

Remarque pointeur() au lieu de PChar () pour le 4ème argument. C'est un comportement documenté des moulages PChar/Pointer (voir l'aide).

+0

Merci! Je voulais faire ça mais je n'étais pas sûr que ça marcherait. À cause du manque de temps, j'ai choisi la voie sûre. Encore merci beaucoup !! 1+ – Ampere

1

même par moi, je l'ai résolu en remplaçant ShellExecute avec ce qui suit:

function TformMain.CreateProcessSimple(
    sExecutableFilePath : string) 
    : string; 

function GetExeByExtension(sExt : string) : string; 
var 
    sExtDesc:string; 
begin 
    with TRegistry.Create do 
    begin 
    try 
     RootKey:=HKEY_CLASSES_ROOT; 
     if OpenKeyReadOnly(sExt) then 
     begin 
     sExtDesc:=ReadString('') ; 
     CloseKey; 
     end; 
     if sExtDesc <>'' then 
     begin 
     if OpenKeyReadOnly(sExtDesc + '\Shell\Open\Command') then 
     begin 
      Result:= ReadString('') ; 
     end 
     end; 
    finally 
     Free; 
    end; 
    end; 
end; 
var 
    pi: TProcessInformation; 
    si: TStartupInfo; 
    fapp: string; 
begin 
    fapp:=GetExeByExtension(ExtractFileExt(sExecutableFilePath)); 
    FillMemory(@si, sizeof(si), 0); 
    si.cb := sizeof(si); 
    if Pos('%1',fApp)>0 then begin 
    sExecutableFilePath:=StringReplace(fapp,'%1',sExecutableFilePath,[rfReplaceAll]); 
    end else begin 
    sExecutableFilePath:=fApp+' "'+sExecutableFilePath+'"'; 
    end; 
    CreateProcess(
    Nil, 

    // path to the executable file: 
    PChar(sExecutableFilePath), 

    Nil, Nil, False, 
    NORMAL_PRIORITY_CLASS, Nil, Nil, 
    si, pi); 

    // "after calling code" such as 
    // the code to wait until the 
    // process is done should go here 

    CloseHandle(pi.hProcess); 
    CloseHandle(pi.hThread); 
end; 
+0

+1 - Beau morceau de code – Ampere

0

ShellExecuteW résoudre mes problèmes avec l'option "debug a donné naissance à des processus" (XE2/Win7/32bit) désactivé :) mybe parce que les chaînes et pchar sont pointeur large de 2010

Questions connexes