Solved

Help creating a service.

Posted on 2002-07-06
9
372 Views
Last Modified: 2010-04-04
I have added a question :
http://www.experts-exchange.com/jsp/qManageQuestion.jsp?ta=delphi&qid=20303736

I don't think that it should be so hard but I didn't got any complete answer.

What I like to do is to create backups of a file if it has been changed.

For exaple say the file
c:\test.tmp

When the service starts I like to make a copy of c:\test.tmp
into

c:\tmp\2002-07-06\10-02-11.tmp

where '2002-07-06 is the current date
and 10-02-11 is the current time. (10:02:54)

then I want the service to check every 10 minute if
the file c:\test.tmp has been changed since the last backup. if so I like to make a new copy
(with a correct name in the same way as before.)

If possible I like to have it that way that the file is not locked for other programs during the copy.

Can someone help me out with this.

0
Comment
Question by:wqclatre
9 Comments
 
LVL 8

Expert Comment

by:TOndrej
ID: 7133562
What do you need help with?
0
 

Expert Comment

by:deansmith
ID: 7133576
hi,

I think you need to be more specfic here. Do you want someone to create the service for you or do you want to know how to create a service.

Have you also considered that you will be creating a backup every 10 minutes, 6 backups an hour and 144 backups a day. depending on the size of the file you could run out of disk space very soon. CAn you describe what you are trying to achieve because there maybe a better way.

What is being stored in the test.tmp file?


Dean


0
 
LVL 2

Author Comment

by:wqclatre
ID: 7133591
Yes. But I only want to back it up if the file has been changed. And I guess it would not be changed so often.

I think I understand how to create a service (or can figure out) But help with this would be greateful to.

THe thing I can't understand is how to make copy of the file.. how to se if the file has changed. how to create those directories etc etc,.,.

0
Master Your Team's Linux and Cloud Stack

Come see why top tech companies like Mailchimp and Media Temple use Linux Academy to build their employee training programs.

 
LVL 2

Author Comment

by:wqclatre
ID: 7133594
the test.tmp file could be anything.
for example a copy of the icq database the seems to get broken for me every now and then....
0
 
LVL 17

Expert Comment

by:geobul
ID: 7133657
Hi,
Using 'File-New-Service Application' create a new app, drop a timer, set its interval to 600000 (10 min) and use the code below.

Save and build the app. Using 'Start button-Run' execute:
path\exename.exe /install
You will see something like: Service was installed successfully

Open the 'services' window, select your service, make it logon on system account and start it.

Regards, Geo
-----
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Consts, Graphics, Controls, SvcMgr, Dialogs,
  ExtCtrls;

type
  TGeoService = class(TService)
    Timer1: TTimer;
    procedure ServiceExecute(Sender: TService);
    procedure Timer1Timer(Sender: TObject);
  private
    { Private declarations }
  public
    function GetServiceController: TServiceController; override;
    { Public declarations }
  end;

var
  GeoService: TGeoService;
  MyFileName: string;
  LastTime, NewTime: TDateTime;

implementation

{$R *.DFM}

uses FileCtrl, ShellApi;

function HasAttr(const FileName: string; Attr: Word): Boolean;
begin
  Result := (FileGetAttr(FileName) and Attr) = Attr;
end;

procedure CopyFile(const FileName, DestName: TFileName);
var
  CopyBuffer: Pointer; { buffer for copying }
  BytesCopied: Longint;
  Source, Dest: Integer; { handles }
  Destination: TFileName; { holder for expanded destination name }
const
  ChunkSize: Longint = 8192; { copy in 8K chunks }
begin
  Destination := ExpandFileName(DestName);  { expand the destination path }
  GetMem(CopyBuffer, ChunkSize); { allocate the buffer }
  try
    Source := FileOpen(FileName, fmOpenRead or fmShareDenyNone); { open source file }
    if Source < 0 then raise EFOpenError.CreateFmt(SFOpenError, [FileName]);
    try
      Dest := FileCreate(Destination); { create output file; overwrite existing }
      if Dest < 0 then raise EFCreateError.CreateFmt(SFCreateError, [Destination]);
      try
        repeat
          BytesCopied := FileRead(Source, CopyBuffer^, ChunkSize); { read chunk }
          if BytesCopied > 0 then { if we read anything... }
            FileWrite(Dest, CopyBuffer^, BytesCopied); { ...write chunk }
        until BytesCopied < ChunkSize; { until we run out of chunks }
      finally
        FileClose(Dest); { close the destination file }
      end;
    finally
      FileClose(Source); { close the source file }
    end;
  finally
    FreeMem(CopyBuffer, ChunkSize); { free the buffer }
  end;
end;

function GetFileTimes(const filename: string; var Modified: TDateTime): boolean;
var sr:TSearchRec;
   SysTimeStruct: TSystemTime;
   lft: TFileTime;
begin
 Result:=False;
 if FindFirst(FileName,faAnyFile,sr) = 0 then
 begin
   if FileTimeToLocalFileTime(sr.FindData.ftLastWriteTime, lft) and
      FileTimeToSystemTime(lft, SysTimeStruct) then
      Modified := SystemTimeToDateTime(SysTimeStruct);
   FindClose(sr);
   Result:=True;
 end;
end;

function CopyMyFile: boolean;
var
  NewDir, NewFile: string;
begin
  result := true;
  try
    NewDir := 'c:\tmp\'+ FormatDateTime('yyyy-mm-dd',NewTime);
    NewFile := NewDir + '\' + FormatDateTime('hh-nn-ss',NewTime) + '.tmp';
    ForceDirectories(NewDir);
    if DirectoryExists(NewDir) then begin
      if not FileExists(NewFile) then begin
        CopyFile(MyFileName, NewFile);
      end;
    end;
  except
    result := false;
  end;
end;

procedure ServiceController(CtrlCode: DWord); stdcall;
begin
  GeoService.Controller(CtrlCode);
end;

function TGeoService.GetServiceController: TServiceController;
begin
  Result := ServiceController;
end;

procedure TGeoService.ServiceExecute(Sender: TService);
begin
  // first copy
  MyFileName := 'c:\test.tmp';
  if GetFileTimes(MyFileName, LastTime) then begin
    NewTime := LastTime;
    CopyMyFile;
  end;
  while not Terminated do begin
    ServiceThread.ProcessRequests(False);
  end;
end;

procedure TGeoService.Timer1Timer(Sender: TObject);
begin
  if GetFileTimes(MyFileName, NewTime) then begin
    if NewTime <> LastTime then begin
      CopyMyFile;
      LastTime := NewTime;
    end;
  end;
end;

end.
0
 
LVL 2

Author Comment

by:wqclatre
ID: 7133674
I get

Undeclared Identifier SFOpenError on row 50:

   if Source < 0 then raise EFOpenError.CreateFmt(SFOpenError, [FileName]);
0
 
LVL 17

Expert Comment

by:geobul
ID: 7133677
add Consts to your uses clause. It's declared there.
0
 
LVL 2

Author Comment

by:wqclatre
ID: 7133681
Hm strange.

I have:

Uses
 Windows, Messages, SysUtils, Classes, Consts, Graphics, Controls, SvcMgr, Dialogs,
 ExtCtrls;

type....

I can't find SFOpenError in this unit either.
0
 
LVL 17

Accepted Solution

by:
geobul earned 200 total points
ID: 7133739
It'd be better to rewrite CopyFile procedure in order to skip raising exceptions. If an exception occurs then the file will NOT be copied.

procedure CopyFile(const FileName, DestName: TFileName);
var
 CopyBuffer: Pointer; { buffer for copying }
 BytesCopied: Longint;
 Source, Dest: Integer; { handles }
 Destination: TFileName; { holder for expanded destination name }
const
 ChunkSize: Longint = 8192; { copy in 8K chunks }
begin
 Destination := ExpandFileName(DestName);  { expand the destination path }
 GetMem(CopyBuffer, ChunkSize); { allocate the buffer }
 try
  try
   Source := FileOpen(FileName, fmOpenRead or fmShareDenyNone); { open source file }
   if not (Source < 0) then begin
    try
     Dest := FileCreate(Destination); { create output file; overwrite existing }
     if not (Dest < 0) then begin
      try
       repeat
         BytesCopied := FileRead(Source, CopyBuffer^, ChunkSize); { read chunk }
         if BytesCopied > 0 then { if we read anything... }
           FileWrite(Dest, CopyBuffer^, BytesCopied); { ...write chunk }
       until BytesCopied < ChunkSize; { until we run out of chunks }
      finally
       FileClose(Dest); { close the destination file }
      end;
     end;
    finally
     FileClose(Source); { close the source file }
    end;
   end;
  finally
    FreeMem(CopyBuffer, ChunkSize); { free the buffer }
  end;
 except
   // do nothing
 end;
end;
0

Featured Post

What is SQL Server and how does it work?

The purpose of this paper is to provide you background on SQL Server. It’s your self-study guide for learning fundamentals. It includes both the history of SQL and its technical basics. Concepts and definitions will form the solid foundation of your future DBA expertise.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Run video youtube webbrowse 10 61
Convert GUI app into console app for Win32 Env 5 100
tvirtualstringtree freeze when load too manny images 10 62
DBGrid or StringGrid ? 6 88
In this tutorial I will show you how to use the Windows Speech API in Delphi. I will only cover basic functions such as text to speech and controlling the speed of the speech. SAPI Installation First you need to install the SAPI type library, th…
Hello everybody This Article will show you how to validate number with TEdit control, What's the TEdit control? TEdit is a standard Windows edit control on a form, it allows to user to write, read and copy/paste single line of text. Usua…
This tutorial gives a high-level tour of the interface of Marketo (a marketing automation tool to help businesses track and engage prospective customers and drive them to purchase). You will see the main areas including Marketing Activities, Design …
Established in 1997, Technology Architects has become one of the most reputable technology solutions companies in the country. TA have been providing businesses with cost effective state-of-the-art solutions and unparalleled service that is designed…

770 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question