Run-once exitproc,exitcode etc.

How to use exitproc?
and exitcode...

i need it to make somthing in a procedure run only the first time the program is run.... any suggestions?

Comments

  • : How to use exitproc?
    : and exitcode...
    :
    : i need it to make somthing in a procedure run only the first time the program is run.... any suggestions?
    :
    :
    ExitProc is a procedural variable, which is called just before the program closes. Here is a small untested code, which shows how to implement it.
    [code]
    var
    OldExitProc: pointer;

    procedure MyExit; far;
    begin
    ExitProc := OldExitProc; { Restore exit procedure address }
    writeln('Press any key to quit.');
    ReadKey;
    end;

    begin
    OldExitProc := ExitProc; { save previous exit proc }
    ExitProc := MyExit; { insert our exit proc in chain }
    writeln('Running program');
    end;
    [/code]
    The ExitCode holds the code, which is sent to DOS telling it the nature of the shutdown. A clean shutdown should return a 0, while other shutdown reasons (such as errors) often have a non-zero result, which can be used by other programs to determine their next course of action. This is mostly implemented in child processes.

    You could write a configuration file, which keeps track if the program ran already. The check itself is than a matter of a simple if-then statement, which also updates the config file.
  • [b][red]This message was edited by Phat Nat at 2003-2-28 15:26:24[/red][/b][hr]
    : How to use exitproc?
    : and exitcode...
    :
    : i need it to make somthing in a procedure run only the first time the program is run.... any suggestions?
    :
    :

    For what you want I don't think Exitproc, etc is what you need. From what I understand, you want your program to be run once and start a setup screen or registration screen, etc and then never show it again, right?

    The easiest way to do this would be to use a configuration file, however, if someone deletes the file then it will be run again.
    If this really isn't what you want, the best way (although more difficult) is to change a certain byte/word/string in the executable file. I have done this a few times, but whenever you change your code, you have to manually figure out the address in the file and then change the code to match that location. If you declared a string like this:
    CONST S : String = '~~~~~~~~~~~~';
    then this string would be in your executable file and you could do a search for that certain string. Here is an example of what I mean (this is tested code, but no guarentees)

    [code]
    (***************************************************************************
    Okay, here goes: The WAVES CONST is what the program will search for. You
    can change this to whatever, but MAKE SURE THAT THIS IS NOT COMMON! if it
    is only 2 bytes long, or if it is a common byte code, the program will find
    an incorrect spot and destroy the program! However, you could probably
    safely change it to '|9I:x' so that if someone looks in the file, it
    just appears to be code.

    NEWST contains the bytes that you want WAVES to be changed to.
    If you run FindString and it returns a -1 then Program has already
    been run!
    ***************************************************************************)
    PROGRAM OnceOnly;
    USES Crt, Dos;
    CONST
    Waves : String[20] = '~~~~~~~~~~';
    NewSt : String[20] = 'TEST';

    VAR
    Pos : LongInt;
    Block : Array[0..50000] Of Char;
    NumRead : Word;

    FUNCTION UpStr(S : String) : String;
    VAR
    X : Byte;
    Begin
    For X := 1 to Length(S) Do
    S[X] := UpCase(S[X]);
    UpStr := S;
    End;

    FUNCTION FindString(S : String) : LongInt;
    VAR
    F : File;
    FName : String;
    X : Word;
    Y : Word;
    Count : Word;
    Found : Boolean;

    Begin
    FName := ParamStr(0);
    If UpStr(Copy(FName,Length(FName)-8,9)) = 'TURBO.EXE' Then
    Begin
    WriteLn('Program Cannot be run from Debugger!');
    Halt;
    End;
    Assign(F, FName); Reset(F,1);
    Count := 0;
    Repeat
    BlockRead(F,Block,SizeOf(Block),NumRead);
    For X := 0 To NumRead Do
    If Block[X] = Waves[1] Then
    Begin
    Y := 1; Found := True;
    While (Y < Length(Waves)) AND (Found) Do
    Begin
    If Block[X+Y] <> Waves[Y] Then Found := False;
    Inc(Y);
    End;
    If Found Then
    Begin
    FindString := Count*SizeOf(Block)+X;
    Exit;
    End;
    End;
    Inc(Count);
    Until Eof(F);
    Close(F);
    FindString := -1;
    End;

    PROCEDURE ChangeString(Pos : LongInt);
    VAR
    FName : String;
    F : File;
    Begin
    FName := ParamStr(0);
    If UpStr(Copy(FName,Length(FName)-8,9)) = 'TURBO.EXE' Then
    Begin
    WriteLn('Program Cannot be run from Debugger!');
    Halt;
    End;
    Assign(F, FName); Reset(F,1);
    Seek(F,Pos);
    BlockWrite(F,NewSt[1],SizeOf(NewSt));
    Close(F);
    End;

    Begin
    Write('Searching File...');
    Pos := FindString(Waves);
    If Pos = -1 Then
    Begin
    WriteLn('Byte Pattern not Found!');
    Halt;
    End
    ELSE
    WriteLn('Byte Pattern Changed.');
    { POS contains WAVESCHECKLENGTH bytes after the start of WAVES }
    { hmm.. that sounds confusing... Read/Write to this position }
    ChangeString(Pos);
    End.
    [/code]

    *Note* Because this uses ASSIGN(F, PARAMSTR(0)); it may point to TURBO.EXE if run within the compiler. I have put a check in for that otherwise, if run from the debugger (compiling to memory), Bye-Bye TURBO.EXE!

    The rest of this should be fairly straight forward and can be changed/adjusted as needed. Ask if you are confused about anything.

    Phat Nat


  • Ok, i kinda thought of a way,
    in my program, ill read somthing from a file, if the file isnt there, ill do the run once and create the file , if the file is there, then the program will go on as normal, how to do this?
    like,
    If exitcode=2 THEN soand so?
  • : Ok, i kinda thought of a way,
    : in my program, ill read somthing from a file, if the file isnt there, ill do the run once and create the file , if the file is there, then the program will go on as normal, how to do this?
    : like,
    : If exitcode=2 THEN soand so?
    :
    That hase nothing to do with exitcode. ExitCode is set by the program to inform DOS about its termination.
    Here is a small code, which creates the file if it isn't there:
    [code]
    Assign(f, 'somefile.txt);
    {$I-}
    reset(f)
    {$I+}
    if IOResult <> 0 then begin { File cannot be opened }
    rewrite(f); { create file }
    end else begin
    { read the file }
    end;
    close(f);
    [/code]
Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Categories