diff --git a/cli/cli.c b/cli/cli.c
index 8e3e025..d4b844b 100644
--- a/cli/cli.c
+++ b/cli/cli.c
@@ -233,6 +233,10 @@ main (int argc, char ** argv)
   size_t        fileLength;
   const char  * str;
 
+#ifdef _WIN32
+  tr_win32_make_args_utf8 (&argc, &argv);
+#endif
+
   tr_formatter_mem_init (MEM_K, MEM_K_STR, MEM_M_STR, MEM_G_STR, MEM_T_STR);
   tr_formatter_size_init (DISK_K,DISK_K_STR, DISK_M_STR, DISK_G_STR, DISK_T_STR);
   tr_formatter_speed_init (SPEED_K, SPEED_K_STR, SPEED_M_STR, SPEED_G_STR, SPEED_T_STR);
diff --git a/daemon/daemon.c b/daemon/daemon.c
index 90bb6f6..cdf2ded 100644
--- a/daemon/daemon.c
+++ b/daemon/daemon.c
@@ -425,6 +425,10 @@ main (int argc, char ** argv)
     tr_session * session = NULL;
     struct event *status_ev;
 
+#ifdef _WIN32
+    tr_win32_make_args_utf8 (&argc, &argv);
+#endif
+
     key_pidfile = tr_quark_new ("pidfile",  7);
 
     signal (SIGINT, gotsig);
diff --git a/daemon/remote.c b/daemon/remote.c
index 4ed17b5..57282f1 100644
--- a/daemon/remote.c
+++ b/daemon/remote.c
@@ -2406,6 +2406,10 @@ main (int argc, char ** argv)
     char * rpcurl = NULL;
     int exit_status = EXIT_SUCCESS;
 
+#ifdef _WIN32
+    tr_win32_make_args_utf8 (&argc, &argv);
+#endif
+
     if (argc < 2) {
         showUsage ();
         return EXIT_FAILURE;
diff --git a/libtransmission/utils.c b/libtransmission/utils.c
index bfd5158..733b7a7 100644
--- a/libtransmission/utils.c
+++ b/libtransmission/utils.c
@@ -41,6 +41,7 @@
  #include <w32api.h>
  #define WINVER WindowsXP /* freeaddrinfo (), getaddrinfo (), getnameinfo () */
  #include <windows.h> /* Sleep (), GetSystemTimeAsFileTime (), GetEnvironmentVariable () */
+ #include <shellapi.h> /* CommandLineToArgv () */
 #endif
 
 #include "transmission.h"
@@ -1217,6 +1218,53 @@ tr_win32_format_message (uint32_t code)
   return text;
 }
 
+void
+tr_win32_make_args_utf8 (int    * argc,
+                         char *** argv)
+{
+  int my_argc, i;
+  char ** my_argv;
+  wchar_t ** my_wide_argv;
+
+  my_wide_argv = CommandLineToArgvW (GetCommandLineW (), &my_argc);
+  if (my_wide_argv == NULL)
+    return;
+
+  assert (*argc == my_argc);
+
+  my_argv = tr_new (char *, my_argc + 1);
+
+  for (i = 0; i < my_argc; ++i)
+    {
+      my_argv[i] = tr_win32_native_to_utf8 (my_wide_argv[i], -1);
+      if (my_argv[i] == NULL)
+        break;
+    }
+
+  if (i < my_argc)
+    {
+      int j;
+
+      for (j = 0; j < i; ++j)
+        {
+          tr_free (my_argv[j]);
+        }
+
+      tr_free (my_argv);
+    }
+  else
+    {
+      my_argv[my_argc] = NULL;
+
+      *argc = my_argc;
+      *argv = my_argv;
+
+      /* TODO: Add atexit handler to cleanup? */
+    }
+
+  LocalFree (my_wide_argv);
+}
+
 #endif
 
 /***
diff --git a/libtransmission/utils.h b/libtransmission/utils.h
index e878566..6c47c60 100644
--- a/libtransmission/utils.h
+++ b/libtransmission/utils.h
@@ -190,6 +190,9 @@ wchar_t * tr_win32_utf8_to_native_ex (const char    * text,
                                       int             extra_chars);
 char    * tr_win32_format_message    (uint32_t        code);
 
+void      tr_win32_make_args_utf8    (int    * argc,
+                                      char *** argv);
+
 #endif
 
 /***
diff --git a/qt/app.cc b/qt/app.cc
index 2382109..7f18725 100644
--- a/qt/app.cc
+++ b/qt/app.cc
@@ -493,7 +493,13 @@ main (int argc, char * argv[])
   int c;
   QStringList addme;
   const char * optarg;
-  char ** argvv = argv;
+  char ** argvv;
+
+#ifdef _WIN32
+  tr_win32_make_args_utf8 (&argc, &argv);
+#endif
+
+  argvv = argv;
   while ( (c = tr_getopt (getUsage (), argc, (const char **)argvv, opts, &optarg)))
     if (c == TR_OPT_UNK)
       addme.append (optarg);
diff --git a/utils/create.c b/utils/create.c
index 729164c..cb0e941 100644
--- a/utils/create.c
+++ b/utils/create.c
@@ -131,6 +131,10 @@ main (int argc, char * argv[])
   char * out2 = NULL;
   tr_metainfo_builder * b = NULL;
 
+#ifdef _WIN32
+  tr_win32_make_args_utf8 (&argc, &argv);
+#endif
+
   tr_logSetLevel (TR_LOG_ERROR);
   tr_formatter_mem_init (MEM_K, MEM_K_STR, MEM_M_STR, MEM_G_STR, MEM_T_STR);
   tr_formatter_size_init (DISK_K, DISK_K_STR, DISK_M_STR, DISK_G_STR, DISK_T_STR);
diff --git a/utils/edit.c b/utils/edit.c
index bf122c4..582f7b8 100644
--- a/utils/edit.c
+++ b/utils/edit.c
@@ -290,6 +290,10 @@ main (int argc, char * argv[])
   int i;
   int changedCount = 0;
 
+#ifdef _WIN32
+  tr_win32_make_args_utf8 (&argc, &argv);
+#endif
+
   files = tr_new0 (const char*, argc);
 
   tr_logSetLevel (TR_LOG_ERROR);
diff --git a/utils/show.c b/utils/show.c
index 55e3d8a..5810e47 100644
--- a/utils/show.c
+++ b/utils/show.c
@@ -289,6 +289,10 @@ main (int argc, char * argv[])
   tr_info inf;
   tr_ctor * ctor;
 
+#ifdef _WIN32
+  tr_win32_make_args_utf8 (&argc, &argv);
+#endif
+
   tr_logSetLevel (TR_LOG_ERROR);
   tr_formatter_mem_init (MEM_K, MEM_K_STR, MEM_M_STR, MEM_G_STR, MEM_T_STR);
   tr_formatter_size_init (DISK_K, DISK_K_STR, DISK_M_STR, DISK_G_STR, DISK_T_STR);
