Last active
March 14, 2018 18:54
-
-
Save johanlindfors/a79b1368466de1082afc7a06ee975532 to your computer and use it in GitHub Desktop.
Publisher shared installId for UWP apps implemented with CppWinRT
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #pragma once | |
| #include <string> | |
| #include <winrt/Windows.Storage.Streams.h> | |
| #include <winrt/Windows.Foundation.Collections.h> | |
| #include <winrt/Windows.Security.Cryptography.Core.h> | |
| #include <winrt/Windows.System.UserProfile.h> | |
| namespace winrt { | |
| using namespace Windows::Storage; | |
| using namespace Windows::Foundation; | |
| using namespace Windows::Foundation::Collections; | |
| using namespace Windows::Storage::Streams; | |
| using namespace Windows::System::UserProfile; | |
| using namespace Windows::Security::Cryptography; | |
| using namespace Windows::Security::Cryptography::Core; | |
| } | |
| class InstallIdForPublisher { | |
| public: | |
| InstallIdForPublisher(std::wstring folderName, std::wstring fileName) | |
| : mFolderName(folderName) | |
| , mFileName(fileName) | |
| { | |
| assert(mFolderName.size() > 0); | |
| assert(mFileName.size() > 0); | |
| } | |
| winrt::Windows::Foundation::IAsyncOperation<winrt::hstring> GetAsync() | |
| { | |
| if (mInstallId.size() == 0) { | |
| auto storageFile = co_await GetStorageFileAsync(mFolderName, mFileName); | |
| if (storageFile != nullptr) { | |
| mInstallId = co_await(winrt::FileIO::ReadTextAsync(storageFile)); | |
| } | |
| if (mInstallId.empty()) { | |
| mInstallId = Generate(); | |
| co_await SetAsync(mInstallId); | |
| } | |
| } | |
| return mInstallId; | |
| } | |
| winrt::IAsyncAction SetAsync(winrt::hstring installId) | |
| { | |
| auto storageFile = co_await GetStorageFileAsync(mFolderName, mFileName, true); | |
| co_await winrt::FileIO::WriteTextAsync(storageFile, installId); | |
| } | |
| private: | |
| static winrt::IAsyncOperation<winrt::IStorageFile> GetStorageFileAsync(winrt::hstring folderName, winrt::hstring fileName, bool createIfNotFound = false) { | |
| winrt::IStorageFile storageFile; | |
| auto storageFolder = winrt::ApplicationData::Current().GetPublisherCacheFolder(folderName); | |
| auto storageItem = co_await storageFolder.TryGetItemAsync(fileName); | |
| if (storageItem != nullptr) { | |
| storageFile = storageItem.as<winrt::StorageFile>(); | |
| } | |
| if (storageFile == nullptr && createIfNotFound) { | |
| storageFile = co_await storageFolder.CreateFileAsync(fileName); | |
| } | |
| return storageFile; | |
| } | |
| static winrt::hstring GenerateGuid() { | |
| GUID guid; | |
| CoCreateGuid(&guid); | |
| winrt::hstring wGuid; | |
| WCHAR *lpwszGUID; | |
| HRESULT hr = StringFromCLSID(guid, (LPOLESTR *)&lpwszGUID); | |
| if (FAILED(hr)) { | |
| return std::wstring(); | |
| } | |
| wGuid = lpwszGUID; | |
| LocalFree(lpwszGUID); | |
| return wGuid; | |
| } | |
| static winrt::hstring Generate() | |
| { | |
| winrt::IBuffer buffer; | |
| // First try with advertising id as base for id | |
| winrt::hstring id(winrt::AdvertisingManager::AdvertisingId()); | |
| if (id == nullptr || id.size() == 0) { | |
| // Secondly generate a new guid as base for id | |
| id = GenerateGuid(); | |
| } | |
| auto algorithm = winrt::HashAlgorithmProvider::OpenAlgorithm(L"MD5"); | |
| auto vector = winrt::CryptographicBuffer::ConvertStringToBinary(id, | |
| winrt::BinaryStringEncoding::Utf8); | |
| buffer = algorithm.HashData(vector); | |
| if (buffer.Length() != algorithm.HashLength()) { | |
| throw winrt::hresult_error(0, L"Failed to generate hash!"); | |
| } | |
| return winrt::CryptographicBuffer::EncodeToHexString(buffer); | |
| } | |
| winrt::hstring mFolderName; | |
| winrt::hstring mFileName; | |
| winrt::hstring mInstallId; | |
| }; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment