View Full Version : سوال: آیا راهی برای یافتن نام کامپیوتری که به سرور ریموت شده است وجود دارد؟
soks_sia
سه شنبه 17 بهمن 1396, 16:53 عصر
سلام دوستان عزیز
یه سوال داشتم و میخواستم ببینم میتونید منو راهنمایی کنید. من برنامه ای دارم که اجازه ورود یک کاربر رو دوبار نمیده. برای کنترل این کار وقتی کاربری وارد برنامه شد وضعیتش رو در حال کار میکنم و اینکه از چه کامپیوتری وصل شده. بعد اگر خروج غیر مترقبه داشت یعنی بصورت غیر معمول از برنامه خارج شد که من نتونستم وضعیت خروج براش ثبت کنم، موقع ورود مجدد اگر از همون کامپیوتر وصل شده بود میفهمم خروج غیرعادی داشته و با هشدار اجازه ورود میدم ولی اگه از کامپیوتر دیگه ای بخواد وصل بشه، با هشدار به کاربر احتمالی اولی و درخواست رمز دوم و فرصت دادن 5 دقیقه ای به جمع بندی میرسیدم که اجازه ورود به نفر دوم بدم یا نه یا اینکه کاربر اول رو خارج کنم. تا حالا هم مشکلی نداشتم. مشکل از اون جایی شروع شد که یکی از جاهایی که برنامه منو گرفتن، کلیه کاربرها بصورت ریموت به سرورشون وصل میشن و برنامه رو اجرا میکنن. حالا چون اسم کامپیوتر برای همه کاربرها یکسان میشه یعنی اسم سرور رو میاره، فرقی نمیکنه با چه کلاینتی وصل شدی؛ عملا اینکه دو نفر با یه کد کاربری از دو کامپیوتر رو نمیتونم کنترل کنم.
حالا سوالم اینه چه جوری میتونم اسم کامپیوتر کلاینتهایی که ریموت شدن رو بدست بیارم؟ با جستجوهایی که کردم هم چیز بدردبخوری پیدا نکردم. مثلا تو پی اچ پی یه دستور داره به اسمgethostname
که نوشته بود همچین کاری میکنه میخواستم ببینم دلفی هم همچین چیزی داره یا نه؟
Mask
سه شنبه 17 بهمن 1396, 18:39 عصر
انتظار شما اصلا ربطی به زبان برنامه نویسی نداره. وقتی کاربران از طریق ریموت وارد برنامه ای میشوند , عملا برنامه اون کاربر رو در سیستم جاری میبینه.
برای تفکیک این موضوع شما باید برای هر کاربر که ریموت میزنه به سرور (بماند که این روش اصلا منطقی نیست و من پیشنهاد نمیدهم. روش استفاده از ریموت منسوخ شده و اکثر برنامه ها دارای نسخه کلاینت و سرور هستند) با کاربری تعریف شده این کار رو انجام بدهد. شما با دستورات api براحتی نام کاربریه ویندوزی، فردی که داره وارد برنامه میشه رو بدست میارید و از این طریق بجای ای پی از سمت Username ویندوزی عملیات احراز هویت رو انجام میدهید.
soks_sia
چهارشنبه 18 بهمن 1396, 18:11 عصر
انتظار شما اصلا ربطی به زبان برنامه نویسی نداره. وقتی کاربران از طریق ریموت وارد برنامه ای میشوند , عملا برنامه اون کاربر رو در سیستم جاری میبینه.
برای تفکیک این موضوع شما باید برای هر کاربر که ریموت میزنه به سرور (بماند که این روش اصلا منطقی نیست و من پیشنهاد نمیدهم. روش استفاده از ریموت منسوخ شده و اکثر برنامه ها دارای نسخه کلاینت و سرور هستند) با کاربری تعریف شده این کار رو انجام بدهد. شما با دستورات api براحتی نام کاربریه ویندوزی، فردی که داره وارد برنامه میشه رو بدست میارید و از این طریق بجای ای پی از سمت Username ویندوزی عملیات احراز هویت رو انجام میدهید.
درود و سپاس از توجهتون
از اینکه کاربران بصورت ریموت وصل میشن، باید بگم که من بصورت ضمنی گفتم البته دوستان در آن شرکت از طریق سرورهای مجازی و سیتریکس به سرور مجازی برنامههاشون وصل میشن و در این شرکت هیچ برنامه اطلاعاتی روی کامپیوترهای کاربران که در دفاتر شهرستان و تهران دارند نصب نمیشه و فقط روی سرور اپلیکشنشون نصب میشه و همه از طریق سیتریکس به اون ریموت میشن.
بعد کسانی هم که ریموت میشن من نمیتونم تشخیص بدم که از کجا وصل میشن حالا از طریق سیتریکس یا ریموت وقتی وصل سرور میشن و برنامه رو اجرا میکنن، من فقط اسم سرور اپلیکیشن رو دارم. با دستوراتی هم که میگین کدهایی که اسم کلاینت و یوزر و آی پی رو برمیگردونه همشون مال سرور رو برمیگردونن.
soks_sia
چهارشنبه 18 بهمن 1396, 18:53 عصر
سلام و درود به دوستان عزیز
مشکلم حل شد و راه حل خیلی ساده اون را پیدا کردم.
یعنی خیلی راحت میشه, اسم کامپیوتر و کلاینتی که ازش وصل شدن و حتی یوزری که این کارو کرده رو پیدا کرد.
خیلی راحت با Environment variable ها میتونین اونها را ببینین چیه.
COMPUTERNAME برای اسم کامپیوتر و
CLIENTNAME برای اسم کامپیوتری که ازش ریموت شدن.
با تابع GetEnvironmentVariable میتونین مقدار این متغییرها رو به صورت متنی بدست بیارین.
برای دیدن سایر متغییرهایی که میتونید استفاده کنید از دستور cmd در run استفاده کنید و بعد دستور set رو اجرا کنین. سایر متغییرها و مقادیرشون رو بهتون نشون میده
بای تیل های
PayamKazemi
دوشنبه 07 اسفند 1396, 17: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.