Autor Téma: Odkud je aplikace spuštěna.  (Přečteno 337 krát)

Offline Viktor Marek

  • Mladík
  • **
  • Příspěvků: 50
  • Karma: 0
    • Verze Delphi: Delphi 5
Odkud je aplikace spuštěna.
« kdy: 03-11-2017, 07:19:39 »
Mám nesíťovou aplikaci. Je možno nějak zjistit z kterého PC na síti byla aplikace spuštěna (Název PC ...), abych mohl dalšímu uživateli, který tuto aplikaci přes síť spustí oznámit "Tato aplikace je již spuštěna uživatelem ....")
Je mi jasné, že to plně nenahradí překlopení aplikace na síťovou verzi, ale vzhledem k využití aplikace by to postačovalo.

Offline martinnr

  • Plnoletý
  • ***
  • Příspěvků: 136
  • Karma: 2
    • Verze Delphi: 7,2009,XE7
Re:Odkud je aplikace spuštěna.
« Odpověď #1 kdy: 03-11-2017, 07:51:49 »
"nesitova" aplikacia znamena, ze aplikacia nevie byt spustena viackrat naraz na roznych pocitacoch?
lebo inak podla toho, co pises evokuje, ze je aplikacia na sieti (sietovom disku) a spusta sa na staniciach z tej sietovej cesty.
alebo je naozaj na pocitacoch lokalne, len nechces aby sa spustila na viac ako jednom pocitaci v jednej chvili...?

ak ide o prvy variant, aplikacia je na spolocnom ulozisku a odtial ju vsetci spustaju, tak by mohlo stacit pri spustani vytvarat nejaky subor v danom ulozisku a pri ukonceni ho zmazat. to ale vyzaduje, aby aplikacia bola stabilna a nepadala, teda aby spolahlivo pri ukonceni doslo k vymazaniu suboru. to je najprimitivnejsi sposob, na par riadkov kodu a v jednoduchych podmienkach moze fungovat.
ak by boli problemy a niekedy by sa subor po ukonceni nevymazal, tak este sa da urobit to, ze dany subor sa otvori na zapis a teda kazde spustenie z ineho pocitaca sa pokusi subor vymazat, pokial tato operacia zlyha, tak je jasne, ze nejaky pocitac ma program otvoreny. pokial sa tam aplikacia ukonci alebo padne, pristup suboru sa uvolni a je mozne ho vymazat. resp. zase ak tam subor neexistuje, tak mozem spustit.
dalsi zlozitejsi sposob je, aby program po spusteni zacal pocuvat sietovu komunikaciu na nejakom porte a zaroven na danom porte osahal ostatne pocitace v sieti. je to uz zlozitejsie riesenie a obsluzi to malu siet (jedna skupinu 255 adries by to este stihalo), aby to prilis nezdrzovalo pri spusteni. ale to uz je viac prace.

Offline Viktor Marek

  • Mladík
  • **
  • Příspěvků: 50
  • Karma: 0
    • Verze Delphi: Delphi 5
Re:Odkud je aplikace spuštěna.
« Odpověď #2 kdy: 03-11-2017, 08:22:04 »
Aplikace je na serveru a spouští se z lokálních stanic přes namapovaný síťový disk. Jelikož je aplikace napsána jako nesíťová, dochází při vicenásobném spuštění k destrukci dat v tabulkách.

Vytvoření souboru při spuštění je dobrá myšlenka ale stále s rizikem, že při pádu aplikace (což nelze nikdy úplně vyloučit) zůstane soubor na disku.

Neexistuje možnost zjistit usera připadně název PC, který je v daném okamžiku vlastníkem procesu?

Online Delfin

  • Hrdina
  • ****
  • Příspěvků: 368
  • Karma: 16
  • SW konzultant
    • Verze Delphi: 2009, Tokyo
    • Ibi Yoyo :)
Re:Odkud je aplikace spuštěna.
« Odpověď #3 kdy: 03-11-2017, 08:31:32 »
...dochází při vicenásobném spuštění k destrukci dat v tabulkách.

Tak omez pocet uzivatelu pripojenych na RDBMS na 1. Appka jim skonci na chybe s limitem poctu uzivatelu a budes mit jistotu ze vic nez 1 uzivatel se k databazi nedostane.
A co chudinky ovce? Koupíš jim snad plovací vesty? Nebo jim nasadíš chůdy? Ještě lepší, kdybys je zkřížil s delfíny na ovce hopkavé!

Offline xnukes

  • Mladík
  • **
  • Příspěvků: 62
  • Karma: 1
    • Verze Delphi: XE7
    • Bludspeed s.r.o.
Re:Odkud je aplikace spuštěna.
« Odpověď #4 kdy: 03-11-2017, 08:35:46 »
a nebo lock soubor ? :) pri spusteni lockne a pri zavreni otevre :)

Offline pepak

  • Guru
  • *****
  • Příspěvků: 1297
  • Karma: 28
    • Pepak.net
Re:Odkud je aplikace spuštěna.
« Odpověď #5 kdy: 03-11-2017, 09:02:52 »
a nebo lock soubor ? :) pri spusteni lockne a pri zavreni otevre :)
Nebo snadněji (i pro případné opravy po pádu) vytvoří soubor se jménem stanice při spuštění a při ukončení ho smaže. Detekce pak je přes FileExists, jméno stanice je možné si přečíst uvnitř.

Offline pepak

  • Guru
  • *****
  • Příspěvků: 1297
  • Karma: 28
    • Pepak.net
Re:Odkud je aplikace spuštěna.
« Odpověď #6 kdy: 03-11-2017, 09:03:43 »
...dochází při vicenásobném spuštění k destrukci dat v tabulkách.

Tak omez pocet uzivatelu pripojenych na RDBMS na 1. Appka jim skonci na chybe s limitem poctu uzivatelu a budes mit jistotu ze vic nez 1 uzivatel se k databazi nedostane.
Pokud píše, že mu víc instancí způsobuje zničení dat, tak mám pochybnosti o tom, že používá (R)DBMS.

Offline Viktor Marek

  • Mladík
  • **
  • Příspěvků: 50
  • Karma: 0
    • Verze Delphi: Delphi 5
Re:Odkud je aplikace spuštěna.
« Odpověď #7 kdy: 03-11-2017, 09:11:36 »
(R)DBMS nepoužívám, daty jsou uloženy v DBIsam

Offline JaroB

  • Guru
  • *****
  • Příspěvků: 819
  • Karma: 20
    • Verze Delphi: D2007, XE2, XE6
Re:Odkud je aplikace spuštěna.
« Odpověď #8 kdy: 03-11-2017, 09:13:59 »
To já mám obdobný ale vlastně jiný problém, kdy se ten samý uživatel přihlásí do aplikace na různých strojích přes vzdálenou plochu (= více ploch) vícekrát naráz. Aplikace pracuje v mezích jeho loginu, je jednoinstanční (na jedné ploše jedna instance) ale DB má jen jednu. A ty plochy mají svůj timeout a občas je systém (Citrix) zabije. Bohužel zabití je bez závazků, takže neproběhnou žádné postfunkce jako při odhlášení, je to prostě vypnutí. A protože je to blikanec, tak nedojde k zápisu do db o ukončení a hromadí se mi odkazy na otevřené tabule :(

Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 2974
  • Karma: 29
    • Verze Delphi: XE7 professional
Re:Odkud je aplikace spuštěna.
« Odpověď #9 kdy: 03-11-2017, 09:15:53 »
Ešte existuje možnosť, aby si sama aplikácia kontrolovala či už je spustená. Pomocou mutexu. To bezchybne funguje na jednom PC. No nemám potuchy akoby sa to správalo pri prístupe z rôznych PC.
Delphi XE7, FireBird
Expert na kladenie nejasne formulovaných otázok.

Offline Viktor Marek

  • Mladík
  • **
  • Příspěvků: 50
  • Karma: 0
    • Verze Delphi: Delphi 5
Re:Odkud je aplikace spuštěna.
« Odpověď #10 kdy: 03-11-2017, 10:46:46 »
Na netu jsem našel něco, co by mohlo pomoct

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, TlHelp32, StdCtrls, ComCtrls;

type
  TForm1 = class(TForm)
    ListView1: TListView;
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

  PTOKEN_USER = ^TOKEN_USER;
  _TOKEN_USER = record
                  User: TSidAndAttributes;
                end;
  TOKEN_USER = _TOKEN_USER;

var
  Form1: TForm1;

implementation

{$R *.dfm}

function GetUserAndDomainFromPID(ProcessId: DWORD; var User, Domain: string): Boolean;
var
  hToken: THandle;
  cbBuf: Cardinal;
  ptiUser: PTOKEN_USER;
  snu: SID_NAME_USE;
  ProcessHandle: THandle;
  UserSize, DomainSize: DWORD;
  bSuccess: Boolean;
begin
  Result := False;
  ProcessHandle := OpenProcess(PROCESS_QUERY_INFORMATION, False, ProcessId);
  if ProcessHandle <> 0 then
  begin
    if OpenProcessToken(ProcessHandle, TOKEN_QUERY, hToken) then
    begin
      bSuccess := GetTokenInformation(hToken, TokenUser, nil, 0, cbBuf);
      ptiUser  := nil;
      while (not bSuccess) and (GetLastError = ERROR_INSUFFICIENT_BUFFER) do
      begin
        ReallocMem(ptiUser, cbBuf);
        bSuccess := GetTokenInformation(hToken, TokenUser, ptiUser, cbBuf, cbBuf);
      end;
      CloseHandle(hToken);
      if not bSuccess then Exit;
      UserSize := 0;
      DomainSize := 0;
      LookupAccountSid(nil, ptiUser.User.Sid, nil, UserSize, nil, DomainSize, snu);
      if (UserSize <> 0) and (DomainSize <> 0) then
      begin
        SetLength(User, UserSize);
        SetLength(Domain, DomainSize);
        if LookupAccountSid(nil, ptiUser.User.Sid, PChar(User), UserSize, PChar(Domain), DomainSize, snu) then
        begin
          Result := True;
          User := StrPas(PChar(User));
          Domain := StrPas(PChar(Domain));
        end;
      end;
      if bSuccess then FreeMem(ptiUser);
    end;
    CloseHandle(ProcessHandle);
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
var
  hProcSnap: THandle;
  pe32: TProcessEntry32;
  Domain, User: string;
begin
  ListView1.Items.BeginUpdate;
  hProcSnap := CreateToolHelp32SnapShot(TH32CS_SNAPALL, 0);
  if hProcSnap = INVALID_HANDLE_VALUE then Exit;
  pe32.dwSize := SizeOf(ProcessEntry32);
  if Process32First(hProcSnap, pe32) then
    while Process32Next(hProcSnap, pe32) do
    begin
      if GetUserAndDomainFromPID(pe32.th32ProcessID, User, Domain) then
      begin
        with Listview1.Items.Add do
          begin
            Caption := IntToStr(pe32.th32ProcessID);
            SubItems.Add(pe32.szExeFile);
            SubItems.Add(user);
            SubItems.Add(domain);
          end;
      end else Listview1.Items.Add.SubItems.Add(pe32.szExeFile);
    end;
  CloseHandle(hProcSnap);
  ListView1.Items.EndUpdate;
end;

end.

Offline martinnr

  • Plnoletý
  • ***
  • Příspěvků: 136
  • Karma: 2
    • Verze Delphi: 7,2009,XE7
Re:Odkud je aplikace spuštěna.
« Odpověď #11 kdy: 03-11-2017, 13:03:58 »
subor vytvoreny na tom sietovom disku nemusi byt prazdny, moze to byt jednoduchy textak, pripadne strukturovany textak/xml s dalsimi udajmi.
plus osetrenie zamknutia suboru, ako som uz pisal.

Offline našinec

  • Hrdina
  • ****
  • Příspěvků: 315
  • Karma: 4
Re:Odkud je aplikace spuštěna.
« Odpověď #12 kdy: 03-11-2017, 13:10:54 »
A proč si třeba jednoduše nevložíš do aplikace příkaz, kterým někam odešle info o spuštění a zároveň požádá o info, jestli není aplikace ještě někde spuštěná?

Online Ján Masaryk

  • Nováček
  • *
  • Příspěvků: 48
  • Karma: 5
    • Verze Delphi: 2010
Re:Odkud je aplikace spuštěna.
« Odpověď #13 kdy: 03-11-2017, 15:32:15 »
Ak som správne pochopil, podporuje to tzv. locking, viď https://www.elevatesoft.com/manual?action=viewtopic&id=dbisam4&product=delphi&version=5&topic=locking_concurrency

1. varianta
Vytvoríš nejakú tabuľku a pri štarte ju zamkneš, pri ukončení ju odomkneš. Neviem však ako by sa to chovalo pri páde
aplikácie, a či je nejaká možnosť urobiť unlock cez nejaké obslužné utility.

2. varianta
Použiješ Semaphore Lock
Riziko je tam podobné ako pri variante 1 pri páde aplikácie, či je možnosť odomknúť semafor.

3. varianta - prerobiť to na sieťovú verziu  ;)

Ja by som použil takéto riešenie:
Vytvor tabuľku napr. pristupy ktorá bude mať jeden stlpec napr. used (Int) a zapisovať sa budú hodnoty 0 (voľná) a 1 (obsadená).
Ak sa spustí aplikácia, vojde do tabuľky a zistí aká hodnota je tam zapísaná. Ak je tam 0, zapíše tam 1. Pri ukončení tam aplikácia zapíše 0.
Ak sa spustí aplikácia druhý krát a bude tam 1, tak vypíše hlásenie, že sa jedná o duplicitné spustenie a ukončí sa.

Samozrejme si tiež priprav aplikáciu, ktorá to prepíše na 0, keď ti spadne tá prvá spustená aplikácia a teda neprepíše 1 na 0  ;D

Ja som toto používal ešte od v časoch xbase (dBase - Clipper), aby som vedel ako mi skončila aplikácia kvoli indexom. Ak tam bola 1, automaticky som robil reindexáciu.
« Poslední změna: 03-11-2017, 15:38:52 od Ján Masaryk »

Offline Viktor Marek

  • Mladík
  • **
  • Příspěvků: 50
  • Karma: 0
    • Verze Delphi: Delphi 5
Re:Odkud je aplikace spuštěna.
« Odpověď #14 kdy: 03-11-2017, 15:55:14 »
Děkuji za rady (.. podporuje to tzv. locking,..), tohle mi uplně uteklo

Offline xnukes

  • Mladík
  • **
  • Příspěvků: 62
  • Karma: 1
    • Verze Delphi: XE7
    • Bludspeed s.r.o.
Re:Odkud je aplikace spuštěna.
« Odpověď #15 kdy: 06-11-2017, 10:58:48 »
Ak som správne pochopil, podporuje to tzv. locking, viď https://www.elevatesoft.com/manual?action=viewtopic&id=dbisam4&product=delphi&version=5&topic=locking_concurrency

1. varianta
Vytvoríš nejakú tabuľku a pri štarte ju zamkneš, pri ukončení ju odomkneš. Neviem však ako by sa to chovalo pri páde
aplikácie, a či je nejaká možnosť urobiť unlock cez nejaké obslužné utility.

2. varianta
Použiješ Semaphore Lock
Riziko je tam podobné ako pri variante 1 pri páde aplikácie, či je možnosť odomknúť semafor.

3. varianta - prerobiť to na sieťovú verziu  ;)

Ja by som použil takéto riešenie:
Vytvor tabuľku napr. pristupy ktorá bude mať jeden stlpec napr. used (Int) a zapisovať sa budú hodnoty 0 (voľná) a 1 (obsadená).
Ak sa spustí aplikácia, vojde do tabuľky a zistí aká hodnota je tam zapísaná. Ak je tam 0, zapíše tam 1. Pri ukončení tam aplikácia zapíše 0.
Ak sa spustí aplikácia druhý krát a bude tam 1, tak vypíše hlásenie, že sa jedná o duplicitné spustenie a ukončí sa.

Samozrejme si tiež priprav aplikáciu, ktorá to prepíše na 0, keď ti spadne tá prvá spustená aplikácia a teda neprepíše 1 na 0  ;D

Ja som toto používal ešte od v časoch xbase (dBase - Clipper), aby som vedel ako mi skončila aplikácia kvoli indexom. Ak tam bola 1, automaticky som robil reindexáciu.

Pád aplikace by se dalo vyřešit timestampem, že budeš testovat zda timestamp uložený bude menší o několik než now :)) Každopádně napsat si vlastní lock bude nejlepší varianta :)

 

S rychlou odpovědí můžete používat BB kódy a emotikony jako v běžném okně pro odpověď, ale daleko rychleji.

Jméno: E-mail:
Ověření:
Křestní jméno zpěváka Gotta: