Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
This quickstart shows you how to use more of the MIP File SDKs. By using one of the sensitivity labels you listed in the previous quickstart, you use a file handler to set and get the label on a file. The file handler class exposes various operations for setting and getting labels, or protection, for supported file types.
Prerequisites
If you haven't already, be sure to complete the following prerequisites before continuing:
- Quickstart: List sensitivity labels (C++). Complete this quickstart first. It builds a starter Visual Studio solution that lists an organization's sensitivity labels. This "Set and get a sensitivity label" quickstart builds on the previous one.
- Optionally: Review File handlers in the MIP SDK concepts.
Implement an observer class to monitor the File handler object
As in the observer you implemented for the file profile and engine in the application initialization quickstart, now you implement an observer class for a file handler object.
Create a basic implementation for a file handler observer by extending the SDK's mip::FileHandler::Observer class. The application instantiates the observer and uses it later to monitor file handler operations.
Open the Visual Studio solution you worked on in the previous "Quickstart: List sensitivity labels (C++)" article.
Add a new class to your project. Visual Studio generates both the header/.h and implementation/.cpp files for you:
- In the Solution Explorer, right-click the project node again, select Add, then select Class.
- On the Add Class dialog:
- In the Class Name field, enter "filehandler_observer". Notice that both the .h file and .cpp file fields are automatically populated, based on the name you enter.
- When finished, select OK.
After Visual Studio generates the .h and .cpp files for the class, both files open in editor tabs. Update each file to implement your new observer class:
Update "filehandler_observer.h", by selecting/deleting the generated
filehandler_observerclass. Don't remove the preprocessor directives generated by the previous step (#pragma, #include). Then copy/paste the following source into the file, after any existing preprocessor directives:#include <memory> #include "mip/file/file_engine.h" #include "mip/file/file_handler.h" class FileHandlerObserver final : public mip::FileHandler::Observer { public: FileHandlerObserver() { } // Observer implementation void OnCreateFileHandlerSuccess(const std::shared_ptr<mip::FileHandler>& fileHandler, const std::shared_ptr<void>& context) override; void OnCreateFileHandlerFailure(const std::exception_ptr& error, const std::shared_ptr<void>& context) override; void OnCommitSuccess(bool committed, const std::shared_ptr<void>& context) override; void OnCommitFailure(const std::exception_ptr& error, const std::shared_ptr<void>& context) override; };Update "filehandler_observer.cpp", by selecting/deleting the generated
filehandler_observerclass implementation. Don't remove the preprocessor directives generated by the previous step (#pragma, #include). Then copy/paste the following source into the file, after any existing preprocessor directives:void FileHandlerObserver::OnCreateFileHandlerSuccess(const std::shared_ptr<mip::FileHandler>& fileHandler, const std::shared_ptr<void>& context) { auto promise = std::static_pointer_cast<std::promise<std::shared_ptr<mip::FileHandler>>>(context); promise->set_value(fileHandler); } void FileHandlerObserver::OnCreateFileHandlerFailure(const std::exception_ptr & error, const std::shared_ptr<void>& context) { auto promise = std::static_pointer_cast<std::promise<std::shared_ptr<mip::FileHandler>>>(context); promise->set_exception(error); } void FileHandlerObserver::OnCommitSuccess(bool committed, const std::shared_ptr<void>& context) { auto promise = std::static_pointer_cast<std::promise<bool>>(context); promise->set_value(committed); } void FileHandlerObserver::OnCommitFailure(const std::exception_ptr & error, const std::shared_ptr<void>& context) { auto promise = std::static_pointer_cast<std::promise<bool>>(context); promise->set_exception(error); }
Optionally, use F6 (Build Solution) to run a test compile/link of your solution and confirm that it builds successfully before continuing.
Add logic to set and get a sensitivity label
Use the File engine object to add logic that sets and gets a sensitivity label on a file.
In Solution Explorer, open the .cpp file in your project that contains the implementation of the
main()method. It defaults to the same name as the project containing it, which you specified during project creation.Add the following
#includeandusingdirectives after the corresponding existing directives at the top of the file:#include "filehandler_observer.h" #include "mip/file/file_handler.h" using mip::FileHandler;Toward the end of the
main()body, aftersystem("pause");and beforereturn 0;where you left off in the previous quickstart, insert the following code:// Set up async FileHandler for input file operations string inputFilePath = "<input-file-path>"; string actualFilePath = "<content-identifier>"; std::shared_ptr<FileHandler> handler; try { auto handlerPromise = std::make_shared<std::promise<std::shared_ptr<FileHandler>>>(); auto handlerFuture = handlerPromise->get_future(); engine->CreateFileHandlerAsync( inputFilePath, actualFilePath, true, std::make_shared<FileHandlerObserver>(), handlerPromise); handler = handlerFuture.get(); } catch (const std::exception& e) { cout << "An exception occurred... did you specify a valid input file path?\n\n" << e.what() << "'\n"; system("pause"); return 1; } // Set a label on input file try { string labelId = "<label-id>"; cout << "\nApplying Label ID " << labelId << " to " << inputFilePath << endl; mip::LabelingOptions labelingOptions(mip::AssignmentMethod::PRIVILEGED); handler->SetLabel(engine->GetLabelById(labelId), labelingOptions, mip::ProtectionSettings()); } catch (const std::exception& e) { cout << "An exception occurred... did you specify a valid label ID?\n\n" << e.what() << "'\n"; system("pause"); return 1; } // Commit changes, save as a different/output file string filePathOut = "<output-file-path>"; try { cout << "Committing changes" << endl; auto commitPromise = std::make_shared<std::promise<bool>>(); auto commitFuture = commitPromise->get_future(); handler->CommitAsync(filePathOut, commitPromise); if (commitFuture.get()) { cout << "\nLabel committed to file: " << filePathOut << endl; } else { cout << "Failed to label: " + filePathOut << endl; return 1; } } catch (const std::exception& e) { cout << "An exception occurred... did you specify a valid commit file path?\n\n" << e.what() << "'\n"; system("pause"); return 1; } system("pause"); // Set up async FileHandler for output file operations actualFilePath = "<content-identifier>"; try { auto handlerPromise = std::make_shared<std::promise<std::shared_ptr<FileHandler>>>(); auto handlerFuture = handlerPromise->get_future(); engine->CreateFileHandlerAsync( filePathOut, actualFilePath, true, std::make_shared<FileHandlerObserver>(), handlerPromise); handler = handlerFuture.get(); } catch (const std::exception& e) { cout << "An exception occurred... did you specify a valid output file path?\n\n" << e.what() << "'\n"; system("pause"); return 1; } // Get the label from output file try { cout << "\nGetting the label committed to file: " << filePathOut << endl; auto label = handler->GetLabel(); cout << "Name: " + label->GetLabel()->GetName() << endl; cout << "Id: " + label->GetLabel()->GetId() << endl; } catch (const std::exception& e) { cout << "An exception occurred... did you specify a valid label ID?\n\n" << e.what() << "'\n"; system("pause"); return 1; } system("pause");Toward the end of
main(), find the application shutdown block created in the first quickstart and uncomment the handler line:// Application shutdown. Null out profile and engine, call ReleaseAllResources(); // Application may crash at shutdown if resources aren't properly released. profile = nullptr; engine = nullptr; handler = nullptr; mipContext = nullptr;Replace the placeholder values in the source code as follows, using string constants:
Placeholder Value <input-file-path> The full path to a test input file, for example: "c:\\Test\\Test.docx".<content-identifier> A human-readable identifier for the content. For example: - For a file, use path\filename:
"c:\Test\Test.docx" - For an email, use subject:sender:
"RE: Audit design:user1@contoso.com"
<label-id> A sensitivity label ID, copied from the console output in the previous Quickstart, for example: "f42a3342-8706-4288-bd31-ebb85995028z".<output-file-path> The full path to the output file, which is a labeled copy of the input file, for example: "c:\\Test\\Test_labeled.docx".- For a file, use path\filename:
Build and test the application
Build and test your client application.
Use F6 (Build Solution) to build your client application. If the build has no errors, use F5 (Start debugging) to run your application.
If your project builds and runs successfully, the application prompts for an access token each time the SDK calls your
AcquireOAuth2Token()method. As you did previously in the "List sensitivity labels" quickstart, run your PowerShell script to acquire the token each time with the values provided for$authorityand$resourceUrl.Run the PowerShell script to generate an access token using the following values, then copy/paste it below: Sensitivity labels for your organization: Non-Business : 87ba5c36-17cf-14793-bbc2-bd5b3a9f95cz Public : 83867195-f2b8-2ac2-b0b6-6bb73cb33afz General : f42a3342-8706-4288-bd31-ebb85995028z Confidential : 074e457c-5848-4542-9a6f-34a182080e7z Highly Confidential : f55c2dea-db0f-47cd-8520-a52e1590fb6z Press any key to continue . . . Applying Label ID 074e457c-5848-4542-9a6f-34a182080e7z to c:\Test\Test.docx Committing changes Label committed to file: c:\Test\Test_labeled.docx Press any key to continue . . . Getting the label committed to file: c:\Test\Test_labeled.docx Name: Confidential Id: 074e457c-5848-4542-9a6f-34a182080e7z Press any key to continue . . .
Verify the label application by opening the output file and visually inspecting the document's information protection settings.
Note
If you're labeling an Office document but aren't signed in by using an account from the Microsoft Entra tenant that issued the access token (and sensitivity labels are configured), you might be prompted to sign in before you can open the labeled document.