다음을 통해 공유


다중 인스턴스 유니버설 Windows 앱 만들기

이 항목에서는 UWP(다중 인스턴스 유니버설 Windows 플랫폼) 앱을 만드는 방법을 설명합니다.

Windows 10 버전 1803(10.0; 빌드 17134) 이후 UWP 앱은 여러 인스턴스를 지원하도록 옵트인할 수 있습니다. 다중 인스턴스 UWP 앱의 인스턴스가 실행 중이고 후속 정품 인증 요청이 들어오는 경우 플랫폼은 기존 인스턴스를 활성화하지 않습니다. 대신 별도의 프로세스에서 실행되는 새 인스턴스를 만듭니다.

중요하다

다중 인스턴싱은 JavaScript 애플리케이션에 대해 지원되지만 다중 인스턴싱 리디렉션은 지원되지 않습니다. JavaScript 애플리케이션에는 다중 인스턴싱 리디렉션이 지원되지 않으므로 AppInstance 클래스는 이러한 애플리케이션에 유용하지 않습니다.

다중 인스턴스 동작에 옵트인

새 다중 인스턴스 애플리케이션을 만드는 경우, Visual Studio Marketplace에서 사용할 수 있는 다중 인스턴스 앱 프로젝트 템플릿.VSIX을 설치할 수 있습니다. 템플릿을 설치하면 Visual C# > Windows 유니버설 아래의새 프로젝트 대화 상자에서 사용할 수 있습니다(또는 Visual C++ > Windows 유니버설 > 다른 언어).

메모

다중 인스턴스 앱 프로젝트 템플릿을 더 이상 사용할 수 없습니다. VSIX 템플릿은 편리했기 때문에 아래에 설명된 대로 기존 프로젝트를 대신 수정해야 합니다. DISABLE_XAML_GENERATED_MAIN 상수를 프로젝트 빌드 기호에 추가해야 합니다. 이렇게 하면 빌드에서 기본 Main()이 생성되지 않습니다. 이렇게 하면 특별히 작성된 앱별 버전의 Main()을 사용할 수 있습니다.

두 개의 템플릿이 설치됩니다. 다중 인스턴스 앱을 만들기 위한 템플릿을 제공하는 다중 인스턴스 UWP 앱다중 인스턴스 리디렉션 UWP 앱. 새 인스턴스를 시작하거나 이미 시작된 인스턴스를 선택적으로 활성화하기 위해 빌드할 수 있는 추가 논리를 제공합니다. 예를 들어 한 번에 하나의 인스턴스만 동일한 문서를 편집할 수 있도록 새 인스턴스를 시작하는 대신 해당 파일이 열려 있는 인스턴스를 포그라운드로 가져올 수 있습니다.

두 템플릿 모두 package.appxmanifest 파일에 SupportsMultipleInstances 추가합니다. 네임스페이스 접두사 desktop4iot2: 데스크톱을 대상으로 하는 프로젝트 또는 IoT(사물 인터넷) 프로젝트만 다중 인스턴싱을 지원합니다.

<Package
  ...
  xmlns:desktop4="http://schemas.microsoft.com/appx/manifest/desktop/windows10/4"
  xmlns:iot2="http://schemas.microsoft.com/appx/manifest/iot/windows10/2"  
  IgnorableNamespaces="uap mp desktop4 iot2">
  ...
  <Applications>
    <Application Id="App"
      ...
      desktop4:SupportsMultipleInstances="true"
      iot2:SupportsMultipleInstances="true">
      ...
    </Application>
  </Applications>
   ...
</Package>

다중 인스턴스 활성화 리디렉션

UWP 앱에 대한 다중 인스턴싱 지원은 단순히 앱의 여러 인스턴스를 시작할 수 있도록 하는 것 이상입니다. 앱의 새 인스턴스가 시작되었는지 또는 이미 실행 중인 인스턴스가 활성화되었는지를 선택하려는 경우 사용자 지정할 수 있습니다. 예를 들어 다른 인스턴스에서 이미 편집 중인 파일을 편집하기 위해 앱을 시작한 경우 이미 파일을 편집 중인 다른 인스턴스를 여는 대신 활성화를 해당 인스턴스로 리디렉션할 수 있습니다.

작동 중인 내용을 보려면 다중 인스턴스 UWP 앱 만들기에 대한 이 비디오를 시청하세요.

다중 인스턴스 리디렉션 UWP 앱 템플릿은 위와 같이 package.appxmanifest 파일에 SupportsMultipleInstances 추가하고 Main() 함수가 포함된 프로젝트에 Program.cs(또는 템플릿의 C++ 버전을 사용하는 경우 Program.cpp)도 추가합니다. 활성화를 리디렉션하는 논리는 Main 함수에 들어갑니다. Program.cs 템플릿은 다음과 같습니다.

AppInstance.RecommendedInstance 속성은 활성화 요청이 있는 경우 셸에서 제공하는 기본 설정 인스턴스를 나타냅니다(또는 없는 경우 null). 셸에서 기본 설정을 제공하는 경우 활성화를 해당 인스턴스로 리디렉션하거나 선택하는 경우 무시할 수 있습니다.

public static class Program
{
    // This example code shows how you could implement the required Main method to
    // support multi-instance redirection. The minimum requirement is to call
    // Application.Start with a new App object. Beyond that, you may delete the
    // rest of the example code and replace it with your custom code if you wish.

    static void Main(string[] args)
    {
        // First, we'll get our activation event args, which are typically richer
        // than the incoming command-line args. We can use these in our app-defined
        // logic for generating the key for this instance.
        IActivatedEventArgs activatedArgs = AppInstance.GetActivatedEventArgs();

        // If the Windows shell indicates a recommended instance, then
        // the app can choose to redirect this activation to that instance instead.
        if (AppInstance.RecommendedInstance != null)
        {
            AppInstance.RecommendedInstance.RedirectActivationTo();
        }
        else
        {
            // Define a key for this instance, based on some app-specific logic.
            // If the key is always unique, then the app will never redirect.
            // If the key is always non-unique, then the app will always redirect
            // to the first instance. In practice, the app should produce a key
            // that is sometimes unique and sometimes not, depending on its own needs.
            string key = Guid.NewGuid().ToString(); // always unique.
                                                    //string key = "Some-App-Defined-Key"; // never unique.
            var instance = AppInstance.FindOrRegisterInstanceForKey(key);
            if (instance.IsCurrentInstance)
            {
                // If we successfully registered this instance, we can now just
                // go ahead and do normal XAML initialization.
                global::Windows.UI.Xaml.Application.Start((p) => new App());
            }
            else
            {
                // Some other instance has registered for this key, so we'll 
                // redirect this activation to that instance instead.
                instance.RedirectActivationTo();
            }
        }
    }
}

Main() 가장 먼저 실행됩니다. OnLaunchedOnActivated전에 실행됩니다. 이렇게 하면 앱의 다른 초기화 코드가 실행되기 전에 이 인스턴스 또는 다른 인스턴스를 활성화할지 여부를 결정할 수 있습니다.

위의 코드는 애플리케이션의 기존 인스턴스 또는 새 인스턴스가 활성화되는지 여부를 결정합니다. 키를 사용하여 활성화하려는 기존 인스턴스가 있는지 여부를 확인합니다. 예를 들어, 앱이 파일 활성화 기능(처리)을 지원하는 경우, 파일 이름을 키로 사용할 수 있습니다. 그런 다음 앱 인스턴스가 해당 키에 이미 등록되어 있는지 확인하고 새 인스턴스를 여는 대신 활성화할 수 있습니다. 코드 뒤에 있는 아이디어입니다. var instance = AppInstance.FindOrRegisterInstanceForKey(key);

키에 등록된 인스턴스가 발견되면 해당 인스턴스가 활성화됩니다. 키를 찾을 수 없으면 현재 인스턴스(Main실행 중인 인스턴스)가 해당 애플리케이션 개체를 만들고 실행을 시작합니다.

백그라운드 작업 및 다중 인스턴싱

  • 프로세스 외부 백그라운드 작업은 여러 인스턴스를 지원합니다. 일반적으로 각 새 트리거는 백그라운드 작업의 새 인스턴스를 생성합니다(기술적으로 여러 백그라운드 작업을 말하는 경우 동일한 호스트 프로세스에서 실행할 수 있음). 그럼에도 불구하고 백그라운드 작업의 다른 인스턴스가 만들어집니다.
  • In-proc 백그라운드 작업은 다중 인스턴싱을 지원하지 않습니다.
  • 백그라운드 오디오 작업은 다중 인스턴싱을 지원하지 않습니다.
  • 앱이 백그라운드 작업을 등록하는 경우 일반적으로 먼저 작업이 이미 등록되어 있는지 확인한 다음 삭제하고 다시 등록하거나 기존 등록을 유지하기 위해 아무 작업도 수행하지 않습니다. 이는 다중 인스턴스 앱의 일반적인 동작입니다. 그러나 다중 인스턴싱 앱은 인스턴스별로 다른 백그라운드 작업 이름을 등록하도록 선택할 수 있습니다. 이렇게 하면 동일한 트리거에 대한 여러 등록이 생성되고 트리거가 실행될 때 여러 백그라운드 작업 인스턴스가 활성화됩니다.
  • App-Services는 모든 연결에 대해 앱 서비스 백그라운드 작업의 별도 인스턴스를 시작합니다. 다중 인스턴스 앱의 경우 변경되지 않습니다. 즉, 다중 인스턴스 앱의 각 인스턴스는 앱 서비스 백그라운드 작업의 자체 인스턴스를 가져옵니다.

추가 고려 사항

  • 다중 인스턴싱은 데스크톱 및 IoT(사물 인터넷) 프로젝트를 대상으로 하는 UWP 앱에서 지원됩니다.
  • 경합 조건 및 경합 문제를 방지하려면 다중 인스턴스 앱이 여러 인스턴스 간에 공유할 수 있는 설정, 앱 로컬 스토리지 및 기타 리소스(예: 사용자 파일, 데이터 저장소 등)에 대한 액세스를 분할/동기화하는 단계를 수행해야 합니다. 뮤텍스, 세마포, 이벤트 등과 같은 표준 동기화 메커니즘을 사용할 수 있습니다.
  • 앱의 Package.appxmanifest 파일에 SupportsMultipleInstances이 포함되어 있는 경우, 확장명은 SupportsMultipleInstances을 선언할 필요가 없습니다.
  • 백그라운드 작업 또는 앱 서비스를 제외한 다른 확장에 SupportsMultipleInstances 추가하고 확장을 호스트하는 앱이 Package.appxmanifest 파일에서 SupportsMultipleInstances 선언하지 않으면 스키마 오류가 생성됩니다.
  • 앱은 매니페스트에서 ResourceGroup 선언을 사용하여 여러 백그라운드 작업을 동일한 호스트로 그룹화할 수 있습니다. 이는 각 활성화가 별도의 호스트로 들어가는 다중 인스턴싱과 충돌합니다. 따라서 앱은 매니페스트에서 SupportsMultipleInstancesResourceGroup 둘 다 선언할 수 없습니다.

견본

다중 인스턴스 활성화 리디렉션의 예는 다중 인스턴스 샘플 참조하세요.

참고

AppInstance.FindOrRegisterInstanceForKeyAppInstance.GetActivatedEventArgsAppInstance.RedirectActivationTo앱 활성화 처리