Skip to content

Instantly share code, notes, and snippets.

@johanlindfors
Last active March 14, 2018 18:54
Show Gist options
  • Select an option

  • Save johanlindfors/a79b1368466de1082afc7a06ee975532 to your computer and use it in GitHub Desktop.

Select an option

Save johanlindfors/a79b1368466de1082afc7a06ee975532 to your computer and use it in GitHub Desktop.
Publisher shared installId for UWP apps implemented with CppWinRT
#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