Textreplace插件的使用:
1 !include "TextReplace.nsh"
2
3 ${textreplace::ReplaceInFile} "c:\1.txt" "c:\1.txt" "%Install%" "替换的内容" "/S=1" $4
4 ${textreplace::FreeReadBuffer} "$4"
5 ${textreplace::Unload}
posted @
2012-05-04 18:12 王海光 阅读(1959) |
评论 (0) |
编辑 收藏
在域环境下,有时受限账户对文件夹需要读、写操作权限,下面为修改文件夹访问权限代码:
1 ReadINIStr $1 "$EXEDIR\Test.ini" "Directory" "DirectoryName"
2 ReadINIStr $2 "$EXEDIR\Test.ini" "Directory" "DriverDirectoryName"
3 ReadEnvStr $3 ALLUSERSPROFILE
4 CreateDirectory "$3\$1"
5 CreateDirectory "$3\$2"
6 ;Make the directory read write accessible by everyone
7 AccessControl::GrantOnFile \
8 "$3\$1" "everyone" "GenericRead + GenericWrite"
9
10 AccessControl::GrantOnFile \
11 "$3\$2" "everyone" "GenericRead + GenericWrite"
在XP64位系统下,如果将提升权限的操作放到禁止重定向下面,修改文件夹权限会失败。如果对C:\WINDOWS\System32下面的配置文件进行修改,则必须放到禁止重定向下面修改。否则修改的将是C:\WINDOWS\SysWOW64下的配置文件。
posted @
2012-05-04 13:16 王海光 阅读(5776) |
评论 (2) |
编辑 收藏
摘要: $INSTDIR
安装目录 ($INSTDIR 可以使用 StrCpy、 ReadRegStr、 ReadINIStr 等等来更改。例如在 .onInit 函数里可以用来做高级的检测安装定位)。
注意在卸载程序代码里,$INSTDIR 为卸载程序所在的目录而不是在安装程序里所指定的目录。例如, 如果你把卸载程序放在 $WINDIR 里并且用户没有移动它,那么在卸载程序里 $INSTDIR 就等于 $WINDIR。如果你要把卸载程序放到另外的位置,那么你应该先把安装程序的 $INSTDIR 值写入注册表或者其它容易保存的地方,然后在卸载程序里读取该值并赋值给卸载程序里的 $INSTDIR。
阅读全文
posted @
2012-05-03 17:30 王海光 阅读(1137) |
评论 (0) |
编辑 收藏
摘要: 本文转自:http://topic.csdn.net/t/20031208/15/2540422.html关于CString总结前言:串操作是编程中最常用也最基本的操作之一 做为VC程序员,无论是菜鸟或高手都曾用过CString.而且好像实际编程中很难离得开它(虽然它不是标准C++中的库).因为MFC中提供的这个类对我们操作字串...
阅读全文
posted @
2012-04-28 09:53 王海光 阅读(481) |
评论 (0) |
编辑 收藏
摘要: 转自:http://www.cppblog.com/humanchao/archive/2011/08/03/152332.html
深入分析MFC文档视图结构(项目实践)
k_eckel:http://www.mscenter.edu.cn/blog/k_eckel
文档视图结构(Document/V...
阅读全文
posted @
2012-04-26 14:06 王海光 阅读(498) |
评论 (0) |
编辑 收藏
MFC socket的使用方法服务器端:
在.h文件中。
1 struct ListeningThreadStruct
2 {
3 CString sSaveDir;
4 int nListenPort;
5 };
6 UINT ListeningThreadProc(LPVOID lparam);
7 struct FileTransferThreadStruct
8 {
9 CString sSaveDir;
10 SOCKET hSOCKET;
11 };
12
13 UINT FileTransferThread(LPVOID lparam);
在.cpp文件中。
1 UINT CSocketFun::ListeningThreadProc(LPVOID lparam)
2 {
3 ListeningThreadStruct *pPara = (ListeningThreadStruct*)lparam;
4 int nListenPort = pPara->nListenPort;
5 CString sSaveDir = pPara->sSaveDir;
6 delete pPara;
7 pPara = NULL;
8
9 SocketThreadInit();
10 try
11 {
12 CSocket liseningSocket;
13 if ( !liseningSocket.Create(nListenPort) )
14 {
15 LOG("创建TCP端口失败, 可能是端口%d被占用", nListenPort);
16 return 1;
17 }
18
19 if ( !liseningSocket.Listen(5) )
20 {
21 LOG("启动Socket监听失败");
22 return 1;
23 }
24
25 while(true)
26 {
27 CSocket clientSocket;
28 if ( liseningSocket.Accept(clientSocket) )
29 {
30 FileTransferThreadStruct *pFileTrans = new FileTransferThreadStruct;
31 pFileTrans->hSOCKET = clientSocket.Detach();
32 pFileTrans->sSaveDir = sSaveDir;
33
34 AfxBeginThread(FileTransferThread2, (LPVOID)pFileTrans);
35 }
36 else
37 {
38 liseningSocket.Close();
39 break;
40 }
41 }
42 }
43 catch()
44 {
45 LOG("监控Socket线程收到异常, 监听结束");
46 return 0;
47 }
48 return 0;
49 }
50
51
52 UINT CSocketFun::FileTransferThread2(LPVOID lparam)
53 {
54 FileTransferThreadStruct *pPara = (FileTransferThreadStruct*)lparam;
55 SOCKET sock = pPara->hSOCKET;
56 CString sSaveDir = pPara->sSaveDir;
57 delete pPara;
58 pPara = NULL;
59
60 SocketThreadInit();
61
62 CSocket aSocket;
63 aSocket.Attach(sock);
64
65 char buffer[SERVER_SOCKET_BUFFERSIZE] = {'\0'};
66 int nLen = aSocket.Receive(buffer, MAX_PATH);
67 } 调用线程.cpp文件中。
1 ListeningThreadStruct *pPara = new ListeningThreadStruct;
2 pPara->sSaveDir = m_sSaveDir;
3 pPara->nListenPort = m_nListenPort;
4
5 CWinThread *pThread = AfxBeginThread(ListeningThreadProc, (LPVOID)pPara);
客户端:
示例代码:
1 #define OutStr(x, ) \
2 {\
3 CString sMsg; \
4 sMsg.Format(x, __VA_ARGS__); \
5 if (sMsg.GetLength() < (int)nErrBufLen) \
6 strcpy_s(pErrorBuf, nErrBufLen, sMsg); \
7 else \
8 strcpy_s(pErrorBuf, nErrBufLen, "缓冲区大小不足"); \
9 }
10
11
12 AFX_MANAGE_STATE(AfxGetStaticModuleState());
13
14 if (!AfxSocketInit())
15 {
16 return 1 ;
17 }
18
19 SocketThreadInit();
20
21 CSocket aSocket;
22 if (!aSocket.Create())
23 {
24 OutStr("创建socket失败");
25 return 1;
26 }
27
28 if (!aSocket.Connect(sServerIP, nPort))
29 {
30 OutStr("连接服务器失败IP %s 端口 %d", sServerIP, nPort);
31 return 1;
32 }
33
34 CFile file;
35 if (!file.Open(sFile, CFile::modeRead))
36 {
37 OutStr("发送文件时, 文件%s打开失败", sFile);
38 return 1;
39 }
40
41 // 1. send file name
42 char fileName[MAX_PATH] = {'\0'};
43 strcpy_s( fileName, MAX_PATH, CCommonFun::GetFileFullName(sFile) );
44 if ( SOCKET_ERROR == aSocket.Send(fileName, MAX_PATH) )
45 {
46 OutStr("文件名通过socket发送失败");
47 return 1;
48 }
49
50 // 2. send file size
51 ULONGLONG ulFileLen = file.GetLength();
52 if (SOCKET_ERROR == aSocket.Send(&ulFileLen, sizeof(ULONGLONG) ) )
53 {
54 OutStr("文件长度通过socket发送失败");
55 return 1;
56 }
57
58 try
59 {
60 char buffer[CLIENT_SOCKET_BUFFERSIZE] = {'\0'};
61 UINT nTotalLen = 0;
62 UINT nLen = 0;
63 while ((nLen = file.Read(buffer, CLIENT_SOCKET_BUFFERSIZE)) > 0)
64 {
65 if (SOCKET_ERROR == aSocket.Send(buffer, nLen))
66 {
67 OutStr("文件数据通过socket发送失败, 已发送%d", nTotalLen);
68 return 1;
69 }
70
71 nTotalLen += nLen;
72 }
73 }
74 catch ()
75 {
76 OutStr("发送文件数据时收到一个异常, 发送失败");
77 return 1;
78 }
79
80 #define SOCKET_OK_BUFFERSIZE 1024
81 char szOK[SOCKET_OK_BUFFERSIZE] = {'\0'};
82 int nLen = aSocket.Receive(szOK, SOCKET_OK_BUFFERSIZE);
83 if (CString(szOK) != "ok")
84 {
85 OutStr("未收到合法的服务器回文, 发送失败");
86 return 1;
87 }
posted @
2012-04-26 13:58 王海光 阅读(1830) |
评论 (0) |
编辑 收藏
MFC一种线程的使用方法在.h文件中。
1 struct MonitorPara
2 {
3 enum SaveType
4 {
5 OnlySend,
6 SendSave,
7 SendErrorSave
8 };
9
10 int m_nListenPort; // monitor local ip port
11 CString m_sServerIP; // send data server ip
12 int m_nServerPort; // send data server port
13
14 SaveType m_SaveType;
15 CString m_sDataBufDir;
16 };
17
18 static UINT ListeningThreadProc(LPVOID lparam);
在.cpp文件中。
1 UINT CSocketPrinter::ListeningThreadProc(LPVOID lparam)
2 {
3 //CFileWatcher* obj = (CFileWatcher*)lParam;
4 CSocketPrinter::MonitorPara para = *((CSocketPrinter::MonitorPara*)lparam);
5
6
7 }
8
9 BOOL CSocketPrinter::StartMonitor(const MonitorPara ¶)
10 {
11 CWinThread* pThread = AfxBeginThread(ListeningThreadProc, (LPVOID)¶);
12
13 return (pThread && pThread->m_hThread);
14 }
调用线程.cpp文件中。
1 CSocketPrinter obj;
2 CSocketPrinter::MonitorPara para;
3
4 HANDLE h_Thread = NULL;
5 h_Thread = obj.StartMonitor(para);
6
7 if (!h_Thread)
8 {
9 LOG("获取线程句柄出错");
10 return;
11 }
强制结束线程
1 ::TerminateThread(h_Thread, 0);
posted @
2012-04-26 13:35 王海光 阅读(497) |
评论 (0) |
编辑 收藏
64位操作系统下拷贝文件重定向问题问题:安装打印机驱动时,系统拷贝驱动文件到系统目录C:\Windows\System32\spool\drivers,有的驱动会出现安装驱动不成功的现象。
原因:64位操作系统下没有禁止重定向。
在程序中加上下面代码解决重定向问题。
1 KWow64FsRedrt redrt;
2 if (redrt.Init())
3 {
4 redrt.Close();
5 }
32位的Windows系统没有重定向这个说法。
其他文章:
http://blog.csdn.net/hcyang/article/details/4578796 http://www.cnblogs.com/BeyondTechnology/archive/2010/10/21/1857881.html
posted @
2012-04-25 16:27 王海光 阅读(631) |
评论 (0) |
编辑 收藏
结构体CString问题
1 struct sTest
2 {
3 CString addr;
4 int port;
5 };
定义CString addr时,编译器会在栈里分配一块内存空间,然后调用CString的默认构造函数初始化addr,此时Cstring内部的m_pchData指向一个空字串 " ",而不是NULL。cstring在结构里也是一样的,结构无论是从栈中分配如 :
ME_REFRESH lpmerefresh
或从堆中分配 :
lpmerefresh=new ME_REFRESH;
type为cstring的分量都会被调用默认构造函数初始化name,使Cstring内部的m_pchData指向一个空字串 " ",该空字串是afxEmptyString的m_pchData。memset CString时,该m_pchData便指向了NULL,那么就表明该CString的值被破坏了,所以报错。
结构体成员如果仅仅是基本类型成员可以直接memset(ST,0,sizeof(ST)),但结构体里面包含有指针,直接memset是不行的,因为指针成员的sizeof都是4字节。你应该专门对指针成员进行memset,sizeof对于包含指针的结构获得的长度不是你想要的。
posted @
2012-04-24 13:56 王海光 阅读(1848) |
评论 (0) |
编辑 收藏
修改左上角的图标和任务栏里图标
在对话框构造函数中
1 CTestDlg::CTestDlg(CWnd* pParent /*=NULL*/)
2 : CDialog(CTestDlg::IDD, pParent)
3 {
4 m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
5 }
改过后:
1 CTestDlg::CTestDlg(CWnd* pParent /*=NULL*/)
2 : CDialog(CTestDlg::IDD, pParent)
3 {
4 m_hIcon = AfxGetApp()->LoadIcon(IDI_ICON1);
5 }
将最后的IDR_MAINFRAME改为自己的图标即可,上面改为了IDI_ICON1,更改的图标需要先导入或者添加进资源icon里,将默认的mfc图标换成自己的。
修改生成EXE文件图标
方法一:
要更改图标,在resource.h中打开之后可以看到各个资源的ID值,一般mfc自动生成的IDR_MAINFRAME是128,自己添加的会大于128,顺序后延,编译时默认将ID最小的作为exe的图标,所以只要我们将其改之就可以了,还是上面的对话框,将IDI_ICON1改为128,将IDR_MAINFRAME改为其他的大一点的数不能太大了,因为可能会有其他用处,然后重新rebuild,这时就可以看到exe图标变成了自己的IDI_ICON1的图标了。
方法二:
1、在程序res文件夹下,删除MFC图标文件,加入自己的图标文件;
2、在图标IDR_MAINFRAME的属性对话框中,修改File name路径为自己的图标文件。
注:(1)一定要先删除原文件,否则会把你的图标文件覆盖掉;
(2)完成后在资源视图中可能发现还是原来的MFC图标,但编译后exe文件的图标已经变成自己的了。
方法三:
在.rc文件中,可以修改默认图标路径来修改生成EXE文件图标。
1 IDR_MAINFRAME ICON "res\\Test.ico"
修改后:
1 IDR_MAINFRAME ICON "res\\Test1.ico"
修改托盘中EXE文件图标
可以用NOTIFYICONDATA来实现。
1 NOTIFYICONDATA _tnd;
2 _tnd.cbSize=sizeof(NOTIFYICONDATA);
3 _tnd.hWnd = this->GetSafeHwnd();
4 _tnd.uID = 0;
5 _tnd.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP | NIF_INFO;
6 _tnd.dwInfoFlags = NIIF_INFO; // add an icon to a balloon ToolTip
7 _tnd.uTimeout = uTimeout;
8
9 CString sStatusMsg = szMsg;
10
11 if (“修改条件”)
12 {
13 _tnd.hIcon = theApp.LoadIcon(IDI_SUCCESSLOGIN);
14 }
posted @
2012-04-20 15:52 王海光 阅读(12179) |
评论 (0) |
编辑 收藏