Announcement

Collapse
No announcement yet.

Multiple instances

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Multiple instances

    How can I detect how many instances of a given program are running on a server? I need this information to block additional users if the licenced number of users has been reached.

    I bet there is an API call for this, but I cannot find one!

    Iain Johnstone
    “None but those who have experienced them can conceive of the enticements of science” - Mary Shelley

  • #2
    >I bet there is an API call for this, but I cannot find one

    I'll bet there isn't anything; you generally do this counting via your application.

    "In theory" I suppose you could try logging on to the server, enumerating all the processes, getting the module names for those processes and looking at the file names for each process. If they are 'myprogram.exe' it's an instance of your program.

    Of course, you can beat this one easily enough.. just rename the exe.

    Then again, programs don't run "on a server", they run on the client.. unless you have a genuine client-server setup, in which case the server should count users in its own application logic.

    (e.g, you can run \\computername\path\programfile.exe from a client machine and it will not show up in an enumeration of processes on the server).

    MCM
    Michael Mattias
    Tal Systems (retired)
    Port Washington WI USA
    [email protected]
    http://www.talsystems.com

    Comment


    • #3
      Couldn't each one create a similar but unique Mutex and then you can enumerate on the mutex names?

      Mutex = MutexSuffix + PID

      and then enumerate how many MutexSuffixes it sees?
      <b>George W. Bleck</b>
      <img src='http://www.blecktech.com/myemail.gif'>

      Comment


      • #4
        I am looking at a Citrix setup where the app runs on the server. What I have at present is a counter in a file that is incremented each time the program is run as a separate instance, and decremented when a session terminates. However, if the user just crashes out of the app, the counter is not decremented. If this happens over time, the counter will reach the maximum number of users even though they are not there! I an fully aware that this is not the best system, but it is all I have at the present, hence the question.

        Iain Johnstone
        “None but those who have experienced them can conceive of the enticements of science” - Mary Shelley

        Comment


        • #5
          Here is a routine that I use in my MP3 player found in the source code forum. It detects if the program is running on the same machine it's installed on.

          You may be able to modify it to suit your own particulars.
          Code:
          'in the main body of the program
              Title$ = "My running application                 '
              CONSOLE NAME Title$                              '
              TitleName = Title$                                  ' This MUST match the console
                                                                        ' name.
              IF Is_already_running(BYCOPY title$) THEN...
          
               
          FUNCTION Is_Already_Running(TitleName AS ASCIIZ) EXPORT AS LONG
              LOCAL hMutex AS LONG
              hMutex = CreateMutex(BYVAL %Null, 0, TitleName)
              IF hMutex = 0 THEN EXIT FUNCTION                ' Error in Mutex
              IF GetLastError = %ERROR_ALREADY_EXISTS OR FindWindow(TitleName, "") > 0 THEN
              FUNCTION = %TRUE
              END IF
              END FUNCTION
          I can't find where I got this routine from. My bad.
          Last edited by Mel Bishop; 9 Jan 2008, 03:45 PM.
          There are no atheists in a fox hole or the morning of a math test.
          If my flag offends you, I'll help you pack.

          Comment


          • #6
            Iain,
            if you want to play with registered Window messages
            I'm pretty confident that you will acheive your goal.

            Code:
            #COMPILE EXE '#Win 8.04#
            #REGISTER NONE
            #DIM ALL
            #INCLUDE "Win32Api.inc" '#2005-01-27#
             
            %Label1      = 101
            %MaxInstance = 3
            '______________________________________________________________________________
             
            CALLBACK FUNCTION DlgProc
             STATIC WhosThere      AS DWORD
             STATIC ImHere         AS DWORD
             STATIC SetCount       AS DWORD
             STATIC InstancesCount AS DWORD
             
             SELECT CASE CBMSG
             
               CASE %WM_INITDIALOG
                 WhosThere = RegisterWindowMessage("WhosThere")  'Message to provoke the "ImHere" response
                 ImHere    = RegisterWindowMessage("ImHere")     'Message to count instances
                 SetCount  = RegisterWindowMessage("SetCount")   'Message to show instances count
                 PostMessage(%HWND_BROADCAST, WhosThere, 0, 0)   'Ask every instances to send a "ImHere" message
             
               CASE WhosThere                                    'An new instance want to count total instances
                 PostMessage(%HWND_BROADCAST, ImHere, 0, 1)      'Send "ImHere" message with "1" to increment InstancesCount
             
               CASE ImHere                                       'Respond to an "ImHere" message
                 IF CBLPARAM = 1 THEN                            'Increment InstancesCount if 1
                   IF GetForeGroundWindow = CBHNDL THEN          'Are we foreground
                     INCR InstancesCount                         'Increment InstancesCount
                     PostMessage(%HWND_BROADCAST, SetCount, 0, InstancesCount) 'Set InstancesCount to every instance
                   END IF
                 ELSE
                   DECR InstancesCount                           'Decrement InstancesCount
                   PostMessage(%HWND_BROADCAST, SetCount, 0, InstancesCount) 'Set InstancesCount to every instance
                 END IF
             
                 IF InstancesCount > %MaxInstance THEN           'Check if maximum count is reached
                   IF GetForeGroundWindow = CBHNDL THEN          'Supress only the foreground windows
                     CONTROL SET TEXT CBHNDL, %Label1, "Sorry, no more than" & STR$(%MaxInstance) & _
                                                       "instances," & $CRLF & "quitting now !"
                     SLEEP 2000
                     PostMessage(%HWND_BROADCAST, SetCount, 0, InstancesCount) 'Set InstancesCount to every instance
                     DIALOG END CBHNDL                           'End application
                   END IF
                 END IF
             
               CASE SetCount
                 InstancesCount = CBLPARAM                      'Set count total instances
                 CONTROL SET TEXT CBHNDL, %Label1, FORMAT$(InstancesCount) & " instance(s)" 'Show result
             
               CASE %WM_DESTROY
                 PostMessage(%HWND_BROADCAST, ImHere, 0, 0) 'Say we're leaving to decrement InstancesCount
             
              END SELECT
             
            END FUNCTION
            '______________________________________________________________________________
             
            FUNCTION PBMAIN()
             LOCAL hDlg AS DWORD
             
             DIALOG NEW %HWND_DESKTOP ,"Max 3 instance", , , 150, 70, _
               %WS_CAPTION OR %WS_MINIMIZEBOX OR %WS_SYSMENU, %WS_EX_TOPMOST TO hDlg
             SetClassLong hDlg, %GCL_HICON, LoadIcon(BYVAL %NULL, BYVAL %IDI_INFORMATION) 'Set a nice dialog icon
             
             CONTROL ADD LABEL, hDlg, %Label1, "Instances count", 10, 30, 130, 20, %SS_CENTER, 0
             
             DIALOG SHOW MODAL hDlg CALL DlgProc
             
            END FUNCTION
            '______________________________________________________________________________

            Comment


            • #7
              The problem is... each instance of your program is actually executing in the memory space of the client computer.

              So, the mutex approach could work if you do something like...
              Code:
              Enumerate all computers on the network
              For each computer
                 Log on to that computer
                 look for mutex or other object with known name
                 If found
                    increment user count
                 end if
              Next
              If userCount > allowed
                 message to user and terminate
              endif
              You'd have to put this code into the client application.

              Until there are no more crashes preventing update of the "user count file" I can't think of anything a whole lot better than this UNLESS you go to a true client-server application.. where each client must contact the server (which runs one instance on named machine) and that server application counts users and then responds to the starting client program that there is an insufficient number of licenses available for him to run right now.

              Hmmm... maybe there would be a market for such a product? There has to be a market.. meaning 'somewhere' there almost certainly exists an off-the-shelf solution.

              MCM
              Michael Mattias
              Tal Systems (retired)
              Port Washington WI USA
              [email protected]
              http://www.talsystems.com

              Comment


              • #8
                Not sure if it's so difficult to write a client/server app.
                There is DCOM and there is TCP..

                However, one can install an app twice isn't?
                If you are willing to accept this fact then imo there is a more simple option i spoke about before.
                You can let such an app seek a free spot in a file shared on a networkdevice.
                (you will get permissionsissues though)

                If you lock a single record in a random file you claim a single user this way.
                If the app is exitted (or crashes ) the record is released again.
                Seems a viable solution to me.
                hellobasic

                Comment


                • #9
                  Michael - on the Citrix thin client system, the app (in fact all apps) execute on the server. The client end can be any old PC/terminal because it is just a screen and a keyboard (basically), though most of the users do not know/understand this, which is just as well!. As this particular installation is on a local authority network, I am keen to keep all the 'housekeeping' within the app just in case it goes pear-shaped.

                  Pierre & Mel - I will have a play with these suggestions. Fortunately I have a brother who is the ICT manager for a large London Borough that runs a Citrix systen, so I can get him to try out code before I attack the system at the other end of the country!


                  Many thanks to you all

                  Iain Johnstone
                  “None but those who have experienced them can conceive of the enticements of science” - Mary Shelley

                  Comment

                  Working...
                  X