現在、私の仕事をしている会社のヘルプデスクを作成しています。それが提供する多くの機能の1つは、ユーザーがアカウントをロック(win + l)したとき、ログオフしたとき、またはユーザーがログインする前に「常に利用可能」であるGUIを使用してWindowsパスワードを簡単にリセットする方法です(Windowsがログオン画面を起動した直後)。C#ロック画面から「ユーザー切り替え」を選択した場合、GUI起動サービスが動作しません
ほとんどの機能は、ISenseLogonインターフェイスとLogonLauncher Open Source projectから入手したコードのおかげで期待どおりに機能します。 GUIは、ISenseLogonイベント(ログオン、ログオフ、DisplayLock、DisplayUnlock、ShellStart)に登録されたサービスによって起動される簡単なWindowsフォームです。
私が直面している問題は以下の通りです:アカウントた後を継続するために削除+ はにロックされ、他のユーザーがロック画面上ユーザーの切り替えボタンを押すと、GUIが閉じられ、プレスCTRL + ALTプロンプトが表示されますが、GUIは再開しません。
コードは他の状況(起動、ログオフ、ロックされた表示はすべてGUIを生成する)で動作するため、他のイベントによってGUIが終了することがあります(プログラム上、ログオンしたユーザーによってのみ殺されます。ディスプレイまたはサービスのシャットダウン)。
サービスクラス:
public partial class Service1:ServiceBase {
private const string LpDesktop = @"WinSta0\Winlogon";
private const string appName = "C:\\LoginAgent.exe";
public Service1() {
InitializeComponent();
Environment.CurrentDirectory = AppDomain.CurrentDomain.BaseDirectory;
SensLogon.DisplayLock += SensLogon_DisplayLock;
SensLogon.DisplayUnlock += SensLogon_DisplayUnlock;
SensLogon.Logon += SensLogon_Logon;
SensLogon.Logoff += SensLogon_Logoff;
SensLogon.ShellStart += SensLogon_ShellStart;
}
#region Cases
protected override void OnStart(string[] args) {
var processEventThread = new Thread(ProcessSensEvent);
processEventThread.Start("ServiceStart");
}
private void SensLogon_Logoff(string userName) {
var processEventThread = new Thread(ProcessSensEvent);
processEventThread.Start("Logoff");
}
private void SensLogon_Logon(string userName) {
var processEventThread = new Thread(ProcessSensEvent);
processEventThread.Start("Logon");
}
private void SensLogon_DisplayUnlock(string userName) {
var processEventThread = new Thread(ProcessSensEvent);
processEventThread.Start("DisplayUnlock");
}
private void SensLogon_DisplayLock(string userName) {
var processEventThread = new Thread(ProcessSensEvent);
processEventThread.Start("DisplayLock");
}
protected void SensLogon_ShellStart(string userName) {
var processEventThread = new Thread(ProcessSensEvent);
processEventThread.Start("ShellStart");
}
protected override void OnStop() {
var processEventThread = new Thread(ProcessSensEvent);
processEventThread.Start("ServiceStop");
}
#endregion
//Starts instance of the InjectProcess class, which starts or kills the LoginAgent process.
private void ProcessSensEvent(object e) {
var ip = new InjectProcess();
if(e.ToString().Equals("Logoff") || e.ToString().Equals("ServiceStart") || e.ToString().Equals("DisplayLock") || e.ToString().Equals("ShellStart")) {
ip.Inject(LpDesktop, appName);
}
else if(e.ToString().Equals("Logon") || e.ToString().Equals("DisplayUnlock") || e.ToString().Equals("ServiceStop"))
ip.TerminateSystemProcess(appName);
}
}
SensLogon:
class SensLogon {
private static SensLogonInterop _eventCatcher;
static SensLogon() {}
#region Event Registers
private static int _registerCount = 0;
private static bool IsRegistered {
get {
return (_registerCount > 0);
}
}
private static SensLogonEventHandler RegisterEvent(SensLogonEventHandler original, SensLogonEventHandler newDel) {
bool shouldRegister = (original == null);
original = original + newDel;
if(shouldRegister) {
if(_registerCount <= 0) {
if(_eventCatcher == null)
_eventCatcher = new SensLogonInterop();
_registerCount = 1;
}
else
_registerCount++;
}
return original;
}
private static SensLogonEventHandler UnregisterEvent(SensLogonEventHandler original, SensLogonEventHandler oldDel) {
original = original - oldDel;
if(original == null) {
_registerCount--;
if(_registerCount == 0) {
_eventCatcher.Dispose();
_eventCatcher = null;
}
}
return original;
}
#endregion
#region ISensLogon Event creation
public static void OnDisplayLock(string bstrUserName) {
if(displayLock != null)
displayLock(bstrUserName);
}
public static void OnDisplayUnlock(string bstrUserName) {
if(displayUnlock != null)
displayUnlock(bstrUserName);
}
public static void OnLogon(string bstrUserName) {
if(logon != null)
logon(bstrUserName);
}
public static void OnLogoff(string bstrUserName) {
if(logoff != null)
logoff(bstrUserName);
}
public static void OnShellStart(string bstrUserName) {
if(shellStart != null)
OnShellStart(bstrUserName);
}
#endregion
#region Event declarations
private static SensLogonEventHandler displayLock = null;
private static SensLogonEventHandler displayUnlock = null;
private static SensLogonEventHandler logon = null;
private static SensLogonEventHandler logoff = null;
private static SensLogonEventHandler shellStart = null;
public static event SensLogonEventHandler DisplayLock {
add {
displayLock = RegisterEvent(displayLock, value);
}
remove {
displayLock = UnregisterEvent(displayLock, value);
}
}
public static event SensLogonEventHandler DisplayUnlock {
add {
displayUnlock = RegisterEvent(displayUnlock, value);
}
remove {
displayUnlock = UnregisterEvent(displayUnlock, value);
}
}
public static event SensLogonEventHandler Logon {
add {
logon = RegisterEvent(logon, value);
}
remove {
logon = UnregisterEvent(logon, value);
}
}
public static event SensLogonEventHandler Logoff {
add {
logoff = RegisterEvent(logoff, value);
}
remove {
logoff = UnregisterEvent(logoff, value);
}
}
public static event SensLogonEventHandler ShellStart {
add {
shellStart = RegisterEvent(logoff, value);
}
remove {
shellStart = UnregisterEvent(logoff, value);
}
}
#endregion
}
私は閉じてからGUIを防ぐ、またはユーザーの切り替えボタンがクリックされた後、それを再度開くことができますどのように任意のアイデア?
さらにコードが必要な場合(EventSystemRegistrar、SensLogonInteropクラス)、私は喜んでそれを添付しますが、すべてがスイッチのユーザーのケースに対応しているので、必要と思われます。 乾杯;長いポストに申し訳ありませんが、問題は私のリーグから多少外れています!
誰かがこのことについてマイクロソフトが「望ましくない」、または潜在的なセキュリティ上のリスクを冒さないようにする前に、私はこれを感謝しています。ブロックされたユーザーの一時パスワードを割り当てる技術サポート以外にも、パスワードリセットをすぐに利用できる唯一の方法です。 – Praetorian