File SDK - Memproses file email .msg (C++)

SDK File mendukung operasi pelabelan untuk file .msg dengan cara yang sama seperti jenis file lainnya, kecuali aplikasi harus mengaktifkan bendera fitur MSG untuk SDK. Di sini, kita akan melihat cara mengatur bendera ini.

Sebagaimana dibahas sebelumnya, instansiasi dari mip::FileEngine memerlukan objek pengaturan, mip::FileEngineSettings. FileEngineSettings can be used to pass parameters for custom settings the application needs to set for a particular instance. CustomSettings property of the mip::FileEngineSettings is used to set the flag for enable_msg_file_type to enable processing of .msg files.

Prasyarat

Jika Anda belum melakukannya, pastikan untuk menyelesaikan prasyarat berikut sebelum melanjutkan:

Langkah-langkah implementasi prasyarat

  1. Buka solusi Visual Studio yang Anda buat di artikel sebelumnya "Panduan Cepat: Inisialisasi Aplikasi Klien (C++)".

  2. Buat skrip PowerShell untuk menghasilkan token akses seperti yang dijelaskan dalam Panduan Memulai Cepat "Daftar label sensitivitas (C++)".

  3. Terapkan kelas pengamat untuk memantau mip::FileHandler seperti yang dijelaskan dalam Mulai Cepat "Atur/dapatkan label sensitivitas (C++)".

Atur enable_msg_file_type dan gunakan File SDK untuk memberi label file .msg

Tambahkan kode konstruksi mesin file di bawah ini untuk mengatur enable_msg_file_type flag dan menggunakan mesin file untuk memberi label file .msg.

  1. Dengan menggunakan Solution Explorer, buka file .cpp dalam proyek Anda yang berisi implementasi dari metode main(). Ini menggunakan nama default yang sama dengan proyek yang memuatnya, yang Anda tentukan selama pembuatan proyek.

  2. Tambahkan #include berikut dan direktif penggunaan, di bawah direktif yang ada yang sesuai, pada bagian paling atas dari file.

    #include "filehandler_observer.h" 
    #include "mip/file/file_handler.h" 
    #include <iostream>    
    using mip::FileHandler;   
    using std::endl;
    
  3. Hapus implementasi dari fungsi main() pada panduan memulai cepat sebelumnya. Di dalam main() badan, masukkan kode berikut. Dalam blok kode di bawah ini, enable_msg_file_type flag diatur selama pembuatan mesin berkas, file .msg kemudian dapat diproses oleh mip::FileHandler objek yang dibuat menggunakan mesin berkas.

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>(mAppInfo,
				                                                                                       "mip_data",
                                                                                        			   mip::LogLevel::Trace,
                                                                                                       false);

    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(mipContext,mip::CacheStorageType::OnDisk,authDelegateImpl,
        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)
                            "<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
    labels = mEngine->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);

    fileHandler->SetLabel(labelId, 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 = handlerPromise->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->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;
    mipContext = nullptr;

    return 0;
}

Untuk detail lebih lanjut tentang operasi berkas, rujuk ke konsep Pengendali Berkas.

  1. Ganti nilai placeholder dalam kode sumber dengan menggunakan nilai berikut:

    Pengganti sementara Nilai
    <application-id> ID aplikasi seperti yang terdaftar di penyewa Microsoft Entra, misalnya: 0edbblll-8773-44de-b87c-b8c6276d41eb.
    <akun mesin> Akun yang digunakan untuk identitas mesin, misalnya: user@tenant.onmicrosoft.com.
    <status mesin> Status aplikasi yang ditentukan pengguna, misalnya: My engine state.
    <input-file-path> The full path to a test input message file, for example: c:\\Test\\message.msg.
    <output-file-path> Jalur lengkap ke file keluaran, yang akan menjadi salinan berlabel dari file masukan, contohnya: c:\\Test\\message_labeled.msg.
    <label-id> LabelId yang diambil menggunakan ListSensitivityLabels, misalnya: 667466bf-a01b-4b0a-8bbf-a79a3d96f720.

Membangun dan menguji aplikasi

Gunakan F6 (Bangun Solusi) untuk membangun aplikasi klien Anda. Jika Anda tidak memiliki kesalahan build, gunakan F5 (Mulai debugging) untuk menjalankan aplikasi Anda.