Magneto_Mystique
asked on
Delphi Help
I am new to Delphi. I have to make changes to a Delphi program which creates an ini and clm files when it is in use. The problem now is that the application is to be placed on a Citrix server where it will be at one location (one exe at one location) and many users accessing the same app at the same location. Because the app creates an ini and clm files when in use, concerns are raised about having mulitple users accessing the same exe at the same time. In fact error messages like "Error writing to XXX.ini file" are popping up.
I was told then to direct the output of these ini and clm files to a local directory specific to each user's machine. Currently, the ini and clm files are created in the same directory in which the exe is stored. However, I don't know how to do it or how to start it. Any ideas? I included the method below which creates the ini and clm files.
procedure TfrmEsnview.FormCreate(Sen der: TObject);
var
i: integer;
begin
CalledFromTargys := False;
Application.OnMessage := AppMessage;
bDebug := False; // MM
if not Assigned(EsnViewDataModule ) then
Application.CreateForm(TEs nViewDataM odule, EsnViewDataModule);
Top := ini.ReadInteger(cfgEVew, 'Top', 100);
Left := ini.ReadInteger(cfgEVew, 'Left', 100);
Width := ini.ReadInteger(cfgEVew, 'Width', 753);
Height := ini.ReadInteger(cfgEVew, 'Height', 550);
dbGrid6.Width := ini.ReadInteger(cfgEVew, 'dbGrid6Width', 600);
clmFile1 := ExtractFilePath(Applicatio n.ExeName) + cfgEVew + '1.clm';
clmFile2 := ExtractFilePath(Applicatio n.ExeName) + cfgEVew + '2.clm';
clmFile3 := ExtractFilePath(Applicatio n.ExeName) + cfgEVew + '3.clm';
clmFile4 := ExtractFilePath(Applicatio n.ExeName) + cfgEVew + '4.clm';
clmFile5 := ExtractFilePath(Applicatio n.ExeName) + cfgEVew + '5.clm';
clmFile6 := ExtractFilePath(Applicatio n.ExeName) + cfgEVew + '6.clm';
if FileExists(clmFile1) then
begin // Status
dbGrid1.Columns.LoadFromFi le(clmFile 1);
end;
if FileExists(clmFile1) then
begin // Channel Information
dbGrid2.Columns.LoadFromFi le(clmFile 2);
end;
if FileExists(clmFile3) then
begin // Attached Cards
dbGrid3.Columns.LoadFromFi le(clmFile 3);
end;
if FileExists(clmFile4) then
begin // Attached Cards (History)
dbGrid4.Columns.LoadFromFi le(clmFile 4);
end;
if FileExists(clmFile5) then
begin // PRL
dbGrid5.Columns.LoadFromFi le(clmFile 5);
end;
if FileExists(clmFile6) then
begin // Warranty
dbGrid6.Columns.LoadFromFi le(clmFile 6);
end;
sgActivity.Cells[colActSer ialNo, 0] := 'Serial Number';
sgActivity.Cells[colActPwr On, 0] := '1st Power On';
sgActivity.Cells[colActPwr Last, 0] := 'Last Power On';
sgActivity.Cells[colActPwr Total, 0] := 'Total Power On';
for i := 0 to sgActivity.ColCount - 1 do
begin
sgActivity.ColWidths[i] :=
ini.ReadInteger(cfgEVew, 'sgActivityCol' + zIntToStr(i, 3),
100);
end;
end;
I was told then to direct the output of these ini and clm files to a local directory specific to each user's machine. Currently, the ini and clm files are created in the same directory in which the exe is stored. However, I don't know how to do it or how to start it. Any ideas? I included the method below which creates the ini and clm files.
procedure TfrmEsnview.FormCreate(Sen
var
i: integer;
begin
CalledFromTargys := False;
Application.OnMessage := AppMessage;
bDebug := False; // MM
if not Assigned(EsnViewDataModule
Application.CreateForm(TEs
Top := ini.ReadInteger(cfgEVew, 'Top', 100);
Left := ini.ReadInteger(cfgEVew, 'Left', 100);
Width := ini.ReadInteger(cfgEVew, 'Width', 753);
Height := ini.ReadInteger(cfgEVew, 'Height', 550);
dbGrid6.Width := ini.ReadInteger(cfgEVew, 'dbGrid6Width', 600);
clmFile1 := ExtractFilePath(Applicatio
clmFile2 := ExtractFilePath(Applicatio
clmFile3 := ExtractFilePath(Applicatio
clmFile4 := ExtractFilePath(Applicatio
clmFile5 := ExtractFilePath(Applicatio
clmFile6 := ExtractFilePath(Applicatio
if FileExists(clmFile1) then
begin // Status
dbGrid1.Columns.LoadFromFi
end;
if FileExists(clmFile1) then
begin // Channel Information
dbGrid2.Columns.LoadFromFi
end;
if FileExists(clmFile3) then
begin // Attached Cards
dbGrid3.Columns.LoadFromFi
end;
if FileExists(clmFile4) then
begin // Attached Cards (History)
dbGrid4.Columns.LoadFromFi
end;
if FileExists(clmFile5) then
begin // PRL
dbGrid5.Columns.LoadFromFi
end;
if FileExists(clmFile6) then
begin // Warranty
dbGrid6.Columns.LoadFromFi
end;
sgActivity.Cells[colActSer
sgActivity.Cells[colActPwr
sgActivity.Cells[colActPwr
sgActivity.Cells[colActPwr
for i := 0 to sgActivity.ColCount - 1 do
begin
sgActivity.ColWidths[i] :=
ini.ReadInteger(cfgEVew, 'sgActivityCol' + zIntToStr(i, 3),
100);
end;
end;
many users accessing the same exe is ok.
you haven't actually shown the ini file creation in your code
if you want to use a different ini or clm file for each user, then perhaps you could include the user's name in the file e.g.
clmFile1 := ExtractFilePath(Applicatio n.ExeName) + cfgEVew + fUsername + '_1.clm';
clmFile2 := ExtractFilePath(Applicatio n.ExeName) + cfgEVew + fUsername + '_2.clm';
etc.
so it actually looks like
bob_1.clm
bob_2.clm
sam_1.clm
sam_2.clm
you mention the error says xxx.ini but i see no .ini in your example code. is the problem elsewhere?
you should access ini files like this
with TIniFile.Create('myname.in i') do
try
i := readinteger(section, ident, default);
finally
free;
end;
that way you can be sure you are not leaving too many files open when not in use
you haven't actually shown the ini file creation in your code
if you want to use a different ini or clm file for each user, then perhaps you could include the user's name in the file e.g.
clmFile1 := ExtractFilePath(Applicatio
clmFile2 := ExtractFilePath(Applicatio
etc.
so it actually looks like
bob_1.clm
bob_2.clm
sam_1.clm
sam_2.clm
you mention the error says xxx.ini but i see no .ini in your example code. is the problem elsewhere?
you should access ini files like this
with TIniFile.Create('myname.in
try
i := readinteger(section, ident, default);
finally
free;
end;
that way you can be sure you are not leaving too many files open when not in use
I get the impression that you probably need 2 sets of data.
The first is the location of your datafiles which are persistent settings.
Leave these as being read from the central ini file
The 2nd set of data is local to the user
i.e. the size and layout of the form and sort order etc
if this is the case then you could add these to the registry
using something like
-----------------put this in the form create to load settings------------------ -
procedure TfrmMain.FormCreate(Sender : TObject);
var
lReg: TRegistry;
begin
lReg:=tRegistry.Create;
try
lReg.RootKey := HKEY_CURRENT_USER;
if lReg.OpenKeyReadOnly('\Sof tware\ESNV iew') then
begin
if lReg.ValueExists('Top') then
Top:=lReg.ReadInteger('Top ');
if lReg.ValueExists('Left') then
Left:=lReg.ReadInteger('Le ft');
if lReg.ValueExists('Height') then
Height:=lReg.ReadInteger(' Height');
if lReg.ValueExists('SortColu mn') then
FColumnSort:=lReg.ReadInte ger('SortC olumn');
if lReg.ValueExists('SortAsce nding') then
FSortAscending:=lReg.ReadB ool('SortA scending') ;
if lReg.ValueExists('NameOrde r') then
FNameSort:=lReg.ReadBool(' NameOrder' );
end;
finally
lReg.CloseKey;
lReg.Free;
end;
end
-----------------put this in the form close to save settings------------------ -
procedure TfrmMain.FormClose(Sender: TObject; var Action: TCloseAction);
//saves the position, size and settings
var
lReg: TRegistry;
lPl : TWindowPlacement;
lR: TRect;
begin
try
LockWindowUpdate(Handle);
lPl.Length := SizeOf(TWindowPlacement);
GetWindowPlacement(Self.Ha ndle, @lPl);
lR := lPl.rcNormalPosition;
lReg:=tRegistry.Create;
try
lReg.RootKey := HKEY_CURRENT_USER;
if lReg.OpenKey('\Software\Es nView',tru e) then
begin
lReg.WriteInteger('Left', lR.Left);
lReg.WriteInteger('Top', lR.Top);
lReg.WriteInteger('Height' , lR.Bottom-lR.Top);
lReg.WriteBool('NameOrder' , FNameSort);
lReg.WriteBool('SortAscend ing', FSortAscending);
lReg.WriteInteger('SortCol umn', FColumnSort);
end;
finally
lReg.CloseKey;
lReg.Free;
end;
finally
LockWindowUpdate(0);
end;
end;
This way local settings will not interfere with the central information
regards
The first is the location of your datafiles which are persistent settings.
Leave these as being read from the central ini file
The 2nd set of data is local to the user
i.e. the size and layout of the form and sort order etc
if this is the case then you could add these to the registry
using something like
-----------------put this in the form create to load settings------------------
procedure TfrmMain.FormCreate(Sender
var
lReg: TRegistry;
begin
lReg:=tRegistry.Create;
try
lReg.RootKey := HKEY_CURRENT_USER;
if lReg.OpenKeyReadOnly('\Sof
begin
if lReg.ValueExists('Top') then
Top:=lReg.ReadInteger('Top
if lReg.ValueExists('Left') then
Left:=lReg.ReadInteger('Le
if lReg.ValueExists('Height')
Height:=lReg.ReadInteger('
if lReg.ValueExists('SortColu
FColumnSort:=lReg.ReadInte
if lReg.ValueExists('SortAsce
FSortAscending:=lReg.ReadB
if lReg.ValueExists('NameOrde
FNameSort:=lReg.ReadBool('
end;
finally
lReg.CloseKey;
lReg.Free;
end;
end
-----------------put this in the form close to save settings------------------
procedure TfrmMain.FormClose(Sender:
//saves the position, size and settings
var
lReg: TRegistry;
lPl : TWindowPlacement;
lR: TRect;
begin
try
LockWindowUpdate(Handle);
lPl.Length := SizeOf(TWindowPlacement);
GetWindowPlacement(Self.Ha
lR := lPl.rcNormalPosition;
lReg:=tRegistry.Create;
try
lReg.RootKey := HKEY_CURRENT_USER;
if lReg.OpenKey('\Software\Es
begin
lReg.WriteInteger('Left', lR.Left);
lReg.WriteInteger('Top', lR.Top);
lReg.WriteInteger('Height'
lReg.WriteBool('NameOrder'
lReg.WriteBool('SortAscend
lReg.WriteInteger('SortCol
end;
finally
lReg.CloseKey;
lReg.Free;
end;
finally
LockWindowUpdate(0);
end;
end;
This way local settings will not interfere with the central information
regards
keeping the same concept you have... something like this:
procedure TForm1.FormCreate(Sender: TObject);
var
i: integer;
BaseFileName, BasePath:string;
procedure LoadFile(const FileName:string; dbGrid:TDBGrid);
begin
if (FileExists(FileName)) then
dbGrid.Columns.LoadFromFil e(FileName )
end;
begin
CalledFromTargys := False;
Application.OnMessage := AppMessage;
bDebug := False; // MM
if not Assigned(EsnViewDataModule ) then
Application.CreateForm(TEs nViewDataM odule, EsnViewDataModule);
Top := ini.ReadInteger(cfgEVew, 'Top', 100);
Left := ini.ReadInteger(cfgEVew, 'Left', 100);
Width := ini.ReadInteger(cfgEVew, 'Width', 753);
Height := ini.ReadInteger(cfgEVew, 'Height', 550);
dbGrid6.Width := ini.ReadInteger(cfgEVew, 'dbGrid6Width', 600);
BasePath:=IncludeTrailingB ackslash(i ni.ReadStr ing('Confi g', 'BasePath', 'c:\')); //default to c:\
BaseFileName:=BasePath+cfg EVew;
clmFile1 := BaseFileName + '1.clm';
clmFile2 := BaseFileName + cfgEVew + '2.clm';
clmFile3 := BaseFileName + cfgEVew + '3.clm';
clmFile4 := BaseFileName + cfgEVew + '4.clm';
clmFile5 := BaseFileName + cfgEVew + '5.clm';
clmFile6 := BaseFileName + cfgEVew + '6.clm';
LoadFile(clmFile1, dbGrid1);
LoadFile(clmFile2, dbGrid2);
LoadFile(clmFile3, dbGrid3);
LoadFile(clmFile4, dbGrid4);
LoadFile(clmFile5, dbGrid5);
LoadFile(clmFile6, dbGrid6);
sgActivity.Cells[colActSer ialNo, 0] := 'Serial Number';
sgActivity.Cells[colActPwr On, 0] := '1st Power On';
sgActivity.Cells[colActPwr Last, 0] := 'Last Power On';
sgActivity.Cells[colActPwr Total, 0] := 'Total Power On';
for i := 0 to sgActivity.ColCount - 1 do
begin
sgActivity.ColWidths[i] :=
ini.ReadInteger(cfgEVew, 'sgActivityCol' + zIntToStr(i, 3),
100);
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
var
i: integer;
BaseFileName, BasePath:string;
procedure LoadFile(const FileName:string; dbGrid:TDBGrid);
begin
if (FileExists(FileName)) then
dbGrid.Columns.LoadFromFil
end;
begin
CalledFromTargys := False;
Application.OnMessage := AppMessage;
bDebug := False; // MM
if not Assigned(EsnViewDataModule
Application.CreateForm(TEs
Top := ini.ReadInteger(cfgEVew, 'Top', 100);
Left := ini.ReadInteger(cfgEVew, 'Left', 100);
Width := ini.ReadInteger(cfgEVew, 'Width', 753);
Height := ini.ReadInteger(cfgEVew, 'Height', 550);
dbGrid6.Width := ini.ReadInteger(cfgEVew, 'dbGrid6Width', 600);
BasePath:=IncludeTrailingB
BaseFileName:=BasePath+cfg
clmFile1 := BaseFileName + '1.clm';
clmFile2 := BaseFileName + cfgEVew + '2.clm';
clmFile3 := BaseFileName + cfgEVew + '3.clm';
clmFile4 := BaseFileName + cfgEVew + '4.clm';
clmFile5 := BaseFileName + cfgEVew + '5.clm';
clmFile6 := BaseFileName + cfgEVew + '6.clm';
LoadFile(clmFile1, dbGrid1);
LoadFile(clmFile2, dbGrid2);
LoadFile(clmFile3, dbGrid3);
LoadFile(clmFile4, dbGrid4);
LoadFile(clmFile5, dbGrid5);
LoadFile(clmFile6, dbGrid6);
sgActivity.Cells[colActSer
sgActivity.Cells[colActPwr
sgActivity.Cells[colActPwr
sgActivity.Cells[colActPwr
for i := 0 to sgActivity.ColCount - 1 do
begin
sgActivity.ColWidths[i] :=
ini.ReadInteger(cfgEVew, 'sgActivityCol' + zIntToStr(i, 3),
100);
end;
end;
ASKER
I tried changing the code like above. I can successfully direct the path of the clm files to C:. The ini file is created in the uGlobal. I would like to direct it to the same path as the clm files. I tried to change it like the below but it doesn't work. Why?
var
ini: TIniFile;
semsfile, semsfilepath: string;
const
ver = '8.30';
cfgMain = 'Main';
cfgStat = 'CardStatus';
cfgView = 'CardView';
cfgEVew = 'ESNViewer';
cfgFirmBrow = 'FirmBrow';
cfgLostStolen = 'LostStolen';
cfgSVew = 'RIM Software Viewer';
techPCS = 'PCS';
techIDEN = 'IDEN';
techSIM = 'SIM';
techANALOG = 'ANALOG';
techPAGER = 'PAGER';
techCDPD = 'MODEM';
stBES = 'BES Software';
stLicense = 'SOFTWARE LICENSE';
SCHEMA = '';
implementation
initialization
semsfilepath := IncludeTrailingBackslash(i ni.ReadStr ing('Confi g', 'semsfilepath', 'c:\Example')); //default to c
semsfile:= semsfilepath + cfgEVew;
ini := TIniFile.Create(semsfile + 'SEMS.ini');
finalization
ini.Free;
end.
var
ini: TIniFile;
semsfile, semsfilepath: string;
const
ver = '8.30';
cfgMain = 'Main';
cfgStat = 'CardStatus';
cfgView = 'CardView';
cfgEVew = 'ESNViewer';
cfgFirmBrow = 'FirmBrow';
cfgLostStolen = 'LostStolen';
cfgSVew = 'RIM Software Viewer';
techPCS = 'PCS';
techIDEN = 'IDEN';
techSIM = 'SIM';
techANALOG = 'ANALOG';
techPAGER = 'PAGER';
techCDPD = 'MODEM';
stBES = 'BES Software';
stLicense = 'SOFTWARE LICENSE';
SCHEMA = '';
implementation
initialization
semsfilepath := IncludeTrailingBackslash(i
semsfile:= semsfilepath + cfgEVew;
ini := TIniFile.Create(semsfile + 'SEMS.ini');
finalization
ini.Free;
end.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
No comment has been added to this question in more than 21 days, so it is now classified as abandoned.
I will leave the following recommendation for this question in the Cleanup topic area:
Accept: kfoster11 {http:#15810258}
Any objections should be posted here in the next 4 days. After that time, the question will be closed.
cwwkie
EE Cleanup Volunteer
I will leave the following recommendation for this question in the Cleanup topic area:
Accept: kfoster11 {http:#15810258}
Any objections should be posted here in the next 4 days. After that time, the question will be closed.
cwwkie
EE Cleanup Volunteer
I dont hink im reading this correctly!
sholmes