Ir para conteúdo

POWERED BY:

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

lucascolferai

[Resolvido] Problema com a função FileExists do D7 no Win 7

Recommended Posts

Olá amigos,

 

Alguém já teve problema com a função FileExists do Delphi 7 rodando em Windows 7? Pra mim tá acontecendo umas coisas estranhas que provavelmente sejam por características do sistema operacional. Pesquisei bastante na Internet e até achei um caso onde tiveram problemas com leitura da pasta system32 (aqui), mas não é bem o meu caso. Eu estou com problema em ler e gravar dados em arquivos no diretório "Arquivos de Programas".

 

Meu sistema

Tenho um sistema com um programa externo de configuração, que grava as informações de conexão a base de dados, diretório de imagens e relatórios em um arquivo ".conf". Esse arquivo é armazenado atualmente na raiz do c:, assim como o arquivo de log. Os clientes rodam em Windows XP SP3.

 

Meu problema

Fiz um primeiro teste no Win 7 e percebi que teria que mudar os arquivos de configuração e de log de lugar. Pensei em colocar na pasta onde o sistema foi instalado, mas estou tendo problemas. Mesmo que o arquivo ".conf" não esteja na pasta, a função FileExists sempre retorna True. E pior, o programa de configuração está gravando os dados, mesmo sem o arquivo (uso a função Rewrite para isso). Não faço idéia onde ele esteja gravando esses dados. E ainda assim, mesmo que o arquivo ".conf" esteja na pasta, o programa grava não-sei-aonde esses dados e não grava nada no arquivo correto.

 

Agora, se eu colocar o sistema em uma outra pasta (c:\sistema, por exemplo), tudo funciona perfeitamente.

 

Dados gerais

Software legado em Delphi 7

Banco Firebird 1.5

SO Windows 7 64 bits

 

Eaí, alguém pode me ajudar?

 

smile.gif

Compartilhar este post


Link para o post
Compartilhar em outros sites

Olá Lucas,

 

Me corrija se estiver errado: você quer grava dentro da pasta Arquivos de Programas (ou em uma sub-pasta da mesma). O Windows Vista/Seven traz um novo conceito em seu sistema de arquivos chamado de 'Junctions'. Segue a relação de pastas em um computador rodando Windows Vista aqui no trampo:

Pasta de C:\

29/10/2010  09:51    <DIR>          $Recycle.Bin
29/10/2010  09:41    <JUNCTION>     Arquivos de programas [C:\Program Files]
01/01/2011  21:32    <DIR>          Assinatura
18/09/2006  19:43                24 autoexec.bat
29/10/2010  10:33    <DIR>          Boot
02/11/2006  07:53           438.840 bootmgr
29/10/2010  10:33             8.192 BOOTSECT.BAK
18/09/2006  19:43                10 config.sys
29/10/2010  10:37    <DIR>          dell
02/11/2006  11:02    <JUNCTION>     Documents and Settings [C:\Users]
25/01/2011  07:52     1.063.165.952 hiberfil.sys
29/10/2010  10:17    <DIR>          Intel
29/10/2010  10:37    <DIR>          MDT
29/10/2010  10:09    <DIR>          MSOCache
25/01/2011  07:52     1.377.112.064 pagefile.sys
21/01/2011  09:22    <DIR>          Program Files
21/01/2011  09:22    <DIR>          ProgramData
29/10/2010  10:37    <DIR>          SHARMAQ
25/01/2011  08:42    <DIR>          System Volume Information
29/10/2010  09:50    <DIR>          Users
14/12/2010  09:36    <DIR>          Windows
              6 arquivo(s)  2.440.725.082 bytes
             15 pasta(s)   115.455.455.232 bytes dispon¡veis

 

Não sei dizer exatamente como funciona os Junctions do Sistema, mas posso dizer que todos os computadores com Windows Vista/Seven tem uma pasta chamada 'Program Files', e os sistemas em português tem também a pasta 'Arquivos de Programas' que geralmente fica vazia. Recomendo sempre que tentar acessar qualquer pasta ou arquivo dentro da verdadeira pasta 'Arquivos de Programas', use o comando

var
 PROGRAMFILESDIR
Begin
 PROGRAMFILESDIR := GetEnvironmentVariable('ProgramFiles');
 // ... SomeCode ... //

Compartilhar este post


Link para o post
Compartilhar em outros sites

bdexterholland,

 

Desculpe, acho que me expressei mal. Quero gravar na pasta "c:\Arquivos de Programas\SisPaper". Eu falei apenas de "Arquivos de Programas" porque o problema acontece em qualquer sub-pasta dentro desta. Tentei criar uma pasta "c:\Arquivos de Programas\temp" e aconteceu o mesmo problema.

 

Percebi essa questão das Junctions (apesar de não saber o nome correto), realmente o windows cria uma espécie de alias para a "Program Files" e pra "Users". Mas acho que não é esse o problema. Eu estou usando

sPath := ExtractFilePath(Application.ExeName)+'sispaper.conf';

 

Tentei colocar assim, mas o problema continua exatamente igual

sPath := GetEnvironmentVariable('ProgramFiles')+'\sispaper\sispaper.conf';

 

O estranho é que a função FileExists continua retornando True, mesmo que o arquivo não esteja lá.

 

huh.gif

Compartilhar este post


Link para o post
Compartilhar em outros sites

Fiz um teste aqui agora e não tenho boas notícias para você não, na verdade, depende do ponto de vista. Para o teste eu criei um novo projeto e adicionei os componente:

2 buttons, 1 edit, 1 OpenDialog

 

um button executa o OpenDialog e passa o FileName para o edit. O Segundo button faz a validação utilizando o conteúdo do edit. segue o código:

 

unit Unit1;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, StdCtrls;

type
 TForm1 = class(TForm)
   Edit1: TEdit;
   OpenDialog1: TOpenDialog;
   Button1: TButton;
   Button2: TButton;
   procedure Button1Click(Sender: TObject);
   procedure Button2Click(Sender: TObject);
 private
   { Private declarations }
 public
   { Public declarations }
 end;

var
 Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
 if OpenDialog1.Execute then
   Edit1.Text  := OpenDialog1.FileName;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
 if FileExists(Edit1.Text) then
   ShowMessage('existe')
 else
   ShowMessage('não existe');
end;

end.

 

 

Estou usando o Windows em portugues e comigo funcionou corretamente. Analise melhor o trecho do source, exiba o conteúdo das variáveis em runtime ou poste o código da function/procedure para a galera analisar...

 

Opa! detalhe que eu me lembrei agora! estou usando o turbo delphi...

 

No TurboDelphi, a function FileExists tem o seguinte código:

function FileExists(const FileName: string): Boolean;
{$IFDEF MSWINDOWS}
var
 Code: Integer;
begin
 Code := GetFileAttributes(PChar(FileName));
 Result := (Code <> -1) and (FILE_ATTRIBUTE_DIRECTORY and Code = 0);
end;
{$ENDIF}
{$IFDEF LINUX}
begin
 Result := euidaccess(PChar(FileName), F_OK) = 0;
end;
{$ENDIF}

 

Se no Delphi 7 o código for diferente, cole este código sobre o original e rode o Build em seu projeto.

Compartilhar este post


Link para o post
Compartilhar em outros sites

bdexterholland,

Realmente a função FileExists no Delphi 7 tem um código diferente.

function FileExists(const FileName: string): Boolean;
{$IFDEF MSWINDOWS}
begin
 Result := FileAge(FileName) <> -1;
end;            
{$ENDIF}
{$IFDEF LINUX}
begin
 Result := euidaccess(PChar(FileName), F_OK) = 0;
end;

Colei o código da função do Turbo Delphi no lugar do código acima (no arquivo C:\Program Files (x86)\Borland\Delphi7\Source\Rtl\Sys\SysUtils.pas). Tentei recompilar o projeto mas não percebi diferença, o erro persistiu. Tem que fazer algo em especial para que o Delphi assuma o código novo da função?

ermm.gif

Compartilhar este post


Link para o post
Compartilhar em outros sites

No windows 7 não existe a pasta c:\ arquivos de programas, podemos dizer que o windows 7 tem essa pasta com um atalho para a pasta C:\Program Files, nos usuários não conseguimos salvar nada no c:\ arquivos de programas, tente fazer a verificacao na pasta C:\Program Files.

 

Boa sorte

Compartilhar este post


Link para o post
Compartilhar em outros sites

Apostilas na Web,

 

Obrigado por sua dica, mas o problema não é exatamente esse. Estou pegando o endereço do executável via

[color=#1C2837][font=monospace][size=2][color=#000000]sPath [/color][color=#666600]:=[/color][color=#000000] [/color][color=#660066]ExtractFilePath[/color][color=#666600]([/color][color=#660066]Application[/color][color=#666600].[/color][color=#660066]ExeName[/color][color=#666600])+[/color][color=#008800]'sispaper.conf'[/color][color=#666600];[/color][/size][/font][/color]

 

Ele tem retornado pra mim o endereço certo, no meu caso "c:\Program Files(x86)\Sispaper" pelo fato de estar usando Win 7 64 bits.

 

bdexterholland,

 

Vou testar sua sugestão. Pode ser isso sim.

 

wink.gif

Compartilhar este post


Link para o post
Compartilhar em outros sites

bdexterholland,

 

Demorei mais respondi... hehehe.

 

Olha, obrigado pela sua ajuda, mas não deu certo. sad.gif Não tem nenhuma BPL para a unit SysUtils, só achei dois DCUs. Tentei remover esses arquivos e recompilar o projeto e não deu. Abri a unit SysUtils.pas, tentei dar um build, mas não deu também (nem consegui rodar o build só pra unit e não consegui achar algum pacote dela).

 

Infelizmente chego a uma triste conclusão: o Delphi 7 não funciona bem no Win 7 (era meio óbvio, né...) e vou ter que migrar meu software para uma versão mais nova (mais trabalho). Chego a essa conclusão pelo fato de no Turbo Delphi (versão que você usou pra teste e que é mais nova do que o D7) funcionar tudo certo. Acho que uma outra hora vou fazer um teste com o Lazarus.

 

Enfim, muito obrigado pela ajuda.

 

Flw

Compartilhar este post


Link para o post
Compartilhar em outros sites

Pessoal,

 

Só pra agregar mais uma informação que julgo ser importante para esse post, adotei 2 medidas depois da minha última postagem. São elas:

 

1) Migrei minha aplicação para o Delphi 2010. Tive alguns problemas com strings por causa da mudança de Ansi para Unicode, mas no fim resolvi tudo.

 

2) Enquanto terminava a migração do sistema, instalei o programa na raiz do C: em "C:\SisPaper". Pra mim isso resolveu (de forma paliativa, claro).

 

Espero que possa ajudar alguém.

 

joia.gif

Compartilhar este post


Link para o post
Compartilhar em outros sites

Esqueci de recomendar criar uma função com o código da FileExists que eu postei.

 

bdexterholland,

 

Taí, não pensei nisso, é uma boa alternativa. No meu caso não mais porque já migrei o software, mas para quem visitar esse post futuramente, pode ser uma saída (não testei, mas deve funcionar).

 

smile.gif

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.