文件 SDK 支持以与任何其他文件类型相同的方式为.msg文件的标记操作,但 SDK 需要应用程序才能启用 MSG 功能标志。 在这里,我们将了解如何设置此标志。
如前所述,实例化 mip::FileEngine 需要设置对象 mip::FileEngineSettings。 FileEngineSettings 可用于传递应用程序为特定实例设置所需的自定义设置的参数。
mip::FileEngineSettings 的 CustomSettings 属性用于为 enable_msg_file_type 设置标志,以启用对 .msg 文件的处理。
先决条件
如果尚未完成,请确保先完成以下先决条件,然后再继续:
- 请先完成快速入门:文件 SDK 应用程序初始化(C++),该快速入门将生成一个入门级的 Visual Studio 解决方案。 此“如何 - 处理电子邮件 .msg 文件 (C++)”快速入门建立在上一个快速入门的基础之上。
- 查看快速入门:列出敏感度标签(C++)。
- 查看快速入门:设置/获取敏感度标签(C++)。
- 查看电子邮件文件 MIP SDK 概念。
- (可选)查看 MIP SDK 概念中的文件引擎 。
- (可选):查看 MIP SDK 概念中的文件处理程序 。
实施前提步骤
打开你在前文“快速入门:客户端应用程序初始化 (C++)”中创建的 Visual Studio 解决方案。
创建 PowerShell 脚本以生成访问令牌,如快速入门“列出敏感度标签(C++)”中所述。
设置 enable_msg_file_type 并使用 File SDK 为 .msg 文件添加标签
添加下面的文件引擎构造代码来设置 enable_msg_file_type flag 和使用文件引擎标记.msg文件。
使用“解决方案资源管理器”,打开项目中包含
main()方法实现的 .cpp 文件。 默认名称与该项目所在的项目名称相同,这是在您创建项目时指定的。在文件顶部的相应现有指令下面添加以下 #include 和 using 指令:
#include "filehandler_observer.h" #include "mip/file/file_handler.h" #include <iostream> using mip::FileHandler; using std::endl;从上一快速入门教程中删除
main()函数的实现。 在main()正文中,插入以下代码。 在下面的代码块中,enable_msg_file_type标志会在创建文件引擎时设置,随后便可使用由该文件引擎创建的mip::FileHandler对象来处理 .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>(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;
}
有关文件操作的更多详细信息,请参阅 文件处理程序概念。
使用以下值替换源代码中的占位符值:
占位符 价值 <application-id> 在 Microsoft Entra 租户中注册的应用程序 ID,例如: 00001111-aaaa-2222-bbbb-3333cccc4444<引擎账户> 用于引擎标识的帐户,例如: user@tenant.onmicrosoft.com<引擎状态> 用户定义的应用程序状态,例如: My engine state<输入文件路径> 测试输入消息文件的完整路径,例如: c:\\Test\\message.msg<输出文件路径> 输出文件的完整路径,该文件将是输入文件的标记副本,例如: c:\\Test\\message_labeled.msg<标签-ID> 使用 检索到的 labelId,例如:。
生成并测试应用
使用 F6 (生成解决方案)生成客户端应用程序。 如果没有生成错误,请使用 F5 (开始调试)来运行应用程序。