Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix issues with this sample #3

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
408 changes: 204 additions & 204 deletions ActivatableOptionalPackage1/ActivatableOptionalPackage1.vcxproj

Large diffs are not rendered by default.

410 changes: 205 additions & 205 deletions ActivatableOptionalPackage2/ActivatableOptionalPackage2.vcxproj

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion ActivatableOptionalPackage2/MainPage.xaml.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,5 @@ using namespace Windows::UI::Xaml::Navigation;

MainPage::MainPage()
{
InitializeComponent();
InitializeComponent();
}
2 changes: 1 addition & 1 deletion MyMainApp/App.xaml.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ App::App()
/// <param name="e">Details about the launch request and process.</param>
void App::OnLaunched(Windows::ApplicationModel::Activation::LaunchActivatedEventArgs^ e)
{
#if _DEBUG
#if 0
// Show graphics profiling information while debugging.
if (IsDebuggerPresent())
{
Expand Down
325 changes: 116 additions & 209 deletions MyMainApp/MainPage.xaml.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,250 +20,157 @@ using namespace Windows::UI::Xaml::Media;
using namespace Windows::UI::Xaml::Navigation;
using namespace Windows::UI::Core;


// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409


MainPage::MainPage()
{
InitializeComponent();
HookupCatalog();

InitializeComponent();
HookupCatalog();
}

void MainPage::ReadOptionalPackageContent()
void MainPage::ReadOptionalPackageContentAsync()
{
concurrency::create_task([this]()
{
WriteToTextBox("Enumerating Packages");
auto optionalPackages = EnumerateInstalledPackages();
for (auto package : optionalPackages)
{
Platform::String^ packageName = ref new String(package->Id->FullName->Data());
WriteToTextBox(packageName);

LoadTextFromPackage(package);
LoadDLLFromPackage(package);
WriteToTextBox("+++++++++++++++++++");
WriteToTextBox("\n");
}
DebugPrint(L" Finished loading all optional packages\n");
DebugPrint(L"\n");
});
concurrency::create_task([this]()
{
WriteToTextBox("Enumerating Packages");
auto optionalPackages = GetOptionalPackages();
for (auto package : optionalPackages)
{
auto packageName = ref new String(package->Id->FullName->Data());
WriteToTextBox(packageName);

LoadTextFromPackage(package);
LoadDLLFromPackage(package);
WriteToTextBox("+++++++++++++++++++");
WriteToTextBox("\n");
}
DebugPrint(L" Finished loading all optional packages\n");
DebugPrint(L"\n");
});
}

std::vector< Windows::ApplicationModel::Package^ > MainPage::EnumerateInstalledPackages()
std::vector<Windows::ApplicationModel::Package^> MainPage::GetOptionalPackages()
{
DebugPrint(L" Searching for optional packages...\n");

// Obtain the app's package first to then find all related packages
auto currentAppPackage = Windows::ApplicationModel::Package::Current;
DebugPrint(L" Searching for optional packages...\n");

// The dependencies list is where the list of optional packages (OP) can be determined
auto dependencies = currentAppPackage->Dependencies;
std::vector< Windows::ApplicationModel::Package^ > optionalPackages;
// The dependencies list is where the list of optional packages (OP) can be determined
std::vector<Windows::ApplicationModel::Package^> optionalPackages;

for (auto package : dependencies)
{
// If it is optional, then add it to our results vector
if (package->IsOptional)
{
DebugPrint(L" Optional Package found - %ws\n", package->Id->FullName->Data());
optionalPackages.push_back(package);
}
}
for (auto package : Windows::ApplicationModel::Package::Current->Dependencies)
{
if (package->IsOptional)
{
DebugPrint(L" Optional Package found - %ws\n", package->Id->FullName->Data());
optionalPackages.push_back(package);
}
}

return optionalPackages; // Return the resulting vector
return optionalPackages;
}

void MainPage::HookupCatalog()
{
catalog = Windows::ApplicationModel::PackageCatalog::OpenForCurrentPackage();
catalog->PackageInstalling += ref new Windows::Foundation::TypedEventHandler<Windows::ApplicationModel::PackageCatalog ^, Windows::ApplicationModel::PackageInstallingEventArgs ^>(this, &MyMainApp::MainPage::OnPackageInstalling);
catalog = Windows::ApplicationModel::PackageCatalog::OpenForCurrentPackage();
catalog->PackageInstalling += ref new Windows::Foundation::TypedEventHandler<Windows::ApplicationModel::PackageCatalog ^, Windows::ApplicationModel::PackageInstallingEventArgs ^>(this, &MyMainApp::MainPage::OnPackageInstalling);
}

void MainPage::OnPackageInstalling(Windows::ApplicationModel::PackageCatalog ^sender, Windows::ApplicationModel::PackageInstallingEventArgs ^args)
{
if (args->IsComplete)
{
WriteToTextBox("PackageCatalog - Done installing package");
WriteToTextBox(args->Package->Id->FamilyName->ToString());
}
if (args->IsComplete)
{
WriteToTextBox("PackageCatalog - Done installing package");
WriteToTextBox(args->Package->Id->FamilyName->ToString());
}
}

void MainPage::LoadTextFromPackage(Windows::ApplicationModel::Package^ package)
{
try
{
Windows::Storage::StorageFolder^ installFolder = package->InstalledLocation;

concurrency::create_task(installFolder->GetFolderAsync(L"Content"))
.then([this](concurrency::task< Windows::Storage::StorageFolder^ > result)
{
try
{
auto assetsFolder = result.get();

auto fileAsyncOp = assetsFolder->GetFileAsync(L"SampleFile.txt");

concurrency::create_task(fileAsyncOp)
.then([this](concurrency::task< Windows::Storage::StorageFile^ > task)
{
try
{
auto targetFile = task.get();

if (targetFile->IsAvailable)
{
WriteToTextBox("Found SampleFile.txt - loading contents");
DebugPrint(L" %ws is available:\n", targetFile->Name->Data());
concurrency::create_task(targetFile->OpenAsync(Windows::Storage::FileAccessMode::Read))
.then([this, targetFile](concurrency::task< Windows::Storage::Streams::IRandomAccessStream^ > task)
{
try
{
auto readStream = task.get();
UINT64 const size = readStream->Size;
if (size <= MAXUINT32)
{
auto dataReader = ref new Windows::Storage::Streams::DataReader(readStream);
concurrency::create_task(dataReader->LoadAsync(static_cast<UINT32>(size)))
.then([this, targetFile, dataReader](unsigned int numBytesLoaded)
{
Platform::String^ fileContent = dataReader->ReadString(numBytesLoaded);

WriteToTextBox(fileContent);

delete dataReader; // As a best practice, explicitly close the dataReader resource as soon as it is no longer needed.
DebugPrint(L" %ws\n", fileContent->Data());
});
}
else
{
delete readStream; // As a best practice, explicitly close the readStream resource as soon as it is no longer needed.
DebugPrint(L" File %ws is too big for LoadAsync to load in a single chunk. Files larger than 4GB need to be broken into multiple chunks to be loaded by LoadAsync.", targetFile->Name->Data());
}
}
catch (Platform::Exception^ ex)
{
DebugPrint(L" Error 0x%x reading text file\n", ex->HResult);
}
}).wait();
}
else
{
DebugPrint(L" File not available\n");
}
}
catch (Platform::Exception^ ex)
{
DebugPrint(L" Error 0x%x getting text file\n", ex->HResult);
}
}).wait();
}
catch (Platform::Exception^ ex)
{
DebugPrint(L" Error 0x%x getting Contents folder\n", ex->HResult);
}

}).wait();

return;
}
catch (Platform::Exception^ ex)
{
DebugPrint(L" Error 0x%x\n", ex->HResult);
}
auto sampleFileRelPath = ref new Platform::String(LR"(Content\SampleFile.txt)");
concurrency::create_task(package->InstalledLocation->TryGetItemAsync(sampleFileRelPath))
.then([this, sampleFileRelPath](concurrency::task<Windows::Storage::IStorageItem^> result)
{
// maybe null (try failed) or might be a folder, not a file.
auto sampleFile = dynamic_cast<Windows::Storage::StorageFile^>(result.get());
if (sampleFile && sampleFile->IsAvailable)
{
WriteToTextBox("Found SampleFile.txt - loading contents");
DebugPrint(L" %ws is available:\n", sampleFile->Name->Data());
concurrency::create_task(sampleFile->OpenAsync(Windows::Storage::FileAccessMode::Read))
.then([this, sampleFile](concurrency::task<Windows::Storage::Streams::IRandomAccessStream^> task)
{
auto readStream = task.get();
UINT64 const size = readStream->Size;
if (size <= MAXUINT32)
{
auto dataReader = ref new Windows::Storage::Streams::DataReader(readStream);
concurrency::create_task(dataReader->LoadAsync(static_cast<UINT32>(size)))
.then([this, sampleFile, dataReader](unsigned int numBytesLoaded)
{
auto fileContent = dataReader->ReadString(numBytesLoaded);

WriteToTextBox(fileContent);

delete dataReader; // As a best practice, explicitly close the dataReader resource as soon as it is no longer needed.
DebugPrint(L" %ws\n", fileContent->Data());
});
}
}).wait();
}
else
{
DebugPrint(L" %ws not available\n", sampleFileRelPath->Data());
}
}).wait();
}

void MainPage::LoadDLLFromPackage(Windows::ApplicationModel::Package^ package)
{
Windows::Storage::StorageFolder^ Folder = package->InstalledLocation;
auto asyncOp = Folder->GetFileAsync(L"OptionalPackageDLL.dll");

Concurrency::create_task(asyncOp)
.then([this, package](concurrency::task< Windows::Storage::StorageFile^ > task)
{
try
{
auto targetFile = task.get();

if (targetFile->IsAvailable)
{
DebugPrint(L" %ws is available:\n", targetFile->Name->Data());
auto DllModule = LoadPackagedLibrary(targetFile->Name->Data(), 0);

if (DllModule != NULL)
{
WriteToTextBox("Contains dll - loading code");
try
{
auto procAddress = GetProcAddress(DllModule, "ExampleAPIExport");

if (procAddress != NULL)
{
DebugPrint(L" Value returned from ExampleAPIExport: %i\n", procAddress());
auto ret = procAddress();
WriteToTextBox(ret.ToString());
}
else
{
DWORD error = GetLastError();
error = error;
}
}
catch (Platform::Exception^ ex)
{
DebugPrint(L" Error getting address for ExampleAPIExport 0x%x\n", GetLastError());
}
FreeLibrary(DllModule);
}
else
{
HRESULT hr = HRESULT_FROM_WIN32(GetLastError());
if (hr == 0x8007007e) //ERROR_MOD_NOT_FOUND
{
DebugPrint(L" Could not load dll from OP - ERROR_MOD_NOT_FOUND. Make sure that your op is in a related set.\n");
WriteToTextBox("Could not load dll from OP - ERROR_MOD_NOT_FOUND. Make sure that your op is in a related set.");
}
else
{
DebugPrint(L" Error getting DLL file in package 0x%x\n", hr);
WriteToTextBox("Error getting DLL file in package");
}
}
}
}
catch (Platform::Exception^ ex)
{
if (ex->HResult == 0x80070002) //E_FILE_NOT_FOUND
{
DebugPrint(L" No DLL to load in package\n");
}
else
{
DebugPrint(L" Error 0x%x loading DLL file from OP package\n %ws\n", ex->HResult, ex->Message->Data());
}

}
}).wait();

return;

concurrency::create_task(package->InstalledLocation->TryGetItemAsync(L"OptionalPackageDLL.dll"))
.then([this, package](concurrency::task<Windows::Storage::IStorageItem^> task)
{
auto targetFile = dynamic_cast<Windows::Storage::StorageFile^>(task.get());
if (targetFile && targetFile->IsAvailable)
{
DebugPrint(L" %ws is available:\n", targetFile->Name->Data());
auto name = targetFile->Name->Data();
auto dllModule = LoadPackagedLibrary(name, 0);
if (dllModule)
{
WriteToTextBox("Contains dll - loading code");

auto procAddress = GetProcAddress(dllModule, "ExampleAPIExport");
if (procAddress)
{
const auto ret = procAddress();
DebugPrint(L" Value returned from ExampleAPIExport: %i\n", ret);
WriteToTextBox(ret.ToString());
}
FreeLibrary(dllModule);
}
else
{
const DWORD error = GetLastError();
DebugPrint(L" LoadPackagedLibrary failed, make sure package certificates are configured: %i\n", error);
}
}
else
{
DebugPrint(L" Could not load dll from the optional package, make sure it is installed.\n");
WriteToTextBox("Could not load dll from the optional package, make sure it is installed.");
}
}).wait();
}

void MainPage::WriteToTextBox(Platform::String^ str)
{
auto dispatcher = Windows::ApplicationModel::Core::CoreApplication::MainView->Dispatcher->RunAsync(Windows::UI::Core::CoreDispatcherPriority::Normal,
ref new Windows::UI::Core::DispatchedHandler([this, str]()
{
ApptextBox->Text += str +"\n";
}));
auto dispatcher = Windows::ApplicationModel::Core::CoreApplication::MainView->Dispatcher->RunAsync(Windows::UI::Core::CoreDispatcherPriority::Normal,
ref new Windows::UI::Core::DispatchedHandler([this, str]()
{
ApptextBox->Text += str + "\n";
}));
}

void MyMainApp::MainPage::button_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
{
ReadOptionalPackageContent();
ReadOptionalPackageContentAsync();
}


Loading