summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar boludoz2023-10-16 23:42:45 -0300
committerGravatar boludoz2023-10-16 23:42:45 -0300
commit1afe6d51eed4a420bb7289955333a2bb10c06b99 (patch)
treeb1baaf7033bff02d09132c136010802499cd3792 /src
parentshortcut_stream.close(); fixed (diff)
downloadyuzu-1afe6d51eed4a420bb7289955333a2bb10c06b99.tar.gz
yuzu-1afe6d51eed4a420bb7289955333a2bb10c06b99.tar.xz
yuzu-1afe6d51eed4a420bb7289955333a2bb10c06b99.zip
More @liamwhite suggestions applied.
Diffstat (limited to 'src')
-rw-r--r--src/common/fs/path_util.cpp12
-rw-r--r--src/yuzu/main.cpp200
2 files changed, 90 insertions, 122 deletions
diff --git a/src/common/fs/path_util.cpp b/src/common/fs/path_util.cpp
index 60c5e477e..732c1559f 100644
--- a/src/common/fs/path_util.cpp
+++ b/src/common/fs/path_util.cpp
@@ -252,29 +252,23 @@ void SetYuzuPath(YuzuPath yuzu_path, const fs::path& new_path) {
252 252
253fs::path GetExeDirectory() { 253fs::path GetExeDirectory() {
254 WCHAR exe_path[MAX_PATH]; 254 WCHAR exe_path[MAX_PATH];
255
256 if (SUCCEEDED(GetModuleFileNameW(nullptr, exe_path, MAX_PATH))) { 255 if (SUCCEEDED(GetModuleFileNameW(nullptr, exe_path, MAX_PATH))) {
257 std::wstring wide_exe_path(exe_path); 256 std::wstring wide_exe_path(exe_path);
258 return fs::path{Common::UTF16ToUTF8(wide_exe_path)}.parent_path(); 257 return fs::path{Common::UTF16ToUTF8(wide_exe_path)}.parent_path();
259 } else {
260 LOG_ERROR(Common_Filesystem, "Failed to get the path to the executable of the current "
261 "process");
262 } 258 }
263 259 LOG_ERROR(Common_Filesystem, "Failed to get the path to the executable of the current "
260 "process");
264 return fs::path{}; 261 return fs::path{};
265} 262}
266 263
267fs::path GetAppDataRoamingDirectory() { 264fs::path GetAppDataRoamingDirectory() {
268 PWSTR appdata_roaming_path = nullptr; 265 PWSTR appdata_roaming_path = nullptr;
269
270 if (SUCCEEDED(SHGetKnownFolderPath(FOLDERID_RoamingAppData, 0, NULL, &appdata_roaming_path))) { 266 if (SUCCEEDED(SHGetKnownFolderPath(FOLDERID_RoamingAppData, 0, NULL, &appdata_roaming_path))) {
271 std::wstring wide_appdata_roaming_path(appdata_roaming_path); 267 std::wstring wide_appdata_roaming_path(appdata_roaming_path);
272 CoTaskMemFree(appdata_roaming_path); 268 CoTaskMemFree(appdata_roaming_path);
273 return fs::path{Common::UTF16ToUTF8(wide_appdata_roaming_path)}; 269 return fs::path{Common::UTF16ToUTF8(wide_appdata_roaming_path)};
274 } else {
275 LOG_ERROR(Common_Filesystem, "Failed to get the path to the %APPDATA% directory");
276 } 270 }
277 271 LOG_ERROR(Common_Filesystem, "Failed to get the path to the %APPDATA% directory");
278 return fs::path{}; 272 return fs::path{};
279} 273}
280 274
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp
index e49de921c..75fbd042a 100644
--- a/src/yuzu/main.cpp
+++ b/src/yuzu/main.cpp
@@ -2845,7 +2845,7 @@ bool GMainWindow::CreateShortcutLink(const std::filesystem::path& shortcut_path,
2845 const std::filesystem::path& icon_path, 2845 const std::filesystem::path& icon_path,
2846 const std::filesystem::path& command, 2846 const std::filesystem::path& command,
2847 const std::string& arguments, const std::string& categories, 2847 const std::string& arguments, const std::string& categories,
2848 const std::string& keywords, const std::string& name) { 2848 const std::string& keywords, const std::string& name) try {
2849 2849
2850 // Copy characters if they are not illegal in Windows filenames 2850 // Copy characters if they are not illegal in Windows filenames
2851 std::string filename = ""; 2851 std::string filename = "";
@@ -2869,145 +2869,120 @@ bool GMainWindow::CreateShortcutLink(const std::filesystem::path& shortcut_path,
2869#if defined(__linux__) || defined(__FreeBSD__) // Linux and FreeBSD 2869#if defined(__linux__) || defined(__FreeBSD__) // Linux and FreeBSD
2870 // Reference for the desktop file template: 2870 // Reference for the desktop file template:
2871 // https://specifications.freedesktop.org/desktop-entry-spec/desktop-entry-spec-1.0.html 2871 // https://specifications.freedesktop.org/desktop-entry-spec/desktop-entry-spec-1.0.html
2872 try {
2873 2872
2874 // Plus 'Type' is required 2873 // Plus 'Type' is required
2875 if (name.empty()) { 2874 if (name.empty()) {
2876 LOG_ERROR(Frontend, "Name is empty"); 2875 LOG_ERROR(Frontend, "Name is empty");
2877 return false; 2876 return false;
2878 } 2877 }
2879
2880 // Append .desktop extension
2881 shortcut_path_full += ".desktop";
2882
2883 // Create shortcut file
2884 std::ofstream shortcut_stream(shortcut_path_full, std::ios::binary | std::ios::trunc);
2885
2886 if (shortcut_stream.is_open()) {
2887
2888 fmt::print(shortcut_stream, "[Desktop Entry]\n");
2889 fmt::print(shortcut_stream, "Type=Application\n");
2890 fmt::print(shortcut_stream, "Version=1.0\n");
2891 fmt::print(shortcut_stream, "Name={}\n", name);
2892
2893 if (!comment.empty()) {
2894 fmt::print(shortcut_stream, "Comment={}\n", comment);
2895 }
2896
2897 if (std::filesystem::is_regular_file(icon_path)) {
2898 fmt::print(shortcut_stream, "Icon={}\n", icon_path.string());
2899 }
2900
2901 fmt::print(shortcut_stream, "TryExec={}\n", command.string());
2902 fmt::print(shortcut_stream, "Exec={}", command.string());
2903
2904 if (!arguments.empty()) {
2905 fmt::print(shortcut_stream, " {}", arguments);
2906 }
2907
2908 fmt::print(shortcut_stream, "\n");
2909 2878
2910 if (!categories.empty()) { 2879 // Append .desktop extension
2911 fmt::print(shortcut_stream, "Categories={}\n", categories); 2880 shortcut_path_full += ".desktop";
2912 }
2913 2881
2914 if (!keywords.empty()) { 2882 // Create shortcut file
2915 fmt::print(shortcut_stream, "Keywords={}\n", keywords); 2883 std::ofstream shortcut_stream(shortcut_path_full, std::ios::binary | std::ios::trunc);
2916 } 2884 if (!shortcut_stream.is_open()) {
2885 LOG_ERROR(Frontend, "Failed to create shortcut");
2886 return false;
2887 }
2917 2888
2918 // Flush and close file 2889 fmt::print(shortcut_stream, "[Desktop Entry]\n");
2919 shortcut_stream.flush(); 2890 fmt::print(shortcut_stream, "Type=Application\n");
2920 shortcut_stream.close(); 2891 fmt::print(shortcut_stream, "Version=1.0\n");
2921 return true; 2892 fmt::print(shortcut_stream, "Name={}\n", name);
2922 } else { 2893 if (!comment.empty()) {
2923 LOG_ERROR(Frontend, "Failed to create shortcut"); 2894 fmt::print(shortcut_stream, "Comment={}\n", comment);
2924 }
2925 shortcut_stream.close();
2926 } catch (const std::exception& e) {
2927 LOG_ERROR(Frontend, "Failed to create shortcut: {}", e.what());
2928 } 2895 }
2929 return false; 2896 if (std::filesystem::is_regular_file(icon_path)) {
2897 fmt::print(shortcut_stream, "Icon={}\n", icon_path.string());
2898 }
2899 fmt::print(shortcut_stream, "TryExec={}\n", command.string());
2900 fmt::print(shortcut_stream, "Exec={}", command.string());
2901 if (!arguments.empty()) {
2902 fmt::print(shortcut_stream, " {}", arguments);
2903 }
2904 fmt::print(shortcut_stream, "\n");
2905 if (!categories.empty()) {
2906 fmt::print(shortcut_stream, "Categories={}\n", categories);
2907 }
2908 if (!keywords.empty()) {
2909 fmt::print(shortcut_stream, "Keywords={}\n", keywords);
2910 }
2911 return true;
2930#elif defined(_WIN32) // Windows 2912#elif defined(_WIN32) // Windows
2931 HRESULT hr = CoInitialize(NULL); 2913 HRESULT hr = CoInitialize(NULL);
2932 if (SUCCEEDED(hr)) { 2914 if (FAILED(hr)) {
2933 2915 LOG_ERROR(Frontend, "CoInitialize failed");
2934 IShellLinkW* ps1 = nullptr; 2916 return false;
2935 IPersistFile* persist_file = nullptr; 2917 }
2936
2937 SCOPE_EXIT({
2938 if (persist_file != nullptr) {
2939 persist_file->Release();
2940 }
2941 if (ps1 != nullptr) {
2942 ps1->Release();
2943 }
2944
2945 CoUninitialize();
2946 });
2947
2948 HRESULT hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
2949 IID_IShellLinkW, (void**)&ps1);
2950
2951 std::wstring wshortcut_path_full =
2952 Common::UTF8ToUTF16W((shortcut_path_full).string() + ".lnk");
2953 std::wstring wicon_path = Common::UTF8ToUTF16W(icon_path.string());
2954 std::wstring wcommand = Common::UTF8ToUTF16W(command.string());
2955 std::wstring warguments = Common::UTF8ToUTF16W(arguments);
2956 std::wstring wcomment = Common::UTF8ToUTF16W(comment);
2957 2918
2958 if (SUCCEEDED(hres)) { 2919 IShellLinkW* ps1 = nullptr;
2959 hres = ps1->SetPath(wcommand.data()); 2920 IPersistFile* persist_file = nullptr;
2960 2921
2961 if (SUCCEEDED(hres) && !arguments.empty()) { 2922 SCOPE_EXIT({
2962 hres = ps1->SetArguments(warguments.data()); 2923 if (persist_file != nullptr) {
2963 } 2924 persist_file->Release();
2964 2925 }
2965 if (SUCCEEDED(hres) && !comment.empty()) { 2926 if (ps1 != nullptr) {
2966 hres = ps1->SetDescription(wcomment.data()); 2927 ps1->Release();
2967 } 2928 }
2968 2929
2969 if (SUCCEEDED(hres) && std::filesystem::is_regular_file(icon_path)) { 2930 CoUninitialize();
2970 hres = ps1->SetIconLocation(wicon_path.data(), 0); 2931 });
2971 }
2972 2932
2973 if (SUCCEEDED(hres)) { 2933 HRESULT hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLinkW,
2974 hres = ps1->QueryInterface(IID_IPersistFile, (void**)&persist_file); 2934 (void**)&ps1);
2975 }
2976 2935
2977 if (SUCCEEDED(hres) && persist_file != nullptr) { 2936 if (SUCCEEDED(hres)) {
2978 hres = persist_file->Save(wshortcut_path_full.data(), TRUE); 2937 hres = ps1->SetPath(Common::UTF8ToUTF16W(command.string()).data());
2979 if (SUCCEEDED(hres)) { 2938 } else {
2980 return true; 2939 LOG_ERROR(Frontend, "Failed to create CoCreateInstance");
2981 } else { 2940 return false;
2982 LOG_ERROR(Frontend, "Failed to create shortcut"); 2941 }
2983 } 2942 if (SUCCEEDED(hres) && !arguments.empty()) {
2984 } 2943 hres = ps1->SetArguments(Common::UTF8ToUTF16W(arguments).data());
2985 } else {
2986 LOG_ERROR(Frontend, "Failed to create CoCreateInstance");
2987 }
2988 } 2944 }
2945 if (SUCCEEDED(hres) && !comment.empty()) {
2946 hres = ps1->SetDescription(Common::UTF8ToUTF16W(comment).data());
2947 }
2948 if (SUCCEEDED(hres) && std::filesystem::is_regular_file(icon_path)) {
2949 hres = ps1->SetIconLocation(Common::UTF8ToUTF16W(icon_path.string()).data(), 0);
2950 }
2951 if (SUCCEEDED(hres)) {
2952 hres = ps1->QueryInterface(IID_IPersistFile, (void**)&persist_file);
2953 }
2954 if (SUCCEEDED(hres) && persist_file != nullptr) {
2955 hres = persist_file->Save(
2956 Common::UTF8ToUTF16W((shortcut_path_full).string() + ".lnk").data(), TRUE);
2957 }
2958 if (SUCCEEDED(hres)) {
2959 return true;
2960 }
2961 LOG_ERROR(Frontend, "Failed to create shortcut");
2989 return false; 2962 return false;
2990#else // Unsupported platform 2963#else // Unsupported platform
2991 return false; 2964 return false;
2992#endif 2965#endif
2966} catch (const std::exception& e) {
2967 LOG_ERROR(Frontend, "Failed to create shortcut: {}", e.what());
2968 return false;
2993} 2969}
2994 2970
2995// Messages in pre-defined message boxes for less code spaghetti 2971// Messages in pre-defined message boxes for less code spaghetti
2996bool GMainWindow::CreateShortcutMessagesGUI(QWidget* parent, int imsg, const QString& game_title) { 2972bool GMainWindow::CreateShortcutMessagesGUI(QWidget* parent, int imsg, const QString& game_title) {
2997 QMessageBox::StandardButtons buttons;
2998
2999 int result = 0; 2973 int result = 0;
2974 QMessageBox::StandardButtons buttons;
3000 switch (imsg) { 2975 switch (imsg) {
3001 case GMainWindow::CREATE_SHORTCUT_MSGBOX_FULLSCREEN_YES: 2976 case GMainWindow::CREATE_SHORTCUT_MSGBOX_FULLSCREEN_YES:
3002 buttons = QMessageBox::Yes | QMessageBox::No; 2977 buttons = QMessageBox::Yes | QMessageBox::No;
3003 result = 2978 result =
3004 QMessageBox::information(parent, tr("Create Shortcut"), 2979 QMessageBox::information(parent, tr("Create Shortcut"),
3005 tr("Do you want to launch the game in fullscreen?"), buttons); 2980 tr("Do you want to launch the game in fullscreen?"), buttons);
3006 return (result == QMessageBox::Yes); 2981 return result == QMessageBox::Yes;
3007 case GMainWindow::CREATE_SHORTCUT_MSGBOX_SUCCESS: 2982 case GMainWindow::CREATE_SHORTCUT_MSGBOX_SUCCESS:
3008 QMessageBox::information(parent, tr("Create Shortcut"), 2983 QMessageBox::information(parent, tr("Create Shortcut"),
3009 tr("Successfully created a shortcut to %1").arg(game_title)); 2984 tr("Successfully created a shortcut to %1").arg(game_title));
3010 break; 2985 return false;
3011 case GMainWindow::CREATE_SHORTCUT_MSGBOX_APPVOLATILE_WARNING: 2986 case GMainWindow::CREATE_SHORTCUT_MSGBOX_APPVOLATILE_WARNING:
3012 buttons = QMessageBox::StandardButton::Ok | QMessageBox::StandardButton::Cancel; 2987 buttons = QMessageBox::StandardButton::Ok | QMessageBox::StandardButton::Cancel;
3013 result = 2988 result =
@@ -3015,20 +2990,19 @@ bool GMainWindow::CreateShortcutMessagesGUI(QWidget* parent, int imsg, const QSt
3015 tr("This will create a shortcut to the current AppImage. This may " 2990 tr("This will create a shortcut to the current AppImage. This may "
3016 "not work well if you update. Continue?"), 2991 "not work well if you update. Continue?"),
3017 buttons); 2992 buttons);
3018 return (result == QMessageBox::Ok); 2993 return result == QMessageBox::Ok;
3019 case GMainWindow::CREATE_SHORTCUT_MSGBOX_ADMIN: 2994 case GMainWindow::CREATE_SHORTCUT_MSGBOX_ADMIN:
3020 buttons = QMessageBox::Ok; 2995 buttons = QMessageBox::Ok;
3021 QMessageBox::critical(parent, tr("Create Shortcut"), 2996 QMessageBox::critical(parent, tr("Create Shortcut"),
3022 tr("Cannot create shortcut in Apps. Restart yuzu as administrator."), 2997 tr("Cannot create shortcut in Apps. Restart yuzu as administrator."),
3023 buttons); 2998 buttons);
3024 break; 2999 return false;
3025 default: 3000 default:
3026 buttons = QMessageBox::Ok; 3001 buttons = QMessageBox::Ok;
3027 QMessageBox::critical(parent, tr("Create Shortcut"), 3002 QMessageBox::critical(parent, tr("Create Shortcut"),
3028 tr("Failed to create a shortcut to %1").arg(game_title), buttons); 3003 tr("Failed to create a shortcut to %1").arg(game_title), buttons);
3029 break; 3004 return false;
3030 } 3005 }
3031 return false;
3032} 3006}
3033 3007
3034bool GMainWindow::MakeShortcutIcoPath(const u64 program_id, const std::string_view game_file_name, 3008bool GMainWindow::MakeShortcutIcoPath(const u64 program_id, const std::string_view game_file_name,