Reputation: 427
Let's suppose my app in named mysoft
and the file I want to READ is afile.bin
. mysoft
is in the program file folder.
Let's also suppose that mysoft is not executed with admin privileges.
procedure TForm1.Button1Click(Sender: TObject);
var
afile: File of Byte;
begin
AssignFile(Infile, 'C:\Program Files\mysoft\afile.bin');
Reset(afile);
CloseFile(afile);
end;
The simple code above will create a copy of afile.bin
in the compatibility files folder.
My questions are:
Again I only read the data file, I don't get it.
Upvotes: 4
Views: 1315
Reputation: 613511
The call to Reset
results in the file being opened for writing. That's because the default value of System.FileMode
is fmOpenReadWrite
. Since your app runs virtualized, and since your user token does not have admin rights, the virtualization layer kicks in and creates a copy of the file in the virtual store.
The solution that is available using legacy Pascal I/O is to set FileMode
to fmOpenRead
. Then Reset
will open the file for reading and the virtualization layer will not be invoked.
Remember that FileMode
is a global variable that affects all legacy Pascal I/O. Woe betide you if you have threads, or forget to set FileMode
back to fmOpenReadWrite
when you need to write a file. Revolting isn't it? Process wide global flags to control file access mode! Well, this stuff was invented long before applications had threads. And long before OOP was invented. So I can understand why it is so.
The lesson to take away from this is that it is time to switch to one of the modern forms of file access. For example, TFileStream
.
Indeed, it's also time that you disabled virtualization in your application. Virtualization was introduced in Vista, nearly 6 years ago. It was meant as a help for old programs that had not yet been re-compiled for Vista. Your application should not be using it still.
Upvotes: 5
Reputation: 11768
If you have a version of Delphi that supports the TStreamReader class and your file is text you can use this code :
procedure TForm1.btn1Click(Sender: TObject);
var
SR : TStreamReader;
line : string;
begin
SR := TStreamReader.Create('C:\Program Files\mysoft\afile.bin');
try
while not SR.EndOfStream do
begin
line := SR.ReadLine;
end;
finally
SR.Free;
end;
end;
If not I suggest a more classical approach that works on any file :
procedure TForm1.btn2Click(Sender: TObject);
var
FS : TFileStream;
mem : array of byte;
begin
FS := TFileStream.Create('C:\Program Files\mysoft\afile.bin',fmOpenRead or fmShareDenyNone);
try
SetLength(mem,FS.Size);
FS.Read(mem[0],FS.Size);
finally
FS.Free;
end;
end;
Upvotes: 2
Reputation: 167
I believe this is because the Windows 7 "new feature", which is disallow you to do directly access a file in file system area (%programfiles%, %systemroot%, %systemdrive%, or %programdata%).
Try to change your code to open file using TFileStream
, and set Mode to fmOpenRead
.
I hope it works. I don't have 7 to try it :)
Upvotes: 0