Как реализовать один экземпляр на приложение машины?

StackOverflow https://stackoverflow.com/questions/4223061

Вопрос

Я должен ограничить мое приложение .NET 4 WPF, чтобы его можно было запускать только один раз на машину. Обратите внимание, что я сказал на машину, а не на сессию.
Я реализовал приложения одного экземпляра, используя простую мьютекс до сих пор, но, к сожалению, такая MUTEX является за сеанс.

Есть ли способ создать машину широкую Mutex или есть ли какое-либо другое решение для реализации одного экземпляра на приложение машины?

Это было полезно?

Решение

Я бы сделал это с глобальным объектом Mutex, который должен храниться для жизни вашего приложения.

MutexSecurity oMutexSecurity;

//Set the security object
oMutexSecurity = new MutexSecurity();
oMutexSecurity.AddAccessRule(new MutexAccessRule(new SecurityIdentifier(WellKnownSidType.BuiltinUsersSid, null), MutexRights.FullControl, AccessControlType.Allow));

//Create the global mutex and set its security
moGlobalMutex = new Mutex(True, "Global\\{5076d41c-a40a-4f4d-9eed-bf274a5bedcb}", bFirstInstance);
moGlobalMutex.SetAccessControl(oMutexSecurity);

Где bFirstInstance Возвращает, если это первый экземпляр вашего приложения, работающего по всему миру. Если вы пропустите глобальную часть Mutex или заменили ее мелькой, то MUTEX будет только за сеанс (вероятно, как работает ваш текущий код).

Я верю, что я получил эту технику сначала от Джон Скеет.

MSDN-тема на Mutex. Объект объясняет около двух принципов для объекта Mutex и подчеркивает, почему это важно при использовании терминальных служб (см. Второе до последней ноты).

Другие советы

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

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

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

Редактировать: Обратите внимание, что я не знаю, если этот подход работает через несколько сеансов Windows на машине. Я думаю, что это должно, как его конструкция уровня ОС, но я не могу сказать наверняка, так как я не тестировал так.

Редактировать 2: Я этого не знал, но после того, как прочитал ответ STEVO2000, я тоже несколько смотрел, и я думаю, что «глобальный » префикс, чтобы сделать объект, применимый к глобальному пространству имен, также применится к семафорам, а также на семафоры и семафоре, Если создано таким образом, следует работать.

Вы можете открыть файл с исключительными правами где-то в% Program DDATA%, второй экземпляр, который запускается, будет пытаться открыть один и тот же файл и сдать неудачу, если он уже открыт.

Как насчет использования реестра?

  1. Вы можете создать registry entry under HKEY_LOCAL_MACHINE.
  2. Пусть значение будет flag Если приложение запущено или нет.
  3. Encrypt the key используя некоторые стандартные symmetric key encryption Способ, так что никто другой не может вмешиваться со значением.
  4. On application start-up check for the key и прервать Продолжить соответственно.
  5. Не забудь obfuscate your assembly, что делает это шифрование дешифрование, так что никто не может взломать ключ в реестре, глядя на код в отражатель.

Я сделал что-то подобное один раз.

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

Это не пуленепробиваемое, конечно, поскольку, поскольку если другое приложение имеет то же самое название одинакового процесса, ваше приложение никогда не запускается, но если вы используете нежененое имя, это, вероятно, будет достаточно более хорошим.

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

Обратите внимание, что я еще не проверил его.

См. Ниже для полного примера того, как выполняется одноместное приложение Instace в WPF 3.5

public class SingleInstanceApplicationWrapper :
Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase
{
public SingleInstanceApplicationWrapper()
{
// Enable single-instance mode.
this.IsSingleInstance = true;
}
// Create the WPF application class.
private WpfApp app;
protected override bool OnStartup(
Microsoft.VisualBasic.ApplicationServices.StartupEventArgs e)
{
app = new WpfApp();
app.Run();
return false;
}
// Direct multiple instances.
protected override void OnStartupNextInstance(
Microsoft.VisualBasic.ApplicationServices.StartupNextInstanceEventArgs e)
{
if (e.CommandLine.Count > 0)
{
app.ShowDocument(e.CommandLine[0]);
}
}
}

Вторая часть:

public class WpfApp : System.Windows.Application
{
protected override void OnStartup(System.Windows.StartupEventArgs e)
{
base.OnStartup(e);
WpfApp.current = this;
// Load the main window.
DocumentList list = new DocumentList();
this.MainWindow = list;
list.Show();
// Load the document that was specified as an argument.
if (e.Args.Length > 0) ShowDocument(e.Args[0]);
}
public void ShowDocument(string filename)
{
try
{
Document doc = new Document();
doc.LoadFile(filename);
doc.Owner = this.MainWindow;
doc.Show();
// If the application is already loaded, it may not be visible.
// This attempts to give focus to the new window.
doc.Activate();
}
catch
{
MessageBox.Show("Could not load document.");
}
}
}

Третья часть:

 public class Startup
    {
    [STAThread]
    public static void Main(string[] args)
    {
    SingleInstanceApplicationWrapper wrapper =
    new SingleInstanceApplicationWrapper();
    wrapper.Run(args);
    }
    }

Возможно, вам понадобится добавить ссылки SOME и добавить некоторые с использованием операторов, но она Shoudl работает.

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

Взятые из «Pro WPF в C # 3 2008, APPR, MATTHEW MACDONALD», купить книгу золота. Я сделал.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top