***********************************************声明************************************************************

原创作品,出自 “晓风残月xj” 博客,欢迎转载。转载时请务必注明出处(http://blog.csdn.net/xiaofengcanyuexj)。

因为各种原因。可能存在诸多不足。欢迎斧正。

****************************************************************************************************************

近期在做安装包解压,涉及到非常多关于路径的操作。当然非常须要调用非常多Windows API函数,本来是没有什么技术含量的,但因为Windows中关于文件夹、路径的操作较为重要。并且当中蕴含着一些重要的编程思想及技巧,所以在此加以总结,希望对以后的学习工作起到作用,同一时候更希望能帮助大家解决这个问题。共同创建一个知识分享型的网络社区。

如今提供下面几个操作方法。持续更新中…

    
  1、在指定路径下创建目录

2、获取程序的安装路径

3、对话框支持文件拖拽

4、获取当前进程已载入模块的文件的完整路径

5、文件(夹)的操作,如复制、删除、移动等

下面是具体介绍。

1、在指定路径下创建目录

void PathRemoveFileSpec(CString& strPath)
{
int nPos = strPath.ReverseFind(_T('\\'));
if (nPos == -1)
{
strPath.Empty();
}
else
{
strPath = strPath.Left(nPos);
}
} BOOL CreateDeepDirectory(LPCTSTR szPath)
{
BOOL bRetCode = FALSE;
CString strPath(szPath);
if (GetFileAttributes(szPath) != INVALID_FILE_ATTRIBUTES)
return TRUE;
bRetCode = CreateDirectory(szPath, NULL);
if (!bRetCode && GetLastError() != ERROR_ALREADY_EXISTS)
{
PathRemoveFileSpec(strPath);
if (strPath.IsEmpty()) return FALSE;
bRetCode = CreateDeepDirectory(strPath);
if (!bRetCode) return FALSE;
bRetCode = CreateDirectory(szPath, NULL);
if (!bRetCode && GetLastError() != ERROR_ALREADY_EXISTS)
return FALSE;
}
return TRUE;
}

2、获取程序的安装路径

     非常多应用程序会在注冊表中存储对应信息,此时能够从注冊表中获取应用程序的安装路径

//InstallSoftwarePath.h

#ifndef _InstallSoftwarePath_H
#define _InstallSoftwarePath_H class CInstallSoftwarePath
{
public:
CInstallSoftwarePath(void);
~CInstallSoftwarePath(void);
CString GetSoftwarePath(void);
private:
CString m_cstrSoftwarePath;
}; #endif
//InstallSoftwarePath.cpp
#include "StdAfx.h"
#include "InstallSoftwarePath.h" TCHAR g_szName[] = _T("XXX");//代表应用程序名 CInstallSoftwarePath::CInstallSoftwarePath(void)
{
m_cstrSoftwarePath=_T("");
} CInstallSoftwarePath::~CInstallSoftwarePath(void)
{
} CString CInstallSoftwarePath::GetSoftwarePath(void)
{
HKEY keyFirst = NULL, keySecond = NULL;
TCHAR szSub[] = _T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall");
TCHAR szName[200] = {0};
TCHAR szDisplay[200] = {0};
TCHAR szShow[200] = {0};
TCHAR szIcon[200] = {0};
DWORD dwIclen = 200;
DWORD dwIndex = 0, dwNameSize = 200, dwShowLen = 200;
DWORD m_attr=REG_BINARY | REG_DWORD | REG_EXPAND_SZ | REG_MULTI_SZ | REG_NONE | REG_SZ; if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, szSub, 0, KEY_ALL_ACCESS, &keyFirst))
{
while(ERROR_NO_MORE_ITEMS != RegEnumKeyEx(keyFirst, dwIndex, szName, &dwNameSize, 0, NULL, NULL, 0))
{
dwIndex++;
if (0 != _tcscmp(szName, _T("")))
{
_tcscpy(szDisplay, szSub);
_tcscat(szDisplay, _T("\\"));
_tcscat(szDisplay, szName);
if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, szDisplay, 0, KEY_ALL_ACCESS, &keySecond))
{
memset(szName, 0, sizeof(szName));
memset(szShow, 0, sizeof(szShow));
memset(szIcon, 0, sizeof(szIcon));
dwIclen=200;
dwNameSize = 200;
dwShowLen = 200;
RegQueryValueEx(keySecond, _T("DisplayName"), NULL, &m_attr, (LPBYTE)szName, &dwNameSize);
RegQueryValueEx(keySecond, _T("DisplayIcon"), NULL, &m_attr, (LPBYTE)szIcon, &dwIclen); if(0 == _tcscmp(szName, g_szName))
{
if (keyFirst)
{
RegCloseKey(keyFirst);
}
if (keySecond)
{
RegCloseKey(keySecond);
}
m_cstrSoftwarePath=szIcon;
m_cstrSoftwarePath.Remove('"');
return m_cstrSoftwarePath;
}
}
memset(szName, 0, sizeof(szName));
memset(szShow, 0, sizeof(szShow));
memset(szDisplay, 0, sizeof(szDisplay));
memset(szIcon, 0, sizeof(szIcon));
dwIclen = 200;
dwNameSize = 200;
dwShowLen = 200;
}
}
}
if (keyFirst)
{
RegCloseKey(keyFirst);
}
if (keySecond)
{
RegCloseKey(keySecond);
}
m_cstrSoftwarePath = _T("");
return m_cstrSoftwarePath;
}

GetSoftwarePath返回的就是应用程序g_szName的完整安装路径。



3、对话框支持文件拖拽

第一步、须要加入消息响应

WM_DROPFILES

1)、假设是MFC,操作例如以下:对话框上点击右键,选择Properties->Extended Styles。点选Accept files选项就可以。

2)、假设不是MFC,如ATL、Win32、金山卫士开源码等,操作例如以下:

LONG dwLong = GetWindowLong(GWL_EXSTYLE);
SetWindowLong(GWL_EXSTYLE, dwLong|WS_EX_ACCEPTFILES);

第二步、文件拖拽消息响应函数

void CMainDlg::OnDropFiles(HDROP hDropInfo)
{ UINT count;
TCHAR strFilePath[MAX_PATH + 1] ;
count = DragQueryFile(hDropInfo, 0xFFFFFFFF, NULL, 0);
if(count)
{
for(UINT i=0; i<count; i++)
//支持多个文件的拖拽操作
{
int pathLen = DragQueryFile(hDropInfo, i, strFilePath, sizeof(strFilePath));
//strFilePath存储的是当前文件的完整路径+文件名称
//此处能够加入待处理的操作。完毕应用程序的功能
}
}
DragFinish(hDropInfo);
//CDialog::OnDropFiles(hDropInfo);//假设是MFC,最好加入此操作
}

4、获取当前进程已载入模块的文件的完整路径,该模块必须由当前进程载入

如以下的C:\Users\jimjxu\Desktop\我的程序\1.cpp源程序运行起来就是  "szPath = C:\Users\jimjxu\Desktop\我的程序\Debug\1.exe"

#include <windows.h>
#include <stdio.h> BOOL GetExactFileName()
{
TCHAR szPath[MAX_PATH];
if( !GetModuleFileName( NULL, szPath, MAX_PATH ) )
{
printf("GetModuleFileName failed (%d)\n", GetLastError());
return FALSE;
}
printf("szPath = %s\n", szPath);
return TRUE;
} int main(int argc, TCHAR* argv[])
{
GetExactFileName();
return 0;
}

5、文件(夹)的操作,如复制、删除、移动等

     关于文件的操作。较为简单。能够直接调用CopyFile,其原型为:

BOOL CopyFile(
LPCTSTR lpExistingFileName, // pointer to name of an existing file
LPCTSTR lpNewFileName, // pointer to filename to copy to
BOOL bFailIfExists // flag for operation if file exists
);
当中各參数的意义:
LPCTSTR lpExistingFileName, // 你要拷贝的源文件名称
LPCTSTR lpNewFileName, // 你要拷贝的目标文件名称
BOOL bFailIfExists // 假设目标已经存在,true:不拷贝并返回False; false:覆盖目标.

关于目录的操作。可能略微复杂一点。目录表现为一组文件的集合,本质上和文件没什么差别。

关于目录的操作,大致有2种方法:

第一种:递归复制单个文件注意处理。推断文件夹与文件。然后创建文件(夹)名称。递归拷贝文件。

另外一种:调用Windows API处理。又分为MFC与Win32程序

假设是MFC程序,能够直接用CFileFind处理。有点第一种方法的味道。详细操作例如以下:

BOOL CopyDirectory(CString strSouDir, CString strDesDir)
{
CFileFind finder;
CString str, strWildcard, strFilePath, strDesFilePath;
BOOL bRetCode ;
if(strDesDir.Right(1) != _T("\\"))
strDesDir += _T("\\");
if(strSouDir.Right(1) != _T("\\"))
strSouDir += _T("\\");
strWildcard = strSouDir + _T("*.*");
BOOL bContinue = finder.FindFile(strWildcard);
while (bContinue)
{
bContinue = finder.FindNextFile();
if(finder.IsDots())
{
continue;
}
str = finder.GetFileName();
if(finder.IsDirectory())
{
CString temstrSouDir = strSouDir + str;
CString temstrDesDir = strDesDir + str;
CreateDirectory(temstrDesDir, NULL);
ret = CopyDirectory(temstrSouDir, temstrDesDir);
}
else
{
strFilePath = finder.GetFilePath();
strDesFilePath = strDesDir+str;
bRetCode = CopyFile(strFilePath, strDesFilePath, FALSE);
if(!bRetCode)
break;
}
}
finder.Close();
return bRetCode;
}

假设是Win32程序,能够直接调用int SHFileOperation(LPSHFILEOPSTRUCT lpFileOp)处理。当中LPSHFILEOPSTRUCT结果例如以下:1.FO_COPY:复制

typedef struct _SHFILEOPSTRUCT {
HWND hwnd; //指向发送消息的窗体
UINT wFunc; //运行的操作
LPCTSTR pFrom; //源文件名称
LPCTSTR pTo ;//目标文件名称
FILEOP_FLAGS fFlags; //操作与确认标识
BOOL fAnyOperationsAborted; //操作是否终止
LPVOID hNameMappings; //文件映射
LPCTSTR lpszProgressTitle; //进度条标题
} SHFILEOPSTRUCT, *LPSHFILEOPSTRUCT;

详细运行文件的操作仅仅需设置对应的值就可以,关于其它成员变量的设置及说明,请点击说明例如以下:

  1.FO_COPY:复制
 2.FO_DELETE:删除
 3.FO_MOVE:移动
 4.FO_RENAME:重命名

例如以下一段代码就可以完毕复制目录的操作:

BOOL KWork::CopyDir(LPCTSTR lpszSrcDir, LPCTSTR lpszDstDir)
{
SHFILEOPSTRUCT sfo;
ZeroMemory(&sfo, sizeof(sfo));
sfo.wFunc = FO_COPY;
sfo.pFrom = lpszSrcDir;
sfo.pTo = lpszDstDir;
sfo.fFlags = FOF_SILENT | FOF_NOCONFIRMATION | FOF_NOCONFIRMMKDIR;
int ret = SHFileOperation(&sfo);
if ( ret == 0 )
return TRUE;
else
return FALSE;
}

当然。对于不同的Windows程序,此处表现不同,是一大坑,详细说明点击说明

本文章持续更新中…

因为写博客时间有限,加之对VC不熟。难免有错误或不足的地方。欢迎斧正!







VC档(夹)文件夹路径的经营方针和代码的更多相关文章

  1. VC 获取指定文件夹路径的方法小结

    VC获取指定文件夹路径 flyfish  2010-3-5 一 使用Shell函数 1 获取应用程序的安装路径 TCHAR buf[_MAX_PATH];SHGetSpecialFolderPath( ...

  2. Atitit 基于图片图像 与文档混合文件夹的分类

    Atitit 基于图片图像 与文档混合文件夹的分类 太小的文档(txt doc csv exl ppt pptx)单独分类 Mov10KminiDoc 但是可能会有一些书法图片迁移,因为他们很微小,需 ...

  3. JavaSE 文件递归之删除&amp;获取文件夹文件夹中全部的以.jpg的文件的绝对路径

    1.递归删除文件 假设一个文件夹以下还有子文件夹,进行删除的话会 报错,这个时候要使用递归的方式来删除这个文件文件夹中的全部文件以及文件夹 package cn.itcast.digui; impor ...

  4. SharePoint文档库文件夹特殊字符转义

    当我们在SharePoint网站文档库中新建文件夹时包含了~ " # % & * : < > ? / \ { | }字符时(一共15个), 或者以.开头或者结束,或者包含 ...

  5. 使用VC++压缩解压缩文件夹

    前言   项目中要用到一个压缩解压缩的模块, 看了很多文章和源代码,  都不是很称心, 现在把我自己实现的代码和大家分享. 要求: 1.使用Unicode(支持中文). 2.使用源代码.(不使用静态或 ...

  6. VC下遍历文件夹中的所有文件的几种方法

    一.使用::FindFirstFile和::FindNextFile方法 #include "StdAfx.h" #include <windows.h> #inclu ...

  7. Java中删除指定文件夹文件夹下面有内容也删除使用递归方案

    import java.io.File; import java.text.ParseException; import java.text.SimpleDateFormat; import java ...

  8. sharepoint rest api 创建文档库 文件夹

    function createFolder() { var requestHeaders = { "Accept": "application/json;odata=ve ...

  9. VC++显示文件或文件夹属性

    When you select a file or folder in Explorer window, and choose 'Properties' from the menu, you get ...

随机推荐

  1. 2013 吉林通化邀请赛 Play Game 记忆化搜索

    dp[ba][ta][bb][tb]表示a堆牌从下面拿了ba张,从上面拿了ta张.b堆牌从下面拿了bb张,从上面拿了tb张.当前玩家能得到的最大的分数. 扩展方式有4种,ba+1,ta+1,bb+1, ...

  2. 2013 吉林通化邀请赛 Tutor 有点坑的水题

    计算12个数的和的平均数.四舍五入,不能有后导0. 我的做法是,将答案算出后,乘以1000,然后看个位是否大于等于5,判断是否要进位…… #include<iostream> #inclu ...

  3. 盒子游戏(The Seventh Hunan Collegiate Programming Contest)

    盒子游戏 有两个相同的盒子,其中一个装了n个球,另一个装了一个球.Alice和Bob发明了一个游戏,规则如下:Alice和Bob轮流操作,Alice先操作.每次操作时,游戏者先看看哪个盒子里的球的数目 ...

  4. cxf和jboss eap 6.2版本号冲突

    升级jboss版本号到jjboss-eap-6.2之后,启动项目时CXF出现异常. 在jboss-as-7.1.1.Final.apache-tomcat-7.0.37以及jboss-eap-6.1 ...

  5. 在ireport中使用checkbox

    在网上搜索了很多实现checkbox的办法, 主要是利用打钩图片实现. 下面是我的做法,也不怎么高明, 不过比利用图片好. 后台 map.put("lifeTimePartFlag" ...

  6. poj1243(经典dp)

    题目链接:http://poj.org/problem?id=1243 题意:让你猜一个物品的价格,猜低了或者猜高了都会提示你.G,L,表示你有G次机会猜一个数,如果猜错了,G会减少1次,如果你的错误 ...

  7. java -D參数简化增加多个jar【简化设置classpath】

    1.-D<name>=<value> set a system property  设置系统属性. java命令引入jar时能够-cp參数,但时-cp不能用通配符(多个jar时 ...

  8. 低版本的 opencv库的 vs2010 打开 高版本opencv

    打开track.vcxproj文件, 注释掉跟版本有关的行就可. 本例子中,当用双击.sln用vs2010打开高版本的opencv项目时,会出现错误, 并且会有错误信息提示,双击该错误信息,就会打开该 ...

  9. 从mina中学习超时程序编写

    从mina中学习超时程序编写 在很多情况下,程序需要使用计时器定,在指定的时间内检查连接过期.例如,要实现一个mqtt服务,为了保证QOS,在服务端发送消息后,需要等待客户端的ack,确保客户端接收到 ...

  10. Android 访问Android Wear数据层Api——同步Data Items

    Data Items它被用来同步手机和wear数据接口,一个Date Items通常包含以下几个部分: Payload 字节数组.无论你需要设置数据类型,我们同意对象序列化和反序列化,大小不能超过10 ...