File SDK - Elaborare file di posta elettronica .msg file (C++)

File SDK supporta le operazioni di etichettatura per .msg file nello stesso modo di qualsiasi altro tipo di file, ad eccezione del fatto che l'SDK necessita dell'applicazione per abilitare il flag di funzionalità MSG. Questa guida introduttiva illustra come impostare questo flag.

Come discusso in precedenza, l'istanziazione di mip::FileEngine richiede l'oggetto di impostazioni mip::FileEngineSettings. L'applicazione usa FileEngineSettings per passare impostazioni personalizzate per una determinata istanza. La proprietà CustomSettings di mip::FileEngineSettings imposta il flag enable_msg_file_type per abilitare l'elaborazione dei file .msg.

Prerequisiti

Se non è già stato fatto, assicurarsi di completare i prerequisiti seguenti prima di continuare:

Passaggi di implementazione dei prerequisiti

  1. Aprire la soluzione di Visual Studio creata nell'articolo precedente "Avvio rapido: Inizializzazione dell'applicazione client (C++)".

  2. Creare uno script di PowerShell per generare token di accesso, come illustrato in Avvio rapido: Elencare le etichette di riservatezza (C++).

  3. Implementare una classe observer per monitorare mip::FileHandler, come illustrato in Avvio rapido: Impostare/ottenere etichette di riservatezza (C++).

Impostare enable_msg_file_type e usare File SDK per etichettare .msg file

Aggiungere il codice di costruzione del motore di file seguente per impostare il enable_msg_file_type flag e usare il motore di file per etichettare un file .msg.

  1. In Esplora soluzioni aprire il file .cpp nel progetto che contiene l'implementazione del main() metodo . Per impostazione predefinita, assume lo stesso nome del progetto che lo contiene, specificato durante la creazione del progetto.

  2. Aggiungere le seguenti direttive #include e using dopo le corrispondenti direttive esistenti, all'inizio del file:

    #include "filehandler_observer.h" 
    #include "mip/file/file_handler.h" 
    #include <iostream>    
    using mip::FileHandler;   
    using std::endl;
    
  3. Rimuovere l'implementazione della funzione main() dalla guida introduttiva rapida precedente. All'interno del main() corpo inserire il codice seguente. Nel blocco di codice seguente, la creazione del motore file imposta il flag enable_msg_file_type. mip::FileHandler gli oggetti creati usando il motore di file possono quindi elaborare un file .msg.

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;
}

Per altre informazioni sulle operazioni sui file, vedere Concetti relativi al gestore di file.

  1. Sostituire i valori segnaposto nel codice sorgente con i valori seguenti:

    Placeholder Valore
    <application-id> ID applicazione registrato con il tenant Microsoft Entra, ad esempio : 00001111-aaaa-2222-bbbb-3333cccc4444.
    <engine-account> L'account utilizzato per l'identità del motore, ad esempio: user@tenant.onmicrosoft.com.
    <stato del motore> Stato dell'applicazione definito dall'utente, ad esempio: My engine state.
    <percorso-del-file-di-input> Il percorso completo di un file di messaggio di input per il test, ad esempio: c:\\Test\\message.msg.
    <percorso-del-file-di-output> Percorso completo del file di output, ovvero una copia etichettata del file di input, ad esempio : c:\\Test\\message_labeled.msg.
    <label-id> ID etichetta recuperato tramite ListSensitivityLabels, ad esempio : 667466bf-a01b-4b0a-8bbf-a79a3d96f720.

Compilare e testare l'applicazione

Usare F6 (Compila soluzione) per compilare l'applicazione client. Se non si verificano errori di compilazione, usare F5 (Avvia debug) per eseguire l'applicazione.