LPCTSTR UtilGetTempPath() { static CPath s_tempPath; if(_tcslen(s_tempPath)==0){ //初期設定 //環境変数取得 std::map<stdString,stdString> envs; UtilGetEnvInfo(envs); if(!has_key(envs,_T("TMP")) && !has_key(envs,_T("TEMP"))){ //%TMP%/%TEMP%が存在しなければ自前の一時フォルダを使う(C:\Users\xxx\AppData\Roaming\LhaForge\temp) TCHAR szPath[_MAX_PATH+1]={0}; SHGetFolderPath(NULL,CSIDL_APPDATA|CSIDL_FLAG_CREATE,NULL,SHGFP_TYPE_CURRENT,szPath); s_tempPath=szPath; s_tempPath.Append(_T("lhaforge\\temp\\")); UtilMakeSureDirectoryPathExists(s_tempPath); }else{ //通常のパス std::vector<TCHAR> buffer(GetTempPath(0,NULL)+1); GetTempPath(buffer.size(),&buffer[0]); buffer.back()=_T('\0'); s_tempPath=&buffer[0]; s_tempPath.AddBackslash(); } } return s_tempPath; }
// アーカイブ名からフォルダパスを作成する void GetArchiveDirectoryPath(const CConfigExtract &ConfExtract,LPCTSTR lpszArcName,CPath &pathDir) { pathDir=lpszArcName; pathDir.StripPath(); //パス名からファイル名を取得 pathDir.RemoveExtension();//アーカイブファイル名から拡張子を削除 //フォルダ名末尾の数字と記号を取り除く if(ConfExtract.RemoveSymbolAndNumber){ CPath pathOrg=pathDir; UtilTrimString(pathDir,g_szTable); //数字と記号を取り除いた結果、文字列が空になってしまっていたら元にもどす if(_tcslen(pathDir)==0){ pathDir=pathOrg; } } //空白を取り除く UtilTrimString(pathDir,_T(".\\ ")); if(_tcslen(pathDir)>0){ pathDir.AddBackslash(); } }
/************************************************************* 出力先フォルダを決定する 出力先フォルダを二重に作成しないよう、bInFolder引数ですべて フォルダに入っているかどうか確認する *************************************************************/ HRESULT GetExtractDestDir(LPCTSTR ArcFileName,const CConfigGeneral &ConfGeneral,const CConfigExtract &ConfExtract,LPCTSTR lpSpecificOutputDir,bool bInFolder,CPath &r_pathOutputDir,const int nItemCount,LPCTSTR lpszBaseDir,CPath &r_pathOpenDir,bool &r_bUseForAll/*以降もこのフォルダに解凍するならtrueが返る*/,CString &strErr) { CPath pathOutputDir; if(lpSpecificOutputDir && 0!=_tcslen(lpSpecificOutputDir)){ //特定ディレクトリを出力先として指定されていた場合 pathOutputDir=lpSpecificOutputDir; }else{ //設定を元に出力先を決める HRESULT hr=GetOutputDirPathFromConfig(ConfExtract.OutputDirType,ArcFileName,ConfExtract.OutputDir,pathOutputDir,r_bUseForAll,strErr); if(FAILED(hr)){ return hr; } } pathOutputDir.AddBackslash(); // 出力先がネットワークドライブ/リムーバブルディスクであるなら警告 // 出力先が存在しないなら、作成確認 HRESULT hStatus=ConfirmOutputDir(ConfGeneral,pathOutputDir,strErr); if(FAILED(hStatus)){ //キャンセルなど return hStatus; } //アーカイブ名からフォルダを作る CPath pathArchiveNamedDir; //アーカイブ名のフォルダ bool bCreateArchiveDir=false; //アーカイブ名のフォルダを作成する場合にはtrue if( (!ConfExtract.CreateNoFolderIfSingleFileOnly || nItemCount!=1)&& ( ((CREATE_OUTPUT_DIR_SINGLE==ConfExtract.CreateDir)&&!bInFolder)|| (CREATE_OUTPUT_DIR_ALWAYS==ConfExtract.CreateDir) ) ){ GetArchiveDirectoryPath(ConfExtract,ArcFileName,pathArchiveNamedDir); if(_tcslen(pathArchiveNamedDir)==0){ hStatus=S_FALSE; //NG }else{ pathOutputDir+=pathArchiveNamedDir; bCreateArchiveDir=true; } } //パス名の長さチェック if(S_OK==hStatus){ if(_tcslen(pathOutputDir)>=_MAX_PATH){ // パス名が長すぎたとき //TODO ErrorMessage(CString(MAKEINTRESOURCE(IDS_ERROR_MAX_PATH))); hStatus=S_FALSE; } } //そのままではフォルダ名を使えない場合 if(S_FALSE==hStatus){ // 名前を付けて保存 CString title(MAKEINTRESOURCE(IDS_INPUT_TARGET_FOLDER_WITH_SHIFT)); CLFFolderDialog dlg(NULL,title,BIF_RETURNONLYFSDIRS|BIF_NEWDIALOGSTYLE); if(IDOK==dlg.DoModal()){ r_bUseForAll=(GetKeyState(VK_SHIFT)<0); //TODO pathOutputDir=dlg.GetFolderPath(); pathOutputDir.AddBackslash(); if(bCreateArchiveDir){ pathOutputDir+=pathArchiveNamedDir; } }else{ //キャンセル return E_ABORT; } } //出力先の(アーカイブ名と同名のフォルダ名も含めた)フォルダが存在することを保証させる if(!UtilMakeSureDirectoryPathExists(pathOutputDir)){ strErr.Format(IDS_ERROR_CANNOT_MAKE_DIR,(LPCTSTR)pathOutputDir); return E_FAIL; } //出力先フォルダ名を返す r_pathOutputDir=pathOutputDir; //開くパスの組み立て CPath pathToOpen=pathOutputDir; if(!bCreateArchiveDir){ //アーカイブ名フォルダを作成しない場合 if(ConfExtract.CreateNoFolderIfSingleFileOnly && nItemCount==1){ //-ファイル・フォルダが一つだけであるためフォルダを作成しなかった //Nothing to do }else if(CREATE_OUTPUT_DIR_SINGLE==ConfExtract.CreateDir && bInFolder){ //-二重にフォルダを作らない設定に従い、フォルダを作成しなかった //アーカイブ内フォルダを開く pathToOpen.Append(lpszBaseDir); pathToOpen.AddBackslash(); } } pathToOpen.QuoteSpaces(); //開くパスを返す r_pathOpenDir=pathToOpen; return true; }