Реализация для изменения текущего пользователя в приложении winforms

#c# #winforms

#c# #winforms

Вопрос:

Я хочу реализовать изменение текущего пользователя в моем приложении. У меня есть следующий код:

 public class Framework
    {
        private MainForm mainForm = null;
        ... // other fields

        public virtual void run()
        {
            if (appInitializer!=null)
            {
                ISecurityManager securityManager = appInitializer.SecurityManager;
                if (securityManager!=null)
                {
                    if (securityManager.DoLogin())
                    {
                        RegisterDefaultActionsGroup();
                        InitializePlugins(appInitializer.Plugins);
                        // Apply rights for user
                        ActionsManager.Inst.ApplySecurity(securityManager, securityManager.CurrentUser);
                        mainForm = new MainForm();
                        mainForm.Text = appInitializer.ApplicationTitle;
                        if (appInitializer.ApplicationIcon != null)
                        {
                            mainForm.Icon = appInitializer.ApplicationIcon;
                        }
                        CorrectFormSizes(mainForm);
                        Context[Constants.MainForm] = mainForm;                     
                        MenuManager.Inst.FillMenu(DefaultGroups.MAIN_MENU, mainForm.MainMenu, ActionClick);
                        if(appInitializer.IsHaveToCreatePanelInfo) PanelInfoManager.Inst.FillInfo(mainForm);
                        if (appInitializer.IsHaveToCreateToolBar)
                        {
                            MenuManager.Inst.FillToolbar(DefaultGroups.MAIN_TOOLBAR, mainForm.MainToolStrip, ActionClick);                            
                        }
                        mainForm.MainToolStrip.Visible = mainForm.MainToolStrip.Items.Count > 0;
                        NotifyPluginsAboutShowing(appInitializer.Plugins);
                        Application.Run(mainForm);
                    }                   
                }
            }
        }

        ...//other methods
    }   

static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);

            Framework framework = new Framework(new EArchiveInitializer());
            framework.run();                
            }           
        }
  

В кнопке для изменения пользователя у меня есть:

  Framework.Instance.MainForm.MainMenuStrip.Items.Clear();   
 Framework.Instance.run();
  

Но я получил ошибку: Starting a second message loop on a single thread is not a valid operation. Use Form.ShowDialog instead.
Я знаю, что это означает эту ошибку, но я не могу переписать свой код. Можете ли вы мне помочь?
Спасибо.

РЕШЕНИЕ: перепишите последнюю строку в run методе:

  if (!Application.MessageLoop)
     Application.Run(mainForm);
  else
     mainForm.Show();
  

Спасибо, Джонатан.

Комментарии:

1. Можете ли вы запустить другую копию программы ( Process.Start ) и уничтожить текущую копию? Если вы хотите избежать переписывания всего своего кода для поддержки нескольких пользователей, это может быть самый простой способ сделать это.

2. запуск второго экземпляра в другом потоке может помочь

3. @Merlyn Morgan-Graham: Нет, потому что приложение запускается примерно через 10-15 секунд.

Ответ №1:

Проблема на самом деле довольно проста, проблема в том, что вы вызываете приложение.Запустите дважды (первый при загрузке, второй при нажатии кнопки)

Быстрым решением для этого было бы иметь приложение.Сначала запустите ApplicationContext вместо формы и из вашего общедоступного метода virtual void run() загрузите требуемую форму.

 public class Framework 
{ 
    private MainForm mainForm = null; 
    ... // other fields 

    public virtual void run() 
    { 
        if (appInitializer!=null) 
        { 
            ISecurityManager securityManager = appInitializer.SecurityManager; 
            if (securityManager!=null) 
            { 
                if (securityManager.DoLogin()) 
                { 
                    RegisterDefaultActionsGroup(); 
                    InitializePlugins(appInitializer.Plugins); 
                    // Apply rights for user 
                    ActionsManager.Inst.ApplySecurity(securityManager, securityManager.CurrentUser); 
                    mainForm = new MainForm(); 
                    mainForm.Text = appInitializer.ApplicationTitle; 
                    if (appInitializer.ApplicationIcon != null) 
                    { 
                        mainForm.Icon = appInitializer.ApplicationIcon; 
                    } 
                    CorrectFormSizes(mainForm); 
                    Context[Constants.MainForm] = mainForm;                      
                    MenuManager.Inst.FillMenu(DefaultGroups.MAIN_MENU, mainForm.MainMenu, ActionClick); 
                    if(appInitializer.IsHaveToCreatePanelInfo) PanelInfoManager.Inst.FillInfo(mainForm); 
                    if (appInitializer.IsHaveToCreateToolBar) 
                    { 
                        MenuManager.Inst.FillToolbar(DefaultGroups.MAIN_TOOLBAR, mainForm.MainToolStrip, ActionClick);                             
                    } 
                    mainForm.MainToolStrip.Visible = mainForm.MainToolStrip.Items.Count > 0; 
                    NotifyPluginsAboutShowing(appInitializer.Plugins); 
                    mainForm.Show(); 
                }                    
            } 
        } 
    } 

    ...//other methods 
}    

static class Program 
{ 
    /// <summary> 
    /// The main entry point for the application. 
    /// </summary> 
    [STAThread] 
    static void Main() 
    { 
        Application.EnableVisualStyles(); 
        Application.SetCompatibleTextRenderingDefault(false); 

        Application.Run(new MyHiddenContext());     
        }            
    } 
public class MyHiddenContext 
    :  ApplicationContext 
{
    private static Form activeFormInstance;
    public MyHiddenContext()
    {
        this.RunFramework();
    }
    public void RunFramework()
    {
        Framework framework = new Framework(new EArchiveInitializer()); 
        this.framework.run();
        activeFormInstance = Framework.Instance.MainForm;
    }
    public static void ChangeUser()
    {
        activeFormInstance.Close();
        activeFormInstance.Dispose();
        Framework.Instance.MainForm.MainMenuStrip.Items.Clear();              
        Framework.Instance.run();           
    }
}
  

Не цитируйте меня о том, что код действительно работает, но это больше для того, чтобы дать представление о том, в какую сторону идти. Проблема в том, что вы не можете вызвать приложение.Запуск более одного раза, поэтому принципал должен иметь содержащий экземпляр или контекст (в любом таком смысле, форме, консоли и т. Д.)

Комментарии:

1. Большое спасибо. Я добавил решение, о котором идет речь.