File SDK – Verarbeiten von E-Mail-.msg-Dateien (C++)

Das Datei-SDK unterstützt Bezeichnungsvorgänge für .msg-Dateien genauso wie für jeden anderen Dateityp, mit der Ausnahme, dass in der Anwendung das MSG-Featureflag aktiviert sein muss. In dieser Schnellstartanleitung wird gezeigt, wie Sie dieses Kennzeichen festlegen.

Wie bereits erwähnt, erfordert die Instanziierung von mip::FileEngine das mip::FileEngineSettings Konfigurationsobjekt. Die Anwendung verwendet FileEngineSettings , um benutzerdefinierte Einstellungen für eine bestimmte Instanz zu übergeben. Die CustomSettings-Eigenschaft von mip::FileEngineSettings setzt das enable_msg_file_type-Flag, um die Verarbeitung von .msg-Dateien zu aktivieren.

Voraussetzungen

Falls noch nicht geschehen, stellen Sie sicher, dass Sie die folgenden Voraussetzungen erfüllen, bevor Sie fortfahren:

Erforderliche Implementierungsschritte

  1. Öffnen Sie die Visual Studio-Lösung, die Sie im vorherigen Artikel "Schnellstart: Clientanwendungsinitialisierung (C++)" erstellt haben.

  2. Erstellen Sie ein PowerShell-Skript zum Generieren von Zugriffstoken, wie in der Schnellstartanleitung erläutert: Auflisten von Vertraulichkeitsbezeichnungen (C++).

  3. Implementieren Sie eine Beobachterklasse, um mip::FileHandler zu überwachen, wie in Schnellstart: Vertraulichkeitsbezeichnungen festlegen/abrufen (C++) erläutert.

Setzen Sie enable_msg_file_type und verwenden Sie das Datei-SDK zum Bezeichnen der .msg-Datei.

Fügen Sie den folgenden Dateimodul-Konstruktionscode hinzu, um das enable_msg_file_type Kennzeichen festzulegen und das Dateimodul zum Bezeichnen einer .msg Datei zu verwenden.

  1. Öffnen Sie in Projektmappen-Explorer die datei .cpp in Ihrem Projekt, die die Implementierung der main() Methode enthält. Standardmäßig wird derselbe Name wie das Projekt verwendet, das es enthält, das Sie während der Projekterstellung angegeben haben.

  2. Fügen Sie die folgenden #include- und using-Direktiven nach den entsprechenden vorhandenen Direktiven oben in der Datei hinzu:

    #include "filehandler_observer.h" 
    #include "mip/file/file_handler.h" 
    #include <iostream>    
    using mip::FileHandler;   
    using std::endl;
    
  3. Entfernen Sie die Implementierung der main() Funktion aus der vorherigen Schnellstartanleitung. Fügen Sie im Textkörper main() den folgenden Code ein. Im folgenden Codeblock wird bei der Erstellung der Datei-Engine das Flag enable_msg_file_type gesetzt. mip::FileHandler Mithilfe des Dateimoduls erstellte Objekte können dann eine .msg Datei verarbeiten.

int main()
{
    // Construct/initialize objects required by the application's profile object
    ApplicationInfo appInfo { "<application-id>",                    // ApplicationInfo object (App ID, name, version)
                              "<application-name>", 
                              "1.0" 
    };

    std::shared_ptr<mip::MipConfiguration> mipConfiguration = std::make_shared<mip::MipConfiguration>(appInfo,
				                                                                                       "mip_data",
                                                                                        			   mip::LogLevel::Trace,
                                                                                                       false,
                                                                                                       mip::CacheStorageType::OnDisk);

    std::shared_ptr<mip::MipContext> mMipContext = mip::MipContext::Create(mipConfiguration);

    auto profileObserver = make_shared<ProfileObserver>();                      // Observer object
    auto authDelegateImpl = make_shared<AuthDelegateImpl>("<application-id>");  // Authentication delegate object (App ID)
    auto consentDelegateImpl = make_shared<ConsentDelegateImpl>();              // Consent delegate object

    // Construct/initialize profile object
    FileProfile::Settings profileSettings(mMipContext, mip::CacheStorageType::OnDisk,
        consentDelegateImpl, profileObserver);

    // Set up promise/future connection for async profile operations; load profile asynchronously
    auto profilePromise = make_shared<promise<shared_ptr<FileProfile>>>();
    auto profileFuture = profilePromise->get_future();
    try
    {
        mip::FileProfile::LoadAsync(profileSettings, profilePromise);
    }
    catch (const std::exception& e)
    {
        std::cout << "An exception occurred. Are the Settings and ApplicationInfo objects populated correctly?\n\n"<< e.what() << "'\n";
        system("pause");
        return 1;
    }

    auto profile = profileFuture.get();

    // Construct/initialize engine object
    FileEngine::Settings engineSettings(
                            mip::Identity("<engine-account>"),      // Engine identity (account used for authentication)
                            authDelegateImpl,                       // Token acquisition implementation
                            "<engine-state>",                       // User-defined engine state
                            "en-US");                               // Locale (default = en-US)

    //Set enable_msg_file_type flag as true
    std::vector<std::pair<string, string>> customSettings;
    customSettings.emplace_back(mip::GetCustomSettingEnableMsgFileType(), "true");
    engineSettings.SetCustomSettings(customSettings);

    // Set up promise/future connection for async engine operations; add engine to profile asynchronously
    auto enginePromise = make_shared<promise<shared_ptr<FileEngine>>>();
    auto engineFuture = enginePromise->get_future();
    profile->AddEngineAsync(engineSettings, enginePromise);
    std::shared_ptr<FileEngine> engine;

    try
    {
        engine = engineFuture.get();
    }
    catch (const std::exception& e)
    {
        cout << "An exception occurred... is the access token incorrect/expired?\n\n"<< e.what() << "'\n";
        system("pause");
        return 1;
    }

    //Set file paths
    string inputFilePath = "<input-file-path>"; //.msg file to be labeled
    string actualFilePath = inputFilePath;
    string outputFilePath = "<output-file-path>"; //labeled .msg file
    string actualOutputFilePath = outputFilePath;

    //Create a file handler for original file
    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);

    auto fileHandler = handlerFuture.get();

    //List labels available to the user    

    // Use mip::FileEngine to list all labels
    auto labels = engine->ListSensitivityLabels();

    // Iterate through each label, first listing details
    for (const auto& label : labels) {
        cout << label->GetName() << " : " << label->GetId() << endl;

        // get all children for mip::Label and list details
        for (const auto& child : label->GetChildren()) {
            cout << "->  " << child->GetName() << " : " << child->GetId() << endl;
        }
    }

    string labelId = "<labelId-id>"; //set a label ID to use

    // Labeling requires a mip::LabelingOptions object. 
    // Review API ref for more details. The sample implies that the file was labeled manually by a user.
    mip::LabelingOptions labelingOptions(mip::AssignmentMethod::PRIVILEGED);

    // Resolve the label ID to a mip::Label, then apply it.
    auto label = engine->GetLabelById(labelId);
    fileHandler->SetLabel(label, labelingOptions, mip::ProtectionSettings());

    // Commit changes, save as outputFilePath
    auto commitPromise = std::make_shared<std::promise<bool>>();
    auto commitFuture = commitPromise->get_future();

    if(fileHandler->IsModified())
    {
        fileHandler->CommitAsync(outputFilePath, commitPromise);
    }
    
    if (commitFuture.get()) {
        cout << "\n Label applied to file: " << outputFilePath << endl;
    }
    else {
        cout << "Failed to label: " + outputFilePath << endl;
        return 1;
    }

    // Create a new handler to read the label
    auto msgHandlerPromise = std::make_shared<std::promise<std::shared_ptr<FileHandler>>>();
    auto msgHandlerFuture = msgHandlerPromise->get_future();

    engine->CreateFileHandlerAsync(inputFilePath,
                                    actualFilePath,
                                    true,
                                    std::make_shared<FileHandlerObserver>(),
                                    msgHandlerPromise);

    auto msgFileHandler = msgHandlerFuture.get();

    cout << "Original file: " << inputFilePath << endl;
    cout << "Labeled file: " << outputFilePath << endl;
    cout << "Label applied to file : " 
            << msgFileHandler->GetLabel()->GetLabel()->GetName() 
            << endl;
    
    // Application shutdown. Null out profile, engine, handler.
    // Application may crash at shutdown if resources aren't properly released.
    msgFileHandler = nullptr;
    fileHandler = nullptr;
    engine = nullptr;
    profile = nullptr;
    mMipContext->ShutDown();
    mMipContext = nullptr;

    return 0;
}

Weitere Informationen zu Dateivorgängen finden Sie unter "Dateihandlerkonzepte".

  1. Ersetzen Sie die Platzhalterwerte im Quellcode durch die folgenden Werte:

    Platzhalter Wert
    <application-id> Die Anwendungs-ID, die beim Microsoft Entra Mandanten registriert ist, z. B.: 00001111-aaaa-2222-bbbb-3333cccc4444.
    <Engine-Konto> Das Konto, das für die Modulidentität verwendet wird, z. B.: user@tenant.onmicrosoft.com.
    <Modulzustand> Benutzerdefinierter Anwendungszustand, z. B.: My engine state.
    <Eingabedateipfad> Der vollständige Pfad zu einer Testeingabemeldungsdatei, z. B.: c:\\Test\\message.msg.
    <Ausgabedateipfad> Der vollständige Pfad zur Ausgabedatei, bei der es sich um eine beschriftete Kopie der Eingabedatei handelt, z. B.: c:\\Test\\message_labeled.msg.
    <Bezeichnungs-ID> Die Bezeichner-ID, die mithilfe von ListSensitivityLabels abgerufen wurde, zum Beispiel: 667466bf-a01b-4b0a-8bbf-a79a3d96f720.

Erstellen und Testen der Anwendung

Verwenden Sie F6 (Buildlösung), um Ihre Clientanwendung zu erstellen. Wenn keine Buildfehler auftreten, verwenden Sie F5 (Debuggen starten), um Ihre Anwendung auszuführen.