[Message Prev][Message Next][Thread Prev][Thread Next][Message Index][Thread Index]

[MD:7148] install.exe の変更



藤井です。

install.exe に手を加えてみました。ショートカット登録に DDE を使用するの
をやめ、COM を利用してます。

これにより、以下のことが可能になります。
(いくつかは現状の DDE による実装の拡張で可能なのかもしれませんが)

  - [スタート] - [プログラム] - Meadow 以外に、以下の場所にショートカッ
    トが作れる(要オプション指定)
      = デスクトップ
      = クイック起動バー ([スタート] の右隣のショートカット)

  - 以下の問題の解決に繋がる。
    http://www.meadowy.org/meadow/netinstall/ticket/24
    (その代わりショートカット作成時の explorer のポップアップが
     なくなります)

  - ショートカットの作業ディレクトリを install.exe 側で指定できる。
    (現状ではとりあえず http://www.meadowy.org/meadow/ticket/154
     のバグだけを修正し、作業ディレクトリの値は従来のままです)

メール末尾にパッチを添付したのでお試し下さい。

パッチを適用すると、-Q, -D オプション付きで起動した場合に、それぞれデス
クトップ、クイック起動バーにもショートカットを登録するようになります。

# オプション名は仮決めです。あとで見直します。

気になる点としては、以下のようなものがあります。

  = 一応 Win9X でも動作するように書いたつもりですが未確認です。
  = デスクトップ、クイック起動バーへのショートカット登録を
    デフォルトにするべきか、オプションにするべきか。
  = 作業ディレクトリをどこに指定すべきか。
  = 他にショートカットを追加できたら便利そうなところ。
    (スタートアップとか... さすがにそんな人はいないですよね。多分)

この修正を加えて良いならば後程 commit します。ご意見、不明な点、不具合
などありましたら宜しくお願いします。

以下、パッチです。(cygwin では動作確認していますが、msvc は未確認)

Index: install.c
===================================================================
--- install.c	(revision 4012)
+++ install.c	(working copy)
@@ -1,12 +1,12 @@
 /* Meadow Install Program */
 #include <windows.h>
-#include <ddeml.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <stdarg.h>
 #include <io.h>
 #include <direct.h>
 #include <mbstring.h>
+#include <shlobj.h>
 
 #include "../src/mw32reg.h"
 
@@ -17,6 +17,8 @@
 #define chdir _chdir
 #endif
 
+#define MEADOW_SHORTCUT_FILENAME "Meadow3.lnk"
+
 LPCTSTR meadow_version_string = MEADOW;
 LPCTSTR meadow_version_root = REG_VERSION_ROOT;
 LPCTSTR meadow_version_env_root = REG_VERSION_ENV_ROOT;
@@ -55,6 +57,8 @@
 slmessage usage[] =
 {
   {ENGLISH, "Usage: install [-s] [-r] [-h dir] [-v]\n"
+   "        -Q          add shortcut to Quick Launch.\n"
+   "        -D          add shortcut to Deskotop.\n"
    "        -s          do not add shortcut to Start Menu.\n"
    "        -r          remove information from Registry Database.\n"
    "        -h dir      specify home directory name.\n"
@@ -129,6 +133,15 @@
   {ENGLISH, "Enter the directory which Meadow read .emacs file from.\n"
    "If you do not specify, Meadow reads .emacs file in following directory.\n"},
 };
+slmessage quicklaunch_not_found[] =
+{
+#ifndef __MINGW32__
+  {NIHONGO, "Quick Launch のディレクトリが存在しません。"
+   "Quick Launch へのショートカット登録は取り止めました。\n"},
+#endif
+  {ENGLISH, "Quick Launch folder is not found. "
+   "Registration to Quick Launch is cancelled.\n"},
+};
 void slmessage_fprintf(int lang, FILE *stream, slmessage* slfmt, ...)
 {
   va_list va;
@@ -139,17 +152,6 @@
   va_end(va);
 }
 
-HDDEDATA CALLBACK DdeCallback (UINT uType, UINT uFmt, HCONV hconv,
-			       HSZ hsz1, HSZ hsz2, HDDEDATA hdata,
-			       DWORD dwData1, DWORD dwData2)
-{
-  return NULL;
-}
-
-#define DdeCommand(str)		\
-	DdeClientTransaction (str, strlen (str)+1, HConversation, (HSZ)NULL, \
-			      CF_TEXT, XTYP_EXECUTE, 30000, NULL)
-
 #define MULE_CLASS ""
 
 void error_op(int errorflag)
@@ -349,36 +351,133 @@
   RegDeleteKey(HKEY_LOCAL_MACHINE, meadow_version_root);
 }
 
-void register_to_shell(char *main_root)
+/* make shortcut of Meadow in a specified directory */
+void make_shortcut(const char *path, const char *main_root)
 {
-  DWORD idDde;
-  HCONV HConversation;
-  HSZ program_manager;
-  char additem[MAX_PATH*2 + 100];
+  char exec_path[MAX_PATH];
+  char icon_path[MAX_PATH];
+  char work_dir[MAX_PATH];
+  IShellLink *sl;
+  IPersistFile *pf;
+  WCHAR wpath[MAX_PATH];
 
-  idDde = 0;
-  DdeInitialize (&idDde, (PFNCALLBACK)DdeCallback, APPCMD_CLIENTONLY, 0);
+  /* main_root has a trailing backslash. */
+  sprintf (exec_path, "%sbin\\RunMW32.exe", main_root);
+  sprintf (icon_path, "%sbin\\meadow.ico", main_root);
+  sprintf (work_dir, "%sbin", main_root);
 
-  program_manager = DdeCreateStringHandle (idDde, "PROGMAN", CP_WINANSI);
+  CoCreateInstance (&CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
+		    &IID_IShellLink, (LPVOID *) &sl);
+  
+  sl->lpVtbl->QueryInterface (sl, &IID_IPersistFile, (void **) &pf);
+  
+  sl->lpVtbl->SetPath (sl, exec_path);
+  sl->lpVtbl->SetArguments (sl, "");
+  sl->lpVtbl->SetIconLocation (sl, icon_path, 0);
+  sl->lpVtbl->SetWorkingDirectory (sl, work_dir);
+  
+  MultiByteToWideChar (CP_ACP, 0, path, -1, wpath, MAX_PATH);
+  pf->lpVtbl->Save (pf, wpath, TRUE);
 
-  if (HConversation = DdeConnect (idDde, program_manager,
-				  program_manager, NULL))
+  pf->lpVtbl->Release (pf);
+  sl->lpVtbl->Release (sl);
+}
+
+/* make shortcut of Meadow in Quick Launch folder */
+void register_to_quicklaunch(const char *main_root)
+{
+  LPITEMIDLIST id;
+  OSVERSIONINFO verinfo = { sizeof verinfo };
+  char path[MAX_PATH];
+  int folder;
+
+  GetVersionEx (&verinfo);
+
+  folder = verinfo.dwPlatformId == VER_PLATFORM_WIN32_NT ?
+	   CSIDL_COMMON_APPDATA : CSIDL_APPDATA;
+
+  SHGetSpecialFolderLocation (NULL, folder, &id);
+  SHGetPathFromIDList (id, path);
+
+  strcat (path, "\\Microsoft\\Internet Explorer\\Quick Launch");
+
+  if (_access (path, 0) != 0)
     {
-      DdeCommand ("[CreateGroup (Meadow)]");
-      DdeCommand ("[ReplaceItem (Meadow3)]");
-      sprintf (additem, "[AddItem (%s\\bin\\RunMW32.exe,Meadow3,"
-	       "%s\\bin\\meadow.ico)]",
-	       main_root, main_root);
-      DdeCommand (additem);
+      if (folder == CSIDL_APPDATA)
+	{
+	  slmessage_fprintf (codepage, stderr, quicklaunch_not_found);
+	  return;
+	}
 
-      DdeDisconnect (HConversation);
+      /* if folder is CSIDL_COMMON_APPDATA, try CSIDL_APPDATA */
+      SHGetSpecialFolderLocation (NULL, CSIDL_APPDATA, &id);
+      SHGetPathFromIDList (id, path);
+
+      strcat (path, "\\Microsoft\\Internet Explorer\\Quick Launch");
+
+      if (_access (path, 0) != 0)
+	{
+	  slmessage_fprintf (codepage, stderr, quicklaunch_not_found);
+	  return;
+	}
     }
 
-  DdeFreeStringHandle (idDde, program_manager);
+  strcat (path, "\\");
+  strcat (path, MEADOW_SHORTCUT_FILENAME);
 
-  DdeUninitialize (idDde);
+  make_shortcut (path, main_root);
 }
 
+/* make shortcut of Meadow in Desktop folder */
+void register_to_desktop(const char *main_root)
+{
+  LPITEMIDLIST id;
+  OSVERSIONINFO verinfo = { sizeof verinfo };
+  char path[MAX_PATH];
+
+  GetVersionEx (&verinfo);
+
+  SHGetSpecialFolderLocation (NULL,
+			      verinfo.dwPlatformId == VER_PLATFORM_WIN32_NT ?
+			      CSIDL_COMMON_DESKTOPDIRECTORY :
+			      CSIDL_DESKTOPDIRECTORY,
+			      &id);
+
+  SHGetPathFromIDList (id, path);
+
+  strcat (path, "\\");
+  strcat (path, MEADOW_SHORTCUT_FILENAME);
+
+  make_shortcut (path, main_root);
+}
+
+/* make shortcut of Meadow in Programs folder */
+void register_to_shell(const char *main_root)
+{
+  LPITEMIDLIST id;
+  OSVERSIONINFO verinfo = { sizeof verinfo };
+  char path[MAX_PATH];
+
+  GetVersionEx (&verinfo);
+
+  SHGetSpecialFolderLocation (NULL,
+			      verinfo.dwPlatformId == VER_PLATFORM_WIN32_NT ?
+			      CSIDL_COMMON_PROGRAMS : CSIDL_PROGRAMS,
+			      &id);
+
+  SHGetPathFromIDList (id, path);
+
+  strcat (path, "\\Meadow");
+
+  if (_access (path, 0) != 0)
+    CreateDirectory (path, 0);
+
+  strcat (path, "\\");
+  strcat (path, MEADOW_SHORTCUT_FILENAME);
+
+  make_shortcut (path, main_root);
+}
+
 int check_opt(char *arg, char *opt)
 {
   if ((arg[0] != '/')
@@ -414,7 +513,11 @@
   unsigned char *p;
   int remove_flag = 0;
   int register_flag = 1;
+  int quicklaunch_flag = 0;
+  int desktop_flag = 0;
 
+  CoInitialize (NULL);
+
   init_current_environment();
 
   GetModuleFileName(NULL, this_prog, MAX_PATH);
@@ -454,6 +557,14 @@
 		error_usage();
 	      }
 	  }
+	else if (check_opt(argv[i], "D"))
+	  {
+	    desktop_flag = 1;
+	  }
+	else if (check_opt(argv[i], "Q"))
+	  {
+	    quicklaunch_flag = 1;
+	  }
 	else
 	  {
 	    error_usage();
@@ -503,7 +614,11 @@
 	  exit(1);
 	}
       if (register_flag)
-	register_to_shell(main_root);
+	register_to_shell (main_root);
+      if (desktop_flag)
+	register_to_desktop (main_root);
+      if (quicklaunch_flag)
+	register_to_quicklaunch (main_root);
     }
 
   return 0;
Index: gmake.mw32.defs
===================================================================
--- gmake.mw32.defs	(revision 4012)
+++ gmake.mw32.defs	(working copy)
@@ -181,6 +181,8 @@
 SHELL32		= -lshell32
 USER32		= -luser32
 WSOCK32		= -lwsock32
+OLE32		= -lole32
+UUID		= -luuid
 
 ifdef NOOPT
 DEBUG_CFLAGS	= -DEMACSDEBUG
Index: nmake.mw32.defs
===================================================================
--- nmake.mw32.defs	(revision 4012)
+++ nmake.mw32.defs	(working copy)
@@ -131,6 +131,8 @@
 WSOCK32		= wsock32.lib
 WINMM     = winmm.lib
 WINSPOOL	= winspool.lib
+OLE32		= ole32.lib
+UUID		= uuid.lib
 
 !ifdef NOOPT
 DEBUG_CFLAGS	= -DEMACSDEBUG -DGLYPH_DEBUG -Fd$(BLD)\vc.pdb \
Index: makefile.mw32-in
===================================================================
--- makefile.mw32-in	(revision 4012)
+++ makefile.mw32-in	(working copy)
@@ -30,7 +30,7 @@
 install_exe:	$(BLD) $(BLD)/install.exe
 $(BLD)/install.exe: $(BLD)/install.$(O)
 		$(LINK) $(LINK_OUT)$@ \
-		$(LINK_FLAGS) $(ALL_DEPS) $(BASE_LIBS) $(ADVAPI32) $(USER32)
+		$(LINK_FLAGS) $(ALL_DEPS) $(BASE_LIBS) $(ADVAPI32) $(USER32) $(OLE32) $(UUID)
 
 fiber:		$(BLD) $(BLD)/fiber.exe
 $(BLD)/fiber.exe: $(BLD)/fiber.$(O)


--
藤井 正行 / Masayuki FUJII