forked from lxm_flutter/FlutterUnit
更新windows
This commit is contained in:
167
plugins/path_provider_fde/windows/path_provider_plugin.cpp
Normal file
167
plugins/path_provider_fde/windows/path_provider_plugin.cpp
Normal file
@@ -0,0 +1,167 @@
|
||||
// Copyright 2019 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
#include "include/path_provider_fde/path_provider_plugin.h"
|
||||
|
||||
#include <ShlObj.h>
|
||||
#include <flutter/method_channel.h>
|
||||
#include <flutter/plugin_registrar_windows.h>
|
||||
#include <flutter/standard_method_codec.h>
|
||||
#include <windows.h>
|
||||
|
||||
#include <codecvt>
|
||||
#include <memory>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
namespace {
|
||||
|
||||
using flutter::EncodableValue;
|
||||
|
||||
// Converts an null-terminated array of wchar_t's to a std::string.
|
||||
std::string StdStringFromWideChars(wchar_t *wide_chars) {
|
||||
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> wide_to_utf8;
|
||||
return wide_to_utf8.to_bytes(wide_chars);
|
||||
}
|
||||
|
||||
// Gets the path to the given folder ID, without verifying that it exists,
|
||||
// or an empty string on failure.
|
||||
std::string GetFolderPath(REFKNOWNFOLDERID folder_id) {
|
||||
wchar_t *wide_path = nullptr;
|
||||
if (!SUCCEEDED(SHGetKnownFolderPath(folder_id, KF_FLAG_DONT_VERIFY, nullptr,
|
||||
&wide_path))) {
|
||||
return "";
|
||||
}
|
||||
std::string path = StdStringFromWideChars(wide_path);
|
||||
CoTaskMemFree(wide_path);
|
||||
return path;
|
||||
}
|
||||
|
||||
// Returns the name of the executable, without the .exe extension, or an empty
|
||||
// string on failure.
|
||||
std::string GetExecutableName() {
|
||||
wchar_t buffer[MAX_PATH];
|
||||
if (GetModuleFileName(nullptr, buffer, MAX_PATH) == 0) {
|
||||
return "";
|
||||
}
|
||||
std::string executable_path = StdStringFromWideChars(buffer);
|
||||
size_t last_separator_position = executable_path.find_last_of('\\');
|
||||
std::string executable_name;
|
||||
if (last_separator_position == std::string::npos) {
|
||||
executable_name = executable_path;
|
||||
} else {
|
||||
executable_name = executable_path.substr(last_separator_position + 1);
|
||||
}
|
||||
// Strip the .exe extension, if present.
|
||||
std::string extension = ".exe";
|
||||
if (executable_name.compare(executable_name.size() - extension.size(),
|
||||
extension.size(), extension) == 0) {
|
||||
executable_name =
|
||||
executable_name.substr(0, executable_name.size() - extension.size());
|
||||
}
|
||||
return executable_name;
|
||||
}
|
||||
|
||||
class PathProviderPlugin : public flutter::Plugin {
|
||||
public:
|
||||
static void RegisterWithRegistrar(flutter::PluginRegistrar *registrar);
|
||||
|
||||
virtual ~PathProviderPlugin();
|
||||
|
||||
private:
|
||||
PathProviderPlugin();
|
||||
|
||||
// Called when a method is called on plugin channel;
|
||||
void HandleMethodCall(
|
||||
const flutter::MethodCall<> &method_call,
|
||||
std::unique_ptr<flutter::MethodResult<>> result);
|
||||
};
|
||||
|
||||
// static
|
||||
void PathProviderPlugin::RegisterWithRegistrar(
|
||||
flutter::PluginRegistrar *registrar) {
|
||||
auto channel = std::make_unique<flutter::MethodChannel<>>(
|
||||
registrar->messenger(), "plugins.flutter.io/path_provider",
|
||||
&flutter::StandardMethodCodec::GetInstance());
|
||||
|
||||
// Uses new instead of make_unique due to private constructor.
|
||||
std::unique_ptr<PathProviderPlugin> plugin(new PathProviderPlugin());
|
||||
|
||||
channel->SetMethodCallHandler(
|
||||
[plugin_pointer = plugin.get()](const auto &call, auto result) {
|
||||
plugin_pointer->HandleMethodCall(call, std::move(result));
|
||||
});
|
||||
|
||||
registrar->AddPlugin(std::move(plugin));
|
||||
}
|
||||
|
||||
PathProviderPlugin::PathProviderPlugin() = default;
|
||||
|
||||
PathProviderPlugin::~PathProviderPlugin() = default;
|
||||
|
||||
void PathProviderPlugin::HandleMethodCall(
|
||||
const flutter::MethodCall<> &method_call,
|
||||
std::unique_ptr<flutter::MethodResult<>> result) {
|
||||
if (method_call.method_name().compare("getTemporaryDirectory") == 0) {
|
||||
wchar_t path_buffer[MAX_PATH];
|
||||
DWORD length = GetTempPath(MAX_PATH, path_buffer);
|
||||
if (length == 0 || length > MAX_PATH) {
|
||||
result->Error("Unable to get temporary path");
|
||||
return;
|
||||
}
|
||||
std::string result_path = StdStringFromWideChars(path_buffer);
|
||||
result->Success(EncodableValue(result_path));
|
||||
} else if (method_call.method_name().compare(
|
||||
"getApplicationSupportDirectory") == 0) {
|
||||
std::string path = GetFolderPath(FOLDERID_RoamingAppData);
|
||||
if (path.empty()) {
|
||||
result->Error("Unable to get application data path");
|
||||
return;
|
||||
}
|
||||
// Use the executable name as the subdirectory for now.
|
||||
std::string exe_name = GetExecutableName();
|
||||
if (exe_name.empty()) {
|
||||
result->Error("Unable to get exe name");
|
||||
return;
|
||||
}
|
||||
std::ostringstream response_stream;
|
||||
response_stream << path << "\\" << exe_name;
|
||||
result->Success(EncodableValue(response_stream.str()));
|
||||
} else if (method_call.method_name().compare(
|
||||
"getApplicationDocumentsDirectory") == 0) {
|
||||
std::string path = GetFolderPath(FOLDERID_Documents);
|
||||
if (path.empty()) {
|
||||
result->Error("Unable to get documents path");
|
||||
return;
|
||||
}
|
||||
result->Success(EncodableValue(path));
|
||||
} else if (method_call.method_name().compare("getDownloadsDirectory") == 0) {
|
||||
std::string path = GetFolderPath(FOLDERID_Downloads);
|
||||
if (path.empty()) {
|
||||
result->Error("Unable to get downloads path");
|
||||
return;
|
||||
}
|
||||
result->Success(EncodableValue(path));
|
||||
} else {
|
||||
result->NotImplemented();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void PathProviderPluginRegisterWithRegistrar(
|
||||
FlutterDesktopPluginRegistrarRef registrar) {
|
||||
PathProviderPlugin::RegisterWithRegistrar(
|
||||
flutter::PluginRegistrarManager::GetInstance()
|
||||
->GetRegistrar<flutter::PluginRegistrarWindows>(registrar));
|
||||
}
|
||||
Reference in New Issue
Block a user