Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   API de Windows (https://www.clubdelphi.com/foros/forumdisplay.php?f=7)
-   -   Delphi XE2, Windows 7, fileexists y shellexecute no funcionan (https://www.clubdelphi.com/foros/showthread.php?t=85012)

sonjeux 14-01-2014 04:59:03

Delphi XE2, Windows 7, fileexists y shellexecute no funcionan
 
Saludos, estoy programando en Delphi XE2, en Windows 7 64Bits, y no me funcionan ninguno de los 2 comandos fileexists y shellexecute. Probe de varias formas. El codigo que estoy usando es uno que vi aqui y no me funciono tampoco, me sale el mensaje file not found pero si existe lo comprobe manualmente, si alguien me podria decir por que no funciona, gracias.

Código Delphi [-]
var Archivo: string;
    errorcode: integer;
begin
    Archivo:=cxTextEdit6.Text;
   errorcode :=
   ShellExecute(0, 'open', pchar(Archivo), nil, nil, SW_NORMAL);
   case errorcode of
      2:showmessage('file not found');
      3:showmessage('path not found');
      5:showmessage('access denied');
      8:showmessage('not enough memory');
      32:showmessage('dynamic-link library not found');
      26:showmessage('sharing violation');
      27:showmessage('filename association incomplete or invalid');
      28:showmessage('DDE request timed out');
      29:showmessage('DDE transaction failed');
      30:showmessage('DDE busy');
      31:showmessage('no application associated with the given filename extension');
   end;

   //ShellExecute(0, nil, pchar(Archivo), '', '', SW_SHOWNORMAL);
end;

ecfisa 14-01-2014 09:39:14

1 Archivos Adjunto(s)
Hola sonjeux.

Lamento no tener otra versión, pero te adjunto un código que funciona correctamente con Delphi 7 en Windows 64bits, estimo que debería hacerlo del mismo modo en Delphi XE2. Para probarlo, crea una carpeta temporal y descomprimilo allí. (El demo incluye un archivo .txt en la misma carpeta)

Algo importante a tomar en cuenta es que en Windows 64bits la carpeta Windows\System32 es redirigida a Windows\SysWOW64, así que el código:
Código Delphi [-]
 procedure TForm1.btnSystem32Click(Sender: TObject);
begin
  if FileExists('C:\Windows\System32\telnet.exe') then
    ShowMessage('Existe')
  else
    ShowMessage('No existe')
end;
nos va a porfiar con un rotundo "No existe" aunque tengamos seleccionado el archivo desde el explorador de windows y precisamente en esa carpeta ...

La solución mas simple es reemplazar "System32" por el alias "Sysnative" que le indica al sistema de archivos que no debe redirigir el acceso:
Código Delphi [-]
procedure TForm1.btnSysnativeClick(Sender: TObject);
begin
  if FileExists('C:\Windows\Sysnative\telnet.exe') then
    ShowMessage('Existe')
  else
    ShowMessage('No existe')
end;

Saludos :)

Neftali [Germán.Estévez] 14-01-2014 11:28:48

A veces es problema de que el nombre incluye espacios.
Haz una sencilla prueba de acceder a un nombre de fichero sencillo (sin espacios y con pocos caracteres).
Por ejemplo: c:\hola.txt

Descartarás de esa forma que sea por ese problema.

La otra opción más común es que sea por tema de permisos.

ecfisa 14-01-2014 12:44:49

Hola sonjeux.

Ampliando el caso de FileExists, se puede encapsular la detección del SO en una función para que trabaje en Win32 y Win64:
Código Delphi [-]
function FileExistsExt(aFileName: TFileName): Boolean;
type
 LPFN_ISWOW64PROCESS = function(hProcess: THandle; var Wow64Proc: BOOL): BOOL; stdcall;
var
  fnIsWow64Proc: LPFN_ISWOW64PROCESS;
  IsWow64: BOOL;
begin
  fnIsWow64Proc:= LPFN_ISWOW64PROCESS(GetProcAddress(GetModuleHandle('kernel32'), 'IsWow64Process'));
  if Assigned(fnIsWow64Proc) then
    fnIsWow64Proc(GetCurrentProcess(), IsWow64);
  if IsWow64 then
    Result:= FileExists(StringReplace(aFileName, 'System32', 'Sysnative', [rfIgnoreCase]))
  else
    Result:= FileExists(aFileName);
end;

Saludos :)

cloayza 14-01-2014 13:23:01

Intenta con este pequeño cambio...

Código Delphi [-]
var Archivo: string;
    errorcode: integer;
begin
    Archivo:=cxTextEdit6.Text;

    If Not FileExists(Archivo) Then Exit;

   errorcode :=
   ShellExecute(0, 'open', PWideChar(Archivo), nil, nil, SW_NORMAL);
   case errorcode of
      2:showmessage('file not found');
      3:showmessage('path not found');
      5:showmessage('access denied');
      8:showmessage('not enough memory');
      32:showmessage('dynamic-link library not found');
      26:showmessage('sharing violation');
      27:showmessage('filename association incomplete or invalid');
      28:showmessage('DDE request timed out');
      29:showmessage('DDE transaction failed');
      30:showmessage('DDE busy');
      31:showmessage('no application associated with the given filename extension');
   end;

   //ShellExecute(0, nil, pchar(Archivo), '', '', SW_SHOWNORMAL);
end;
Saludos

sonjeux 14-01-2014 19:25:08

cloayza gracias por responder te comento que no funciona con PWideChar,

ecfisa gracias por responder, te comento que no me funciona en delphi XE2, en delphi 7 me funciona, Neftali te comento que probe con una direccion similar a c:\hola.txt y no me funciono, lei que varias personas tienen ese problema en las versiones de XE en el foro de embarcadero, probe ejecutar el programa que hize como administrador y tampoco funciono, pero tal vez mi windows 7 este mal, me interesa solucionar el problema que tengo con shellexecute ya que el programa que hice tiene un campo donde se adjunta la direccion de un archivo, word, txt o imagen, y quisiera otro boton para ver ese archivo, gracias a todos por su ayuda.

Alguien puede probar si le funciona shellexecute en un delphi XE, gracias.

cloayza 14-01-2014 19:35:03

La modificación que te envié la prove en XE2 y si funciona...(Win7 x64).

Este es el código que probe....
Código Delphi [-]
var Archivo: string;
    errorcode: integer;
begin
     Archivo:='c:\Windows\SysWOW64\calc.exe';

     //Archivo:='c:\Windows\System32\calc.exe';

    If Not FileExists(Archivo) Then Exit;

    Errorcode:=ShellExecute(0, 'open', PWideChar(Archivo), nil, nil, SW_NORMAL);
end;

Verifica la ruta y nombre del comando a ejecutar...
Puede ser otro el problema...

sonjeux 14-01-2014 21:39:18

Cita:

Empezado por cloayza (Mensaje 471705)
La modificación que te envié la prove en XE2 y si funciona...(Win7 x64).

Este es el código que probe....
Código Delphi [-]
var Archivo: string;
    errorcode: integer;
begin
     Archivo:='c:\Windows\SysWOW64\calc.exe';

     //Archivo:='c:\Windows\System32\calc.exe';

    If Not FileExists(Archivo) Then Exit;

    Errorcode:=ShellExecute(0, 'open', PWideChar(Archivo), nil, nil, SW_NORMAL);
end;

Verifica la ruta y nombre del comando a ejecutar...
Puede ser otro el problema...

Gracias si lo probe y funciona, ahora no se por que si quiero abrir desde la direccion que esta en un edti1.text no quiere abrirlo, sera por que text devuelve una variable de tipo tcaption? :P, el codigo que uso es el siguiente

Para seleccionar el archivo

Código Delphi [-]
procedure TConsulta.cxButton3Click(Sender: TObject);
begin
    if OpenDialog1.Execute then
         Edit1.Text:=OpenDialog1.Files.Text;
end;

Para ejecutar el archivo

Código Delphi [-]
procedure TConsulta.cxButton6Click(Sender: TObject);
var Archivo: string;
    errorcode: integer;
begin
    ShowMessage(Archivo);
    If Not FileExists(Edit1.Text) Then Exit;

    Errorcode:=ShellExecute(handle, 'open', PWideChar(Edit1.Text), nil, nil, SW_SHOWNORMAL);   
end;

Como vez es el mismo codigo

Si coloco la direccion asi

Código Delphi [-]
Archivo:='c:\Windows\SysWOW64\calc.exe';
Archivo:='C:\Compartida\Villanueva Agosto 2013\esvillanueva\facturasvillanueva.txt';

Funciona en los dos casos, pero si coloco asi

Código Delphi [-]
Archivo:=edit1.text;

ya no funciona :(, muchas gracias por tu tiempo.

cloayza 14-01-2014 21:42:09

Creo que el problema está aquí...

Código Delphi [-]
procedure TConsulta.cxButton3Click(Sender: TObject);
begin
    if OpenDialog1.Execute then
         //Edit1.Text:=OpenDialog1.Files.Text;
         Edit1.Text:=OpenDialog1.Filename;
end;

Prueba realizando este pequeño cambio

sonjeux 14-01-2014 21:57:51

Cita:

Empezado por cloayza (Mensaje 471719)
Creo que el problema está aquí...

Código Delphi [-]
procedure TConsulta.cxButton3Click(Sender: TObject);
begin
    if OpenDialog1.Execute then
         //Edit1.Text:=OpenDialog1.Files.Text;
         Edit1.Text:=OpenDialog1.Filename;
end;

Prueba realizando este pequeño cambio

Muchas gracias, si funciona :o ahora a leer sobre eso, jajaja, muchas gracias por su ayuda.


La franja horaria es GMT +2. Ahora son las 22:33:14.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi