سؤال

أنا أعمل على برنامج نصي يعمل تحت أداة تثبيت مخصصة، والتي تعمل كخدمة. للحصول على اسم المستخدم الحالي ينفذ البرنامج النصي هذا الأمر:

str_Acct_Name_Val = "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Logon User Name"
str_Acct_Name = RegRead(str_Acct_Name_Val)

عندما أقوم بتشغيل البرنامج النصي من موجه الأوامر، يمكنه قراءة هذه القيمة بشكل جيد فقط (ضمن حساب المسؤول). عند محاولة قراءة القيمة مع امتيازات الخدمة / الخدمات المحلية، فشل القراءة.

ماهي المشكلة هنا؟

تحرير: بعض المعلومات الإضافية. عند تشغيل كخدمة تدعو إلى إرجاع اسم المستخدم الحالي "النظام"، تخميني هو أن HKCU لا "موجود" ضمن رأي النظام، حيث يوجد مستخدم حاليا من الناحية الفنية. يوجد مستخدم تسجيل الدخول في ذلك الوقت، ولكن ليس في نطاق البرنامج النصي قيد التشغيل. ربما هناك مكان ما في HKLM، يمكنني العثور على مستخدم تسجيل الدخول حاليا؟

هل كانت مفيدة؟

المحلول

إذا كنت مصمما على الحصول على معلومات من السجل، فسيتعين عليك مسح المفاتيح تحت HKEY_USERS (باستثناء .إفتراضي و *_الطبقات) لمعرفة المستخدمين الذين يتم تحميل ملفاتهم الشخصية ومن ثم تسجيل الدخول. هذا هو كيف sysinternals psloggedon. أداة تعمل، بالمناسبة؛ يمكنك إلقاء نظرة على شفرة المصدر (Archive.org لديه ذلك) للحصول على الفكرة.

بدلا من ذلك، إذا كنت تستطيع استخدام WMI، يمكنك الحصول على قائمة المستخدمين المسجلين من خلال تعداد Win32_LogonSession حالات الطبقة واسترداد المرتبطة Win32_Account أشياء؛ شيء من هذا القبيل:

strComputer = "."

Set oWMI = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2") 

Set colSessions = oWMI.ExecQuery _ 
    ("SELECT * FROM Win32_LogonSession WHERE LogonType = 2")  ' Interactive sessions only

For Each oSession in colSessions 
  Set colAccounts = oWMI.ExecQuery("ASSOCIATORS OF {Win32_LogonSession.LogonId=" & oSession.LogonId & "} " _ 
    & "WHERE AssocClass=Win32_LoggedOnUser Role=Dependent" ) 
  For Each oAccount in colAccounts
    WScript.Echo "Caption: " & oAccount.Caption
    WScript.Echo "Domain: "  & oAccount.Domain
    WScript.Echo "Name: "    & oAccount.Name
  Next 
Next

هناك أيضا Win32ComputerSystem.UserName الممتلكات التي تحمل اسم المستخدم الذي سجله على سطح مكتبه نشط حاليا:

strComputer = "." 
Set oWMI = GetObject("winmgmts:\\" & strComputer & "\root\CIMV2") 
Set colItems = oWMI.ExecQuery("SELECT * FROM Win32_ComputerSystem") 
For Each objItem in colItems 
  Wscript.Echo objItem.UserName
Next

نصائح أخرى

HRM، وأتساءل عما إذا كان سيعمل على استخدام الأمر Windows Scripting المضيف للمستخدم الذي قام بتسجيل الدخول حاليا. أعتقد أنه من شأنه أن يعمل حتى لو تم استدعاؤه من حساب الخدمة.

Set WSHNetwork = CreateObject("WScript.Network")    
strUSERID = UCase(WSHNetwork.UserName)

إذا كانت عمليةك تعمل كخدمة، ك "النظام المحلي"، فسيحصل بالفعل على "النظام" كمستخدم الحالي. تعني HKCU في بداية مفتاح التسجيل HKEY_CURRENT_USER، والتي ستكون "النظام".

نظرا لأن Windows يمكن أن يكون لديك مستخدمين متعددين تسجيل الدخول، حتى على إصدارات "مستوى المستهلك" (بفضل تبديل المستخدم السريع)، فلا توجد طريقة موثوقة لتحديد من المستخدم "الحالي"، بقدر ما أعرف. اعتمادا على كيفية استدعاء خدمة المثبت، يمكنك تجربة شيء مثل وجود عملية يتم تشغيله عند بدء التشغيل لكل مستخدم (أي في برامج بدء التشغيل في قائمة "ابدأ") التي تسجل مع الخدمة لمعرفة ذلك ما يسميه اسم تسجيل الدخول حاليا المستخدم هو. ربما يمكن أن تتواصل هذه العملية أيضا إلى الخدمة عند تشغيل المستخدم بسرعة، لذلك يمكنه أيضا التعامل مع الحالة حيث يتم تسجيل أكثر من مستخدم واحد على الجهاز.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top