Udostępnij za pośrednictwem


API przesyłania w Sklepie Microsoft Store dla aplikacji MSI lub EXE

Użyj interfejsu API przesyłania ze sklepu Microsoft Store dla aplikacji MSI lub EXE, aby programowo wykonywać zapytania i tworzyć zgłoszenia dla aplikacji MSI lub EXE dla konta Centrum partnerskiego organizacji. Ten interfejs API jest przydatny, jeśli twoje konto zarządza wieloma aplikacjami i chcesz zautomatyzować i zoptymalizować proces przesyłania dla tych zasobów. Ten interfejs API używa usługi Azure Active Directory (Azure AD) do uwierzytelniania wywołań z aplikacji lub usługi.

W poniższych krokach opisano proces od początku do końca korzystania z interfejsu API do przesyłania w Microsoft Store.

  1. Upewnij się, że zostały spełnione wszystkie wymagania wstępne.
  2. Przed wywołaniem metody w interfejsie API przesyłania sklepu Microsoft Store uzyskaj token dostępu usługi Azure AD. Po uzyskaniu tokenu masz 60 minut na użycie tego tokenu w wywołaniach interfejsu API przesyłania do Microsoft Store, zanim token wygaśnie. Po wygaśnięciu tokenu możesz wygenerować nowy token.
  3. Uruchom interfejs API przesyłania aplikacji MSI lub EXE do sklepu Microsoft Store.

Krok 1. Pełne wymagania wstępne dotyczące korzystania z interfejsu API przesyłania do sklepu Microsoft Store

Przed rozpoczęciem pisania kodu w celu wywołania interfejsu API przesyłania aplikacji do sklepu Microsoft Store dla aplikacji MSI lub EXE, upewnij się, że spełniono następujące wymagania wstępne.

  • Ty (lub Twoja organizacja) musisz mieć katalog usługi Azure AD i musisz mieć uprawnienia administratora globalnego dla katalogu. Jeśli korzystasz już z platformy Microsoft 365 lub innych usług biznesowych, masz już katalog usługi Azure AD. W przeciwnym razie możesz utworzyć nową usługę Azure AD w Centrum partnerskim bez dodatkowych opłat.
  • Musisz skojarzyć aplikację usługi Azure AD z kontem Centrum partnerskiego i uzyskać identyfikator dzierżawy, identyfikator klienta i klucz. Te wartości są niezbędne do uzyskania tokenu dostępu Azure AD, który zostanie użyty w wywołaniach do interfejsu API Microsoft Store Submission.
  • Przygotuj swoją aplikację do użycia z interfejsem API przesyłania do sklepu Microsoft Store.
    • Jeśli Twoja aplikacja nie istnieje jeszcze w Centrum Partnerskiego, musisz utworzyć aplikację, rezerwując jej nazwę w Centrum Partnerskiego. Nie można użyć interfejsu API przesyłania Microsoft Store do utworzenia aplikacji w Centrum partnerskim; musisz pracować w Centrum partnerskim, aby ją utworzyć, a następnie za pomocą interfejsu API można uzyskać dostęp do aplikacji i programowo tworzyć dla niej przesyłki.
    • Przed utworzeniem zgłoszenia dla danej aplikacji przez ten interfejs API, należy najpierw utworzyć zgłoszenie dla aplikacji w Centrum partnerskim, które obejmuje wypełnienie kwestionariusza dotyczącego oceny wieku. Po wykonaniu tej czynności będzie można programowo utworzyć nowe przesłania dla tej aplikacji przy użyciu interfejsu API.
    • Jeśli tworzysz lub aktualizujesz zgłoszenie aplikacji i musisz dołączyć nowy pakiet, przygotuj szczegóły pakietu.
    • Jeśli tworzysz lub aktualizujesz zgłoszenie aplikacji i musisz uwzględnić zrzuty ekranu lub obrazy do listingu w Sklepie, przygotuj zrzuty ekranu i obrazy aplikacji.

Jak skojarzyć aplikację usługi Azure AD z kontem Centrum partnerskiego

Aby skorzystać z interfejsu API przesyłania do Microsoft Store dla aplikacji MSI lub EXE, należy skojarzyć aplikację Azure AD z kontem w Centrum partnerskim, pobrać dla tej aplikacji identyfikatory dzierżawy i klienta oraz wygenerować klucz. Aplikacja Azure AD reprezentuje aplikację lub usługę, z której chcesz wywołać API przesyłania do Microsoft Store. Potrzebujesz identyfikatora dzierżawcy, identyfikatora klienta i klucza, aby uzyskać token dostępu Azure AD, który następnie przekazujesz do interfejsu API.

Uwaga / Notatka

To zadanie trzeba wykonać tylko raz. Po utworzeniu identyfikatora dzierżawy, identyfikatora klienta i klucza możesz użyć ich ponownie w dowolnym momencie, gdy musisz utworzyć nowy token dostępu usługi Azure AD.

  1. W Partner Center skojarz konto Partner Center swojej organizacji z katalogiem Azure AD Twojej organizacji.
  2. Następnie na stronie Użytkownicy w sekcji Ustawienia konta Centrum partnerskiego dodać aplikację usługi Azure AD reprezentującą aplikację lub usługę, której będziesz używać do uzyskiwania dostępu do przesyłania dla konta Centrum partnerskiego. Upewnij się, że przypiszesz tej aplikacji rolę Menedżera. Jeśli aplikacja jeszcze nie istnieje w katalogu usługi Azure AD, możesz utworzyć nową aplikację usługi Azure AD w Centrum partnerskim.
  3. Wróć do strony Użytkownicy, kliknij nazwę aplikacji usługi Azure AD, aby przejść do ustawień aplikacji, a następnie skopiuj wartości Identyfikatora dzierżawcy i Identyfikatora klienta.
  4. Aby dodać nowy klucz lub klucz tajny klienta, zobacz następujące instrukcje lub zapoznaj się z instrukcjami dotyczącymi rejestrowania aplikacji za pośrednictwem witryny Azure Portal:

Aby zarejestrować aplikację:

  1. Zaloguj się do witryny Azure Portal.

  2. Jeśli masz dostęp do wielu dzierżaw, użyj filtru Katalogów i subskrypcji w górnym menu, aby przełączyć się do dzierżawy, w której chcesz zarejestrować aplikację.

  3. Wyszukaj pozycję Azure Active Directory i wybierz ją.

  4. W obszarze Zarządzanie wybierz pozycję Rejestracje aplikacji, a następnie wybierz swoją aplikację.

  5. Wybierz Certyfikaty i sekrety > Sekrety klienta > Nowy sekret klienta.

  6. Dodaj opis tajemnicy klienta.

  7. Wybierz datę wygaśnięcia klucza tajnego lub określ niestandardowy okres ważności.

  8. Czas ważności tajemnicy klienta jest ograniczony do dwóch lat (24 miesięcy) lub mniej. Nie można określić niestandardowego okresu ważności dłuższego niż 24 miesiące.

    Uwaga / Notatka

    Firma Microsoft zaleca ustawienie wartości wygaśnięcia mniejszej niż 12 miesięcy.

  9. Wybierz Dodaj.

  10. Zapisz wartość sekretu do użycia w kodzie aplikacji klienckiej. Ta wartość tajna nigdy nie jest wyświetlana ponownie po opuszczeniu strony.

Krok 2. Uzyskiwanie tokenu dostępu usługi Azure AD

Przed wywołaniem dowolnej metody w interfejsie API dla aplikacji MSI lub EXE w sklepie Microsoft Store, należy najpierw uzyskać token dostępu Azure AD, który należy przekazać do nagłówka Autoryzacja każdej metody w tym interfejsie API. Po uzyskaniu tokenu dostępu należy 60 minut używać go przed jego wygaśnięciem. Po wygaśnięciu tokenu możesz odświeżyć token, aby móc nadal używać go w kolejnych wywołaniach interfejsu API.

Aby uzyskać token dostępu, postępuj zgodnie z instrukcjami w temacie [Service to Service Calls Using Client Credentials]/azure/active-directory/azuread-dev/v1-oauth2-client-creds-grant-flow) w celu wysłania żądania HTTP POST do punktu końcowego https://login.microsoftonline.com/<tenant_id>/oauth2/token. Oto przykładowe żądanie.

POST https://login.microsoftonline.com/<tenant-id>/oauth2/v2.0/token HTTP/1.1
Host: login.microsoftonline.com
Content-Type: application/x-www-form-urlencoded; charset=utf-8

grant_type=client_credentials
&client_id=<your_client_id>
&client_secret=<your_client_secret>
&scope=https://api.store.microsoft.com/.default

Dla wartości tenant_id w URI POST oraz parametrów client_id i client_secret określ identyfikator dzierżawy, identyfikator klienta oraz klucz aplikacji, które uzyskałeś z Centrum partnerskiego w poprzedniej sekcji. Dla parametru zakresu należy określić wartość https://api.store.microsoft.com/.default.

Po wygaśnięciu tokenu dostępu możesz go odświeżyć, postępując zgodnie z instrukcjami podanymi tutaj.

Aby zapoznać się z przykładami ilustrującymi sposób uzyskania tokenu dostępu przy użyciu języka C# lub Node.js, zobacz przykłady kodu dla interfejsu API przesyłania aplikacji MSI lub EXE do Microsoft Store.

Krok 3: Użyj API wysyłania w sklepie Microsoft Store

Po uzyskaniu tokenu dostępu Azure AD można wywołać metody w interfejsie API do przesyłania Microsoft Store dla aplikacji MSI lub EXE. Interfejs API zawiera wiele metod, które są pogrupowane w scenariusze dla aplikacji. Aby utworzyć lub zaktualizować zgłoszenia, zazwyczaj wywołujesz wiele metod w określonej kolejności. Aby uzyskać informacje o poszczególnych scenariuszach i składni każdej metody, zobacz następujące sekcje:

Uwaga / Notatka

Po uzyskaniu tokenu dostępu masz 60 minut na wywołanie metod w interfejsie Microsoft Store submission API dla aplikacji MSI lub EXE przed wygaśnięciem tokenu.

Podstawowy adres URL

Podstawowy adres URL interfejsu API przesyłania sklepu Microsoft Store dla aplikacji EXE lub MSI to: https://api.store.microsoft.com

Kontrakty API

Pobieranie bieżącego interfejsu API metadanych przesyłania wersji roboczej

Pobiera metadane w każdym module (listy, właściwości lub dostępność) w bieżącej wersji roboczej przesyłania.

Ścieżka [Wszystkie moduły]: /submission/v1/product/{productId}/metadata?languages={languages}&includelanguagelist={true/false}
Ścieżka [pojedynczy moduł]: /submission/v1/product/{productId}/metadata/{moduleName}?languages={languages}&includelanguagelist={true/false}
, metoda: GET

Parametry ścieżki

Parametr Opis
ID produktu Identyfikator Partner Center produktu
nazwa modułu Moduł Centrum Partnera — oferty, zasoby lub dostępność

Parametry zapytania

Parametr Opis
Języki Opcjonalne Filtr języków listy jako ciąg znaków rozdzielony przecinkami [limit do 200 języków].

Jeśli jest nieobecny, zostaną pobrane metadane dla pierwszych 200 dostępnych języków listy. [ np. "en-us, en-gb"].
dodajlistęjęzyków opcjonalne typ logiczny — jeśli jest to prawda, zwraca listę dodanych języków ofert i ich status kompletności.

Wymagane nagłówki

Nagłówek Wartość
Authorization: Bearer <Token> Identyfikator aplikacji usługi Azure AD zarejestrowany w koncie Centrum partnerskiego
X-Seller-Account-Id Identyfikator konta sprzedawcy w Centrum partnerskim

nagłówki odpowiedzi

Nagłówek Wartość
X-Correlation-ID Unikatowy identyfikator typu GUID dla każdego żądania. Można to udostępnić zespołowi pomocy technicznej w celu analizowania dowolnego problemu.
Retry-After Czas w sekundach, który klient musi czekać przed ponownym wywołaniem interfejsów API z powodu ograniczania szybkości.

Parametry odpowiedzi

Nazwa Typ Opis
wsparcie dostępności Boolowski
dodatkowe warunki licencji Sznurek
dostępność Przedmiot Dane modułu dostępności
kategoria Sznurek Zobacz listę kategorii poniżej
notatki certyfikacyjne Sznurek
kod Sznurek Kod błędu komunikatu
informacje kontaktowe Sznurek
prawo autorskie Sznurek
ZależyOdSterownikówLubNT Boolowski
opis Sznurek
opracowany przez Sznurek
Łatwość odnalezienia Sznurek [ODNAJDYWANIE, DEEPLINK_ONLY]
enableInFutureMarkets Boolowski
Błędy Tablica obiektów Lista komunikatów o błędach lub ostrzeżeniach, jeśli istnieją
freeTrial Sznurek [BRAK_DARMOWEJ_WERSJI_PRÓBNEJ, DARMOWA_WERSJA_PRÓBNA]
typElementuSprzętowego Sznurek
isPrivacyPolicyRequired (ZasadyPrywatnościWymagane) This includes both the original and a translated version in parentheses for clarity if needed in documentation or user-facing text. Boolowski
jestZalecane Boolowski
wymagane Boolowski
czySukces Boolowski
czySystemowaFunkcjaJestWymagana Tablica obiektów
Język Sznurek Zobacz listę języków poniżej
Ogłoszenia Tablica obiektów Wyświetlanie listy danych modułu dla każdego języka
Rynki Tablica ciągów znaków Zobacz listę rynków poniżej
Komunikat Sznurek Opis błędu
minimalne wymagania sprzętowe Sznurek
minimalne wymagania Sznurek
wsparcie dla pióra i tuszu Boolowski
cennik Sznurek [DARMOWY, FREEMIUM, ABONAMENTOWY, PŁATNY]
URLPolitykiPrywatności Sznurek
deklaracje produktów Przedmiot
cechy produktu Tablica ciągów znaków
właściwości Przedmiot Dane modułu właściwości
zalecany sprzęt Sznurek
zalecane wymaganie Sznurek
dane odpowiedzi Przedmiot Zawiera rzeczywisty ładunek odpowiedzi dla żądania
wymagania Tablica obiektów
terminy wyszukiwania Tablica ciągów znaków
krótki opis Sznurek
Podkategorii Sznurek Zobacz listę podkategorii poniżej
supportContactInfo Sznurek
szczegóły wymagań systemowych Tablica obiektów
cel Sznurek Jednostka, z której pochodzi błąd
witryna sieci Web Sznurek
Co nowego Sznurek

Przykładowa odpowiedź

{
    "isSuccess": true,
    "errors": [{
        "code": "badrequest",
        "message": "Error Message 1",
        "target": "listings"
        }, {
        "code": "warning",
        "message": "Warning Message 1",
        "target": "properties"
    }],
    "responseData": {
        "availability":{
            "markets": ["US"],
            "discoverability": "DISCOVERABLE",
            "enableInFutureMarkets": true,
            "pricing": "PAID",
            "freeTrial": "NO_FREE_TRIAL"
        },
        "properties":{
            "isPrivacyPolicyRequired": true,
            "privacyPolicyUrl": "http://contoso.com",
            "website": "http://contoso.com",
            "supportContactInfo": "http://contoso.com",
            "certificationNotes": "Certification Notes",
            "category": "DeveloperTools",
            "subcategory": "Database",
            "productDeclarations": {
                "dependsOnDriversOrNT": false,
                "accessibilitySupport": false,
                "penAndInkSupport": false
            },
            "isSystemFeatureRequired": [
                {
                    "isRequired": true,
                    "isRecommended": false,
                    "hardwareItemType": "Touch"
                },
                {
                    "isRequired": true,
                    "isRecommended": false,
                    "hardwareItemType": "Keyboard"
                },
                {
                    "isRequired": false,
                    "isRecommended": false,
                    "hardwareItemType": "Mouse"
                },
                {
                    "isRequired": false,
                    "isRecommended": false,
                    "hardwareItemType": "Camera"
                },
                {
                    "isRequired": false,
                    "isRecommended": false,
                    "hardwareItemType": "NFC_HCE"
                },
                {
                    "isRequired": false,
                    "isRecommended": false,
                    "hardwareItemType": "NFC_Proximity"
                },
                {
                    "isRequired": false,
                    "isRecommended": false,
                    "hardwareItemType": "Bluetooth_LE"
                },
                {
                    "isRequired": false,
                    "isRecommended": false,
                    "hardwareItemType": "Telephony"
                },
                {
                    "isRequired": false,
                    "isRecommended": false,
                    "hardwareItemType": "Microphone"
                }
            ],
            "systemRequirementDetails": [
                {
                    "minimumRequirement": "1GB",
                    "recommendedRequirement": "4GB",
                    "hardwareItemType": "Memory"
                },
                {
                    "minimumRequirement": "",
                    "recommendedRequirement": "",
                    "hardwareItemType": "DirectX"
                },
                {
                    "minimumRequirement": "",
                    "recommendedRequirement": "",
                    "hardwareItemType": "Video_Memory"
                },
                {
                    "minimumRequirement": "",
                    "recommendedRequirement": "",
                    "hardwareItemType": "Processor"
                },
                {
                    "minimumRequirement": "",
                    "recommendedRequirement": "",
                    "hardwareItemType": "Graphics"
                }
            ]
        },
        "listings":[{
            "language": "en-us",
            "description": "Description",
            "whatsNew": "What's New",
            "productFeatures": ["Feature 1"],
            "shortDescription": "Short Description",
            "searchTerms": ["Search Ter 1"],
            "additionalLicenseTerms": "License Terms",
            "copyright": "Copyright Information",
            "developedBy": "Developer Details",
            "sortTitle": "Product 101",
            "requirements": [
                {
                    "minimumHardware": "Pentium4",
                    "recommendedHardware": "Corei9"
                }
            ],
            "contactInfo": "contactus@contoso.com"               
        }],      
        "listingLanguages": [{"language":"en-us", "isComplete": true}]
    }
}

Aktualizowanie bieżącego interfejsu API metadanych przesyłania wersji roboczej

Aktualizuje metadane w każdym module w wersji roboczej przesyłania. Sprawdzanie interfejsu API

  • W przypadku aktywnego przesyłania. Jeśli istnieje, niepowodzenie z komunikatem o błędzie.
  • Jeśli wszystkie moduły są w stanie gotowości, aby umożliwić operację Zapisu wersji roboczej.
  • Każde pole w zgłoszeniu jest weryfikowane zgodnie z wymaganiami Sklepu
  • Reguły sprawdzania poprawności szczegółów wymagań systemowych:
    • Dozwolone wartości w hardwareItemType = Pamięć: 300 MB, 750 MB, 1 GB, 2 GB, 4 GB, 6 GB, 8 GB, 12 GB, 16 GB, 20 GB
    • Dozwolone wartości w hardwareItemType = DirectX: DX9, DX10, DX11, DX12-FEATURELEVEL11, DX12-FEATURELEVEL12
    • Dozwolone wartości w hardwareItemType = Video_Memory: 1 GB, 2 GB, 4 GB, 6 GB

ścieżka [pełna aktualizacja modułu]: /submission/v1/product/{productId}/metadata
, metoda: PUT

ścieżka [aktualizacja poprawki modułu]: /submission/v1/product/{productId}/metadata
: metoda: PATCH

zachowania interfejsu API

W przypadku interfejsu API pełnej aktualizacji modułu — wszystkie dane modułu muszą być uwzględnione w żądaniu, aby dokonać pełnej aktualizacji każdego pola. Jeśli jakieś pole nie jest obecne w żądaniu, jego wartość domyślna zostanie użyta do nadpisania bieżącej wartości dla danego modułu.
W przypadku interfejsu API aktualizacji modułu poprawek — w żądaniu muszą znajdować się tylko pola, które mają zostać zaktualizowane. Te dane z pól z żądania zastąpią istniejące wartości, zachowując niezmienione wszystkie inne pola, które nie znajdują się w żądaniu, tak jak obecnie dla tego konkretnego modułu.

Parametry ścieżki

Parametr Opis
ID produktu Identyfikator Partner Center produktu

Wymagane nagłówki

Nagłówek Wartość
Authorization: Bearer <Token> Identyfikator aplikacji usługi Azure AD zarejestrowany w koncie Centrum partnerskiego
X-Seller-Account-Id Identyfikator konta sprzedawcy w Centrum partnerskim

Parametry żądania

Nazwa Typ Opis
dostępność Przedmiot Obiekt do przechowywania metadanych modułu dostępności
Rynki Tablica ciągów znaków Wymagane Zobacz listę rynków poniżej
Łatwość odnalezienia Sznurek wymagane [ODNAJDYWANIE, DEEPLINK_ONLY]
enableInFutureMarkets Boolowski Wymagane
cennik Sznurek Wymagane [BEZPŁATNA, FREEMIUM, SUBSKRYPCJA, PŁATNA]
freeTrial Sznurek wymagane, jeśli cennik jest płatny lub subskrypcja [NO_FREE_TRIAL, FREE_TRIAL]
właściwości Przedmiot Obiekt do przechowywania metadanych modułu właściwości
isPrivacyPolicyRequired (ZasadyPrywatnościWymagane) This includes both the original and a translated version in parentheses for clarity if needed in documentation or user-facing text. Boolowski Wymagane
URLPolitykiPrywatności Sznurek Wymagane, jeśli parametr isPrivacyPolicyRequired = true Musi być prawidłowym adresem URL
witryna sieci Web Sznurek Musi być prawidłowym adresem URL
supportContactInfo Sznurek Musi być prawidłowym adresem URL lub adresem e-mail
notatki certyfikacyjne Sznurek Zalecane Limit znaków = 2000
kategoria Sznurek Wymagane Zobacz listę kategorii poniżej
Podkategorii Sznurek Wymagane Zobacz listę podkategorii poniżej
deklaracje produktów Przedmiot Wymagane
czySystemowaFunkcjaJestWymagana Tablica obiektów [Touch, Klawiatura, Mysz, Kamera, NFC_HCE, NFC_Proximity, Bluetooth_LE, Telefonia, Mikrofon]
wymagane Boolowski Wymagane
jestZalecane Boolowski Wymagane
typElementuSprzętowego Sznurek Wymagane
szczegóły wymagań systemowych Tablica obiektów [Procesor, grafika, pamięć, DirectX, Video_Memory]
minimalne wymagania Sznurek wymagane dla elementu systemRequirementsText, MaxLength = 200

Dozwolone wartości w hardwareItemType = Pamięć: [300 MB, 750 MB, 1 GB, 2 GB, 4 GB, 6 GB, 8 GB, 12 GB, 16 GB, 20 GB]

Dozwolone wartości w hardwareItemType = DirectX: [DX9, DX10, DX11, DX12-FEATURELEVEL11, DX12-FEATURELEVEL12]

Dozwolone wartości w hardwareItemType = Video_Memory: [1 GB, 2 GB, 4 GB, 6 GB]
zalecane wymaganie Sznurek wymagane dla elementu systemRequirementsText, MaxLength = 200

Dozwolone wartości w hardwareItemType = Pamięć: [300 MB, 750 MB, 1 GB, 2 GB, 4 GB, 6 GB, 8 GB, 12 GB, 16 GB, 20 GB]

Dozwolone wartości w hardwareItemType = DirectX: [DX9, DX10, DX11, DX12-FEATURELEVEL11, DX12-FEATURELEVEL12]

Dozwolone wartości w hardwareItemType = Video_Memory: [1 GB, 2 GB, 4 GB, 6 GB]
ZależyOdSterownikówLubNT Boolowski Wymagane
wsparcie dostępności Boolowski Wymagane
wsparcie dla pióra i tuszu Boolowski Wymagane
Ogłoszenia Przedmiot Obiekt wyświetlania listy danych modułu dla pojedynczego języka
Język Sznurek Wymagane Zobacz listę języków poniżej
opis Sznurek Limit znaków wymagany to 10000
Co nowego Sznurek Limit znaków = 1500
cechy produktu Tablica ciągów 200 znaków na funkcję; Maksymalnie 20 funkcji
krótki opis Sznurek Limit znaków = 1000
terminy wyszukiwania Tablica ciągów 30 znaków na termin wyszukiwania; Do 7 terminów wyszukiwania

21 unikatowych wyrazów ŁĄCZNIE we wszystkich terminach wyszukiwania
dodatkowe warunki licencji Sznurek Limit znaków wymagany to 10000
prawo autorskie Sznurek Limit znaków = 200
opracowany przez Sznurek Limit znaków = 255
wymagania Tablica obiektów 200 znaków na element; Maksymalnie 11 elementów łącznie między minimalną a zalecaną ilością]
minimalne wymagania sprzętowe Sznurek Limit znaków = 200
zalecany sprzęt Sznurek Limit znaków = 200
informacje kontaktowe Sznurek Limit znaków = 200
listyDoDodania Tablica ciągów znaków Zobacz listę języków poniżej
listyDoUsunięcia Tablica ciągów znaków Zobacz listę języków poniżej

Rynki

Rynek Skrót
Afganistan AF
Albania AL
Algieria DZ
Samoa Amerykańskie JAKO
Andora REKLAMA
Angola AO
Anguilla Sztuczna inteligencja
Antarktyda AQ
Antigua i Barbuda AG
Argentyna Rzeczywistość rozszerzona
Armenia rano
Aruba AW
Australia AU
Austria PRZY
Azerbejdżan AZ
Bahamy Licencjat nauk ścisłych
Bahrajn BH
Bangladesz BD
Barbados BB
Białoruś PRZEZ
Belgia BYĆ
Belize BZ
Benin BJ
Bermudy BM
Bhutan BT
Boliwizańska Republika Wenezueli VE
Boliwia Bo
Bonaire BQ
Bośnia i Hercegowina BA
Botswana BW
Wyspa Bouvet BV
Brazylia BR
Terytorium Brytyjskiego Oceanu Indyjskiego IO
Brytyjskie Wyspy Dziewicze VG
Brunei BN
Bułgaria BG
Burkina Faso BF
Burundi Analityka Biznesowa (BI)
Kambodża KH
Kamerun CENTYMETR
Kanada CA
Cabo Verde Życiorys zawodowy
Wyspy Kajamańskie KY
Republika Środkowoafrykańska POR
Czad TD
Chile CL
Chiny CN
Wyspa Bożego Narodzenia CX
Wyspy Kokosowe (Keeling) DW
Kolumbia Kobalt
Komory km
Kongo Grafika komputerowa
Kongo (DRC) Płyta CD
Wyspy Cooka CK
Kostaryka CR
Chorwacja Zasoby Ludzkie
Curaçao CW
Cypr CY
Republika Czeska CZ
Côte d'Ivoire Ciągła integracja
Dania DK
Dżibuti DJ
Dominika dm
Dominikana ZRÓB
Ekwador Komisja Europejska
Egipt NP
Salwador SV
Gwinea Równikowa GQ
Erytrea ER
Estonia EE
Etiopia ET
Wyspy Falklandzkie FK
Wyspy Owcze FO
Fidżi FJ
Finlandia Fi
Francja Francja
Gujana Francuska bezglutenowy (assuming "GF" stands for "gluten-free")
Polinezja Francuska PF
Francuskie Lądy Południowe i Antarktydy TF
Gabon Zgromadzenie Ogólne
Gambia General Motors
Gruzja GE
Niemcy Niemcy
Ghana GH
Gibraltar Indeks glikemiczny
Grecja GR
Grenlandia GL
Grenada GD
Gwadelupa Lekarz rodzinny
Guam GU
Gwatemala GT
Guernsey GG
Gwinea GN
Gwinea Bissau GW
Gujana GY
Haiti HT
Wyspy Heard i McDonald HM
Watykan VA
Honduras HN
Specjalny Region Administracyjny Hongkong HK
Węgry HU
Islandia JEST
Indie W
Indonezja Identyfikator
Irak IQ
Irlandia IE (Internet Explorer)
Izrael Illinois
Włochy Dział IT
Jamajka JM
Japonia JP
Jersey JE
Jordania JO
Kazachstan Kazachstan
Kenia Komisja Europejska
Kiribati KI
Korea KR
Kuwejt KW
Kirgistan kg
Laos LA
Łotwa Łotwa
Liban FUNT
Lesotho LS
Liberia LR
Libia LY
Liechtenstein LI
Litwa LT
Luksemburg LU
Makau SAR MO
Macedonia Północna MK
Madagaskar MG
Malawi MW
Malezja moje
Malediwy MV
Mali ML (uczenie maszynowe)
Malta MT
Wyspa Mana Komunikator internetowy
Wyspy Marshalla MH
Martynika MQ
Mauretania PAN
Mauritius MU
Majotta YouTube
Meksyk MX
Mikronezja FM
Mołdawia Lekarz medycyny
Monako MC
Mongolia MN
Montenegr - ME
Montserrat MS
Maroko mgr
Mozambik MZ
Myanmar MM
Namibia NIE
Nauru NR
Nepal NP
Holandia Holandia
Nowa Kaledonia NC
Nowa Zelandia NZ
Nikaragua NI
Niger NE
Nigeria NG
Niue NU
Wyspa Norfolk NF
Mariany Północne poseł
Norwegia NIE
Oman OM
Pakistan PK
Palau PW
Autonomia Palestyńska Postscriptum
Panama TATUŚ
Papua-Nowa Gwinea PG
Paragwaj PY
Peru PE
Filipiny PH
Wyspy Pitcairn PN
Polska Polska
Portugalia PT
Katar Zapewnienie Jakości
Spotkanie ODP
Rumunia RO
Rosja Rosja
Rwanda RW
Saint-Barthélemy BL
Święte Helena, Wniebowstąpienie i Tristan da Cunha SH
Saint Kitts i Nevis KN
Saint Lucia LC
Saint Martin (część francuska) Ministerstwo Finansów
Saint Pierre i Miquelon po południu
Saint Vincent i Grenadyny Kapitał podwyższonego ryzyka (VC)
Samoa WS
San Marino SM
Arabia Saudyjska S.A.
Senegal SN
Serbia RS
Seszele SC
Sierra Leone SL
Singapur SG
Sint Maarten (część holenderska) SX
Słowacja SK
Słowenia Międzynarodowy Układ Jednostek SI
Wyspy Salomona SB
Somalia WIĘC
Republika Południowej Afryki ZA
Georgia Południowa i Południowe Wyspy Sandwich GS
Hiszpania ES
Sri Lanka LK
Surinam SR
Svalbard i Jan Mayen SJ
Eswatini SZ
Szwecja SE
Szwajcaria CH
São Tomé i Príncipe ST
Tajwan TW
Tadżykistan TJ
Tanzania TZ
Tajlandia TH
Timor-Leste TL
Tog — TG
Tokelau TK
Tonga DO
Trynidad i Tobag - TT
Tunezja TN
Turcja Turcja
Turkmenistan TM
Wyspy Turks i Caicos TC
Tuvalu TELEWIZJA
Niewielkie wyspy zewnętrzne USA Uniwersytet Michigan
Wyspy Dziewicze Stanów Zjednoczonych VI
Uganda UG
Ukraina UA
Zjednoczone Emiraty Arabskie AE
Wielka Brytania GB
Stany Zjednoczone USA
Urugwaj UY
Uzbekistan UZ
Vanuatu VU
Wietnam VN
Wallis i Futuna WF
Jemen Jemen
Zambia ZM
Zimbabwe ZW
Wyspy Alandzkie SIEKIERA

Kategorie i podkategorie

Kategoria Podkategorie
Książki i Odniesienia Czytnik e-booków, Fikcja, Literatura faktu, Literatura naukowa
Biznes Księgowość i finanse, Współpraca, CRM, Dane i analityka, Zarządzanie plikami, Inwentaryzacja i logistyka, Prawo i HR, Zarządzanie projektami, Pulpit zdalny, Sprzedaż i marketing, Czas i wydatki
DeveloperTools Bazy danych, Narzędzia projektowe, Zestawy deweloperskie, Sieć komputerowa, Materiały referencyjne i szkoleniowe, Serwery, Narzędzia administracyjne, Hosting stron WWW
Edukacja KsiążkiEdukacyjneIReferencyjne, WczesnaNauka, NarzędziaInstruktażowe, Język, PomocNaukowa
Rozrywka (N/A)
FoodAndDining (N/A)
Rząd i polityka (N/A)
Zdrowie i Fitness (N/A)
Dzieci i Rodzina KsiążkiIDokumentyDlaDzieciIRodziny, RozrywkaDlaDzieciIRodziny, HobbyIZabawki, SportIAktywności, PodróżeDlaDzieciIRodziny
Styl życia Automotive, DIY, Dom i Ogród, Relacje, Zainteresowania Specjalne, Styl i Moda
Medyczny (N/A)
Projektowanie multimedialne Ilustracja i projektowanie graficzne, Produkcja muzyczna, Produkcja fotograficzna i wideo
Muzyka (N/A)
NavigationAndMaps (N/A)
WiadomościIPogoda Wiadomości, pogoda
Finanse osobiste Bankowość I Inwestycje, Budżetowanie I Podatki
Personalizacja Dzwonki i Dźwięki, motywy, Tapety i Ekrany Blokady
Zdjęcie i Video (N/A)
Produktywność (N/A)
Bezpieczeństwo PCProtection, PersonalSecurity
Zakupy (N/A)
Społeczny (N/A)
Sport (N/A)
Podróż CityGuides, Hotele
Narzędzia i narzędzia pomocnicze BackupAndManage, FileManager

Języki

Nazwa języka Obsługiwane kody języków
Afrikaans af, af-za
Albański sq, sq-al
Amharski rano, am-et
Armeński Cześć, hy-am
język assamski as, as-in
Azerbejdżańcy az-arab, az-arab-az, az-cyrl, az-cyrl-az, az-latn, az-latn-az
Baskijski (baskijski) ja, eu-es
Białoruski bądź, be-by
język bengalski bn, bn-bd, bn-in
Bośniacki bs, bs-cyrl, bs-cyrl-ba, bs-latn, bs-latn-ba
Bułgarski bg, bg-bg
Kataloński ca, ca-es, ca-es-valencia
Cherokee chr-cher, chr-cher-us, chr-latn
Chiński (uproszczony) zh-Hans, zh-cn, zh-hans-cn, zh-sg, zh-hans-sg
Chiński (tradycyjny) zh-Hant, zh-hk, zh-mo, zh-tw, zh-hant-hk, zh-potent-mo, zh-potent-tw, zh-mo, zh-tw, zh-tweet-hk, zh-tweet-mo, zh-hant-tw
Chorwacki hr, hr-hr, hr-ba
Czeski cs, cs-cz
Duński tak, da-dk
Dari prs, prs-af, prs-arab
Niderlandzki nl, nl-nl, nl-be
angielski en, en-au, en-ca, en-gb, en-ie, en-in, en-nz, en-sg, en-us, en-za, en-bz, en-hk, en-id, en-jm, en-kz, en-mt, en-my, en-phen-pk, en-tt, en-vn, en-zw
Estoński oraz, et-ee
Filipin - fil, fil-latn, fil-ph
Fiński fi, fi-fi
Francuski fr, fr-be , fr-ca , fr-ch , fr-fr , fr-lu, fr-cd, fr-ci, fr-cm, fr-ht, fr-ma, fr-mc, fr-ml, fr-re, frc-latn, frp-latn
Galicyjski gl, gl-es
Gruziński ka, ka-ge
Niemiecki de, de-at, de-ch, de-de, de-lu, de-li
Grecki el, el-gr
Gudżarati gu, gu-in
Hausa ha, ha-latn, ha-latn-ng
Hebrajski on, he-il
Język hindi cześć, hi-in
Węgierski hu, hu-hu
Islandzki jest, is-is
Igb — ig-latn, ig-ng
Indonezyjski id, id-id
Inuktitut (łaciński) iu-cans, iu-latn, iu-latn-ca
Irlandzki ga, ga-ie
isiXhosa xh, xh-za
isiZulu zu, zu-za
Włoski to, it-it, it-ch
Japoński tak , ja-jp
Kannada kn, kn-in
język kazachski kk, kk-kz
język khmerski km, km-kh
K'iche' quc-latn, qut-gt, qut-latn
Kinyarwanda rw, rw-rw
Suahili sw, sw-ke
Konkani kok, kok-in
Koreański ko, ko-kr
Kurdyjski ku-arab, ku-arab-iq
Kirgiski ky-kg, ky-cyrl
Laotański lo, lo-la
Łotewski lv, lv-lv
Litewski lt, lt-lt
Luksemburski lb, lb-lu
Macedoński mk, mk-mk
Malajski ms, ms-bn, ms-my
Malayalam ml, ml-in
Maltański mt, mt-mt
Māori mi, mi-latn, mi-nz
Marathi pan, mr-in
Mongolski (cyrylica) mn-cyrl, mn-mong, mn-mn, mn-phag
Nepalski nie, ne-np
Norweski nb, nb-no, nn, nn-no, nie, no-no
Orija lub, or-in
Perski fa, fa-ir
Polski pl, pl-pl
portugalski (Brazylia) pt-br
Język portugalski (Portugalia) pt, pt-pt
Pendżabski pa, pa-arab, pa-arab-pk, pa-deva, pa-in
Keczua quz, quz-bo, quz-ec, quz-pe
Rumuński ro, ro-ro
Rosyjski ru , ru-ru
Szkocki gaelicki gd-gb, gd-latn
Serbski (łaciński) sr-Latn, sr-latn-cs, sr-latn-ba, sr-latn-me, sr-latn-rs
Serbski (cyrylica) sr-cyrl, sr-cyrl-ba, sr-cyrl-cs, sr-cyrl-me, sr-cyrl-rs
Sesotho sa Leboa nso, nso-za
Setswana tn, tn-bw, tn-za
Sindhi sd-arab, sd-arab-pk, sd-deva
Sinhala tak, si-lk
Słowacki sk, sk-sk
Słoweński sl, sl-si
Hiszpański es, es-cl, es-co, es-es, es-mx, es-ar, es-bo, es-cr, es-do, es-ec, es-gt, es-hn, es-ni, es-pa, es-pe, es-pr, es-py, es-sv, es-uses-uy, es-ve
Szwedzki sv, sv-se, sv-fi
język tadżycki (cyrylica) tg-arab, tg-cyrl, tg-cyrl-tj, tg-latn
język tamilski ta, ta-in
Tatarski tt-arab, tt-cyrl, tt-latn, tt-ru
Telugu te, te-in
Tajska th, th-th
Tigrinia ti, ti-et
Turecki tr, tr-tr
Turkmeński tk-cyrl, tk-latn, tk-tm, tk-latn-tr, tk-cyrl-tr
Ukraiński uk, uk-ua
urdu twój, ur-pk
Ujgur ug-arab, ug-cn, ug-cyrl, ug-latn
Uzbek (łaciński) uz, uz-cyrl, uz-latn, uz-latn-uz
Wietnamski vi, vi-vn
Walijski cy, cy-gb
Wolof wo, wo-sn
Joruba yo-latn, yo-ng

Przykładowe żądanie

{
    "availability":{
        "markets": ["US"],
        "discoverability": "DISCOVERABLE",
        "enableInFutureMarkets": true,
        "pricing": "PAID",
        "freeTrial": "NO_FREE_TRIAL"
    },
    "properties":{
        "isPrivacyPolicyRequired": true,
        "privacyPolicyUrl": "http://contoso.com",
        "website": "http://contoso.com",
        "supportContactInfo": "http://contoso.com",
        "certificationNotes": "Certification Notes",
        "category": "DeveloperTools",
        "subcategory": "Database",
        "productDeclarations": {
            "dependsOnDriversOrNT": false,
            "accessibilitySupport": false,
            "penAndInkSupport": false
        },
        "isSystemFeatureRequired": [
        {
            "isRequired": true,
                "isRecommended": false,
                "hardwareItemType": "Touch"
            },
            {
                "isRequired": true,
                "isRecommended": false,
                "hardwareItemType": "Keyboard"
            },
            {
                "isRequired": false,
                "isRecommended": false,
                "hardwareItemType": "Mouse"
            },
            {
                "isRequired": false,
                "isRecommended": false,
                "hardwareItemType": "Camera"
            },
            {
                "isRequired": false,
                "isRecommended": false,
                "hardwareItemType": "NFC_HCE"
            },
            {
                "isRequired": false,
                "isRecommended": false,
                "hardwareItemType": "NFC_Proximity"
            },
            {
                "isRequired": false,
                "isRecommended": false,
                "hardwareItemType": "Bluetooth_LE"
            },
            {
                "isRequired": false,
                "isRecommended": false,
                "hardwareItemType": "Telephony"
            },
            {
                "isRequired": false,
                "isRecommended": false,
                "hardwareItemType": "Microphone"
            }
        ],
        "systemRequirementDetails": [
            {
                "minimumRequirement": "1GB",
                "recommendedRequirement": "4GB",
                "hardwareItemType": "Memory"
            },
            {
                "minimumRequirement": "",
                "recommendedRequirement": "",
                "hardwareItemType": "DirectX"
            },
            {
                "minimumRequirement": "",
                "recommendedRequirement": "",
                "hardwareItemType": "Video_Memory"
            },
            {
                "minimumRequirement": "",
                "recommendedRequirement": "",
                "hardwareItemType": "Processor"
            },
            {
                "minimumRequirement": "",
                "recommendedRequirement": "",
                "hardwareItemType": "Graphics"
            }
        ]
    },
    "listings":{
        "language": "en-us",
        "description": "Description",
        "whatsNew": "What's New",
        "productFeatures": ["Feature 1"],
        "shortDescription": "Short Description",
        "searchTerms": ["Search Ter 1"],
        "additionalLicenseTerms": "License Terms",
        "copyright": "Copyright Information",
        "developedBy": "Developer Details",
        "sortTitle": "Product 101",
        "requirements": [
            {
                "minimumHardware": "Pentium4",
                "recommendedHardware": "Corei9"
            }
        ],
        "contactInfo": "contactus@contoso.com"               
    },      
    "listingsToAdd": ["en-au"],
    "listingsToRemove": ["en-gb"]
}

nagłówki odpowiedzi

Nagłówek Wartość
X-Correlation-ID Unikatowy identyfikator typu GUID dla każdego żądania. Można to udostępnić zespołowi pomocy technicznej w celu analizowania dowolnego problemu.
Retry-After Czas w sekundach, przez który klient musi czekać przed ponownym wywołaniem interfejsów API z powodu ograniczania szybkości

Parametry odpowiedzi

Nazwa Typ Opis
czySukces Boolowski
Błędy Tablica obiektów Lista komunikatów o błędach lub ostrzeżeniach, jeśli istnieją
kod Sznurek Kod błędu komunikatu
Komunikat Sznurek Opis błędu
cel Sznurek Jednostka, z której pochodzi błąd
dane odpowiedzi Przedmiot Zawiera rzeczywisty ładunek odpowiedzi dla żądania
adres ankiety Sznurek Adres URL do sondowania w celu sprawdzenia statusu każdego przesłania In-Progress
identyfikatorTrwającegoZgłoszenia Sznurek Identyfikator zgłoszenia jakiegokolwiek już przesłanego In-Progress

Przykładowa odpowiedź

{
    "isSuccess": true,
    "errors": [{
        "code": "badrequest",
        "message": "Error Message 1",
        "target": "listings"
        }, {
        "code": "warning",
        "message": "Warning Message 1",
        "target": "properties"
    }],
    "responseData": {
        "pollingUrl": "/submission/v1/product/{productId}/submission/{submissionId}/status",
        "ongoingSubmissionId": ""
    } 
}

Pozyskaj bieżące wersje robocze pakietów interfejsu API

Pobiera szczegóły pakietu w bieżącej wersji roboczej przesyłania.

ścieżka [Wszystkie pakiety]: /submission/v1/product/{productId}/packages
, metoda: GET

ścieżka [pojedynczy pakiet]: /submission/v1/product/{product/{productId}/packages/{packageId}
, metoda: GET

Parametry ścieżki

Nazwa Opis
ID produktu Identyfikator Partner Center produktu
packageId (identyfikator pakietu) Unikatowy identyfikator pakietu do pobrania

Wymagane nagłówki

Nagłówek Wartość
Authorization: Bearer <Token> Używanie identyfikatora aplikacji usługi Azure AD zarejestrowanego przy użyciu konta Centrum partnerskiego
X-Seller-Account-Id Identyfikator konta sprzedawcy w Centrum partnerskim

nagłówki odpowiedzi

Nagłówek Wartość
X-Correlation-ID Unikatowy identyfikator typu GUID dla każdego żądania. Może to być udostępniane zespołowi pomocy technicznej w celu analizowania dowolnego problemu.
Retry-After Czas w sekundach, który klient musi czekać przed ponownym wywołaniem interfejsów API z powodu ograniczania szybkości.

Parametry odpowiedzi

Nazwa Typ Opis
czySukces Boolowski
Błędy Tablica obiektów Lista błędów lub komunikatów ostrzegawczych, jeśli istnieją
kod Sznurek Kod błędu komunikatu
Komunikat Sznurek Opis błędu
cel Sznurek Jednostka, z której pochodzi błąd
dane odpowiedzi Przedmiot
pakiety Tablica obiektów Obiekt do przechowywania danych modułu pakietu
packageId (identyfikator pakietu) Sznurek
adresPakietu Sznurek
Języki Tablica ciągów znaków
Architektury Tablica ciągów znaków [Neutral, X86, X64, Arm, Arm64]
isSilentInstall Boolowski Należy oznaczyć jako prawda, jeśli instalator działa w trybie dyskretnym bez potrzeby użycia przełączników, w przeciwnym razie nieprawda.
parametry instalatora Sznurek
genericDocUrl Sznurek
szczegóły błędu Tablica obiektów
scenariusz błędu Sznurek
SzczegółyScenariuszaBłędu Tablica obiektów
wartość błędu Sznurek
adresURLbłąd Sznurek
typ pakietu Sznurek

Przykładowa odpowiedź

{   
    "isSuccess": true,
    "errors": [{
        "code": "badrequest",
        "message": "Error Message 1",
        "target": "listings"
    }, {
        "code": "warning",
        "message": "Warning Message 1",
        "target": "properties"
    }],
    "responseData":{
        "packages":[{
            "packageId": "pack0832",
            "packageUrl": "https://www.contoso.com/downloads/1.1/setup.exe",
            "languages": ["en-us"],
            "architectures": ["X86"],
            "isSilentInstall": true,
            "installerParameters": "/s",
            "genericDocUrl": "https://docs.contoso.com/doclink",
            "errorDetails": [{
                "errorScenario": "rebootRequired",
                "errorScenarioDetails": [{
                    "errorValue": "ERR001001",
                    "errorUrl": "https://errors.contoso.com/errors/ERR001001"
                }]
            }],
            "packageType": "exe",
        }]
    }
}

Zaktualizuj interfejs API bieżących pakietów roboczych

Uzupełnia szczegóły pakietu w ramach bieżącej wersji roboczej zgłoszenia.

Ścieżka [pełna aktualizacja modułu]: /submission/v1/product/{productId}/packages
, metoda: PUT

ścieżka [aktualizacja poprawki pojedynczego pakietu]: /submission/v1/product/{productId}/packages/{packageId}
: metoda: PATCH

zachowania interfejsu API

W przypadku interfejsu API aktualizacji pełnego modułu — kompletne dane pakietów muszą być zawarte w żądaniu, aby zaktualizować wszystkie pola. Każde pole, które nie jest obecne w żądaniu, jej wartość domyślna zostaje użyta do zastąpienia bieżącej wartości dla danego modułu. Spowoduje to zastąpienie wszystkich istniejących pakietów nowym zestawem pakietów wynikających z żądania. Spowoduje to ponowne generowanie identyfikatorów pakietów, a użytkownik powinien wywołać interfejs API GET Packages dla najnowszych identyfikatorów pakietów.

W przypadku interfejsu API aktualizacji pojedynczego pakietu — w żądaniu muszą znajdować się tylko pola, które mają zostać zaktualizowane dla danego pakietu. Te wartości pól z żądania zastąpią ich istniejące wartości, zachowując wszystkie inne pola, które nie są obecne w żądaniu, takie jak bieżące dla tego konkretnego pakietu. Inne pakiety w zestawie pozostają w niezmienionej postaci.

Parametry ścieżki

Nazwa Opis
ID produktu Identyfikator Partner Center produktu
packageId (identyfikator pakietu) Unikatowy identyfikator pakietu

Wymagane nagłówki

Nagłówek Wartość
Authorization: Bearer <Token> Używanie identyfikatora aplikacji usługi Azure AD zarejestrowanego przy użyciu konta Centrum partnerskiego
X-Seller-Account-Id Identyfikator konta sprzedawcy w Centrum partnerskim

Parametry żądania

Nazwa Typ Opis
pakiety Tablica obiektów Obiekt do przechowywania danych modułu pakietu [Wymagane tylko do pełnej aktualizacji modułu]
adresPakietu Sznurek Wymagane
Języki Tablica ciągów znaków Wymagane
Architektury Tablica ciągów znaków wymagane powinna zawierać jedną architekturę — Neutral, X86, X64, Arm, Arm64
isSilentInstall Boolowski Wymagane Powinno być ustawione jako prawda, jeśli instalator działa w trybie dyskretnym bez konieczności użycia przełączników, w przeciwnym razie jako fałsz.
parametry instalatora Sznurek Wymagane, jeśli isSilentInstall ma wartość false
genericDocUrl Sznurek Wymagane, jeśli parametr packageType jest exe Link do dokumentu zawierającego szczegóły niestandardowych kodów błędów instalatora typu EXE
szczegóły błędu Tablica obiektów Metadane przeznaczone do przechowywania niestandardowych kodów błędów i szczegółów dla instalatorów typu EXE.
scenariusz błędu Sznurek Zidentyfikuj konkretny scenariusz błędu. [instalacjaAnulowanaPrzezUżytkownika, aplikacjaJużIstnieje, instalacjaJużWTrakcie, brakMiejscaNaDysku, wymaganePonowneUruchomienie, awariaSieci, pakietOdrzuconyPodczasInstalacji, instalacjaZakończonaSukcesem, różne]
SzczegółyScenariuszaBłędu Tablica obiektów
wartość błędu Sznurek Kod błędu, który może być obecny podczas instalacji
adresURLbłąd Sznurek Adres URL, aby uzyskać szczegółowe informacje o błędzie
typ pakietu Sznurek wymagane [exe, msi]

Przykładowe żądanie [pełna aktualizacja modułu]

{
    "packages":[{
        "packageUrl": "https://www.contoso.com/downloads/1.1/setup.exe",
        "languages": ["en-us"],
        "architectures": ["X86"],
        "isSilentInstall": true,
        "installerParameters": "/s",
        "genericDocUrl": "https://docs.contoso.com/doclink",
        "errorDetails": [{
            "errorScenario": "rebootRequired",
            "errorScenarioDetails": [{
                "errorValue": "ERR001001",
                "errorUrl": "https://errors.contoso.com/errors/ERR001001"
            }]
        }],
        "packageType": "exe",
    }]
}

przykładowe żądanie [aktualizacja poprawki pojedynczego pakietu]

{
    "packageUrl": "https://www.contoso.com/downloads/1.1/setup.exe",
    "languages": ["en-us"],
    "architectures": ["X86"],
    "isSilentInstall": true,
    "installerParameters": "/s",
    "genericDocUrl": "https://docs.contoso.com/doclink",
    "errorDetails": [{
        "errorScenario": "rebootRequired",
        "errorScenarioDetails": [{
            "errorValue": "ERR001001",
            "errorUrl": "https://errors.contoso.com/errors/ERR001001"
        }]
    }],
    "packageType": "exe",
}

nagłówki odpowiedzi

Nagłówek Wartość
X-Correlation-ID Unikatowy identyfikator typu GUID dla każdego żądania. Może to być udostępniane zespołowi pomocy technicznej w celu analizowania dowolnego problemu.
Retry-After Czas w sekundach, który klient musi czekać przed ponownym wywołaniem interfejsów API z powodu ograniczania szybkości.

Parametry odpowiedzi

Nazwa Typ Opis
czySukces Boolowski
Błędy Tablica obiektów [Lista komunikatów o błędach lub ostrzeżeniach, jeśli istnieje]
kod Sznurek Kod błędu komunikatu
Komunikat Sznurek Opis błędu
cel Sznurek Jednostka, z której pochodzi błąd
dane odpowiedzi Przedmiot
adres ankiety Sznurek [Adres URL do odpytywania, aby uzyskać stan przesłania w razie już przesłania In-Progress]
identyfikatorTrwającegoZgłoszenia Sznurek [Identyfikator dowolnego już istniejącego przesłania In-Progress]

Przykładowa odpowiedź

{
    "isSuccess": true,
    "errors": [{
        "code": "badrequest",
        "message": "Error Message 1",
        "target": "listings"
        }, {
        "code": "warning",
        "message": "Warning Message 1",
        "target": "properties"
    }],
    "responseData": {
        "pollingUrl": "/submission/v1/product/{productId}/submission/{submissionId}/status",
        "ongoingSubmissionId": ""
    } 
}

Interfejs API zatwierdzania pakietów

Zatwierdza nowy zestaw pakietów zaktualizowanych przy użyciu interfejsów API aktualizacji pakietów w ramach bieżącej wersji roboczej. Ten interfejs API zwraca adres URL sondowania do śledzenia przesyłania pakietu.

ścieżka: /submission/v1/product/{productId}/packages/commit
, metoda: POST

Parametry ścieżki

Nazwa Opis
ID produktu Identyfikator Partner Center produktu

Wymagane nagłówki

Nagłówek Wartość
Authorization: Bearer <Token> Używanie identyfikatora aplikacji usługi Azure AD zarejestrowanego przy użyciu konta Centrum partnerskiego
X-Seller-Account-Id Identyfikator konta sprzedawcy w Centrum partnerskim

nagłówki odpowiedzi

Nagłówek Wartość
X-Correlation-ID Unikatowy identyfikator typu GUID dla każdego żądania. Może to być udostępniane zespołowi pomocy technicznej w celu analizowania dowolnego problemu.
Retry-After Czas w sekundach, który klient musi czekać przed ponownym wywołaniem interfejsów API z powodu ograniczania szybkości.

Parametry odpowiedzi

Nazwa Typ Opis
czySukces Boolowski
Błędy Tablica obiektów [Lista komunikatów o błędach lub ostrzeżeniach, jeśli istnieje]
kod Sznurek Kod błędu komunikatu
Komunikat Sznurek Opis błędu
cel Sznurek Jednostka, z której pochodzi błąd
dane odpowiedzi Przedmiot
adres ankiety Sznurek [Adres URL sondowania, aby uzyskać stan przekazywania lub przesyłania pakietu w przypadku dowolnego już In-Progress przesyłania]
identyfikatorTrwającegoZgłoszenia Sznurek [Identyfikator przesyłania dowolnego już In-Progress przesłania]

Przykładowa odpowiedź

{
    "isSuccess": true,
    "errors": [{
        "code": "badrequest",
        "message": "Error Message 1",
        "target": "listings"
        }, {
        "code": "warning",
        "message": "Warning Message 1",
        "target": "properties"
    }],
    "responseData": {
        "pollingUrl": "/submission/v1/product/{productId}/status",
        "ongoingSubmissionId": ""
    } 
}

Pobierz bieżący interfejs API zasobów listy roboczej

Pobiera szczegóły elementów zawartości w bieżącej wersji roboczej przesyłania.

ścieżka: /submission/v1/product/{productId}/listings/assets?languages={languages}
, metoda: GET

Parametry ścieżki

Nazwa Opis
ID produktu Identyfikator Partner Center produktu

Parametry zapytania

Nazwa Opis
Języki [Opcjonalnie] Lista języków filtruje jako ciąg rozdzielony przecinkami [limit do 200 języków]. W przypadku nieobecności, zostaną pobrane dane pierwszych 200 dostępnych zasobów w języku ogłoszenia. (np. "en-us, en-gb")

Wymagane nagłówki

Nagłówek Wartość
Authorization: Bearer <Token> Używanie identyfikatora aplikacji usługi Azure AD zarejestrowanego przy użyciu konta Centrum partnerskiego
X-Seller-Account-Id Identyfikator konta sprzedawcy w Centrum partnerskim

nagłówki odpowiedzi

Nagłówek Wartość
X-Correlation-ID Unikatowy identyfikator typu GUID dla każdego żądania. Może to być udostępniane zespołowi pomocy technicznej w celu analizowania dowolnego problemu.
Retry-After Czas w sekundach, który klient musi czekać przed ponownym wywołaniem interfejsów API z powodu ograniczania szybkości.

Parametry odpowiedzi

Nazwa Typ Opis
czySukces Boolowski
Błędy Tablica obiektów Lista komunikatów o błędach lub ostrzeżeniach, jeśli istnieją
kod Sznurek Kod błędu komunikatu
Komunikat Sznurek Opis błędu
cel Sznurek Jednostka, z której pochodzi błąd
dane odpowiedzi Przedmiot
wyświetlanie zasobów Tablica obiektów Wyświetlanie szczegółów zasobów dla każdego języka
Język Sznurek
logotypySklepów Tablica obiektów
zrzuty ekranu Tablica obiektów
id Sznurek
assetUrl Sznurek Musi być prawidłowym adresem URL
rozmiarObrazu Przedmiot
Szerokość Liczba całkowita
wysokość Liczba całkowita

Przykładowa odpowiedź

{   
"isSuccess": true,
    "errors": [{
        "code": "badrequest",
        "message": "Error Message 1",
        "target": "listings"
        }, {
        "code": "warning",
        "message": "Warning Message 1",
        "target": "properties"
    }],
    "responseData":{
        "listingAssets": [{
            "language": "en-us",
            "storeLogos": [
                {
                    "id": "1234567890abcdefgh",
                    "assetUrl": "https://contoso.com/blob=1234567890abcdefgh",
                    "imageSize": {
                        "width": 2160,
                        "height": 2160
                    }
                }
            ],
            "screenshots": [
                {
                    "id": "1234567891abcdefgh",
                    "assetUrl": "https://contoso.com/blob=1234567891abcdefgh",
                    "imageSize": {
                        "width": 2160,
                        "height": 2160
                    }
                }
            ]
        }]
    }
}

Interfejs API do tworzenia zasobów listingu

Tworzy nowe przesyłanie zasobów listingu w ramach bieżącej wersji roboczej zgłoszenia.

Aktualizacja zasobów listy

Interfejs API przesyłania ze sklepu Microsoft Store dla pliku EXE lub aplikacji MSI używa adresów SAS generowanych przez środowisko uruchomieniowe do magazynów Blob dla każdego przekazywania poszczególnych zasobów obrazu oraz wywołania interfejsu API zatwierdzania po pomyślnym przekazaniu. Aby mieć możliwość aktualizowania zasobów listy i z kolei, aby można było dodawać/usuwać ustawienia regionalne w module listy, można użyć następującego podejścia:

  1. Użyj interfejsu API Create Listing Asset, aby wysłać żądanie dotyczące przesyłania zasobów wraz z językiem, typem i ilością zasobów.
  2. Na podstawie liczby żądanych zasobów identyfikatory zasobów są tworzone na żądanie i mogłyby utworzyć krótkoterminowy adres URL sygnatury dostępu współdzielonego i wysłać go z powrotem w treści odpowiedzi pod typem zasobów. Za pomocą tego adresu URL można przekazać zasoby obrazów określonego typu przy użyciu klientów HTTP [Put Blob (interfejs API REST) — Azure Storage | Microsoft Docs].
  3. Po przekazaniu możesz skorzystać z interfejsu API zatwierdzania zasobów na liście, aby również wysłać nowe informacje o identyfikatorze zasobu, które otrzymano wcześniej z poprzedniego wywołania interfejsu API. Pojedynczy interfejs API wewnętrznie zatwierdzi dane zasobów listy po weryfikacji.
  4. Takie podejście skutecznie zastąpi cały zestaw poprzednich obrazów typu zasobu w określonym języku, który jest wysyłany w żądaniu. W związku z tym wcześniej przesłane zasoby zostaną usunięte.

ścieżka: /submission/v1/product/{productId}/listings/assets/create
, metoda: POST

Parametry ścieżki

Nazwa Opis
ID produktu Identyfikator Partner Center produktu

Wymagane nagłówki

Nagłówek Opis
Authorization: Bearer <Token> Używanie identyfikatora aplikacji usługi Azure AD zarejestrowanego przy użyciu konta Centrum partnerskiego
X-Seller-Account-Id Identyfikator konta sprzedawcy w Centrum partnerskim

Parametry żądania

Nazwa Typ Opis
Język Sznurek Wymagane
utwórzŻądanieUtworzeniaZasobu Przedmiot Wymagane
Zrzut ekranu Liczba całkowita Wymagane, jeśli niezależny dostawca oprogramowania musi zaktualizować zrzuty ekranu lub dodać nowy język opisu [1–10]
Logo Liczba całkowita Wymagane, jeśli niezależny dostawca oprogramowania musi zaktualizować logo lub dodać nowy język ogłoszenia [1 lub 2]

nagłówki odpowiedzi

Nagłówek Opis
X-Correlation-ID Unikatowy identyfikator typu GUID dla każdego żądania. Może to być udostępniane zespołowi pomocy technicznej w celu analizowania dowolnego problemu.
Retry-After Czas w sekundach, który klient musi czekać przed ponownym wywołaniem interfejsów API z powodu ograniczania szybkości.

Parametry odpowiedzi

Nazwa Typ Opis
czySukces Boolowski
Błędy Tablica obiektów Lista komunikatów o błędach lub ostrzeżeniach, jeśli istnieją
kod Sznurek Kod błędu komunikatu
Komunikat Sznurek Opis błędu
cel Sznurek Jednostka, z której pochodzi błąd
dane odpowiedzi Przedmiot
wyświetlanie zasobów Przedmiot Obiekt zawierający szczegółowe informacje o StoreLogos i Zrzutach ekranu do przesłania
Język Sznurek
logotypySklepów Tablica obiektów
zrzuty ekranu Tablica obiektów
id Sznurek
primaryAssetUploadUrl Sznurek Podstawowy adres URL do przekazywania elementu zawartości listy przy użyciu interfejsu API REST obiektu blob platformy Azure
adres przesyłania dodatkowych zasobów Sznurek Pomocniczy adres URL do przekazywania elementu zawartości listy przy użyciu interfejsu API REST usługi Azure Blob
HTTPMetoda Metoda HTTP Metoda HTTP musi służyć do przekazywania zasobów za pośrednictwem adresów URL przekazywania zasobów — podstawowy lub pomocniczy
Nagłówki HTTP Przedmiot Obiekt, w którym kluczami są wymagane nagłówki do umieszczenia w wywołaniu API do przekazywania na adresy URL przesyłania zasobów. Jeśli wartość jest niepusta, nagłówki muszą mieć określone wartości. W przeciwnym razie wartości są obliczane podczas wywoływania interfejsu API.

Przykładowa odpowiedź

{
    "isSuccess": true,
    "errors": [{
        "code": "badrequest",
        "message": "Error Message 1",
        "target": "listings"
        }, {
        "code": "warning",
        "message": "Warning Message 1",
        "target": "properties"
    }],
    "responseData": {
        "listingAssets": {
            "language": "en-us",
            "storeLogos":[{
                "id": "1234567890abcdefgh",
                "primaryAssetUploadUrl": "https://contoso.com/upload?blob=1234567890abcdefgh&sig=12345",
                "secondaryAssetUploadUrl": "https://contoso.com/upload?blob=0987654321abcdfger&sig=54326",
                "httpMethod": "PUT",
                "httpHeaders": {"Required Header Name": "Header Value"}
            }],
            "screenshots":[{
                "id": "0987654321abcdfger",
                "primaryAssetUploadUrl": "https://contoso.com/upload?blob=0987654321abcdfger&sig=54321",
                "secondaryAssetUploadUrl": "https://contoso.com/upload?blob=0987654321abcdfger&sig=54322",
                "httpMethod": "PUT",
                "httpHeaders": {"Required Header Name": "Header Value"}

            }]
        }
    } 
}

Interfejs API zarządzania listą zasobów

Zatwierdza nowy przesłany zasób listingu, korzystając ze szczegółów z interfejsu API tworzenia aktywów, w ramach bieżącej wersji roboczej zgłoszenia.

ścieżka: /submission/v1/product/{productId}/listings/assets/commit
, metoda: PUT

Parametry ścieżki

Nazwa Opis
ID produktu Identyfikator Partner Center produktu

Wymagane nagłówki

Nagłówek Opis
Authorization: Bearer <Token> Używanie identyfikatora aplikacji usługi Azure AD zarejestrowanego przy użyciu konta Centrum partnerskiego
X-Seller-Account-Id Identyfikator konta sprzedawcy w Centrum partnerskim

Parametry żądania

Nazwa Typ Opis
wyświetlanie zasobów Przedmiot
Język Sznurek
logotypySklepów Tablica obiektów
zrzuty ekranu Tablica obiektów
id Sznurek Powinien być albo istniejącym identyfikatorem, który użytkownik chce zachować z interfejsu API Pobierz Bieżące Zasoby Listy, albo nowym identyfikatorem, pod którym nowy zasób został przekazany w interfejsie API Utwórz Zasoby Listy.
assetUrl Sznurek Powinien być adresem URL istniejącego zasobu, który użytkownik chce zachować z interfejsu API Pobierz bieżące zasoby listy, lub adresem URL przesyłania — podstawowym lub pomocniczym, za pomocą którego nowy zasób został przesłany w interfejsie API Tworzenie zasobów listy. Musi być prawidłowym adresem URL

Przykładowe żądanie

{
    "listingAssets": { 
        "language": "en-us",    
        "storeLogos": [
            {
                "id": "1234567890abcdefgh",
                "assetUrl": "https://contoso.com/blob=1234567890abcdefgh",
            }
        ],
        "screenshots": [
            {
                "id": "1234567891abcdefgh",
                "assetUrl": "https://contoso.com/blob=1234567891abcdefgh",
            }
        ]
    }
}

nagłówki odpowiedzi

Nagłówek Opis
X-Correlation-ID Unikatowy identyfikator typu GUID dla każdego żądania. Może to być udostępniane zespołowi pomocy technicznej w celu analizowania dowolnego problemu.
Retry-After Czas w sekundach, który klient musi czekać przed ponownym wywołaniem interfejsów API z powodu ograniczania szybkości.

Parametry odpowiedzi

Nazwa Typ Opis
czySukces Boolowski
Błędy Tablica obiektów Lista komunikatów o błędach lub ostrzeżeniach, jeśli istnieją
kod Sznurek Kod błędu komunikatu
Komunikat Sznurek Opis błędu
cel Sznurek Jednostka, z której pochodzi błąd
dane odpowiedzi Przedmiot
adres ankiety Sznurek Adres URL do regularnego sprawdzania statusu przesyłania w toku
identyfikatorTrwającegoZgłoszenia Sznurek Identyfikator zgłoszenia jakiegokolwiek w trakcie przesłania

Przykładowa odpowiedź

{
    "isSuccess": true,
    "errors": [{
        "code": "badrequest",
        "message": "Error Message 1",
        "target": "listings"
        }, {
        "code": "warning",
        "message": "Warning Message 1",
        "target": "properties"
    }],
    "responseData": {
        "pollingUrl": "/submission/v1/product/{productId}/submission/{submissionId}/status",
        "ongoingSubmissionId": ""
    } 
}

Interfejs API odpytywania stanu modułu

Interfejs API do sprawdzenia gotowości modułu przed przesłaniem może być utworzony. Sprawdza również stan przesyłania pakietu.

ścieżka: /submission/v1/product/{productId}/status
, metoda: GET

Parametry ścieżki

Nazwa Opis
ID produktu Identyfikator Partner Center produktu

Wymagane nagłówki

Nagłówek Opis
Authorization: Bearer <Token> Używanie identyfikatora aplikacji usługi Azure AD zarejestrowanego przy użyciu konta Centrum partnerskiego
X-Seller-Account-Id Identyfikator konta sprzedawcy w Centrum partnerskim

nagłówki odpowiedzi

Nagłówek Opis
X-Correlation-ID Unikatowy identyfikator typu GUID dla każdego żądania. Może to być udostępniane zespołowi pomocy technicznej w celu analizowania dowolnego problemu.
Retry-After Czas w sekundach, który klient musi czekać przed ponownym wywołaniem interfejsów API z powodu ograniczania szybkości.

Parametry odpowiedzi

Nazwa Typ Opis
czySukces Boolowski
Błędy Tablica obiektów Lista komunikatów o błędach lub ostrzeżeniach, jeśli istnieją
kod Sznurek Kod błędu komunikatu
Komunikat Sznurek Opis błędu
cel Sznurek Jednostka, z której pochodzi błąd
dane odpowiedzi Przedmiot
gotowy Boolowski Wskazuje, czy wszystkie moduły są w gotowym stanie, w tym przesyłanie pakietu.
identyfikatorTrwającegoZgłoszenia Sznurek Identyfikator zgłoszenia jakiegokolwiek w trakcie przesłania

Przykładowa odpowiedź

{
    "isSuccess": true,
    "errors": [{
        "code": "badrequest",
        "message": "Error Message 1",
        "target": "listings"
        }, {
        "code": "warning",
        "message": "Warning Message 1",
        "target": "properties"
    }],
    "responseData": {
        "isReady": true,
        "ongoingSubmissionId": ""
    }
}

Utwórz interfejs API przesyłania

Tworzy zgłoszenie z bieżącej wersji roboczej aplikacji typu MSI lub EXE. Interfejs API sprawdza:

  • Jeśli istnieje aktywne przesyłanie, próba zakończy się niepowodzeniem i pojawi się komunikat o błędzie.
  • jeśli wszystkie moduły są w stanie gotowości, aby utworzyć zgłoszenie.
  • każde pole w zgłoszeniu jest weryfikowane zgodnie z wymaganiami sklepu

ścieżka:/submit/v1/product/{productId}/submit
, metoda: POST

Parametry ścieżki

Nazwa Opis
ID produktu Identyfikator Partner Center produktu

Wymagane nagłówki

Nagłówek Opis
Authorization: Bearer <Token> Używanie identyfikatora aplikacji usługi Azure AD zarejestrowanego przy użyciu konta Centrum partnerskiego
X-Seller-Account-Id Identyfikator konta sprzedawcy w Centrum partnerskim

nagłówki odpowiedzi

Nagłówek Opis
X-Correlation-ID Unikatowy identyfikator typu GUID dla każdego żądania. Może to być udostępniane zespołowi pomocy technicznej w celu analizowania dowolnego problemu.
Retry-After Czas w sekundach, który klient musi czekać przed ponownym wywołaniem interfejsów API z powodu ograniczania szybkości.

Parametry odpowiedzi

Nazwa Typ Opis
czySukces Boolowski
Błędy Tablica obiektów Lista komunikatów o błędach lub ostrzeżeniach, jeśli istnieją
kod Sznurek Kod błędu komunikatu
Komunikat Sznurek Opis błędu
cel Sznurek Jednostka, z której pochodzi błąd
dane odpowiedzi Przedmiot
adres ankiety Sznurek Adres URL odpytywania w celu uzyskania statusu gotowości modułu, w tym przesyłania pakietu do zgłoszenia.
ID zgłoszenia Sznurek Identyfikator nowo utworzonego zgłoszenia
identyfikatorTrwającegoZgłoszenia Sznurek Identyfikator zgłoszenia jakiegokolwiek w trakcie przesłania

Przykładowa odpowiedź

{
    "isSuccess": true,
    "errors": [{
        "code": "badrequest",
        "message": "Error Message 1",
        "target": "listings"
        }, {
        "code": "warning",
        "message": "Warning Message 1",
        "target": "properties"
    }],
    "responseData": {
        "submissionId": "1234567890", 
        "pollingUrl": "/submission/v1/product/{productId}/submission/{submissionId}/status",
        "ongoingSubmissionId": ""
    }
}

Interfejs API sondowania statusu przesyłki

Interfejs API do sprawdzenia statusu przesyłania.

ścieżka: /submission/v1/product/{productId}/submission/{submissionId}/status
, metoda: GET

Parametry ścieżki

Nazwa Opis
ID produktu Identyfikator Partner Center produktu

Wymagane nagłówki

Nagłówek Opis
Authorization: Bearer <Token> Używanie identyfikatora aplikacji usługi Azure AD zarejestrowanego przy użyciu konta Centrum partnerskiego
X-Seller-Account-Id Identyfikator konta sprzedawcy w Centrum partnerskim

nagłówki odpowiedzi

Nagłówek Opis
X-Correlation-ID Unikatowy identyfikator typu GUID dla każdego żądania. Może to być udostępniane zespołowi pomocy technicznej w celu analizowania dowolnego problemu.
Retry-After Czas w sekundach, który klient musi czekać przed ponownym wywołaniem interfejsów API z powodu ograniczania szybkości.

Parametry odpowiedzi

Nazwa Typ Opis
czySukces Boolowski
Błędy Tablica obiektów Lista komunikatów o błędach lub ostrzeżeniach, jeśli istnieją
kod Sznurek Kod błędu komunikatu
Komunikat Sznurek Opis błędu
cel Sznurek Jednostka, z której pochodzi błąd
dane odpowiedzi Przedmiot
status publikacji Sznurek Status publikacji zgłoszenia — [W TRAKCIE, OPUBLIKOWANO, NIE POWIODŁO SIĘ, NIEZNANY]
niepowodzenie nastąpiło Boolowski Wskazuje, czy publikowanie nie powiodło się i nie zostanie ponowione

Przykładowa odpowiedź

{
    "isSuccess": true,
    "errors": [{
        "code": "badrequest",
        "message": "Error Message 1",
        "target": "listings"
        }, {
        "code": "warning",
        "message": "Warning Message 1",
        "target": "properties"
    }],
    "responseData": {
        "publishingStatus": "INPROGRESS",
        "hasFailed": false
    }
}

Przykłady kodu

Poniższe artykuły zawierają szczegółowe przykłady kodu, które pokazują, jak używać interfejsu API przesyłania ze sklepu Microsoft Store w różnych językach programowania:

Przykład w języku C#: API przesyłania do sklepu Microsoft Store dla aplikacji MSI lub EXE

Ten artykuł zawiera przykłady kodu w języku C#, pokazujące, jak używać API przesyłania Microsoft Store dla aplikacji MSI lub EXE. Możesz przejrzeć każdy przykład, aby dowiedzieć się więcej o przedstawionym zadaniu lub utworzyć wszystkie przykłady kodu w tym artykule w aplikacji konsolowej.

Warunki wstępne W poniższych przykładach użyto następującej biblioteki:

  • Pakiet NuGet Newtonsoft.Json firmy Newtonsoft.

Program główny Poniższy przykład implementuje przykładowy program wiersza polecenia, który wywołuje inne przykładowe metody w tym artykule, aby zademonstrować różne sposoby korzystania z interfejsu API przesyłania do sklepu Microsoft Store. Aby dostosować ten program do własnego użycia:

  • Przypisz właściwość SellerId do identyfikatora sprzedawcy konta Centrum partnerskiego.
  • Przypisz właściwość ApplicationId do identyfikatora aplikacji, którą chcesz zarządzać.
  • Przypisz właściwości ClientId i ClientSecret do identyfikatora klienta i klucza dla swojej aplikacji, a następnie zastąp ciąg tenantid w adresie URL TokenEndpoint identyfikatorem dzierżawy dla Twojej aplikacji. Aby uzyskać więcej informacji, zobacz Jak skojarzyć aplikację usługi Azure AD z kontem Centrum partnerskiego
using System;
using System.Threading.Tasks;

namespace Win32SubmissionApiCSharpSample
{
    public class Program
    {
        static async Task Main(string[] args)
        {
            var config = new ClientConfiguration()
            {
                ApplicationId = "...",
                ClientId = "...",
                ClientSecret = "...",
                Scope = "https://api.store.microsoft.com/.default",
                ServiceUrl = "https://api.store.microsoft.com",
                TokenEndpoint = "...",
                SellerId = 0
            };

            await new AppSubmissionUpdateSample(config).RunAppSubmissionUpdateSample();

        }
    }
}

ClientConfiguration, klasa pomocnika używająca języka C#

Przykładowa aplikacja używa klasy pomocniczej ClientConfiguration do przekazywania danych Azure Active Directory oraz danych aplikacji do metod przykładowych korzystających z API przesyłania Microsoft Store.

using System;
using System.Collections.Generic;
using System.Text;

namespace Win32SubmissionApiCSharpSample
{
    public class ClientConfiguration
    {
        /// <summary>
        /// Client Id of your Azure Active Directory app.
        /// Example" 00001111-aaaa-2222-bbbb-3333cccc4444
        /// </summary>
        public string ClientId { get; set; }

        /// <summary>
        /// Client secret of your Azure Active Directory app
        /// </summary>
        public string ClientSecret { get; set; }

        /// <summary>
        /// Service root endpoint.
        /// Example: "https://api.store.microsoft.com"
        /// </summary>
        public string ServiceUrl { get; set; }

        /// <summary>
        /// Token endpoint to which the request is to be made. Specific to your Azure Active Directory app
        /// Example: https://login.microsoftonline.com/d454d300-128e-2d81-334a-27d9b2baf002/oauth2/v2.0/token
        /// </summary>
        public string TokenEndpoint { get; set; }

        /// <summary>
        /// Resource scope. If not provided (set to null), default one is used for the production API
        /// endpoint ("https://api.store.microsoft.com/.default")
        /// </summary>
        public string Scope { get; set; }

        /// <summary>
        /// Partner Center Application ID.
        /// Example: 3e31a9f9-84e8-4d2d-9eba-487878d02ebf
        /// </summary>
        public string ApplicationId { get; set; }


        /// <summary>
        /// The Partner Center Seller Id
        /// Example: 123456892
        /// </summary>
        public int SellerId { get; set; }
    }
}

Utwórz zgłoszenie aplikacji przy użyciu języka C#

Poniższy przykład implementuje klasę, która używa kilku metod w interfejsie API przesyłania aplikacji do sklepu Microsoft Store do aktualizacji przesyłania aplikacji.

using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.IO;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;

namespace Win32SubmissionApiCSharpSample
{
    public class AppSubmissionUpdateSample
    {
        private ClientConfiguration ClientConfig;

        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="configuration">An instance of ClientConfiguration that contains all parameters populated</param>
        public AppSubmissionUpdateSample(ClientConfiguration configuration)
        {
            this.ClientConfig = configuration;
        }

        /// <summary>
        /// Main method to Run the Sample Application
        /// </summary>
        /// <returns></returns>
        /// <exception cref="InvalidOperationException"></exception>
        public async Task RunAppSubmissionUpdateSample()
        {
            // **********************
            //       SETTINGS
            // **********************
            var appId = this.ClientConfig.ApplicationId;
            var clientId = this.ClientConfig.ClientId;
            var clientSecret = this.ClientConfig.ClientSecret;
            var serviceEndpoint = this.ClientConfig.ServiceUrl;
            var tokenEndpoint = this.ClientConfig.TokenEndpoint;
            var scope = this.ClientConfig.Scope;

            // Get authorization token.
            Console.WriteLine("Getting authorization token");
            var accessToken = await SubmissionClient.GetClientCredentialAccessToken(
                tokenEndpoint,
                clientId,
                clientSecret,
                scope);

            var client = new SubmissionClient(accessToken, serviceEndpoint);

            client.DefaultHeaders = new Dictionary<string, string>()
            {
                {"X-Seller-Account-Id", this.ClientConfig.SellerId.ToString() }
            };

            Console.WriteLine("Getting Current Application Draft Status");
            
            dynamic AppDraftStatus = await client.Invoke<dynamic>(HttpMethod.Get, string.Format(SubmissionClient.ProductDraftStatusPollingUrlTemplate,
                SubmissionClient.Version, appId), null);
            
            Console.WriteLine(AppDraftStatus.ToString());

            Console.WriteLine("Getting Application Packages ");

            dynamic PackagesResponse = await client.Invoke<dynamic>(HttpMethod.Get, string.Format(SubmissionClient.PackagesUrlTemplate,
                SubmissionClient.Version, appId), null);

            Console.WriteLine(PackagesResponse.ToString());

            Console.WriteLine("Getting Single Package");

            dynamic SinglePackageResponse = await client.Invoke<dynamic>(HttpMethod.Get, string.Format(SubmissionClient.PackageByIdUrlTemplate,
                SubmissionClient.Version, appId, (string)PackagesResponse.responseData.packages[0].packageId), null);

            Console.WriteLine(SinglePackageResponse.ToString());

            Console.WriteLine("Updating Entire Package Set");

            // Update data in Packages list to have final set of updated Packages

            // Example - Updating Installer Parameters
            PackagesResponse.responseData.packages[0].installerParameters = "/s /r new-args";

            dynamic PackagesUpdateRequest = new
            {
                packages = PackagesResponse.responseData.packages
            };

            dynamic PackagesUpdateResponse = await client.Invoke<dynamic>(HttpMethod.Put, string.Format(SubmissionClient.PackagesUrlTemplate,
                SubmissionClient.Version, appId), PackagesUpdateRequest);

            Console.WriteLine(PackagesUpdateResponse.ToString());

            Console.WriteLine("Updating Single Package's Download Url");

            // Update data in the SinglePackage object

            var SinglePackageUpdateRequest = SinglePackageResponse.responseData.packages[0];

            // Example - Updating Installer Parameters
            SinglePackageUpdateRequest.installerParameters = "/s /r /t new-args";

            dynamic PackageUpdateResponse = await client.Invoke<dynamic>(HttpMethod.Patch, string.Format(SubmissionClient.PackageByIdUrlTemplate,
                SubmissionClient.Version, appId, SinglePackageUpdateRequest.packageId), SinglePackageUpdateRequest);

            Console.WriteLine("Committing Packages");

            dynamic PackageCommitResponse = await client.Invoke<dynamic>(HttpMethod.Post, string.Format(SubmissionClient.PackagesCommitUrlTemplate,
                SubmissionClient.Version, appId), null);

            Console.WriteLine(PackageCommitResponse.ToString());

            Console.WriteLine("Polling Package Upload Status");

            AppDraftStatus = await client.Invoke<dynamic>(HttpMethod.Get, string.Format(SubmissionClient.ProductDraftStatusPollingUrlTemplate,
                SubmissionClient.Version, appId), null);

            while (!((bool)AppDraftStatus.responseData.isReady))
            {
                AppDraftStatus = await client.Invoke<dynamic>(HttpMethod.Get, string.Format(SubmissionClient.ProductDraftStatusPollingUrlTemplate,
                    SubmissionClient.Version, appId), null);

                Console.WriteLine("Waiting for Upload to finish");

                await Task.Delay(TimeSpan.FromSeconds(2));

                if(AppDraftStatus.errors != null && AppDraftStatus.errors.Count > 0)
                {
                    for(var index = 0; index < AppDraftStatus.errors.Count; index++)
                    {
                        if(AppDraftStatus.errors[index].code == "packageuploaderror")
                        {
                            throw new InvalidOperationException("Package Upload Failed. Please try committing packages again.");
                        }
                    }
                }
            }

            Console.WriteLine("Getting Application Metadata - All Modules");

            dynamic AppMetadata = await client.Invoke<dynamic>(HttpMethod.Get, string.Format(SubmissionClient.AppMetadataUrlTemplate,
                SubmissionClient.Version, appId), null);

            Console.WriteLine(AppMetadata.ToString());

            Console.WriteLine("Getting Application Metadata - Listings");

            dynamic AppListingsMetadata = await client.Invoke<dynamic>(HttpMethod.Get, string.Format(SubmissionClient.AppListingsFetchMetadataUrlTemplate,
                SubmissionClient.Version, appId), null);

            Console.WriteLine(AppListingsMetadata.ToString());

            Console.WriteLine("Updating Listings Metadata - Description");

            // Update Required Fields in Listings Metadata Object - Per Language. For eg. AppListingsMetadata.responseData.listings[0]

            // Example - Updating Description
            AppListingsMetadata.responseData.listings[0].description = "New Description Updated By C# Sample Code";

            dynamic ListingsUpdateRequest = new
            {
                listings = AppListingsMetadata.responseData.listings[0]
            };

            dynamic UpdateListingsMetadataResponse = await client.Invoke<dynamic>(HttpMethod.Put, string.Format(SubmissionClient.AppMetadataUrlTemplate,
                SubmissionClient.Version, appId), ListingsUpdateRequest);

            Console.WriteLine(UpdateListingsMetadataResponse.ToString());

            Console.WriteLine("Getting All Listings Assets");

            dynamic ListingAssets = await client.Invoke<dynamic>(HttpMethod.Get, string.Format(SubmissionClient.ListingAssetsUrlTemplate,
                SubmissionClient.Version, appId), null);

            Console.WriteLine(ListingAssets.ToString());

            Console.WriteLine("Creating Listing Assets for 1 Screenshot");

            
            dynamic AssetCreateRequest = new
            {
                language = ListingAssets.responseData.listingAssets[0].language,
                createAssetRequest = new Dictionary<string, int>()
                {
                    {"Screenshot", 1 },
                    {"Logo", 0 }
                }
            };

            dynamic AssetCreateResponse = await client.Invoke<dynamic>(HttpMethod.Post, string.Format(SubmissionClient.ListingAssetsCreateUrlTemplate,
               SubmissionClient.Version, appId), AssetCreateRequest);

            Console.WriteLine(AssetCreateResponse.ToString());

            Console.WriteLine("Uploading Listing Assets");

            // Path to PNG File to be Uploaded as Screenshot / Logo
            var PathToFile = "./Image.png";
            var AssetToUpload = File.OpenRead(PathToFile);

            await client.UploadAsset(AssetCreateResponse.responseData.listingAssets.screenshots[0].primaryAssetUploadUrl.Value as string, AssetToUpload);

            Console.WriteLine("Committing Listing Assets");

            dynamic AssetCommitRequest = new
            {
                listingAssets = new
                {
                    language = ListingAssets.responseData.listingAssets[0].language,
                    storeLogos = ListingAssets.responseData.listingAssets[0].storeLogos,
                    screenshots = JToken.FromObject(new List<dynamic>() { new
                {
                    id = AssetCreateResponse.responseData.listingAssets.screenshots[0].id.Value as string,
                    assetUrl = AssetCreateResponse.responseData.listingAssets.screenshots[0].primaryAssetUploadUrl.Value as string
                }
                }.ToArray())
                }
            };

            dynamic AssetCommitResponse = await client.Invoke<dynamic>(HttpMethod.Put, string.Format(SubmissionClient.ListingAssetsCommitUrlTemplate,
               SubmissionClient.Version, appId), AssetCommitRequest);

            Console.WriteLine(AssetCommitResponse.ToString());

            Console.WriteLine("Getting Current Application Draft Status before Submission");

            AppDraftStatus = await client.Invoke<dynamic>(HttpMethod.Get, string.Format(SubmissionClient.ProductDraftStatusPollingUrlTemplate,
                SubmissionClient.Version, appId), null);

            Console.WriteLine(AppDraftStatus.ToString());

            if (AppDraftStatus == null || !((bool)AppDraftStatus.responseData.isReady))
            {
                throw new InvalidOperationException("Application Current Status is not in Ready Status for All Modules");
            }

            Console.WriteLine("Creating Submission");

            dynamic SubmissionCreationResponse = await client.Invoke<dynamic>(HttpMethod.Post, string.Format(SubmissionClient.CreateSubmissionUrlTemplate,
                SubmissionClient.Version, appId), null);

            Console.WriteLine(SubmissionCreationResponse.ToString());

            Console.WriteLine("Current Submission Status");

            dynamic SubmissionStatus = await client.Invoke<dynamic>(HttpMethod.Get, string.Format(SubmissionClient.SubmissionStatusPollingUrlTemplate,
                SubmissionClient.Version, appId, SubmissionCreationResponse.responseData.submissionId.Value as string), null);

            Console.Write(SubmissionStatus.ToString());

            // User can Poll on this API to know if Submission Status is INPROGRESS, PUBLISHED or FAILED.
            // This Process involves File Scanning, App Certification and Publishing and can take more than a day.
        }
    }
}

IngestionClient, klasa pomocnika używająca języka C#

Klasa IngestionClient udostępnia metody pomocnicze, które są używane przez inne metody w przykładowej aplikacji do wykonywania następujących zadań:

  • Uzyskaj token dostępu do Azure AD, który może służyć do wywoływania metod w interfejsie API zgłoszeń do sklepu Microsoft Store. Po uzyskaniu tokenu masz 60 minut na użycie tego tokenu w wywołaniach interfejsu API przesyłania do Microsoft Store, zanim token wygaśnie. Po wygaśnięciu tokenu możesz wygenerować nowy token.
  • Przetwarzanie żądań HTTP dla interfejsu API przesyłania sklepu Microsoft Store.
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.IO;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;

namespace Win32SubmissionApiCSharpSample
{
    /// <summary>
    /// This class is a proxy that abstracts the functionality of the API service
    /// </summary>
    public class SubmissionClient : IDisposable
    {
        public static readonly string Version = "1";
        private HttpClient httpClient;
        private HttpClient imageUploadClient;

        private readonly string accessToken;

        public static readonly string PackagesUrlTemplate = "/submission/v{0}/product/{1}/packages";
        public static readonly string PackageByIdUrlTemplate = "/submission/v{0}/product/{1}/packages/{2}";
        public static readonly string PackagesCommitUrlTemplate = "/submission/v{0}/product/{1}/packages/commit";
        public static readonly string AppMetadataUrlTemplate = "/submission/v{0}/product/{1}/metadata";
        public static readonly string AppListingsFetchMetadataUrlTemplate = "/submission/v{0}/product/{1}/metadata/listings";
        public static readonly string ListingAssetsUrlTemplate = "/submission/v{0}/product/{1}/listings/assets";
        public static readonly string ListingAssetsCreateUrlTemplate = "/submission/v{0}/product/{1}/listings/assets/create";
        public static readonly string ListingAssetsCommitUrlTemplate = "/submission/v{0}/product/{1}/listings/assets/commit";
        public static readonly string ProductDraftStatusPollingUrlTemplate = "/submission/v{0}/product/{1}/status";
        public static readonly string CreateSubmissionUrlTemplate = "/submission/v{0}/product/{1}/submit";
        public static readonly string SubmissionStatusPollingUrlTemplate = "/submission/v{0}/product/{1}/submission/{2}/status";

        public const string JsonContentType = "application/json";
        public const string PngContentType = "image/png";
        public const string BinaryStreamContentType = "application/octet-stream";

        /// <summary>
        /// Initializes a new instance of the <see cref="SubmissionClient" /> class.
        /// </summary>
        /// <param name="accessToken">
        /// The access token. This is JWT a token obtained from Azure Active Directory allowing the caller to invoke the API
        /// on behalf of a user
        /// </param>
        /// <param name="serviceUrl">The service URL.</param>
        public SubmissionClient(string accessToken, string serviceUrl)
        {
            if (string.IsNullOrEmpty(accessToken))
            {
                throw new ArgumentNullException("accessToken");
            }

            if (string.IsNullOrEmpty(serviceUrl))
            {
                throw new ArgumentNullException("serviceUrl");
            }

            this.accessToken = accessToken;
            this.httpClient = new HttpClient
            {
                BaseAddress = new Uri(serviceUrl)
            };
            this.imageUploadClient = new HttpClient();
            this.DefaultHeaders = new Dictionary<string, string>();
        }

        /// <summary>
        /// Gets or Sets the default headers.
        /// </summary>
        public Dictionary<string, string> DefaultHeaders { get; set; }

        /// <summary>
        /// Performs application-defined tasks associated with freeing, releasing, or resetting
        /// unmanaged resources.
        /// </summary>
        public void Dispose()
        {
            if (this.httpClient != null)
            {
                this.httpClient.Dispose();
                this.httpClient = null;
                GC.SuppressFinalize(this);
            }
        }

        /// <summary>
        /// Gets the authorization token for the provided client id, client secret, and the scope.
        /// This token is usually valid for 1 hour, so if your submission takes longer than that to complete,
        /// make sure to get a new one periodically.
        /// </summary>
        /// <param name="tokenEndpoint">Token endpoint to which the request is to be made. Specific to your
        /// Azure Active Directory app. Example: https://login.microsoftonline.com/d454d300-128e-2d81-334a-27d9b2baf002/oauth2/v2.0/token </param>
        /// <param name="clientId">Client Id of your Azure Active Directory app. Example" 00001111-aaaa-2222-bbbb-3333cccc4444</param>
        /// <param name="clientSecret">Client secret of your Azure Active Directory app</param>
        /// <param name="scope">Scope. If not provided, default one is used for the production API endpoint.</param>
        /// <returns>Autorization token. Prepend it with "Bearer: " and pass it in the request header as the
        /// value for "Authorization: " header.</returns>
        public static async Task<string> GetClientCredentialAccessToken(
            string tokenEndpoint,
            string clientId,
            string clientSecret,
            string scope = null)
        {
            if (scope == null)
            {
                scope = "https://api.store.microsoft.com/.default";
            }

            dynamic result;
            using (HttpClient client = new HttpClient())
            {
                string tokenUrl = tokenEndpoint;
                using (
                    HttpRequestMessage request = new HttpRequestMessage(
                        HttpMethod.Post,
                        tokenUrl))
                {
                    string strContent =
                        string.Format(
                            "grant_type=client_credentials&client_id={0}&client_secret={1}&scope={2}",
                            clientId,
                            clientSecret,
                            scope);

                    request.Content = new StringContent(strContent, Encoding.UTF8,
                        "application/x-www-form-urlencoded");

                    using (HttpResponseMessage response = await client.SendAsync(request))
                    {
                        string responseContent = await response.Content.ReadAsStringAsync();
                        result = JsonConvert.DeserializeObject(responseContent);
                    }
                }
            }

            return result.access_token;
        }


        /// <summary>
        /// Invokes the specified HTTP method.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="httpMethod">The HTTP method.</param>
        /// <param name="relativeUrl">The relative URL.</param>
        /// <param name="requestContent">Content of the request.</param>
        /// <returns>instance of the type T</returns>
        /// <exception cref="ServiceException"></exception>
        public async Task<T> Invoke<T>(HttpMethod httpMethod,
            string relativeUrl,
            object requestContent)
        {
            using (var request = new HttpRequestMessage(httpMethod, relativeUrl))
            {
                this.SetRequest(request, requestContent);

                using (HttpResponseMessage response = await this.httpClient.SendAsync(request))
                {
                    T result;
                    if (this.TryHandleResponse(response, out result))
                    {
                        return result;
                    }

                    if (response.IsSuccessStatusCode)
                    {
                        var resource = JsonConvert.DeserializeObject<T>(await response.Content.ReadAsStringAsync());
                        return resource;
                    }

                    throw new Exception(await response.Content.ReadAsStringAsync());
                }
            }
        }

        /// <summary>
        /// Uploads a given Image Asset file to Asset Storage
        /// </summary>
        /// <param name="assetUploadUrl">Asset Storage Url</param>
        /// <param name="fileStream">The Stream instance of file to be uploaded</param>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        public async Task UploadAsset(string assetUploadUrl, Stream fileStream)
        {
            using (var request = new HttpRequestMessage(HttpMethod.Put, assetUploadUrl))
            {
                request.Headers.Add("x-ms-blob-type", "BlockBlob");
                request.Content = new StreamContent(fileStream);
                request.Content.Headers.ContentType = new MediaTypeHeaderValue(PngContentType);
                using (HttpResponseMessage response = await this.imageUploadClient.SendAsync(request))
                {
                    if (response.IsSuccessStatusCode)
                    {
                        return;
                    }
                    throw new Exception(await response.Content.ReadAsStringAsync());
                }
            }
        }

        /// <summary>
        /// Sets the request.
        /// </summary>
        /// <param name="request">The request.</param>
        /// <param name="requestContent">Content of the request.</param>
        protected virtual void SetRequest(HttpRequestMessage request, object requestContent)
        {
            request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", this.accessToken);

            foreach (var header in this.DefaultHeaders)
            {
                request.Headers.Add(header.Key, header.Value);
            }

            if (requestContent != null)
            {
                request.Content = new StringContent(JsonConvert.SerializeObject(requestContent),
                        Encoding.UTF8,
                        JsonContentType);
                
            }
        }


        /// <summary>
        /// Tries the handle response.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="response">The response.</param>
        /// <param name="result">The result.</param>
        /// <returns>true if the response was handled</returns>
        protected virtual bool TryHandleResponse<T>(HttpResponseMessage response, out T result)
        {
            result = default(T);
            return false;
        }
    }
}

przykład Node.js: API Microsoft Store do przesyłania aplikacji MSI lub EXE

Ten artykuł zawiera przykłady kodu Node.js, które pokazują, jak używać interfejsu API przesyłania do Microsoft Store zarówno dla aplikacji MSI, jak i EXE. Możesz przejrzeć każdy przykład, aby dowiedzieć się więcej o przedstawionym zadaniu lub utworzyć wszystkie przykłady kodu w tym artykule w aplikacji konsolowej.

Warunki wstępne W poniższych przykładach użyto następującej biblioteki:

  • Biblioteka node-fetch w wersji 2 [npm install node-fetch@2]

Przesyłanie aplikacji przy użyciu node.js

Poniższy przykład wywołuje inne przykładowe metody w tym artykule, aby zademonstrować różne sposoby korzystania z API przesyłania do Microsoft Store. Aby dostosować ten program do własnego użycia:

  • Przypisz właściwość SellerId do identyfikatora sprzedawcy konta Centrum partnerskiego.
  • Przypisz właściwość ApplicationId do identyfikatora aplikacji, którą chcesz zarządzać.
  • Przypisz właściwości ClientId i ClientSecret do identyfikatora klienta i klucza dla swojej aplikacji, a następnie zastąp ciąg tenantid w adresie URL TokenEndpoint identyfikatorem dzierżawy dla Twojej aplikacji. Aby uzyskać więcej informacji, zobacz Jak skojarzyć aplikację usługi Azure AD z kontem Centrum partnerskiego

Poniższy przykład implementuje klasę, która używa kilku metod w interfejsie API przesyłania aplikacji do sklepu Microsoft Store do aktualizacji przesyłania aplikacji.

const config = require('./Configuration');
const submissionClient = require('./SubmissionClient');
const fs = require('fs');

var client = new submissionClient(config);

/**
 * Main entry method to Run the Store Submission API Node.js Sample
 */
async function RunNodeJsSample(){
    print('Getting Access Token');
    await client.getAccessToken();
    
    print('Getting Current Application Draft Status');
    var currentDraftStatus = await client.callStoreAPI(client.productDraftStatusPollingUrlTemplate, 'get');
    print(currentDraftStatus);

    print('Getting Application Packages');
    var currentPackages = await client.callStoreAPI(client.packagesUrlTemplate, 'get');
    print(currentPackages);

    print('Getting Single Package');
    var packageId = currentPackages.responseData.packages[0].packageId;
    var packageIdUrl = `${client.packageByIdUrlTemplate}`.replace('{packageId}', packageId);
    var singlePackage = await client.callStoreAPI(packageIdUrl, 'get');
    print(singlePackage);

    print('Updating Entire Package Set');
    // Update data in Packages list to have final set of updated Packages
    currentPackages.responseData.packages[0].installerParameters = "/s /r new-args";
    var packagesUpdateRequest = {
        'packages': currentPackages.responseData.packages
    };
    print(packagesUpdateRequest);
    var packagesUpdateResponse = await client.callStoreAPI(client.packagesUrlTemplate, 'put', packagesUpdateRequest);
    print(packagesUpdateResponse);

    print('Updating Single Package\'s Download Url');
    // Update data in the SinglePackage object
    singlePackage.responseData.packages[0].installerParameters = "/s /r /t new-args";
    var singlePackageUpdateResponse = await client.callStoreAPI(packageIdUrl, 'patch', singlePackage.responseData.packages[0]);
    print(singlePackageUpdateResponse);

    print('Committing Packages');
    var commitPackagesResponse = await client.callStoreAPI(client.packagesCommitUrlTemplate, 'post');
    print(commitPackagesResponse);

    await poll(async ()=>{
        print('Waiting for Upload to finish');
        return await client.callStoreAPI(client.productDraftStatusPollingUrlTemplate, 'get');
    }, 2);

    print('Getting Application Metadata - All Modules');
    var appMetadata = await client.callStoreAPI(client.appMetadataUrlTemplate, 'get');
    print(appMetadata);

    print('Getting Application Metadata - Listings');
    var appListingMetadata = await client.callStoreAPI(client.appListingsFetchMetadataUrlTemplate, 'get');
    print(appListingMetadata);

    print('Updating Listings Metadata - Description');   
    // Update Required Fields in Listings Metadata Object - Per Language. For eg. AppListingsMetadata.responseData.listings[0]
    // Example - Updating Description
    appListingMetadata.responseData.listings[0].description = 'New Description Updated By Node.js Sample Code';
    var listingsUpdateRequest = {
        'listings': appListingMetadata.responseData.listings[0]
    };
    var listingsMetadataUpdateResponse = await client.callStoreAPI(client.appMetadataUrlTemplate, 'put', listingsUpdateRequest);
    print(listingsMetadataUpdateResponse);

    print('Getting All Listings Assets');
    var listingAssets = await client.callStoreAPI(client.listingAssetsUrlTemplate, 'get');
    print(listingAssets);

    print('Creating Listing Assets for 1 Screenshot');
    var listingAssetCreateRequest = {
        'language': listingAssets.responseData.listingAssets[0].language,
        'createAssetRequest': {
            'Screenshot': 1,
            'Logo': 0
        }
    };
    var listingAssetCreateResponse = await client.callStoreAPI(client.listingAssetsCreateUrlTemplate, 'post', listingAssetCreateRequest);
    print(listingAssetCreateResponse);

    print('Uploading Listing Assets');
    const pathToFile = './Image.png';
    const stats = fs.statSync(pathToFile);
    const fileSize = stats.size;
    const fileStream = fs.createReadStream(pathToFile);
    await client.uploadAssets(listingAssetCreateResponse.responseData.listingAssets.screenshots[0].primaryAssetUploadUrl, fileStream, fileSize);

    print('Committing Listing Assets');
    var assetCommitRequest = {
        'listingAssets': {
            'language': listingAssets.responseData.listingAssets[0].language,
            'storeLogos': listingAssets.responseData.listingAssets[0].storeLogos,
            'screenshots': [{
                'id': listingAssetCreateResponse.responseData.listingAssets.screenshots[0].id,
                'assetUrl': listingAssetCreateResponse.responseData.listingAssets.screenshots[0].primaryAssetUploadUrl
            }]
        }
    };
    var assetCommitResponse = await client.callStoreAPI(client.listingAssetsCommitUrlTemplate, 'put', assetCommitRequest);
    print(assetCommitResponse);

    print('Getting Current Application Draft Status before Submission');
    currentDraftStatus = await client.callStoreAPI(client.productDraftStatusPollingUrlTemplate, 'get');
    print(currentDraftStatus);
    if(!currentDraftStatus.responseData.isReady){
        throw new Error('Application Current Status is not in Ready Status for All Modules');
    }

    print('Creating Submission');
    var submissionCreationResponse = await client.callStoreAPI(client.createSubmissionUrlTemplate, 'post');
    print(submissionCreationResponse);

    print('Current Submission Status');
    var submissionStatusUrl = `${client.submissionStatusPollingUrlTemplate}`.replace('{submissionId}', submissionCreationResponse.responseData.submissionId);
    var submissionStatusResponse = await client.callStoreAPI(submissionStatusUrl, 'get');
    print(submissionStatusResponse);

    // User can Poll on this API to know if Submission Status is INPROGRESS, PUBLISHED or FAILED.
    // This Process involves File Scanning, App Certification and Publishing and can take more than a day.
}

/**
 * Utility Method to Poll using a given function and time interval in seconds
 * @param {*} func 
 * @param {*} intervalInSeconds 
 * @returns 
 */
async function poll(func, intervalInSeconds){
var result = await func();
if(result.responseData.isReady){
    Promise.resolve(true);
}
else if(result.errors && result.errors.length > 0 && result.errors.find(element => element.code == 'packageuploaderror') != undefined){
throw new Error('Package Upload Failed');
}
else{
    await new Promise(resolve => setTimeout(resolve, intervalInSeconds*1000));
    return await poll(func, intervalInSeconds); 
}
}

/**
 * Utility function to Print a Json or normal string
 * @param {*} json 
 */
function print(json){
    if(typeof(json) == 'string'){
        console.log(json);
    }
    else{
        console.log(JSON.stringify(json));
    }
    console.log("\n");
}

/** Run the Node.js Sample Application */
RunNodeJsSample();

Narzędzie wspomagające KonfiguracjęKlienta

Przykładowa aplikacja używa klasy pomocniczej ClientConfiguration do przekazywania danych Azure Active Directory oraz danych aplikacji do metod przykładowych korzystających z API przesyłania Microsoft Store.

/** Configuration Object for Store Submission API */
var config = {
    version : "1",
    applicationId : "...",
    clientId : "...",
    clientSecret : "...",
    serviceEndpoint : "https://api.store.microsoft.com",
    tokenEndpoint : "...",
    scope : "https://api.store.microsoft.com/.default",
    sellerId : "...",
    jsonContentType : "application/json",
    pngContentType : "image/png",
    binaryStreamContentType : "application/octet-stream"
};

module.exports = config;

Klient IngestionClient wykorzystujący node.js

Klasa IngestionClient udostępnia metody pomocnicze, które są używane przez inne metody w przykładowej aplikacji do wykonywania następujących zadań:

  • Uzyskaj token dostępu do Azure AD, który może służyć do wywoływania metod w interfejsie API zgłoszeń do sklepu Microsoft Store. Po uzyskaniu tokenu masz 60 minut na użycie tego tokenu w wywołaniach interfejsu API przesyłania do Microsoft Store, zanim token wygaśnie. Po wygaśnięciu tokenu możesz wygenerować nowy token.
  • Przetwarzanie żądań HTTP dla interfejsu API przesyłania sklepu Microsoft Store.
const fetch = require('node-fetch');
/**
 * Submission Client to invoke all available Store Submission API and Asset Upload to Blob Store
 */
class SubmissionClient{

    constructor(config){
        this.configuration = config;
        this.accessToken = "";
        this.packagesUrlTemplate = `/submission/v${this.configuration.version}/product/${this.configuration.applicationId}/packages`;
        this.packageByIdUrlTemplate = `/submission/v${this.configuration.version}/product/${this.configuration.applicationId}/packages/{packageId}`;
        this.packagesCommitUrlTemplate = `/submission/v${this.configuration.version}/product/${this.configuration.applicationId}/packages/commit`;
        this.appMetadataUrlTemplate = `/submission/v${this.configuration.version}/product/${this.configuration.applicationId}/metadata`;
        this.appListingsFetchMetadataUrlTemplate = `/submission/v${this.configuration.version}/product/${this.configuration.applicationId}/metadata/listings`;
        this.listingAssetsUrlTemplate = `/submission/v${this.configuration.version}/product/${this.configuration.applicationId}/listings/assets`;
        this.listingAssetsCreateUrlTemplate = `/submission/v${this.configuration.version}/product/${this.configuration.applicationId}/listings/assets/create`;
        this.listingAssetsCommitUrlTemplate = `/submission/v${this.configuration.version}/product/${this.configuration.applicationId}/listings/assets/commit`;
        this.productDraftStatusPollingUrlTemplate = `/submission/v${this.configuration.version}/product/${this.configuration.applicationId}/status`;
        this.createSubmissionUrlTemplate = `/submission/v${this.configuration.version}/product/${this.configuration.applicationId}/submit`;
        this.submissionStatusPollingUrlTemplate = `/submission/v${this.configuration.version}/product/${this.configuration.applicationId}/submission/{submissionId}/status`;
    }
    
    async getAccessToken(){
        var params = new URLSearchParams();
        params.append('grant_type','client_credentials');
        params.append('client_id',this.configuration.clientId);
        params.append('client_secret',this.configuration.clientSecret);
        params.append('scope',this.configuration.scope);
        var response = await fetch(this.configuration.tokenEndpoint,{
            method: "POST",
            body: params
        });    
        var data = await response.json();
        this.accessToken = data.access_token;
    }

    async callStoreAPI(url, method, data){
        var request = {
            method: method,
            headers:{
                'Authorization': `Bearer ${this.accessToken}`,
                'Content-Type': this.configuration.jsonContentType,
                'X-Seller-Account-Id': this.configuration.sellerId
            },            
        };
        if(data){
            request.body = JSON.stringify(data);
        }
        var response = await fetch(`${this.configuration.serviceEndpoint}${url}`,request);
        var jsonResponse = await response.json();
        return jsonResponse;
    }

    async uploadAssets(url, stream, size){
        var request = {
            method: 'put',
            headers:{
                'Content-Type': this.configuration.pngContentType,
                'x-ms-blob-type': 'BlockBlob',
                "Content-length": size
            },            
            body: stream
        };
        var response = await fetch(`${url}`,request);
        if(response.ok){
            return response;
        }
        else{
            throw new Error('Uploading of assets failed');
        }
    }
}
module.exports = SubmissionClient;

Dodatkowa pomoc

Jeśli masz pytania dotyczące interfejsu API przesyłania do sklepu Microsoft Store lub potrzebujesz pomocy w zarządzaniu przesyłaniem za pomocą tego interfejsu API, skorzystaj z następujących zasobów:

  • Zadaj swoje pytania na naszych forach.
  • Odwiedź naszą stronę pomocy technicznej i poproś o jedną z opcji wsparcia asystowanego dla Partner Center. Jeśli zostanie wyświetlony monit o wybranie typu i kategorii problemu, wybierz odpowiednio pozycję Przesyłanie aplikacji i certyfikacja oraz Przesyłanie aplikacji.