다음을 통해 공유


Windows Share와 패키징되지 않은 앱 통합

이 문서에서는 패키징되지 않은 앱을 Windows Share 기능과 통합하는 방법을 설명합니다. Share 기능을 사용하면 사용자가 한 Windows 앱에서 다른 앱으로 콘텐츠를 공유할 수 있습니다. 패키징되지 않은 앱은 공유 대상으로 등록할 수 있도록 패키지 ID를 제공해야 합니다. 등록되면 앱은 공유 파일을 수신하고 처리할 수 있습니다.

패키징되지 않은 앱을 공유 대상으로 온보딩하는 방법:

  • 패키지 ID를 앱에 제공
  • Share 계약 구현

패키지 ID를 사용하여 패키징되지 않은 앱 제공

앱은 다음 두 가지 방법으로 패키지 ID를 가져올 수 있습니다.

  • 새 MSIX 설치 패키지 만들기(선호 방법) 또는
  • 외부 위치로 패키징된 앱을 현재 설치 관리자와 호환되도록 하기 기존 설치 관리자가 있고 MSIX 설치로 전환할 수 없는 앱에만 권장됩니다.

새 MSIX 설치 패키지 만들기

Visual Studio에서 Windows 애플리케이션 패키징 프로젝트 템플릿을 사용하여 MSIX로 앱을 패키징하는 것이 좋습니다. 여기에는 MSIX 패키지의 모든 이진 파일이 포함되며 문제가 없고 신뢰할 수 있는 설치 환경을 제공합니다.

데스크톱 앱을 패키징하기 전에 주의해야 할 사항: 데스크톱 애플리케이션(MSIX) 패키지 준비

Visual Studio에서 MSIX 패키징용 데스크톱 애플리케이션 설정의 단계에 따라 기존 앱의 프로젝트를 위한 패키지를 생성합니다.

참고 항목

패키징 프로젝트를 만들 때 Windows 10 버전 2004(10.0; 빌드 19041) 이상을 최소 버전으로 사용합니다.

완료되면 Visual Studio에서 데스크톱 또는 UWP 앱 패키지에 따라 패키지를 만듭니다.

외부 위치 패키징을 현재 설치 관리자와 호환되도록 하기

앱 패키지 ID를 제공하는 두 번째 방법은 외부 위치가 있는 패키지를 애플리케이션에 추가하고 기존 설치 관리자에 등록하는 것입니다. 외부 위치가 있는 패키지는 ID, 공유 대상 등록 및 시각적 자산이 있는 .appxmanifest가 포함된 빈 MSIX 패키지입니다. 앱의 이진 파일은 여전히 앱의 기존 설치 관리자가 관리합니다. 패키지를 등록할 때 API에서 앱의 설치 위치를 제공해야 합니다. MSIX 패키지 매니페스트 및 Win32 앱 매니페스트의 ID를 앱 서명에 사용되는 인증서와 동기화된 상태로 유지하는 것이 중요합니다.

패키징되지 않은 앱에 패키지 ID를 부여하는 단계

외부 위치로 패키지를 만드는 방법에 대한 설명서는 사용할 템플릿에 대한 정보를 포함하여 여기에서 사용할 수 있습니다. 외부 위치로 패키징하여 패키지 ID 부여.

전체 샘플 앱은 GitHub: SparsePackages(외부 위치로 패키지됨)에서 사용할 수 있습니다.

공유 대상으로 등록

앱에 패키지 ID가 있으면 다음 단계는 Share 계약을 구현하는 것입니다. Share 계약을 사용하면 앱이 다른 앱에서 데이터를 받을 수 있습니다.

패키징된 앱이 공유 시트와 통합될 수 있도록 설명서의 공유 대상으로 등록 섹션에서 동일한 단계를 수행할 수 있습니다.

샘플 PhotoStore 앱 연습

패키지 ID, 패키징되지 않은 Win32 애플리케이션에 대한 등록 & 공유 활성화에 대한 이 연습에서는 외부 위치가 있는 패키지를 만들어 패키지가 없는 Win32 애플리케이션에 패키지 ID를 부여하는 방법을 알아봅니다. 앱에 패키지 ID가 있으면 활성화를 공유 대상으로 등록하고 처리할 수 있습니다. PhotoStoreDemo 샘플을 사용하여 다음 단계를 수행합니다.

  • AppxManifest.xml 파일을 생성합니다.
  • 패키지 만들기
  • 패키지 서명
  • 패키지를 등록합니다.
  • 앱 활성화 처리

먼저 필요한 속성(예: <AllowExternalContent>, ID, 기능 & 공유 대상 확장성)을 포함하는 AppxManifest.xml 파일을 만듭니다. AppxManifest.xml 파일의 Publisher PackageName & ApplicationId 값이 PhotoStoreDemo.exe.manifest 파일의 값과 일치하는지 확인합니다. 또한 Publisher 값은 패키지에 서명하는 데 사용되는 인증서의 값과 일치해야 합니다. AppxManifest.xml에 필요하고 참조된 시각적 자산을 추가합니다. Visual Studio에서 애플리케이션 패키징 프로젝트에서 package.manifest을(를) 편집할 때 Visual Assets 노드를 사용하여 필요한 시각적 자산을 생성할 수 있습니다.

외부 콘텐츠가 허용되는 샘플 AppxManifest.xml 조각입니다.

<Identity Name="PhotoStoreDemo" ProcessorArchitecture="neutral" Publisher="CN=YourPubNameHere" Version="1.0.0.0" />
  <Properties>
    <DisplayName>PhotoStoreDemo</DisplayName>
    <PublisherDisplayName>Sparse Package</PublisherDisplayName>
    <Logo>Assets\storelogo.png</Logo>
    <uap10:AllowExternalContent>true</uap10:AllowExternalContent>
  </Properties>
  <Resources>
    <Resource Language="en-us" />
  </Resources>
  <Dependencies>
    <TargetDeviceFamily Name="Windows.Desktop" MinVersion="10.0.19041.0" MaxVersionTested="10.0.19041.0" />
  </Dependencies>
  <Capabilities>
    <rescap:Capability Name="runFullTrust" />
    <rescap:Capability Name="unvirtualizedResources"/>
  </Capabilities>
  <Applications>
    <Application Id="PhotoStoreDemo" Executable="PhotoStoreDemo.exe" uap10:TrustLevel="mediumIL" uap10:RuntimeBehavior="win32App">
      <uap:VisualElements AppListEntry="none" DisplayName="PhotoStoreDemo" Description="PhotoStoreDemo" BackgroundColor="transparent" Square150x150Logo="Assets\Square150x150Logo.png" Square44x44Logo="Assets\Square44x44Logo.png">
        <uap:DefaultTile Wide310x150Logo="Assets\Wide310x150Logo.png" Square310x310Logo="Assets\LargeTile.png" Square71x71Logo="Assets\SmallTile.png"></uap:DefaultTile>
        <uap:SplashScreen Image="Assets\SplashScreen.png" />
      </uap:VisualElements>
      <Extensions>
        <uap:Extension Category="windows.shareTarget">
          <uap:ShareTarget Description="Send to PhotoStoreDemo">
            <uap:SupportedFileTypes>
              <uap:FileType>.jpg</uap:FileType>
              <uap:FileType>.png</uap:FileType>
              <uap:FileType>.gif</uap:FileType>
            </uap:SupportedFileTypes>
            <uap:DataFormat>StorageItems</uap:DataFormat>
            <uap:DataFormat>Bitmap</uap:DataFormat>
          </uap:ShareTarget>
        </uap:Extension>
        ...

샘플 Application.exe.manifest 파일입니다.

<?xml version="1.0" encoding="utf-8"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
  <assemblyIdentity version="1.0.0.0" name="PhotoStoreDemo.app"/>
  <msix xmlns="urn:schemas-microsoft-com:msix.v1"
          publisher="CN=YourPubNameHere"
          packageName="PhotoStoreDemo"
          applicationId="PhotoStoreDemo"
        />
</assembly>

다음으로, 외부 위치가 있는 패키지를 만들려면 /nv 명령과 함께 MakeAppx.exe 도구를 사용하여 AppxManifest.xml 파일이 포함된 패키지를 만듭니다.

예제:

MakeAppx.exe pack /d <Path to directory with AppxManifest.xml> /p <Output Path>\mypackage.msix /nv

참고 항목

외부 위치가 있는 패키지에는 패키지 매니페스트가 포함되지만 다른 앱 이진 파일 및 콘텐츠는 없습니다. 외부 위치가 있는 패키지의 매니페스트는 미리 지정된 외부 위치의 패키지 외부에 있는 파일을 참조할 수 있습니다.

SignTool.exe을(를) 사용하여 신뢰할 수 있는 인증서로 패키지에 서명합니다.

예시:

SignTool.exe sign /fd SHA256 /a /f <path to cert>  /p <cert key> <Path to Package>​

패키지 서명에 사용되는 인증서는 컴퓨터의 신뢰할 수 있는 위치에 설치되어야 합니다.

애플리케이션을 처음 실행할 때 Windows에 패키지를 등록합니다. 앱에 자체 설치 관리자가 있는 경우 서명된 MSIX도 페이로드로 포함해야 하며 지정된 위치(예: 앱의 설치 위치)에 배치해야 합니다. 앱이 MSIX의 절대 경로를 등록해야 하므로 런타임에 이 위치를 앱에 알려야 합니다. 자산을 resources.pri 앱의 설치 위치에도 배치합니다.

다음 코드는 앱의 Main 메서드를 패키징하지 않은 채 실행한 예시입니다.

[STAThread]
public static void Main(string[] cmdArgs)
{
    //if app isn't running with identity, register its package with external identity
    if (!ExecutionMode.IsRunningWithIdentity())
    {
        //TODO - update the value of externalLocation to match the output location of your VS Build binaries and the value of 
        //externalPkgPath to match the path to your signed package with external identity (.msix). 
        //Note that these values cannot be relative paths and must be complete paths
        string externalLocation = Environment.CurrentDirectory;
        string externalPkgPath = externalLocation + @"\PhotoStoreDemo.package.msix";

        //Attempt registration
        bool bPackageRegistered = false;
        //bPackageRegistered = registerPackageWithExternalLocation(externalLocation, externalPkgPath);
        if (bPackageRegistered)
        {
            //Registration succeeded, restart the app to run with identity
            System.Diagnostics.Process.Start(Application.ResourceAssembly.Location, arguments: cmdArgs?.ToString());
        }
        else //Registration failed, run without identity
        {
            Debug.WriteLine("Package Registration failed, running WITHOUT Identity");
            SingleInstanceManager wrapper = new SingleInstanceManager();
            wrapper.Run(cmdArgs);
        }
    }
    ...

이 예시에서는 앱의 최초 실행에서 MSIX를 등록하는 방법을 보여줍니다.

[STAThread]
public static void Main(string[] cmdArgs)
{
    //If app isn't running with identity, register its package with external identity
    if (!ExecutionMode.IsRunningWithIdentity())
    {
        //TODO - update the value of externalLocation to match the output location of your VS Build binaries and the value of 
        //externalPkgPath to match the path to your signed package with external identity (.msix). 
        //Note that these values cannot be relative paths and must be complete paths
        string externalLocation = Environment.CurrentDirectory;
        string externalPkgPath = externalLocation + @"\PhotoStoreDemo.package.msix";

        //Attempt registration
        if (registerPackageWithExternalLocation(externalLocation, externalPkgPath))
        {
            //Registration succeeded, restart the app to run with identity
            System.Diagnostics.Process.Start(Application.ResourceAssembly.Location, arguments: cmdArgs?.ToString());
        }
        else //Registration failed, run without identity
        {
            Debug.WriteLine("Package Registration failed, running WITHOUT Identity");
            SingleInstanceManager wrapper = new SingleInstanceManager();
            wrapper.Run(cmdArgs);
        }
    }
    ...

마지막으로 앱의 활성화를 처리합니다.

[STAThread]
public static void Main(string[] cmdArgs)
{
    //if app isn't running with identity, register its sparse package
    if (!ExecutionMode.IsRunningWithIdentity())
    {
        ...
    }
    else //App is registered and running with identity, handle launch and activation
    {
        //Handle Sparse Package based activation e.g Share target activation or clicking on a Tile
        // Launching the .exe directly will have activationArgs == null
        var activationArgs = AppInstance.GetActivatedEventArgs();
        if (activationArgs != null)
        {
            switch (activationArgs.Kind)
            {
                case ActivationKind.Launch:
                    HandleLaunch(activationArgs as LaunchActivatedEventArgs);
                    break;
                case ActivationKind.ToastNotification:
                    HandleToastNotification(activationArgs as ToastNotificationActivatedEventArgs);
                    break;
                case ActivationKind.ShareTarget: // Handle the activation as a share target
                    HandleShareAsync(activationArgs as ShareTargetActivatedEventArgs);
                    break;
                default:
                    HandleLaunch(null);
                    break;
            }

        }
        //This is a direct exe based launch e.g. double click app .exe or desktop shortcut pointing to .exe
        else
        {
            SingleInstanceManager singleInstanceManager = new SingleInstanceManager();
            singleInstanceManager.Run(cmdArgs);
        }
    }

패키지 ID 데모를 사용한 Windows Share

다음 비디오에서는 패키지 ID를 부여하고 공유 대상으로 등록한 후 패키징되지 않은 앱이 공유 대상이 될 수 있는 방법을 보여줍니다.

참고 항목