Bagikan melalui


Mengintegrasikan aplikasi desktop kemasan dengan File Explorer

Beberapa aplikasi Windows menentukan ekstensi File Explorer yang menambahkan entri menu konteks yang memungkinkan pelanggan melakukan opsi yang terkait dengan aplikasi. Teknologi penyebaran aplikasi Windows yang lebih lama seperti MSI dan ClickOnce menentukan ekstensi File Explorer melalui registri. Registri memiliki serangkaian sarang yang mengontrol ekstensi File Explorer dan jenis ekstensi Shell lainnya. Alat penginstal ini biasanya membuat serangkaian kunci registri untuk mengonfigurasi berbagai item untuk disertakan dalam menu konteks.

Jika Anda mengemas aplikasi Windows menggunakan MSIX, registri divirtualisasi, dan oleh karena itu aplikasi Anda tidak dapat mendaftarkan ekstensi File Explorer melalui registri. Sebagai gantinya, Anda harus menentukan ekstensi File Explorer Melalui ekstensi paket, yang Anda tentukan dalam manifes paket. Artikel ini menjelaskan beberapa cara untuk melakukan ini.

Anda dapat menemukan kode sampel lengkap yang digunakan dalam artikel ini di GitHub.

Menambahkan entri menu konteks yang mendukung parameter startup

Salah satu cara paling sederhana untuk diintegrasikan dengan File Explorer adalah dengan menentukan ekstensi paket yang menambahkan aplikasi Anda ke daftar aplikasi yang tersedia di menu konteks saat pengguna mengklik kanan jenis file tertentu di File Explorer. Jika pengguna membuka aplikasi, ekstensi Anda dapat meneruskan parameter ke aplikasi Anda.

Skenario ini memiliki beberapa batasan:

  • Ini hanya berfungsi dalam kombinasi dengan fitur asosiasi jenis file. Anda dapat menampilkan opsi tambahan di menu konteks hanya untuk jenis file yang terkait dengan aplikasi utama (misalnya, aplikasi Anda mendukung pembukaan file dengan mengklik dua kali di File Explorer).
  • Opsi di menu konteks akan ditampilkan hanya jika aplikasi Anda diatur sebagai default untuk jenis file tersebut.
  • Satu-satunya tindakan yang didukung adalah meluncurkan executable utama aplikasi (yaitu, executable yang sama yang terhubung ke entri menu Mulai). Namun, setiap tindakan dapat menentukan parameter yang berbeda, yang dapat Anda gunakan saat aplikasi mulai memahami tindakan mana yang memicu eksekusi dan melakukan tugas yang berbeda.

Terlepas dari keterbatasan ini, pendekatan ini cukup untuk banyak skenario. Misalnya, jika Anda membangun editor gambar, Anda dapat dengan mudah menambahkan entri di menu konteks untuk mengubah ukuran gambar, yang akan meluncurkan editor gambar secara langsung dengan wizard untuk memulai proses pengubahan ukuran.

Menerapkan entri menu konteks

Untuk mendukung skenario ini, tambahkan elemen Ekstensi dengan kategori windows.fileTypeAssociation ke manifes paket Anda. Elemen ini harus ditambahkan sebagai turunan dari elemen Ekstensi di bawah elemen Aplikasi .

Contoh berikut menunjukkan pendaftaran untuk aplikasi yang memungkinkan menu konteks untuk file dengan .foo ekstensi. Contoh ini menentukan .foo ekstensi karena ini adalah ekstensi palsu yang biasanya tidak terdaftar ke aplikasi lain di komputer tertentu. Jika Anda perlu mengelola jenis file yang mungkin sudah diambil (seperti .txt atau .jpg), ingatlah bahwa Anda tidak akan dapat melihat opsi hingga aplikasi Anda diatur sebagai default untuk jenis file tersebut. Contoh ini adalah kutipan dari file Package.appxmanifest dalam sampel terkait di GitHub.

<Extensions>
  <uap3:Extension Category="windows.fileTypeAssociation">
    <uap3:FileTypeAssociation Name="foo" Parameters="&quot;%1&quot;">
      <uap:SupportedFileTypes>
        <uap:FileType>.foo</uap:FileType>
      </uap:SupportedFileTypes>
      <uap2:SupportedVerbs>
        <uap3:Verb Id="Resize" Parameters="&quot;%1&quot; /p">Resize file</uap3:Verb>
      </uap2:SupportedVerbs>
    </uap3:FileTypeAssociation>
  </uap3:Extension>
</Extensions>

Contoh ini mengasumsikan bahwa namespace dan alias berikut dideklarasikan dalam elemen akar <Package> dalam manifes.

<Package
  xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
  xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
  xmlns:uap2="http://schemas.microsoft.com/appx/manifest/uap/windows10/2"
  xmlns:uap3="http://schemas.microsoft.com/appx/manifest/uap/windows10/3"
  xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"
  IgnorableNamespaces="uap uap2 uap3 rescap">
  ...
</Package>

Elemen FileTypeAssociation mengaitkan aplikasi Anda dengan jenis file yang ingin Anda dukung. Untuk detail selengkapnya, lihat Mengaitkan aplikasi paket Anda dengan sekumpulan jenis file. Berikut adalah item terpenting yang terkait dengan elemen ini.

Atribut atau elemen Deskripsi
atribut Name Cocok dengan nama ekstensi yang ingin Anda daftarkan dikurangi titik (dalam contoh sebelumnya, foo).
atribut Parameters Berisi parameter yang ingin Anda teruskan ke aplikasi Anda saat pengguna mengklik dua kali file dengan ekstensi tersebut. Biasanya, setidaknya, Anda meneruskan %1, yang merupakan parameter khusus yang berisi jalur file yang dipilih. Dengan cara ini, ketika Anda mengklik dua kali pada file, aplikasi tahu jalur lengkapnya dan dapat memuatnya.
Elemen SupportedFileTypes Menentukan nama ekstensi yang ingin Anda daftarkan, termasuk titik (dalam contoh ini, .foo). Anda dapat menentukan beberapa <FileType> entri yang ingin Anda dukung lebih banyak tipe file.

Untuk menentukan integrasi menu konteks, Anda juga harus menambahkan elemen turunan SupportedVerbs . Elemen ini berisi satu atau beberapa elemen Kata Kerja yang menentukan opsi yang akan dicantumkan ketika pengguna mengklik kanan file dengan ekstensi .foo di File Explorer. Untuk detail selengkapnya, lihat Menambahkan opsi ke menu konteks file yang memiliki jenis file tertentu. Berikut adalah item terpenting yang terkait dengan elemen Kata Kerja .

Atribut atau elemen Deskripsi
atribut Id Menentukan pengidentifikasi unik untuk tindakan tersebut.
atribut Parameters Mirip dengan elemen FileTypeAssociation , atribut ini untuk elemen Verb berisi parameter yang diteruskan ke aplikasi Anda saat pengguna mengklik entri menu konteks. Biasanya, selain %1 parameter khusus untuk mendapatkan jalur file yang dipilih, Anda juga meneruskan satu atau beberapa parameter untuk mendapatkan konteks. Ini memungkinkan aplikasi Anda untuk memahami bahwa aplikasi dibuka dari entri menu konteks.
Nilai elemen Nilai elemen Kata Kerja berisi label untuk ditampilkan di entri menu konteks (dalam contoh ini, Ubah ukuran file).

Mengakses parameter startup di kode aplikasi Anda

Cara aplikasi Anda menerima parameter tergantung pada jenis aplikasi yang telah Anda buat. Misalnya, aplikasi WPF biasanya memproses arg peristiwa startup dalam OnStartup metode App kelas . Anda dapat memeriksa apakah ada parameter startup dan, berdasarkan hasilnya, mengambil tindakan yang paling tepat (seperti membuka jendela aplikasi tertentu alih-alih yang utama).

public partial class App : Application
{
    protected override void OnStartup(StartupEventArgs e)
    {
        if (e.Args.Contains("Resize"))
        {
            // Open a specific window of the app.
        }
        else
        {
            MainWindow main = new MainWindow();
            main.Show();
        }
    }
}

Cuplikan layar berikut menunjukkan entri menu ubah ukuran konteks File yang dibuat oleh contoh sebelumnya.

Cuplikan layar perintah Ubah Ukuran file di menu pintasan

Mendukung file atau folder generik dan melakukan tugas kompleks

Meskipun menggunakan ekstensi FileTypeAssociation dalam manifes paket seperti yang dijelaskan di bagian sebelumnya cukup untuk banyak skenario, Anda mungkin merasa membatasinya. Dua tantangan terbesar adalah:

  • Anda hanya dapat menangani jenis file yang terkait dengan Anda. Misalnya, Anda tidak dapat menangani folder generik.
  • Anda hanya dapat meluncurkan aplikasi dengan serangkaian parameter. Anda tidak dapat melakukan operasi lanjutan, seperti meluncurkan executable lain atau melakukan tugas tanpa membuka aplikasi utama.

Untuk mencapai tujuan ini, Anda harus membuat ekstensi Shell, yang menyediakan cara yang lebih kuat untuk berintegrasi dengan File Explorer. Dalam skenario ini, Anda membuat DLL yang berisi semua yang diperlukan untuk mengelola menu konteks file, termasuk label, ikon, status, dan tugas yang harus dilakukan. Karena fungsionalitas ini diterapkan dalam DLL, Anda dapat melakukan hampir semua yang dapat Anda lakukan dengan aplikasi normal. Setelah menerapkan DLL, Anda harus mendaftarkannya melalui ekstensi yang Anda tentukan dalam manifes paket Anda.

Catatan

Proses yang dijelaskan di bagian ini memiliki satu batasan. Setelah paket MSIX yang berisi ekstensi diinstal pada komputer target, File Explorer harus dimulai ulang sebelum ekstensi Shell dapat dimuat. Untuk mencapai hal ini, pengguna dapat memulai ulang komputer, atau mereka dapat memulai ulang proses explorer.exe menggunakan Task Manager.

Menerapkan ekstensi Shell

Ekstensi shell didasarkan pada COM (Model Objek Komponen). DLL Anda mengekspos satu atau beberapa objek COM yang terdaftar di registri sistem. Windows menemukan objek COM ini dan mengintegrasikan ekstensi Anda dengan File Explorer. Karena Anda mengintegrasikan kode Anda dengan Windows Shell, performa dan jejak memori penting. Oleh karena itu, ekstensi semacam ini biasanya dibangun dengan C++.

Untuk kode sampel yang menggambarkan cara menerapkan ekstensi Shell, lihat proyek ExplorerCommandVerb dalam sampel terkait di GitHub. Proyek ini didasarkan pada sampel ini dalam sampel desktop Windows, dan memiliki beberapa revisi untuk membuat sampel lebih mudah digunakan dengan versi terbaru Visual Studio.

Proyek ini berisi banyak kode boilerplate untuk tugas yang berbeda, seperti menu dinamis vs statis dan pendaftaran manual DLL. Sebagian besar kode ini tidak diperlukan jika Anda mengemas aplikasi menggunakan MSIX, karena dukungan pengemasan akan mengurus tugas-tugas ini untuk Anda. File ExplorerCommandVerb.cpp berisi implementasi menu konteks, dan ini adalah file kode utama yang menarik untuk panduan ini.

Fungsi utamanya adalah CExplorerCommandVerb::Invoke. Ini adalah fungsi yang dipanggil ketika pengguna mengklik entri di menu konteks. Dalam sampel, untuk meminimalkan dampak pada performa, operasi dilakukan pada utas lain, sehingga Anda benar-benar akan menemukan implementasi nyata di CExplorerCommandVerb::_ThreadProc.

DWORD CExplorerCommandVerb::_ThreadProc()
{
	IShellItemArray* psia;
	HRESULT hr = CoGetInterfaceAndReleaseStream(_pstmShellItemArray, IID_PPV_ARGS(&psia));
	_pstmShellItemArray = NULL;
	if (SUCCEEDED(hr))
	{
		DWORD count;
		psia->GetCount(&count);

		IShellItem2* psi;
		HRESULT hr = GetItemAt(psia, 0, IID_PPV_ARGS(&psi));
		if (SUCCEEDED(hr))
		{
			PWSTR pszName;
			hr = psi->GetDisplayName(SIGDN_DESKTOPABSOLUTEPARSING, &pszName);
			if (SUCCEEDED(hr))
			{
				WCHAR szMsg[128];
				StringCchPrintf(szMsg, ARRAYSIZE(szMsg), L"%d item(s), first item is named %s", count, pszName);

				MessageBox(_hwnd, szMsg, L"ExplorerCommand Sample Verb", MB_OK);

				CoTaskMemFree(pszName);
			}

			psi->Release();
		}
		psia->Release();
	}

	return 0;
}

Saat pengguna mengklik kanan pada file atau folder, fungsi ini menampilkan kotak pesan dengan jalur lengkap file atau folder yang dipilih. Jika Anda ingin menyesuaikan ekstensi Shell dengan cara lain, Anda dapat memperluas fungsi berikut dalam sampel:

  • Anda dapat mengubah fungsi GetTitle untuk menyesuaikan label entri di menu konteks.
  • Anda dapat mengubah fungsi GetIcon untuk menyesuaikan ikon yang ditampilkan di dekat entri di menu konteks.
  • Anda dapat mengubah fungsi GetTooltip untuk menyesuaikan tipsalat yang ditampilkan saat Anda mengarahkan mouse ke entri di menu konteks.

Mendaftarkan ekstensi Shell

Karena ekstensi Shell didasarkan pada COM, DLL implementasi harus diekspos sebagai server COM sehingga Windows dapat mengintegrasikannya dengan File Explorer. Biasanya, ini dilakukan dengan menetapkan ID unik (disebut CLSID) ke server COM dan dengan mendaftarkannya di sarang tertentu dari registri sistem. Dalam proyek ExplorerCommandVerb, CLSID untuk CExplorerCommandVerb ekstensi ditentukan dalam file Dll.h.

class __declspec(uuid("CC19E147-7757-483C-B27F-3D81BCEB38FE")) CExplorerCommandVerb;

Saat Anda mengemas DLL ekstensi Shell dalam paket MSIX, Anda mengikuti pendekatan serupa. Namun, GUID harus terdaftar di dalam manifes paket alih-alih registri, seperti yang dijelaskan di sini.

Dalam manifes paket Anda, mulailah dengan menambahkan namespace berikut ke elemen Paket Anda.

<Package
  xmlns:desktop="http://schemas.microsoft.com/appx/manifest/desktop/windows10"
  xmlns:desktop4="http://schemas.microsoft.com/appx/manifest/desktop/windows10/4"
  xmlns:desktop5="http://schemas.microsoft.com/appx/manifest/desktop/windows10/5"
  xmlns:com="http://schemas.microsoft.com/appx/manifest/com/windows10" 
  IgnorableNamespaces="desktop desktop4 desktop5 com">
    
    ...
</Package>

Untuk mendaftarkan CLSID, tambahkan com. Elemen ekstensi dengan kategori windows.comServer ke manifes paket Anda. Elemen ini harus ditambahkan sebagai turunan dari elemen Ekstensi di bawah elemen Aplikasi . Contoh ini adalah kutipan dari file Package.appxmanifest dalam sampel terkait di GitHub.

<com:Extension Category="windows.comServer">
  <com:ComServer>
    <com:SurrogateServer DisplayName="ContextMenuSample">
      <com:Class Id="CC19E147-7757-483C-B27F-3D81BCEB38FE" Path="ExplorerCommandVerb.dll" ThreadingModel="STA"/>
    </com:SurrogateServer>
  </com:ComServer>
</com:Extension>

Ada dua atribut penting untuk dikonfigurasi dalam elemen com:Class .

Atribut Deskripsi
atribut Id Ini harus cocok dengan CLSID objek yang ingin Anda daftarkan. Dalam contoh ini, ini adalah CLSID yang dideklarasikan dalam file yang Dll.h terkait dengan CExplorerCommandVerb kelas .
atribut Path Ini harus berisi nama DLL yang mengekspos objek COM. Contoh ini mencakup DLL di akar paket, sehingga hanya dapat menentukan nama DLL yang dihasilkan oleh ExplorerCommandVerb proyek.

Selanjutnya, tambahkan ekstensi lain yang mendaftarkan menu konteks file. Untuk melakukan ini, tambahkan elemen desktop4:Extension dengan kategori windows.fileExplorerContextMenus ke manifes paket Anda. Elemen ini juga harus ditambahkan sebagai turunan dari elemen Ekstensi di bawah elemen Aplikasi .

<desktop4:Extension Category="windows.fileExplorerContextMenus">
  <desktop4:FileExplorerContextMenus>
    <desktop5:ItemType Type="Directory">
      <desktop5:Verb Id="Command1" Clsid="CC19E147-7757-483C-B27F-3D81BCEB38FE" />
    </desktop5:ItemType>
  </desktop4:FileExplorerContextMenus>
</desktop4:Extension>

Ada dua atribut penting untuk dikonfigurasi di bawah elemen desktop4:Extension .

Atribut atau elemen Deskripsi
Typeatribut desktop5:ItemType Ini menentukan jenis item yang ingin Anda kaitkan dengan menu konteks. Ini bisa menjadi bintang (*) jika Anda ingin menampilkannya untuk semua file; itu bisa menjadi ekstensi file tertentu (.foo); atau dapat tersedia untuk folder (Directory).
Clsidatribut desktop5:Verb Ini harus cocok dengan CLSID yang sebelumnya telah Anda daftarkan sebagai server COM dalam file manifes paket.

Mengonfigurasi DLL dalam paket

Sertakan DLL yang mengimplementasikan ekstensi Shell (dalam sampel ini, ExplorerCommandVerb.dll) di akar paket MSIX. Jika Anda menggunakan Proyek Pengemasan Aplikasi Windows, solusi termudah adalah menyalin dan menempelkan DLL ke dalam proyek dan memastikan bahwa opsi Salin ke Direktori Output untuk properti file DLL diatur ke Salin jika lebih baru.

Untuk memastikan bahwa paket selalu menyertakan versi DLL terbaru, Anda dapat menambahkan peristiwa pasca-build ke proyek ekstensi Shell sehingga, setiap kali Anda membuatnya, DLL disalin ke Proyek Kemasan Aplikasi Windows.

Mulai ulang File Explorer

Setelah menginstal paket ekstensi Shell, Anda harus memulai ulang File Explorer sebelum ekstensi Shell dapat dimuat. Ini adalah batasan ekstensi Shell yang disebarkan dan didaftarkan melalui paket MSIX.

Untuk menguji ekstensi Shell, hidupkan ulang PC Anda atau mulai ulang proses explorer.exe menggunakan Task Manager. Setelah melakukannya, Anda akan dapat melihat entri di menu konteks.

Cuplikan layar entri menu konteks kustom

Jika Anda mengkliknya, CExplorerCommandVerb::_ThreadProc fungsi akan dipanggil untuk menampilkan kotak pesan dengan jalur folder yang dipilih.

Cuplikan layar popup kustom