C#: перечислите все классы в блоке

Вот очень хорошее статья относительно Взаимоисключающего решения. Подход, описанный статьей, выгоден по двум причинам.

Первый, это не требует зависимости от Microsoft. Блок VisualBasic. Если бы мой проект уже имел зависимость от того блока, то я, вероятно, рекомендовал бы использовать подход показанный в другом ответе . Но как это, я не использую Microsoft. Блок VisualBasic, и я не добавил бы ненужную зависимость к своему проекту.

1126-секундный, статья показывает, как принести существующий экземпляр приложения к переднему плану, когда пользователь пытается запустить другой экземпляр. Это - очень приятная черта, к которой здесь не обращаются другие Взаимоисключающие решения, описанные.

ОБНОВЛЕНИЕ

С 01.08.2014, статья, которую я связал с вышеупомянутым, все еще активна, но блог не был обновлен в некоторое время. Это заставляет меня волноваться, что в конечном счете это могло бы исчезнуть, и с ним, защищенное решение. Я воспроизвожу содержание статьи здесь для потомства. Слова принадлежат только владельцу блога в Исправность Бесплатное Кодирование .

Сегодня я хотел осуществить рефакторинг некоторый код, который мешал моему приложению выполнять несколько экземпляров себя.

Ранее у меня было использование Система. Диагностика. Процесс для поиска экземпляра моего myapp.exe в списке процессов. В то время как это работает, это навлекает много издержек, и я хотел что-то инструмент для очистки.

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

В классе моего приложения, основного, я создал помехи, именованные Взаимное исключение :

static class Program
{
    static Mutex mutex = new Mutex(true, "{8F6F0AC4-B9A1-45fd-A8CF-72F04E6BDE8F}");
    [STAThread]
    ...
}

Наличие именованного взаимного исключения позволяет нам складывать синхронизацию через несколько потоков и процессы, который является просто волшебством, которое я ищу.

Взаимное исключение. WaitOne имеет перегрузку, которая указывает количество времени для нас для ожидания. Так как мы на самом деле не желаем к синхронизации нашего кода (более справедливая проверка, если это используется в настоящее время), мы используем перегрузку с двумя параметрами: Взаимное исключение. WaitOne (Тайм-аут промежутка, bool exitContext) . Ожидайте каждый возвращает true, если он может войти, и ложь, если это не было. В этом случае мы не хотим ожидать вообще; Если наше взаимное исключение используется, пропустите его, и движение, таким образом, мы передаем в TimeSpan. Нуль (ожидают 0 миллисекунд), и установил exitContext на истинный, таким образом, мы можем выйти из контекста синхронизации, прежде чем мы попробуем к aquire блокировку на нем. Используя это, мы переносим наше Приложение. Выполненный код в чем-то вроде этого:

static class Program
{
    static Mutex mutex = new Mutex(true, "{8F6F0AC4-B9A1-45fd-A8CF-72F04E6BDE8F}");
    [STAThread]
    static void Main() {
        if(mutex.WaitOne(TimeSpan.Zero, true)) {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
            mutex.ReleaseMutex();
        } else {
            MessageBox.Show("only one instance at a time");
        }
    }
}

Так, если наше приложение работает, WaitOne возвратит false, и мы получим окно сообщения.

Вместо того, чтобы показать окно сообщения, я решил использовать немного Win32, чтобы уведомить мой рабочий экземпляр, что кто-то забыл, что это уже работало (путем приведения себя к вершине всех других окон). Для достижения этого, я использовал постсообщение для широковещательной передачи пользовательского сообщения к каждому окну (пользовательское сообщение было зарегистрировано в [1 113] RegisterWindowMessage моим запущенным приложением, что означает, что только мое приложение знает то, что это), затем мои вторые выходы экземпляра. Экземпляр запущенного приложения получил бы то уведомление и обработал бы его. Чтобы сделать это, я переопределил WndProc в моей основной форме и прислушался к своему пользовательскому уведомлению. Когда я получил то уведомление, я установил свойство TopMost формы на истинный для перевода в рабочее состояние его на вершине.

Вот то, с чем я закончил:

  • Program.cs
static class Program
{
    static Mutex mutex = new Mutex(true, "{8F6F0AC4-B9A1-45fd-A8CF-72F04E6BDE8F}");
    [STAThread]
    static void Main() {
        if(mutex.WaitOne(TimeSpan.Zero, true)) {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
            mutex.ReleaseMutex();
        } else {
            // send our Win32 message to make the currently running instance
            // jump on top of all the other windows
            NativeMethods.PostMessage(
                (IntPtr)NativeMethods.HWND_BROADCAST,
                NativeMethods.WM_SHOWME,
                IntPtr.Zero,
                IntPtr.Zero);
        }
    }
}
  • NativeMethods.cs
// this class just wraps some Win32 stuff that we're going to use
internal class NativeMethods
{
    public const int HWND_BROADCAST = 0xffff;
    public static readonly int WM_SHOWME = RegisterWindowMessage("WM_SHOWME");
    [DllImport("user32")]
    public static extern bool PostMessage(IntPtr hwnd, int msg, IntPtr wparam, IntPtr lparam);
    [DllImport("user32")]
    public static extern int RegisterWindowMessage(string message);
}
  • Fo rm1.cs (неравнодушная передняя сторона)
public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }
    protected override void WndProc(ref Message m)
    {
        if(m.Msg == NativeMethods.WM_SHOWME) {
            ShowMe();
        }
        base.WndProc(ref m);
    }
    private void ShowMe()
    {
        if(WindowState == FormWindowState.Minimized) {
            WindowState = FormWindowState.Normal;
        }
        // get our current "TopMost" value (ours will always be false though)
        bool top = TopMost;
        // make our form jump to the top of everything
        TopMost = true;
        // set it back to whatever it was
        TopMost = top;
    }
}

98
задан Alex 22 August 2009 в 09:59
поделиться

2 ответа

Используйте Assembly.GetTypes . Например:

Assembly mscorlib = typeof(string).Assembly;
foreach (Type type in mscorlib.GetTypes())
{
    Console.WriteLine(type.FullName);
}
142
ответ дан 24 November 2019 в 05:12
поделиться

Я просто хотел бы добавить к примеру Джона. Чтобы получить ссылку на вашу собственную сборку, вы можете использовать:

Assembly myAssembly = Assembly.GetExecutingAssembly();

System.Reflection пространство имен.

Если вы хотите проверить сборку, на которую у вас нет ссылки, вы можете использовать любое из этих:

Assembly assembly = Assembly.ReflectionOnlyLoad(fullAssemblyName);
Assembly assembly = Assembly.ReflectionOnlyLoadFrom(fileName);

Если вы собираетесь создать экземпляр своего типа после того, как найдете его:

Assembly assembly = Assembly.Load(fullAssemblyName);
Assembly assembly = Assembly.LoadFrom(fileName);

См. Дополнительную информацию в документации класса сборки .

Если у вас есть ссылка на сборку объект, вы можете использовать assembly.GetTypes () , как уже продемонстрировал Джон.

97
ответ дан 24 November 2019 в 05:12
поделиться
Другие вопросы по тегам:

Похожие вопросы: