Home > Delphi > WinAPI temp filename

WinAPI temp filename

IIK! Found a couple of really, really nasty temp-file procedures in a customer app. Here is one that does it “by the book” so to speak. I havent tested it under Delphi-7 or below but it should compile nicely under freepascal as well (give or take a @ prefix).

  unit jlTempFile;

  interface

  //##########################################################################
  //  Class:    TTempFile
  //  Author:   Jon Lennart Aasenden
  //  Purpose:  General purpose class for obtaining filenames for temporary use
  //            through the Windows API.
  //
  //  Note:     Dont create instances of this class. Simply use the class
  //            functions directly, e.g: TTempfile.getTempStream();
  //
  //  Sources:  http://msdn.microsoft.com/en-us/library/windows/desktop/aa364992%28v=vs.85%29.aspx
  //            http://msdn.microsoft.com/en-us/library/windows/desktop/aa364991%28v=vs.85%29.aspx
  //
  //##########################################################################


  uses  Winapi.Windows, System.SysUtils, System.Classes;


  type

  TTempFile = Class
  public
    class function  getTempFileName:String;
    class function  getTempDirectory:String;
    class function  getTempStream(out aStream:TFileStream):Boolean;
  End;

  implementation

  class function  TTempFile.getTempStream(out aStream:TFileStream):Boolean;
  var
    mName:  String;
  Begin
    result:=False;
    aStream:=NIL;

    mName:=getTempFileName;
    try
      aStream:=TFileStream.Create(mName,fmCreate);
    except
      on e: exception do
      Raise Exception.CreateFmt(
        'Failed to create temporary file [%s]' + #13
      + 'System error: "%s"',[mName,e.Message]);
    end;

    result:=True;
  end;

  class function TTempFile.getTempDirectory:String;
  var
    mtempPath: String;
    mtempFile: String;
    mBufLen:  Integer;
    mLen:     Integer;
    mMoniker: String;
  Begin
    (* Init result *)
    setlength(result,0);

    (* Allocate normal size path buffer *)
    SetLength(mtempPath, MAX_PATH);
    mBufLen:=MAX_PATH;

    (* obtain temp path from WINAPI *)
    mLen:=WinApi.Windows.GetTempPath(mBufLen, PChar(@mtempPath[1]));

    if mLen>0 then
    Begin
      (* MSDN:  If the return value is greater than nBufferLength,
                the return value is the length, in TCHARs, of the
                buffer required to hold the path.
                http://msdn.microsoft.com/en-us/library/windows/desktop/aa364992%28v=vs.85%29.aspx *)
      If (mLen>mBufLen) then
      Begin
        (* re-allocate & get the path *)
        SetLength(mtempPath,mLen);
        mLen:=WinApi.Windows.GetTempPath(mLen, PChar(@mtempPath[1]));
      end;

      result:=Copy(mTempPath,1,mLen);
    end else
    Raise Exception.Create(SysErrorMessage(getLastError));
  end;

  class Function TTempFile.GetTempFileName:String;
  var
    mtempPath: String;
    mtempFile: String;
    mBufLen:  Integer;
    mLen:     Integer;
    mMoniker: String;
  Begin
    (* Init result *)
    setlength(result,0);

    (* Allocate normal size path buffer *)
    SetLength(mtempPath, MAX_PATH);
    mBufLen:=MAX_PATH;

    (* obtain temp path from WINAPI *)
    mLen:=WinApi.Windows.GetTempPath(mBufLen, PChar(@mtempPath[1]));

    if mLen>0 then
    Begin
      (* MSDN:  If the return value is greater than nBufferLength,
                the return value is the length, in TCHARs, of the
                buffer required to hold the path.
                http://msdn.microsoft.com/en-us/library/windows/desktop/aa364992%28v=vs.85%29.aspx *)
      If (mLen>mBufLen) then
      Begin
        SetLength(mtempPath,mLen);
        mLen:=WinApi.Windows.GetTempPath(mLen, PChar(@mtempPath[1]));
      end;

      (* setup prefix and memory for filename, which is not the
         same as the path we obtained above *)
      mMoniker:='JL_';
      SetLength(mtempFile, MAX_PATH + mLen);

      (* Obtain the filename, include the path.
         http://msdn.microsoft.com/en-us/library/windows/desktop/aa364991%28v=vs.85%29.aspx *)
      mLen:=WinApi.Windows.GetTempFileName(PChar(@mtempPath[1]),
      PChar(@mMoniker[1]), 0,
      PChar(@mtempFile[1]));

      (* Function returns 0 (zero) if it fails, check and return *)
      if mLen<>0 then
      Result:=trim(mtempFile) else
      Raise Exception.Create(SysErrorMessage(getLastError));
    end else
    Raise Exception.Create(SysErrorMessage(getLastError));
  end;

end.

Advertisements
  1. No comments yet.
  1. No trackbacks yet.

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: