/* リンク あらかじめ、CoInitialize(NULL); を実行しておくこと */ BOOL SymLink(LPCSTR src, LPSTR dest, LPCSTR arg) { IShellLink *shellLink; IPersistFile *persistFile; Wstr wsrc(src), wdest(dest), warg(arg); BOOL ret = FALSE; char buf[MAX_PATH_U8]; if (SUCCEEDED(CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLinkW, (void **)&shellLink))) { shellLink->SetPath((char *)wsrc.Buf()); shellLink->SetArguments((char *)warg.Buf()); GetParentDirU8(src, buf); shellLink->SetWorkingDirectory((char *)U8toWs(buf)); if (SUCCEEDED(shellLink->QueryInterface(IID_IPersistFile, (void **)&persistFile))) { if (SUCCEEDED(persistFile->Save(wdest.s(), TRUE))) { ret = TRUE; GetParentDirU8(WtoU8(wdest.s()), buf); ::SHChangeNotify(SHCNE_UPDATEDIR, SHCNF_PATH|SHCNF_FLUSH, U8toAs(buf), NULL); } persistFile->Release(); } shellLink->Release(); } return ret; }
/* BrowseDlg用サブクラス生成 */ BOOL TBrowseDirDlg::AttachWnd(HWND _hWnd) { BOOL ret = TSubClass::AttachWnd(_hWnd); dirtyFlg = FALSE; // ディレクトリ設定 DWORD attr = GetFileAttributesU8(fileBuf); if (attr == 0xffffffff || (attr & FILE_ATTRIBUTE_DIRECTORY) == 0) GetParentDirU8(fileBuf, fileBuf); SendMessageW(BFFM_SETSELECTIONW, TRUE, (LPARAM)U8toWs(fileBuf)); SetWindowText(IPMSG_FULLNAME); // ボタン作成 RECT tmp_rect; ::GetWindowRect(GetDlgItem(IDOK), &tmp_rect); POINT pt = { tmp_rect.left, tmp_rect.top }; ::ScreenToClient(hWnd, &pt); int cx = (pt.x - 30) / 2, cy = tmp_rect.bottom - tmp_rect.top; ::CreateWindowU8(BUTTON_CLASS, GetLoadStrU8(IDS_MKDIR), WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON, 10, pt.y, cx, cy, hWnd, (HMENU)MKDIR_BUTTON, TApp::GetInstance(), NULL); ::CreateWindowU8(BUTTON_CLASS, GetLoadStrU8(IDS_RMDIR), WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON, 18 + cx, pt.y, cx, cy, hWnd, (HMENU)RMDIR_BUTTON, TApp::GetInstance(), NULL); HFONT hDlgFont = (HFONT)SendDlgItemMessage(IDOK, WM_GETFONT, 0, 0L); if (hDlgFont) { SendDlgItemMessage(MKDIR_BUTTON, WM_SETFONT, (UINT)hDlgFont, 0L); SendDlgItemMessage(RMDIR_BUTTON, WM_SETFONT, (UINT)hDlgFont, 0L); } return ret; }
void DebugU8(const char *fmt,...) { char buf[8192]; va_list ap; va_start(ap, fmt); _vsnprintf(buf, sizeof(buf), fmt, ap); va_end(ap); WCHAR *wbuf = U8toWs(buf); ::OutputDebugStringW(wbuf); delete [] wbuf; }
BOOL TInstDlg::Install(void) { char buf[MAX_PATH_U8], setupDir[MAX_PATH_U8], setupPath[MAX_PATH_U8]; char installPath[MAX_PATH_U8]; BOOL extract_only = IsDlgButtonChecked(EXTRACT_CHECK); // 現在、起動中の ipmsg を終了 int st = extract_only ? 0 : TerminateIPMsg(); if (st == 1) return FALSE; // インストールパス設定 GetDlgItemTextU8(FILE_EDIT, setupDir, sizeof(setupDir)); if (IsWinVista() && !::IsUserAnAdmin() && TIsEnableUAC() && TIsVirtualizedDirW(U8toWs(setupDir))) { if (MessageBox(GetLoadStr(IDS_REQUIREADMIN), INSTALL_STR, MB_OKCANCEL|MB_ICONINFORMATION) != IDOK) return FALSE; return RunAsAdmin(hWnd, TRUE); } CreateDirectoryU8(setupDir, NULL); DWORD attr = GetFileAttributesU8(setupDir); if (attr == 0xffffffff || (attr & FILE_ATTRIBUTE_DIRECTORY) == 0) return MessageBox(GetLoadStr(IDS_NOTCREATEDIR), INSTALL_STR), FALSE; MakePath(setupPath, setupDir, IPMSG_EXENAME); if (st == 2) { MessageBox(GetLoadStr(IDS_CANTTERMINATE), INSTALL_STR); return FALSE; } if (!runasImm && MessageBox(GetLoadStr(IDS_START), INSTALL_STR, MB_OKCANCEL|MB_ICONINFORMATION) != IDOK) { return FALSE; } runasImm = FALSE; // ファイル生成 for (int i=0; SetupFiles[i]; i++) { MakePath(installPath, setupDir, SetupFiles[i]); CreateStatus cs = CreateFileBySelf(installPath, SetupFiles[i]); if (cs == CS_BROKEN) { MessageBox(GetLoadStr(IDS_BROKENARCHIVE), INSTALL_STR); return FALSE; } else if (cs == CS_ACCESS) { const char *msg = Fmt("%s\r\n%s", GetLoadStrU8(IDS_NOTCREATEFILE), installPath); MessageBoxU8(msg, INSTALL_STR); return FALSE; } } // 展開のみ if (extract_only) { ShellExecuteW(NULL, NULL, U8toWs(setupDir), 0, 0, SW_SHOW); return TRUE; } // スタートアップ&デスクトップに登録 TRegistry reg(HKEY_CURRENT_USER); if (reg.OpenKey(REGSTR_SHELLFOLDERS)) { char *regStr[] = { REGSTR_STARTUP, REGSTR_PROGRAMS, REGSTR_DESKTOP, NULL }; BOOL resId[] = { STARTUP_CHECK, PROGRAM_CHECK, DESKTOP_CHECK, NULL }; for (int i=0; regStr[i]; i++) { if (reg.GetStr(regStr[i], buf, sizeof(buf))) { if (i != 0 || !RemoveSameLink(buf, buf)) ::wsprintf(buf + strlen(buf), "\\%s", IPMSG_SHORTCUT_NAME); if (IsDlgButtonChecked(resId[i])) SymLink(setupPath, buf); else DeleteLink(buf); } } reg.CloseKey(); } // レジストリにアプリケーション情報を登録 reg.ChangeTopKey(HKEY_LOCAL_MACHINE); if (reg.OpenKey(REGSTR_PATH_APPPATHS)) { if (reg.CreateKey(IPMSG_EXENAME)) { reg.SetStr(NULL, setupPath); reg.SetStr(REGSTR_PATH, setupDir); reg.CloseKey(); } reg.CloseKey(); } // レジストリにアンインストール情報を登録 if (reg.OpenKey(REGSTR_PATH_UNINSTALL)) { if (reg.CreateKey(IPMSG_NAME)) { MakePath(buf, setupDir, SETUP_EXENAME); strcat(buf, " /r"); reg.SetStr(REGSTR_VAL_UNINSTALLER_DISPLAYNAME, IPMSG_FULLNAME); reg.SetStr(REGSTR_VAL_UNINSTALLER_COMMANDLINE, buf); reg.CloseKey(); } reg.CloseKey(); } // コピーしたアプリケーションを起動 const char *msg = GetLoadStr(IDS_SETUPCOMPLETE); int flg = MB_OKCANCEL|MB_ICONINFORMATION; // if (IsWinVista() && ::IsUserAnAdmin() && TIsEnableUAC()) { // msg = Fmt("%s%s", msg, GetLoadStr(IDS_COMPLETE_UACADD)); // flg |= MB_DEFBUTTON2; // } TLaunchDlg dlg(msg, this); if (dlg.Exec() == IDOK) { if (runasWnd) { Wstr wbuf(setupDir); if (::SendDlgItemMessageW(runasWnd, FILE_EDIT, WM_SETTEXT, 0, (LPARAM)wbuf.Buf())) { ::PostMessage(runasWnd, WM_IPMSG_QUIT, 1, 0); runasWnd = NULL; } } else { AppKick(); } } else { HWND hHelp = ShowHelpU8(0, setupDir, GetLoadStrU8(IDS_IPMSGHELP), "#history"); if (hHelp) { Show(SW_HIDE); while (::IsWindow(hHelp)) { this->Sleep(100); } } } if (runasWnd) { ::PostMessage(runasWnd, WM_IPMSG_QUIT, 0, 0); runasWnd = NULL; } // ShellExecuteU8(NULL, NULL, setupDir, 0, 0, SW_SHOW); ::PostQuitMessage(0); return TRUE; }