Usamos cookies para medir audiência e melhorar sua experiência. Você pode aceitar ou recusar a qualquer momento. Veja sobre o iMasters.
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?
/applications/core/interface/imageproxy/imageproxy.php?img=http://forum.imasters.com.br/public/style_emoticons/default/smile.gif&key=15294d64c22e9e9c4ae0bf82a62ec27d13f27d6ba7078a5f7982077798029364" alt="smile.gif" />
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á.
/applications/core/interface/imageproxy/imageproxy.php?img=http://forum.imasters.com.br/public/style_emoticons/default/huh.gif&key=796dd2e8f5e667be07f01ae4a535735ac497e0cf1e7e3fc219233ca4d7b2023c" alt="huh.gif" />
Vou fazer um teste hoje e te falo amanhã...
Nossa, muito obrigado bdexterholland
Aguardo seu retorno.
/applications/core/interface/imageproxy/imageproxy.php?img=http://forum.imasters.com.br/public/style_emoticons/default/laugh.gif&key=fb9a849ac525d2fd317adad061adf02e38bd5f5cb2c664d803c1667dd70a2af1" alt="laugh.gif" />
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); 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; Result := euidaccess(PChar(FileName), F_OK) = 0;
end;Se no Delphi 7 o código for diferente, cole este código sobre o original e rode o Build em seu projeto.
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; 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?
/applications/core/interface/imageproxy/imageproxy.php?img=http://forum.imasters.com.br/public/style_emoticons/default/ermm.gif&key=0e759cbb73a282996291068c8fe8bad4f08911c74e6678b73eb234bf96d43c00" alt="ermm.gif" />Talvez se excluir a bpl referente a unit ou mesmo abrir a unit e rodar o Build para ela.
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
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=#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.
/applications/core/interface/imageproxy/imageproxy.php?img=http://forum.imasters.com.br/public/style_emoticons/default/wink.gif&key=0566fd943552bcff9cb1b879403ca34b5ff8f67befaac7fe4648006e9f764689" alt="wink.gif" />
bdexterholland,
Demorei mais respondi... hehehe.
Olha, obrigado pela sua ajuda, mas não deu certo. /applications/core/interface/imageproxy/imageproxy.php?img=http://forum.imasters.com.br/public/style_emoticons/default/sad.gif&key=02b1574f7da1e723d8a7dbae07272745fb341b432c19ce24d0490ce410222838" alt="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
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.
/applications/core/interface/imageproxy/imageproxy.php?img=http://forum.imasters.com.br/public/style_emoticons/default/joia.gif&key=0939d868f1ee3d17e7bb4735cf3a3dcbce722238baa0148d397de30444cef221" alt="joia.gif" />
Esqueci de recomendar criar uma função com o código da FileExists que eu postei.
>
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).
/applications/core/interface/imageproxy/imageproxy.php?img=http://forum.imasters.com.br/public/style_emoticons/default/smile.gif&key=15294d64c22e9e9c4ae0bf82a62ec27d13f27d6ba7078a5f7982077798029364" alt="smile.gif" />
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:\
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 25/01/2011 07:52 1.063.165.952 hiberfil.sys 25/01/2011 07:52 1.377.112.064 pagefile.sysNã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