Board index » delphi » MORE THAN ONE COPY OF THE MAIN FORM (MAIN FORM.EXE)

MORE THAN ONE COPY OF THE MAIN FORM (MAIN FORM.EXE)

Dear Sirs,

I am writing a database application on MS Window 98/95/2000.  I want to stop
users from running more than one copy of my *.Exe.   I hope there is a way
around in controlling this complex situation.

The situation can be simplified if only one copy of a modeless form,
controlling through the Main Form, is to be displayed, by using the
following two procedures:

//Inside the main Form.
Procedure Tform1.btnSingleclick(Sender: Tobject);
Begin
   If not Assigened(Form2) then
      Form2 := Tform2.Create(Application);
   Form2.Show;
End;

//Inside the Form2.
Procedure Tform.FormClose(Sender: Tobject;
   Var Action: TcloseAction);
Begin
   Action := caFree;
   // important: set pointer to nil!
   Form2 := nil;
End;

None the less, the situation is a little more complex when only one copy of
the Main Form or Main Form.exe to be run.

I would like users be able to run only one copy of the Main Form (Main
Form.exe).  I would most grateful if there is any way to stop users from
running more than one copy of the Main *.EXE application.

Faithfully,
Rakam

 

Re:MORE THAN ONE COPY OF THE MAIN FORM (MAIN FORM.EXE)


Dear Sirs,

I am writing a database application on MS Window 98/95/2000.  I want to stop
users from running more than one copy of my *.Exe.   I hope there is a way
around in controlling this complex situation.

The situation can be simplified if only one copy of a modeless form,
controlling through the Main Form, is to be displayed, by using the
following two procedures:

//Inside the main Form.
Procedure Tform1.btnSingleclick(Sender: Tobject);
Begin
   If not Assigened(Form2) then
      Form2 := Tform2.Create(Application);
   Form2.Show;
End;

//Inside the Form2.
Procedure Tform.FormClose(Sender: Tobject;
   Var Action: TcloseAction);
Begin
   Action := caFree;
   // important: set pointer to nil!
   Form2 := nil;
End;

None the less, the situation is a little more complex when only one copy of
the Main Form or Main Form.exe to be run.

I would like users be able to run only one copy of the Main Form (Main
Form.exe).  I would most grateful if there is any way to stop users from
running more than one copy of the Main *.EXE application.

Faithfully,
Rakam

Re:MORE THAN ONE COPY OF THE MAIN FORM (MAIN FORM.EXE)


The most common solution to this problem is to use a mutex as shown in the
following example.

procedure TForm1.FormCreate(Sender: TObject);
{Posted by Bill Sparrow}
begin
  // Create a mutex.  Don't bother to retain the returned
  // handle.  The system closes the handle automatically
  // when the process terminates, and the mutex object is
  // destroyed when its last handle has been closed.
  CreateMutex(nil, FALSE, pchar(Application.Title));
  // The following is safe, because CreateMutex always
  // sets the thread's last-error code, even on success.
  if GetLastError() <> ERROR_SUCCESS then
  begin  // Something went wrong, but what?
    if (GetLastError() = ERROR_ALREADY_EXISTS) then
      ShowMessage('You can only have one instance of [' +
            Application.Title + '] running at one time.')
    else // Other unexpected error.
      ShowMessage(SysErrorMessage(GetLastError()));
    // Keep mainform from flickering.
    Application.ShowMainForm := FALSE;
    // Terminate our application.
    Application.Terminate;
  end;
end;

--
Bill

Re:MORE THAN ONE COPY OF THE MAIN FORM (MAIN FORM.EXE)


Dear Bill,

It perfectly worked as I wanted.  How nice of you to help me.   It is
fantastic to do programming in Delphi than in any languages.

Thank your very much.

sincerely
rakam

"Bill Todd (TeamB)" <billtodd...@nospam.qwest.net> wrote in message
news:3b13c3ea$1_1@dnews...

Quote
> The most common solution to this problem is to use a mutex as shown in the
> following example.

> procedure TForm1.FormCreate(Sender: TObject);
> {Posted by Bill Sparrow}
> begin
>   // Create a mutex.  Don't bother to retain the returned
>   // handle.  The system closes the handle automatically
>   // when the process terminates, and the mutex object is
>   // destroyed when its last handle has been closed.
>   CreateMutex(nil, FALSE, pchar(Application.Title));
>   // The following is safe, because CreateMutex always
>   // sets the thread's last-error code, even on success.
>   if GetLastError() <> ERROR_SUCCESS then
>   begin  // Something went wrong, but what?
>     if (GetLastError() = ERROR_ALREADY_EXISTS) then
>       ShowMessage('You can only have one instance of [' +
>             Application.Title + '] running at one time.')
>     else // Other unexpected error.
>       ShowMessage(SysErrorMessage(GetLastError()));
>     // Keep mainform from flickering.
>     Application.ShowMainForm := FALSE;
>     // Terminate our application.
>     Application.Terminate;
>   end;
> end;

> --
> Bill

Re:MORE THAN ONE COPY OF THE MAIN FORM (MAIN FORM.EXE)


I write variables to the registry. This gives me more control than the
mutex approach. With the registry approach, I can decide to ignore the
first program if it is too old. E.g., if the first program started
yesterday, then it is okay to run the second exe. Furthermore, the
registry approach permits me to write to a log file so that I can
monitor what is happening.

The code is confusing, and I'd be glad to share it.

Re:MORE THAN ONE COPY OF THE MAIN FORM (MAIN FORM.EXE)


Dear Sanford,

How it is done?  I am quite novice in matters of playing with registry.

I would very glad if you could help in this matter.

Sincerely,
rakam

--

Quote
"Sanford Aranoff" <saran...@nusinc.com> wrote in message

news:3B14F72D.FE6E3E16@nusinc.com...
Quote
> I write variables to the registry. This gives me more control than the
> mutex approach. With the registry approach, I can decide to ignore the
> first program if it is too old. E.g., if the first program started
> yesterday, then it is okay to run the second exe. Furthermore, the
> registry approach permits me to write to a log file so that I can
> monitor what is happening.

> The code is confusing, and I'd be glad to share it.

Re:MORE THAN ONE COPY OF THE MAIN FORM (MAIN FORM.EXE)


Dear Sanford,

How it is done?  I am quite novice in matters of playing with registry.

I would very glad if you could help in this matter.

Sincerely,
rakam

--

Quote
"Sanford Aranoff" <saran...@nusinc.com> wrote in message

news:3B14F72D.FE6E3E16@nusinc.com...
Quote
> I write variables to the registry. This gives me more control than the
> mutex approach. With the registry approach, I can decide to ignore the
> first program if it is too old. E.g., if the first program started
> yesterday, then it is okay to run the second exe. Furthermore, the
> registry approach permits me to write to a log file so that I can
> monitor what is happening.

> The code is confusing, and I'd be glad to share it.

Re:MORE THAN ONE COPY OF THE MAIN FORM (MAIN FORM.EXE)


const
        SECTION = 'NUS_EDI';
        section_key = 'Working';

function write_working(const lwork: boolean; FIniFile: TRegIniFile):
boolean;
var
        line_   : string;
begin
        Result:= false;
        if assigned(FIniFile) then
        with FIniFile do
        begin
                if OpenKey(section,true) then
                begin
                        WriteBool(section_key,'Working',lwork);
                        if lwork then
                                WriteString(section_key,'Date Working',DateTimeToStr(Now));
                        CloseKey;
                        Result:= true
                end
                else begin
        if lwork then
                line_:= 'OpenKey false. Working not set'
         else
                line_:=  'OpenKey false. Working not cleared';
                Raise Ewrite_err.Create_write(line_,true,48,0)
                end
        end
end;

function read_working(var FIniFile: TRegIniFile): boolean;
begin
        Result:= assigned(FIniFile);
        if Result then
        with FIniFile do
        begin
                if OpenKey(section,false) then
                begin
                        Result:= ReadBool(section_key,'Working',false);
                        if Result then
                        begin
                                line_:= ReadString(section_key,'Date Working','');
                                ThisDate:= StrToDateTime(line_);
                                Result:= Now - ThisDate <= 1/24  // okay if an hour apart
                        end;
                        CloseKey;
                        if Result and not l_auto then
                        begin
                                bel;
                                Result:= not confirm('Clear working key?')
                        end;
                        if Result then
         begin
                      FIniFile:= nil; //Close will not set working to false
            Raise EWork.Create('Working previously set ' + line_,false)
         end
                        else
                                write_working(true,FIniFile)
                end
                else
                Raise Ewrite_err.Create_write('OpenKey false',true,48,0)
        end
end;

Quote
Rakam Limbu Begha wrote:

> Dear Sanford,

> How it is done?  I am quite novice in matters of playing with registry.

> I would very glad if you could help in this matter.

> Sincerely,
> rakam

> --

> "Sanford Aranoff" <saran...@nusinc.com> wrote in message
> news:3B14F72D.FE6E3E16@nusinc.com...
> > I write variables to the registry. This gives me more control than the
> > mutex approach. With the registry approach, I can decide to ignore the
> > first program if it is too old. E.g., if the first program started
> > yesterday, then it is okay to run the second exe. Furthermore, the
> > registry approach permits me to write to a log file so that I can
> > monitor what is happening.

> > The code is confusing, and I'd be glad to share it.

Other Threads