.NET 앱에서 URI 프로토콜 활성화 처리

프로토콜 활성화( 딥 링크 또는 URI 활성화라고도 함)를 사용하면 다른 앱, 브라우저 또는 명령줄에서 URI(예: URI)로 myapp://action?param=value이동하여 앱을 시작할 수 있습니다.

이 문서에서는 특히 WPF 앱에 대한 코드를 보여 줍니다. 전체 지침은 기본 핸들 URI 활성화 문서를 참조하세요. Windows 앱 SDK 풍부한 활성화에 대한 자세한 내용은 앱 수명 주기 API를 사용한 활성화를 참조하세요.

프로토콜 활성화 등록

프로토콜 활성화를 처리하려면 앱을 등록해야 합니다. 패키지되지 않은 앱의 경우 코드에 등록합니다. 패키지된 앱의 경우 앱 매니페스트에 등록합니다.

비 패키지 앱

패키지되지 않은 .NET 앱(기본 WPF/WinForms 설정)의 경우 시작 시 ActivationRegistrationManager 사용하여 프로토콜을 등록합니다. 등록은 사용자별로 유지되므로 모든 시작 시 이를 호출하는 것이 안전합니다.

App.xaml.cs에서 OnStartup 재정의:

using Microsoft.Windows.AppLifecycle;

protected override void OnStartup(StartupEventArgs e)
{
    // Register the URI scheme "myapp://" for this app.
    // For the logo, pass the exe path + resource index (or "" to use the default icon).
    string exePath = System.Diagnostics.Process.GetCurrentProcess().MainModule?.FileName ?? "";
    string logo = string.IsNullOrEmpty(exePath) ? "" : exePath + ",0";
    ActivationRegistrationManager.RegisterForProtocolActivation(
        "myapp",                // URI scheme (no "://")
        logo,                   // logo: exe path + resource index, or "" for default icon
        "My App",               // display name for the protocol
        exePath);               // path of this EXE; pass "" to default to the current process

    base.OnStartup(e);
}

등록을 정리하려면 (예를 들어, 제거 단계에서는) ActivationRegistrationManager.UnregisterForProtocolActivation("myapp", "")을 호출하십시오.

패키지에 포함된 앱

패키지된 .NET 앱의 경우 Package.appxmanifest 요소 아래에 <Applications><Application> 프로토콜을 선언합니다.

<Applications>
  <Application ...>
    <Extensions>
      <uap:Extension Category="windows.protocol">
        <uap:Protocol Name="myapp">
          <uap:DisplayName>My App</uap:DisplayName>
        </uap:Protocol>
      </uap:Extension>
    </Extensions>
  </Application>
</Applications>

uap XML 네임스페이스가 Package 요소에 선언되었는지 확인하십시오 xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10".

활성화 처리

AppInstance.GetCurrent()를 사용하여 활성화 인수를 검색합니다. GetActivatedEventArgs. 다음 예제에는 시작 시 RegisterForProtocolActivation 호출하는 패키지되지 않은 WPF 앱에 대한 코드가 포함되어 있습니다. 패키지된 앱은 매니페스트 등록을 통해 활성화를 수신하므로 호출을 RegisterForProtocolActivation 건너뛸 수 있습니다.

using Microsoft.Windows.AppLifecycle;
using Windows.ApplicationModel.Activation;

protected override void OnStartup(StartupEventArgs e)
{
    // Unpackaged apps only: register the protocol at startup.
    // Packaged apps (MSIX): skip these lines — the manifest handles registration.
    string exePath = System.Diagnostics.Process.GetCurrentProcess().MainModule?.FileName ?? "";
    string logo = string.IsNullOrEmpty(exePath) ? "" : exePath + ",0";
    ActivationRegistrationManager.RegisterForProtocolActivation(
        "myapp", logo, "My App", exePath);

    // Get the activation args for this specific launch.
    AppActivationArguments args = AppInstance.GetCurrent().GetActivatedEventArgs();
    if (args?.Kind == ExtendedActivationKind.Protocol)
    {
        var protocolArgs = (ProtocolActivatedEventArgs)args.Data;
        HandleProtocolActivation(protocolArgs.Uri);
    }

    base.OnStartup(e);
}

private void HandleProtocolActivation(Uri uri)
{
    // Navigate to or open content based on uri.AbsolutePath or uri.Query.
}

메모

WPF 및 Windows Forms 앱은 URI 활성화 데이터를 검색하려면 반드시 AppInstance.GetCurrent().GetActivatedEventArgs()을 호출해야 합니다. C++ Win32 앱과 달리 .NET 앱은 시작 진입점 매개 변수를 통해 활성화 인수를 수신하지 않습니다.

단일 인스턴스 리디렉션 처리

앱이 한 번에 하나의 인스턴스만 실행해야 하는 경우 후속 URI 실행을 실행 중인 인스턴스로 리디렉션하는 데 사용합니다 AppInstance.FindOrRegisterForKey .

protected override void OnStartup(StartupEventArgs e)
{
    string exePath = System.Diagnostics.Process.GetCurrentProcess().MainModule?.FileName ?? "";
    string logo = string.IsNullOrEmpty(exePath) ? "" : exePath + ",0";
    ActivationRegistrationManager.RegisterForProtocolActivation(
        "myapp", logo, "My App", exePath);

    // Try to claim the "main" key. If another instance already has it, redirect and exit.
    AppInstance currentInstance = AppInstance.FindOrRegisterForKey("main");
    if (!currentInstance.IsCurrent)
    {
        var activationArgs = AppInstance.GetCurrent().GetActivatedEventArgs();
        // Run the async redirect on a thread-pool thread to avoid a potential deadlock
        // with the WPF SynchronizationContext. Signal completion via an event so that
        // this code path exits cleanly without re-entering the STA message pump.
        var redirectCompleted = new System.Threading.ManualResetEventSlim(false);
        System.Threading.Tasks.Task.Run(async () =>
        {
            await currentInstance.RedirectActivationToAsync(activationArgs);
            redirectCompleted.Set();
        });
        redirectCompleted.Wait();
        Shutdown();
        return;
    }

    // This is the first instance. Subscribe to future activations.
    currentInstance.Activated += OnActivated;
    base.OnStartup(e);
}

private void OnActivated(object sender, AppActivationArguments args)
{
    Dispatcher.Invoke(() =>
    {
        if (args.Kind == ExtendedActivationKind.Protocol)
        {
            var protocolArgs = (ProtocolActivatedEventArgs)args.Data;
            HandleProtocolActivation(protocolArgs.Uri);
        }
        MainWindow?.Activate();
    });
}

앱 인스턴스화에 대한 자세한 내용은 앱 수명 주기 API를 사용한 앱 인스턴싱을 참조하세요.