native: further improve Unicode support on Windows

This commit is contained in:
liushuyu 2019-06-29 08:53:28 -06:00 committed by James
parent f80db92188
commit b3b686ed53
2 changed files with 30 additions and 33 deletions

View File

@ -2,6 +2,15 @@
* Misc interop helpers. * Misc interop helpers.
**/ **/
// Explicitly use the Unicode version of the APIs
#ifndef UNICODE
#define UNICODE
#endif
#ifndef _UNICODE
#define _UNICODE
#endif
#include "windows.h" #include "windows.h"
#include "winnls.h" #include "winnls.h"
#include "shobjidl.h" #include "shobjidl.h"
@ -30,25 +39,17 @@ extern "C" int isDarkThemeActive()
} }
extern "C" int saveShortcut( extern "C" int saveShortcut(
const char *shortcutPath, const wchar_t *shortcutPath,
const char *description, const wchar_t *description,
const char *path, const wchar_t *path,
const char *args, const wchar_t *args,
const char *workingDir) const wchar_t *workingDir)
{ {
char *errStr = NULL; char *errStr = NULL;
HRESULT h; HRESULT h;
IShellLink *shellLink = NULL; IShellLink *shellLink = NULL;
IPersistFile *persistFile = NULL; IPersistFile *persistFile = NULL;
#ifdef _WIN64
wchar_t wName[MAX_PATH + 1];
#else
WORD wName[MAX_PATH + 1];
#endif
int id;
// Initialize the COM library // Initialize the COM library
h = CoInitialize(NULL); h = CoInitialize(NULL);
if (FAILED(h)) if (FAILED(h))
@ -72,12 +73,9 @@ extern "C" int saveShortcut(
goto err; goto err;
} }
//Append the shortcut name to the folder
MultiByteToWideChar(CP_UTF8, 0, shortcutPath, -1, wName, MAX_PATH);
// Load the file if it exists, to get the values for anything // Load the file if it exists, to get the values for anything
// that we do not set. Ignore errors, such as if it does not exist. // that we do not set. Ignore errors, such as if it does not exist.
h = persistFile->Load(wName, 0); h = persistFile->Load(shortcutPath, 0);
// Set the fields for which the application has set a value // Set the fields for which the application has set a value
if (description != NULL) if (description != NULL)
@ -90,7 +88,7 @@ extern "C" int saveShortcut(
shellLink->SetWorkingDirectory(workingDir); shellLink->SetWorkingDirectory(workingDir);
//Save the shortcut to disk //Save the shortcut to disk
h = persistFile->Save(wName, TRUE); h = persistFile->Save(shortcutPath, TRUE);
if (FAILED(h)) if (FAILED(h))
{ {
errStr = "Failed to save shortcut"; errStr = "Failed to save shortcut";
@ -118,8 +116,8 @@ extern "C" int spawnDetached(const wchar_t *app, const wchar_t *cmdline)
PROCESS_INFORMATION pi; PROCESS_INFORMATION pi;
// make non-constant copy of the parameters // make non-constant copy of the parameters
// this is allowed per https://docs.microsoft.com/en-us/windows/desktop/api/processthreadsapi/nf-processthreadsapi-createprocessw#security-remarks // this is allowed per https://docs.microsoft.com/en-us/windows/desktop/api/processthreadsapi/nf-processthreadsapi-createprocessw#security-remarks
wchar_t *app_copy = wcsdup(app); wchar_t *app_copy = _wcsdup(app);
wchar_t *cmdline_copy = wcsdup(cmdline); wchar_t *cmdline_copy = _wcsdup(cmdline);
if (app_copy == NULL || cmdline_copy == NULL) if (app_copy == NULL || cmdline_copy == NULL)
{ {

View File

@ -15,8 +15,6 @@ mod natives {
const PROCESS_LEN: usize = 10192; const PROCESS_LEN: usize = 10192;
use std::ffi::CString;
use logging::LoggingErrors; use logging::LoggingErrors;
use std::env; use std::env;
@ -36,11 +34,11 @@ mod natives {
extern "C" { extern "C" {
pub fn saveShortcut( pub fn saveShortcut(
shortcutPath: *const ::std::os::raw::c_char, shortcutPath: *const winapi::ctypes::wchar_t,
description: *const ::std::os::raw::c_char, description: *const winapi::ctypes::wchar_t,
path: *const ::std::os::raw::c_char, path: *const winapi::ctypes::wchar_t,
args: *const ::std::os::raw::c_char, args: *const winapi::ctypes::wchar_t,
workingDir: *const ::std::os::raw::c_char, workingDir: *const winapi::ctypes::wchar_t,
) -> ::std::os::raw::c_int; ) -> ::std::os::raw::c_int;
pub fn isDarkThemeActive() -> ::std::os::raw::c_uint; pub fn isDarkThemeActive() -> ::std::os::raw::c_uint;
@ -70,15 +68,16 @@ mod natives {
info!("Generating shortcut @ {:?}", source_file); info!("Generating shortcut @ {:?}", source_file);
let native_target_dir = CString::new(source_file.clone()) let native_target_dir = U16CString::from_str(source_file.clone())
.log_expect("Error while converting to C-style string"); .log_expect("Error while converting to wchar_t");
let native_description = let native_description =
CString::new(description).log_expect("Error while converting to C-style string"); U16CString::from_str(description).log_expect("Error while converting to wchar_t");
let native_target = let native_target =
CString::new(target).log_expect("Error while converting to C-style string"); U16CString::from_str(target).log_expect("Error while converting to wchar_t");
let native_args = CString::new(args).log_expect("Error while converting to C-style string"); let native_args =
U16CString::from_str(args).log_expect("Error while converting to wchar_t");
let native_working_dir = let native_working_dir =
CString::new(working_dir).log_expect("Error while converting to C-style string"); U16CString::from_str(working_dir).log_expect("Error while converting to wchar_t");
let shortcutResult = unsafe { let shortcutResult = unsafe {
saveShortcut( saveShortcut(