Revision: 10237 https://osdn.net/projects/ttssh2/scm/svn/commits/10237 Author: zmatsuo Date: 2022-09-05 00:04:35 +0900 (Mon, 05 Sep 2022) Log Message: ----------- ttreg 追加 - ポータブル版や開発中のTera Termのためのツール - エクスプローラーの右クリック(コンテキストメニュー)に項目を追加するための reg ファイルを生成する - 生成された reg ファイルをダブルクリックするとコンテキストメニューが追加される - Tera Term を起動するためのショートカットを作成する - 準備できる環境 - cygwin - msys2(MSYS, MinGW x32, MinGW x64) - git bash - cmd, powershell Modified Paths: -------------- trunk/tools/CMakeLists.txt Added Paths: ----------- trunk/tools/ttreg/ trunk/tools/ttreg/CMakeLists.txt trunk/tools/ttreg/README.md trunk/tools/ttreg/ttreg.cpp -------------- next part -------------- Modified: trunk/tools/CMakeLists.txt =================================================================== --- trunk/tools/CMakeLists.txt 2022-09-04 15:04:24 UTC (rev 10236) +++ trunk/tools/CMakeLists.txt 2022-09-04 15:04:35 UTC (rev 10237) @@ -2,10 +2,16 @@ set_target_properties( ttbroadcast PROPERTIES FOLDER tools - ) +) add_subdirectory(lscom) set_target_properties( lscom PROPERTIES FOLDER tools - ) +) + +add_subdirectory(ttreg) +set_target_properties( + ttreg + PROPERTIES FOLDER tools +) Added: trunk/tools/ttreg/CMakeLists.txt =================================================================== --- trunk/tools/ttreg/CMakeLists.txt (rev 0) +++ trunk/tools/ttreg/CMakeLists.txt 2022-09-04 15:04:35 UTC (rev 10237) @@ -0,0 +1,31 @@ +set(PACKAGE_NAME "ttreg") + +project(${PACKAGE_NAME}) + +add_executable( + ${PACKAGE_NAME} + ttreg.cpp +) + +if(MSVC) + if(${CMAKE_VERSION} VERSION_LESS "3.13.0") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /ENTRY:wmainCRTStartup") + else() + target_link_options( + ${PACKAGE_NAME} + PRIVATE + /ENTRY:wmainCRTStartup + ) + endif() +else(MSVC) + target_link_options( + ${PACKAGE_NAME} + PRIVATE + -municode + ) +endif(MSVC) + +install( + TARGETS ${PACKAGE_NAME} + DESTINATION . +) Added: trunk/tools/ttreg/README.md =================================================================== --- trunk/tools/ttreg/README.md (rev 0) +++ trunk/tools/ttreg/README.md 2022-09-04 15:04:35 UTC (rev 10237) @@ -0,0 +1,57 @@ +# ttreg + +カレントディレクトリの ttermpro.exe のショートカットの作成とエクスプローラー +のコンテキストメニューを追加するための reg ファイルを作成するツール。 + +インストーラーを使用しなくてもポータブル版や開発中フォルダの Tera Term +を便利に使用することができます。 + +Tera Term から cygwin, msys2(MSYS, MinGW x32, MinGW x64), git bash を使 +用するためのショートカット、エクスプローラーのコンテキストメニューから +フォルダを指定しての起動が簡単にできます + +## 使用方法 + +ttreg.exe を実行すると次のファイルが出力されます。 + +- shortcuts/ にショートカット +- explorer_context.reg + +実行例 + + >./ttreg.exe + cygwin found + msys2 found + git bash found + mkdir 'C:\tmp\snapshot\shortcuts' + 'explorer_context.reg' write + >ls *.reg shortcuts/ + explorer_context.reg* + + shortcuts/: + 'Tera Term + cmd.lnk'* 'Tera Term + msys2_MinGW_x64.lnk'* + 'Tera Term + cygwin.lnk'* 'Tera Term + msys2_MSYS.lnk'* + 'Tera Term + git_bash.lnk'* 'Tera Term.lnk'* + 'Tera Term + msys2_MinGW_x32.lnk'* + +## ショートカット + +ショートカットを適宜コピーして使用することができます。 + +## explorer context + +出力された explorer_context.reg をダブルクリックすると +explorerの右クリックにメニューが追加されます。 + +次のレジストリに登録されます。 +HKEY_CURRENT_USER\SOFTWARE\Classes\Folder\shell +不要になったらregeditで削除してください。 + +## 制限 + +cygterm.exe 経由で cygwin を利用することは以前から行われていましたが、 +msys2term.exe 経由で msys2, git bash を利用することは行われていないので +何らかの問題が出る可能性があります。 + +cmd, powershell, wsl の利用はある程度動作していますが、 +何らかの不具合が出る可能性があります。 Added: trunk/tools/ttreg/ttreg.cpp =================================================================== --- trunk/tools/ttreg/ttreg.cpp (rev 0) +++ trunk/tools/ttreg/ttreg.cpp 2022-09-04 15:04:35 UTC (rev 10237) @@ -0,0 +1,254 @@ +/* + * Copyright (C) 2022- TeraTerm Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <wchar.h> +#include <locale.h> +#include <windows.h> +#include <shobjidl.h> +#include <shlguid.h> + +static wchar_t *EscapeCommand(const wchar_t *command) +{ + size_t len = wcslen(command); + wchar_t *escaped_command = (wchar_t *)malloc(sizeof(wchar_t) * len * 2); + wchar_t *p = escaped_command; + + wchar_t c; + while((c = *command++) != L'\0') { + if (c == L'"' || c == L'\\') { + *p++ = L'\\'; + } + *p++ = c; + } + *p = 0; + return escaped_command; +} + +/** + * \x83V\x83\x87\x81[\x83g\x83J\x83b\x83g\x82\xF0\x8D\xEC\x82\xE9 + * Win32 API + */ +HRESULT CreateShortcut(const wchar_t *exe, const wchar_t *args, const wchar_t *dest) +{ + HRESULT hres; + + IShellLinkW* psl; + hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLinkW, (LPVOID*)&psl); + if (FAILED(hres)) { + return hres; + } + + hres = psl->SetPath(exe); + if (args != NULL) { + hres = psl->SetArguments(args); + } + //hres = psl->SetDescription(desc); + + // save + IPersistFile* ppf; + hres = psl->QueryInterface(IID_IPersistFile, (LPVOID*)&ppf); + + if (SUCCEEDED(hres)) + { + hres = ppf->Save(dest, TRUE); + ppf->Release(); + } + + psl->Release(); + return hres; +} + +/** + * \x83V\x83\x87\x81[\x83g\x83J\x83b\x83g\x82\xF0\x8D\xEC\x82\xE9 + */ +void CreateShortcut(const wchar_t *dir, const wchar_t *shortcut, const wchar_t *teraterm, const wchar_t *args) +{ + wchar_t shortcut_full[MAX_PATH]; + swprintf(shortcut_full, _countof(shortcut_full), L"%s\\%s", dir, shortcut); + wchar_t *escaped_command = EscapeCommand(teraterm); + CreateShortcut(escaped_command, args, shortcut_full); + free(escaped_command); +} + +/** + * \x83\x8C\x83W\x83X\x83g\x83\x8A\x82\xF0\x8F\x91\x82\xAB\x8Fo\x82\xB7 + */ +void WriteReg(FILE *fp, const wchar_t *menu, const wchar_t *key, const wchar_t *command, const wchar_t *arg) +{ + wchar_t *escaped_command = EscapeCommand(command); + wchar_t *escaped_arg = EscapeCommand(arg); + fwprintf(fp, + L"[HKEY_CURRENT_USER\\SOFTWARE\\Classes\\Folder\\shell\\%s]\n" + L"@=\"%s\"\n" + L"\n" + L"[HKEY_CURRENT_USER\\SOFTWARE\\Classes\\Folder\\shell\\%s\\command]\n" + L"@=\"%s %s\"\n\n", + key, + menu, + key, + escaped_command, escaped_arg); + free(escaped_arg); + free(escaped_command); +} + +BOOL CheckExist(const wchar_t *file) +{ + DWORD r = GetFileAttributesW(file); + if (r == INVALID_FILE_ATTRIBUTES) { + return FALSE; + } + return TRUE; +} + +BOOL CheckCygwin(void) +{ + return CheckExist(L"C:\\cygwin64\\bin\\cygwin1.dll"); +} + +BOOL CheckMsys2(void) +{ + return CheckExist(L"C:\\msys64\\usr\\bin\\msys-2.0.dll"); +} + +BOOL CheckGitbash(void) +{ + return CheckExist(L"C:\\Program Files\\Git\\usr\\bin\\msys-2.0.dll"); +} + +BOOL CheckMsys2term(void) +{ + return CheckExist(L"msys2term.exe"); +} + +int wmain(int argc, wchar_t *argv[]) +{ + setlocale(LC_ALL, ""); + CoInitialize(NULL); + + BOOL cygwin_installed = CheckCygwin(); + BOOL msys2tarm = CheckMsys2term(); + BOOL msys2_installed = CheckMsys2(); + BOOL gitbash_installed = CheckGitbash(); + + if (cygwin_installed) { + printf("cygwin found\n"); + } + if (msys2_installed && msys2tarm) { + printf("msys2 found\n"); + } + if (gitbash_installed) { + printf("git bash found\n"); + } + + const wchar_t *reg_fname = L"explorer_context.reg"; + + wchar_t curdir[MAX_PATH]; + GetCurrentDirectoryW(_countof(curdir), curdir); + + wchar_t teraterm_full[MAX_PATH]; + swprintf(teraterm_full, _countof(teraterm_full), L"%s\\%s", curdir, L"ttermpro.exe"); + + wchar_t cyglaunch_full[MAX_PATH]; + swprintf(cyglaunch_full, _countof(cyglaunch_full), L"%s\\%s", curdir, L"cyglaunch.exe"); + + wchar_t shortcut_dir[MAX_PATH]; + swprintf(shortcut_dir, _countof(shortcut_dir), L"%s\\%s", curdir, L"shortcuts"); + CreateDirectoryW(shortcut_dir, NULL); + wprintf(L"mkdir '%s'\n", shortcut_dir); + + FILE *fp = _wfopen(reg_fname, L"wt, ccs=UTF-16LE"); + //fwrite("\xff\xfe", 2, 1, fp); // write UTF16LE bom + + fwprintf(fp, L"Windows Registry Editor Version 5.00\n\n"); + + CreateShortcut(shortcut_dir, L"Tera Term.lnk", teraterm_full, NULL); + + if (cygwin_installed) { + CreateShortcut(shortcut_dir, L"Tera Term + cmd.lnk", cyglaunch_full, L"-cygwin -s \"c:/windows/system32/cmd.exe\""); + WriteReg(fp, + L"Tera Term + cmd Here", + L"cygterm_cmd", + cyglaunch_full, + L"-nocd -v CHERE_INVOKING=y -d \"\\\"%L\\\"\" -s \"c:/windows/system32/cmd.exe\""); + + CreateShortcut(shortcut_dir, L"Tera Term + powershell.lnk", cyglaunch_full, L"-cygwin -s \"c:/Windows/System32/WindowsPowerShell/v1.0/powershell.exe\""); + CreateShortcut(shortcut_dir, L"Tera Term + wsl.lnk", cyglaunch_full, L"-cygwin -s \"c:/windows/system32/wsl.exe\""); + } + + if (cygwin_installed) { + CreateShortcut(shortcut_dir, L"Tera Term + Cygwin.lnk", cyglaunch_full, L"-cygwin"); + + WriteReg(fp, + L"Tera Term + Cygwin Here", + L"cygterm", + cyglaunch_full, + L"-nocd -v CHERE_INVOKING=y -d \"\\\"%L\\\"\""); + } + + if (msys2tarm && msys2_installed) { + CreateShortcut(shortcut_dir, L"Tera Term + MSYS2 MSYS.lnk", cyglaunch_full, L"-msys2 -v MSYSTEM=MSYS"); + CreateShortcut(shortcut_dir, L"Tera Term + MSYS2 MinGW x32.lnk", cyglaunch_full, L"-msys2 -v MSYSTEM=MINGW32"); + CreateShortcut(shortcut_dir, L"Tera Term + MSYS2 MinGW x64.lnk", cyglaunch_full, L"-msys2 -v MSYSTEM=MINGW64"); + + WriteReg(fp, + L"Tera Term + MSYS2 MSYS Here", + L"msys2term_msys", + cyglaunch_full, + L"-msys2 -nocd -v CHERE_INVOKING=y -d \"\\\"%L\\\"\" -v MSYSTEM=MSYS"); + + WriteReg(fp, + L"Tera Term + MSYS2 MinGW x32 Here", + L"msys2term_mingw32", + cyglaunch_full, + L"-msys2 -nocd -v CHERE_INVOKING=y -d \"\\\"%L\\\"\" -v MSYSTEM=MINGW32"); + + WriteReg(fp, + L"Tera Term + MSYS2 MinGW x64 Here", + L"msys2term_mingw64", + cyglaunch_full, + L"-msys2 -nocd -v CHERE_INVOKING=y -d \"\\\"%L\\\"\" -v MSYSTEM=MINGW64"); + } + + if (gitbash_installed) { + CreateShortcut(shortcut_dir, L"Tera Term + git_bash.lnk", cyglaunch_full, L"-gitbash"); + + WriteReg(fp, + L"Tera Term + Git Bash Here", + L"gitbash", + cyglaunch_full, + L"-gitbash -nocd -v CHERE_INVOKING=y -d \"\\\"%L\\\"\""); + } + + fclose(fp); + + wprintf(L"'%s' write\n", reg_fname); + CoUninitialize(); + return 0; +}