3

I’ve created a program with a login system where the user enters his information and the program checks the database the program is connected to to see if the results match and then logs the user in. I want to make a log file for each time a user logs in. The log file’s name should contain the user’s username and the date and time the user logged in. I’m using the following code to check for the user’s credentials and write his details to a log file. Also I want the date in the file name to be something like 23 January 2013.. So the coding for that is before the "with dmPredictGame do..."

 sDate := DateToStr(Date());
 sTime := TimeToStr(Time());

  iYear := StrToInt(Copy(sDate,1,4));
  iDay := StrToInt(Copy(sDate,9,2));
  K := StrToInt(Copy(sDate,6,2));

 Case K of
    1 : sMonth := 'January';
    2 : sMonth := 'February';
    3 : sMonth := 'March';
    4 : sMonth := 'April';
    5 : sMonth := 'May';
    6 : sMonth := 'June';
    7 : sMonth := 'July';                      //Check for the     current month
    8 : sMonth := 'August';
    9 : sMonth := 'September';
    10 : sMonth := 'Oktober';
    11 : sMonth := 'November';
    12 : sMonth := 'December';
  end;

  sTime1 := copy(sTime,1,2);
  sTime2 := copy(sTime,4,2);
  sLoginTime := sTime1 + ';' + sTime2;    //Use ; because windows does not allow : in file names
  sLoginDate := IntToStr(iDay) + ' ' + sMonth + ' ' + IntToStr(iYear);


with dmPredictGame do
  begin
    if tblUserInfo.Locate('Username', edtUsername.Text,  []) AND ((edtPassword.Text) = tblUserInfo['Password'])  then         //Check if the username and password is  correct.
     begin
        MessageDlg('Login was successful! Welcome back ' + edtUsername.Text, mtInformation, [mbOK],0);
      edtUsername.Text := tblUserInfo['Username'];
      begin
        sUsername := edtUsername.Text;
        sPassword := tblUserInfo['Password'];
        sName := tblUserInfo['Name'];
        sSurname := tblUserInfo['Surname'];
        assignFile(UserLogFile, 'Log ' + sUsername + ' (' + sLoginDate + ') ' + sLoginTime + '.txt');
        Rewrite(UserLogFile);
        writeln(UserLogFile, 'Username: ' + sUsername);
        writeln(UserLogFile, 'Password: ' + sPassword);
        writeln(UserLogFile, 'Name: ' + sName);
        writeln(UserLogFile, 'Surname: ' + sSurname);
        writeln(UserLogFile, 'Date Logged In: ' + sDate);
        writeln(UserLogFile, 'Time Logged In: ' + sTime);
        closeFile(UserLogFile);
      end;

Now my question: How can I create the text file in a different directory than the current directory that the program is in? I have a folder named “Logs” in the same folder that the program itself is in. I want the logs to be saved to that folder when they are created.

Any advice?

5
  • @JerryDodge, relative path. By the way, relative will work too if CWD has been set properly. Commented Nov 22, 2013 at 20:07
  • 2
    I suggest you reconsider writing your logs to a sub-directory of your application folder. This is one of the things that can cause your program to unnecessarily require elevated privileges. The recommended alternative is to use the Shell API to obtain an appropriate 'User Documents' or 'AppData' folder. Commented Nov 23, 2013 at 6:44
  • @Craig Perhaps this is a portable app, meant to reside on a memory stick, wich takes its settings with it Commented Nov 23, 2013 at 7:38
  • @DavidHeffernan OP said log files, not settings. And I would be even more wary of writing log files directly to a USB. (Although the description does imply only a small amount of logging.) OP is welcome to pursue the current path. I'm just warning of a potential pitfall that can be avoided by using a different approach; one that might not have been considered, but could still be appropriate. Commented Nov 23, 2013 at 8:03
  • @Craig Fair enough. And reading again, connection to DB does not suggest portable app. Commented Nov 23, 2013 at 8:05

1 Answer 1

11

Just retrieve the application's path first, append the \Log\ and filename, and then provide the full path to AssignFile.

(All of the following presumes that you actually have write access to the application's directory, of course. Note that if your app is installed in the Windows %ProgramFiles% folder, it doesn't typically have write access to the installation folder.)

var
  LogFile: string;
begin
  // ... other code
  LogFile := ExtractFilePath(Application.ExeName);
  LogFile := IncludeTrailingPathDelimiter(LogFile) + 'Logs';
  LogFile := IncludeTrailingPathDelimiter(LogFile);
  LogFile := LogFile +
             'Log ' +
             sUserName +
             ' (' + sLoginDate
             + ') ' + sLoginTime + '.txt';
  AssignFile(UserLogFile, LogFile);
  // Write to log and other code
end;

If you're using a more modern version of Delphi, you can use the functionality in TPath to make this a little easier:

uses
  IOUtils;          // For TPath

var
  LogFile: string;
begin
  LogFile := TPath.Combine(ExtractFilePath(ParamStr(0)), 'Log');
  LogFile := TPath.Combine(LogFile, 
                           'Log ' +
                           sUserName +
                         ' (' + sLoginDate
                         + ') ' + sLoginTime + '.txt';
  AssignFile(UserLogFile, LogFile);
end;

For the filename part, I much prefer using Format instead of all of the concatenations:

const
  LogFileTemplate = 'Log %s(%s)%s.txt';

...
var
  LogFile: string;
begin
  LogFile := TPath.Combine(ExtractFilePath(ParamStr(0)), 'Log');
  LogFile := TPath.Combine(LogFile,
                           Format(LogFileTemplate,
                                  [sUserName, sLoginDate, sLoginTime]));
  AssignFile(UserLogFile, LogFile);
  // Other code
end;

To address your file naming question (the date/time portion), you're going about it totally wrong. :-) You're doing far too much work:

var
  sDate: string;

  sDate := FormatDateTime('(dd mmmm yyyy) hhmm', Now); 
  // Run now on my system shows (22 November 2013) 1645
  ShowMessage(sDate);

This means your filename is simplified. Replace sLoginDate and sLoginTime with a single sTimeStamp: string;, and use something like this:

sTimeStamp := FormatDateTime('(dd mmmm yyyy) hhmm', Now);
LogFile := LogFile + 
           'Log ' + 
           sUserName + 
           sTimeStamp +
           '.txt';
Sign up to request clarification or add additional context in comments.

1 Comment

I would suggest rather using ISO date format (yyyy-mm-dd) because this will sort naturally by name if there are a large number log files in the folder.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.