View Full Version : سوال: آیا راهی برای یافتن نام کامپیوتری که به سرور ریموت شده است وجود دارد؟
  
soks_sia
سه شنبه 17 بهمن 1396, 17:53 عصر
سلام دوستان عزیز
یه سوال داشتم و میخواستم ببینم میتونید منو راهنمایی کنید. من برنامه ای دارم که اجازه ورود یک کاربر رو دوبار نمیده. برای کنترل این کار وقتی کاربری وارد برنامه شد وضعیتش رو در حال کار میکنم و اینکه از چه کامپیوتری وصل شده. بعد اگر خروج غیر مترقبه داشت یعنی بصورت غیر معمول از برنامه خارج شد که من نتونستم وضعیت خروج براش ثبت کنم، موقع ورود مجدد اگر از همون کامپیوتر وصل شده بود میفهمم خروج غیرعادی داشته و با هشدار اجازه ورود میدم ولی اگه از کامپیوتر دیگه ای بخواد وصل بشه، با هشدار به کاربر احتمالی اولی و درخواست رمز دوم و فرصت دادن 5 دقیقه ای به جمع بندی میرسیدم که اجازه ورود به نفر دوم بدم یا نه یا اینکه کاربر اول رو خارج کنم. تا حالا هم مشکلی نداشتم. مشکل از اون جایی شروع شد که یکی از جاهایی که برنامه منو گرفتن، کلیه کاربرها بصورت ریموت به سرورشون وصل میشن و برنامه رو اجرا میکنن. حالا چون اسم کامپیوتر برای همه کاربرها یکسان میشه یعنی اسم سرور رو میاره، فرقی نمیکنه با چه کلاینتی وصل شدی؛ عملا اینکه دو نفر با یه کد کاربری از دو کامپیوتر رو نمیتونم کنترل کنم. 
حالا سوالم اینه چه جوری میتونم اسم کامپیوتر کلاینتهایی که ریموت شدن رو بدست بیارم؟ با جستجوهایی که کردم هم چیز بدردبخوری پیدا نکردم. مثلا تو پی اچ پی یه دستور داره به اسمgethostname
که نوشته بود همچین کاری میکنه میخواستم ببینم دلفی هم همچین چیزی داره یا نه؟
Mask
سه شنبه 17 بهمن 1396, 19:39 عصر
انتظار شما اصلا ربطی به زبان برنامه نویسی نداره. وقتی کاربران از طریق ریموت وارد برنامه ای میشوند , عملا برنامه اون کاربر رو در سیستم جاری میبینه.
برای تفکیک این موضوع شما باید برای هر کاربر که ریموت میزنه به سرور (بماند که این روش اصلا منطقی نیست و من پیشنهاد نمیدهم. روش استفاده از ریموت منسوخ شده و اکثر برنامه ها دارای نسخه کلاینت و سرور هستند) با کاربری تعریف شده این کار رو انجام بدهد. شما با دستورات api براحتی نام کاربریه ویندوزی، فردی که داره وارد برنامه میشه رو بدست میارید و از این طریق بجای ای پی از سمت Username ویندوزی عملیات احراز هویت رو انجام میدهید.
soks_sia
چهارشنبه 18 بهمن 1396, 19:11 عصر
انتظار شما اصلا ربطی به زبان برنامه نویسی نداره. وقتی کاربران از طریق ریموت وارد برنامه ای میشوند , عملا برنامه اون کاربر رو در سیستم جاری میبینه.
برای تفکیک این موضوع شما باید برای هر کاربر که ریموت میزنه به سرور (بماند که این روش اصلا منطقی نیست و من پیشنهاد نمیدهم. روش استفاده از ریموت منسوخ شده و اکثر برنامه ها دارای نسخه کلاینت و سرور هستند) با کاربری تعریف شده این کار رو انجام بدهد. شما با دستورات api براحتی نام کاربریه ویندوزی، فردی که داره وارد برنامه میشه رو بدست میارید و از این طریق بجای ای پی از سمت Username ویندوزی عملیات احراز هویت رو انجام میدهید.
درود و سپاس از توجهتون
از اینکه کاربران بصورت ریموت وصل میشن، باید بگم که من بصورت ضمنی گفتم البته دوستان در آن شرکت از طریق سرورهای مجازی و سیتریکس به سرور مجازی برنامههاشون وصل میشن و در این شرکت هیچ برنامه اطلاعاتی روی کامپیوترهای کاربران که در دفاتر شهرستان و تهران دارند نصب نمیشه و فقط روی سرور اپلیکشنشون نصب میشه و همه از طریق سیتریکس به اون ریموت میشن.
بعد کسانی هم که ریموت میشن من نمیتونم تشخیص بدم که از کجا وصل میشن حالا از طریق سیتریکس یا ریموت وقتی وصل سرور میشن و برنامه رو اجرا میکنن، من فقط اسم سرور اپلیکیشن رو دارم. با دستوراتی هم که میگین کدهایی که اسم کلاینت و یوزر و آی پی رو برمیگردونه همشون مال سرور رو برمیگردونن.
soks_sia
چهارشنبه 18 بهمن 1396, 19:53 عصر
سلام و درود به دوستان عزیز
مشکلم حل شد و راه حل خیلی ساده اون را پیدا کردم.
یعنی خیلی راحت میشه, اسم کامپیوتر و کلاینتی که ازش وصل شدن و حتی یوزری که این کارو کرده رو پیدا کرد.
خیلی راحت با  Environment variable ها میتونین اونها را ببینین چیه. 
COMPUTERNAME برای اسم کامپیوتر و 
CLIENTNAME برای اسم کامپیوتری که ازش ریموت شدن.
با تابع GetEnvironmentVariable میتونین مقدار این متغییرها رو به صورت متنی بدست بیارین.
برای دیدن سایر متغییرهایی که میتونید استفاده کنید از دستور cmd در run استفاده کنید و بعد دستور set رو اجرا کنین. سایر متغییرها و مقادیرشون رو بهتون نشون میده
بای تیل های
PayamKazemi
دوشنبه 07 اسفند 1396, 18:55 عصر
function GetIPFromHost(var HostName, IPaddr, WSAErr: string): Boolean;
type
  Name = array [0 .. 100] of AnsiChar;
  PName = ^Name;
var
  HEnt: pHostEnt;
  HName: PName;
  WSAData: TWSAData;
  i: Integer;
begin
  Result := False;
  if WSAStartup($0101, WSAData) <> 0 then
  begin
    WSAErr := 'در اتصال به شبکه مشکل به وجود آماده است"';
    Exit;
  end;
  IPaddr := '';
  New(HName);
  if GetHostName(HName^, SizeOf(Name)) = 0 then
  begin
    HostName := StrPas(HName^);
    HEnt := GetHostByName(HName^);
    for i := 0 to HEnt^.h_length - 1 do
      IPaddr := Concat(IPaddr, IntToStr(Ord(HEnt^.h_addr_list^[i])) + '.');
    SetLength(IPaddr, Length(IPaddr) - 1);
    Result := True;
  end
  else
  begin
    case WSAGetLastError of
      WSANOTINITIALISED:
        WSAErr := 'WSANotInitialised';
      WSAENETDOWN:
        WSAErr := 'WSAENetDown';
      WSAEINPROGRESS:
        WSAErr := 'WSAEInProgress';
    end;
  end;
  Dispose(HName);
  WSACleanup;
end;
{$R *.dfm}
function CreateNetResourceList(ResourceType: DWord; NetResource: PNetResource;
  out Entries: DWord; out List: PNetResourceArray): Boolean;
var
  EnumHandle: THandle;
  BufSize: DWord;
  Res: DWord;
begin
  Result := False;
  List := Nil;
  Entries := 0;
  if WNetOpenEnum(RESOURCE_GLOBALNET, ResourceType, 0, NetResource, EnumHandle)
    = NO_ERROR then
  begin
    try
      BufSize := $4000; // 16 kByte
      GetMem(List, BufSize);
      try
        repeat
          Entries := DWord(-1);
          FillChar(List^, BufSize, 0);
          Res := WNetEnumResource(EnumHandle, Entries, List, BufSize);
          if Res = ERROR_MORE_DATA then
          begin
            ReAllocMem(List, BufSize);
          end;
        until Res <> ERROR_MORE_DATA;
        Result := Res = NO_ERROR;
        if not Result then
        begin
          FreeMem(List);
          List := Nil;
          Entries := 0;
        end;
      except
        FreeMem(List);
        raise;
      end;
    finally
      WNetCloseEnum(EnumHandle);
    end;
  end;
end;
procedure ScanNetworkResources(ResourceType, DisplayType: DWord;
  List: TStrings);
  procedure ScanLevel(NetResource: PNetResource);
  var
    Entries: DWord;
    NetResourceList: PNetResourceArray;
    i: Integer;
    Host: string;
  begin
    if CreateNetResourceList(ResourceType, NetResource, Entries, NetResourceList)
    then
      try
        Application.ProcessMessages;
        for i := 0 to Integer(Entries) - 1 do
        begin
          if (DisplayType = RESOURCEDISPLAYTYPE_GENERIC) or
            (NetResourceList[i].dwDisplayType = DisplayType) then
          begin
            List.AddObject(NetResourceList[i].lpRemoteName,
              Pointer(NetResourceList[i].dwDisplayType));
          end;
          if (NetResourceList[i].dwUsage and RESOURCEUSAGE_CONTAINER) <> 0 then
            ScanLevel(@NetResourceList[i]);
          Application.ProcessMessages;
        end;
      finally
        FreeMem(NetResourceList);
      end;
  end;
begin
  ScanLevel(Nil);
end;
function GetIPAddress(NetworkName: String): String;
var
  Error: DWord;
  HostEntry: pHostEnt;
  Data: WSAData;
  Address: In_Addr;
begin
  Error := WSAStartup(MakeWord(1, 1), Data);
  if Error = 0 then
  begin
    HostEntry := GetHostByName(PansiChar(AnsiString(NetworkName)));
    Error := GetLastError();
    if Error = 0 then
    begin
      Address := PInAddr(HostEntry^.h_addr_list^)^;
      Result := inet_ntoa(Address);
    end
    else
    begin
      Result := 'Unknown';
    end;
  end
  else
  begin
    Result := 'Error';
  end;
  WSACleanup();
end;
اینم نحوه فراخوانی :
    ScanNetworkResources(RESOURCETYPE_DISK, RESOURCEDISPLAYTYPE_SERVER,
      EdtServerName.Items);
به جای این EdtServerName.Items آبجکت مورد نظرت رو بزار
 
vBulletin® v4.2.5, Copyright ©2000-1404, Jelsoft Enterprises Ltd.