Loading code from an optional package

In the last blog we looked at how to create a basic optional package and how to load content from it. So now lets try to load code from an optional package. In my GitHub solution, I have an ActivatableOptionalPackage. This is basically an optional package with a tile and it contains a dll that I will load from my Main app.

So here is what I did to create the ActivatableOptionalPackage. I followed the same Steps 1 - 4 from the  previous blog. The big difference here is that the ActivatableOptionalPackage can be launched from the Start. To do this you need to change the Application Id of your optional package to something unique. Your optional package runs with your main application's identity, so if your optional package can be activated the Application Id must be different from what Id of your main application.

 <applications>
    <application id="ActivatableOP" entrypoint="ActivatableOptionalPackage.App" executable="$targetnametoken$.exe">
</applications>

Now for how to load the dll in my optional package from my main app, take a look at GitHub for the definition of the LoadDLLFromPackage method, but in a nutshell, I got a reference to the InstalledLocation of the optional package I enumerated and then proceeded to do a LoadPackagedLibrary of  "OptionalPackageDLL.dll"

 Windows::Storage::StorageFolder^ opFolder = package->InstalledLocation;
    auto asyncOp = opFolder->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)
         {
               auto DllModule = LoadPackagedLibrary(targetFile->Name->Data(), 0);
                if (DllModule != NULL)
              {                   
                    try
                 {
                       auto procAddress = GetProcAddress(DllModule, "ExampleAPIExport");

                       if (procAddress != NULL)
                        {                           
                            auto ret = procAddress();                                                       
                        }
                       else
                        {
                           DWORD error = GetLastError();
                           error = error;
                      }
                   }
                   catch (Platform::Exception^ ex)
                 {
                       DebugPrint(L"    Error getting address for ExampleAPIExport 0x%x\n", GetLastError());
                   }
                   FreeLibrary(DllModule);
             }
           }
       }
   }

If you deploy MyMainApp followed by the ActivatableOptionalPackage and then launch MyMainApp from start, and click on Load Content, you will see that we are not able to load the dll!! Read this next blog to understand why and how you can enable this scenario.

Sandeep George
Senior Program Manager