[2 days left] What’s wrong with your cloud strategy? Learn why multicloud solutions matter with Nimble Storage.Register Now

x
?
Solved

Help creating a service.

Posted on 2002-07-06
9
Medium Priority
?
388 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
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
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
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 800 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

Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

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

Have you ever had your Delphi form/application just hanging while waiting for data to load? This is the article to read if you want to learn some things about adding threads for data loading in the background. First, I'll setup a general applica…
Introduction I have seen many questions in this Delphi topic area where queries in threads are needed or suggested. I know bumped into a similar need. This article will address some of the concepts when dealing with a multithreaded delphi database…
Visualize your data even better in Access queries. Given a date and a value, this lesson shows how to compare that value with the previous value, calculate the difference, and display a circle if the value is the same, an up triangle if it increased…
In response to a need for security and privacy, and to continue fostering an environment members can turn to for support, solutions, and education, Experts Exchange has created anonymous question capabilities. This new feature is available to our Pr…
Suggested Courses

649 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