VC fix .pch file missing

表现:

Error   1   fatal error C1083: Cannot open precompiled header file: 'Debug\????.pch': No such file or directory

解决方法:
1、保证stdafx.h及stdafx.cpp在项目的最顶层,stdafx.h用于保存需要的头文件,stdafx.cpp中只有对stdafx.h的引用;
2、在VS中,右击需要修改的工程,选择”Properties”;
3、在左上角,选择“ All Configurations”;
4、在左边,找到“C/C++”,并定位到“Precompiled Headers”;
5、将选项Precompiled Header修改为: “Use (/Yu)”;
6、将选项“Precompiled Header File”修改为:“stdafx.h”;
7、保存设置;
8、保证#include “stdafx.h”为所有需要预编译的cpp文件的第一行;
9、VS中,右击stdafx.cpp,选择”Properties”;
10、在左上角,选择“ All Configurations”;
11、将选项Precompiled Header修改为: “Create (/Yc).”;
12、保存设置,重新编译。

Win2008下调试Service程序

Win2008下调试Service程序时,发现无法使用DebugBreak(),否则程序直接挂掉,无法进行调试。

有资料说是,修改错误报告的选项就可以修正这个问题了,尝试后发现无效,暂时只能一点儿一点儿调试了。

另外,Win2008上内存检测严格了很多,需要注意。

winxpx86+cygwin+vs2008编译32位openjdk7

除了win7x64+cygwin+vs2010编译64位openjdk6中的问题外,还会遇下面问题:
1、配套的WindowsSDK为6.0
2、编译器版本校验会出错,要调整Makefile
3、缺少头文件:stdint.h
主要是因为VS2008不符合c99规范
stdint.h

win7x64+cygwin+vs2010编译64位openjdk6

用VS2010编译OpenJDK6,是一个比OpenJDK7更痛苦的过程。

除了OpenJDK7里需要注意的,还有下面几个:
1、编译器版本不同,所以要自行在Makefile中,增加编译器版本
同样的,还有cp一些dll的命令,需要屏蔽

2、命令冲突
主要是sort和echo

3、Windows版本问题,导致部分define失败,以及部分结构体不存在
从而无法编译通过,主要是

jdk/src/windows/native/sun/windows/awtmsg.h
jdk/src/windows/native/sun/windows/awtMMStub.h
jdk/src/windows/native/java/net/NetworkInterface.h

4、jchar*与LPWCHAR之间的CAST失败,主要存在于

jdk/src/windows/native/sun/windows
jdk/src/windows/native/sun/nio/sun
jdk/src/windows/native/sun/java2d/windows
jdk/src/windows/native/sun/awt/splashscreen

5、设置环境变量的命令行:

@set PATH=C:\Windows\system32;

@call "C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\vcvarsall.bat" x64
@set VS100COMNTOOLS=C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\Tools

@set ANT_HOME=D:/JavaTools/apache-ant-1.8.1
@set PATH=%PATH%;%ANT_HOME%\bin;

@set FREETYPE_HOME=D:/GnuWin/freetype2.4.10
@set PATH=%PATH%;%FREETYPE_HOME%/bin;
@set ALT_FREETYPE_LIB_PATH=%FREETYPE_HOME%/lib64
@set ALT_FREETYPE_HEADERS_PATH=%FREETYPE_HOME%/include

@set ALT_BOOTDIR=D:/JavaJDK/jdk1.6.0_34
@set ARCH_DATA_MODEL=64
@set ARCH=amd64
@set PLATFORM=windows
@set ALT_DROPS_DIR=D:/DiskF/OpenJDK/openjdk6_VS2010_x64/drops
@set ALT_COMPILER_PATH=C:/Program Files (x86)/Microsoft Visual Studio 10.0/VC/bin/amd64

@set PATH=%PATH%;D:\Cygwin\bin;

@set JAVA_HOME=
@set CLASSPATH=

@color 02
@title OpenJDK6+VS2010+x64

@cmd

win7x64+cygwin+vs2010编译64位openjdk7

建议:
1、这是一个比较折腾的过程,可能的话建议用linux
2、建议用英文系统
3、建议用英文版的vc++
4、请不要用带空格的路径,尤其是不要用带中文的路径,

主要问题有:
1、可执行文件版本不兼容
2、win和linux路径问题
3、字符集问题,鄙视一下corba的注释,根本没考虑其他字符
4、cl的MT和MD要统一
5、不同路径下文件名冲突问题,

准备与编译:
1、安装VS2010、windows sdk7.1、VS2010 sp1,注意sp1和windows sdk的安装顺序
也有说只有VS的Express版本才需要安装windows sdk的,我反正都安装了。
2、安装directx sdk9(Summer 2004)
3、安装cygwin,并按照要求,下载相应组件,
http://www.cygwin.com/
http://hg.openjdk.java.net/jdk7/jdk7/raw-file/tip/README-builds.html
其中make组件太新,需要替换为3.8.1以前的版本
http://www.cmake.org/files/cygwin/make.exe-cygwin1.7
4、下载JDK6u22+,并安装
5、下载ant,并解压
6、下载并编译FreeType2.4
http://sourceforge.net/projects/freetype/files/
x64+MD+Release
7、下载OpenJDK7,并解压
8、新建drops文件夹,下载下面三个文件,并放到dorps文件夹中:
jaxp145_01.zip
jdk7-jaf-2010_08_19.zip
jdk7-jaxws2_2_4-b03-2011_05_27.zip
理论上,ant应该可以自动下载这三个文件,但我这里下不到
手工下载的话,在Makefile里找下面三个关键字就好了:
jaxp_src.bundle.name
jaxws_src.bundle.name
jaf_src.bundle.name

9、准备编译,新建run.bat,按自己的路径进行修改:

rem 这里是为了解决路径冲突问题
@set PATH=C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;

rem 注意,这里我的VS和WindowsSDK有冲突,导致VS100COMNTOOLS路径错误
@call "C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\vcvarsall.bat" x64
@set VS100COMNTOOLS=C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\Tools

rem ANT配置
@set ANT_HOME=D:/JavaTools/apache-ant-1.8.1
@set PATH=%PATH%;%ANT_HOME%\bin;

rem FreeType配置
@set FREETYPE_HOME=D:/GnuWin/freetype2.4.10
@set PATH=%PATH%;%FREETYPE_HOME%/bin;
@set ALT_FREETYPE_LIB_PATH=%FREETYPE_HOME%/lib64
@set ALT_FREETYPE_HEADERS_PATH=%FREETYPE_HOME%/include

rem Cygwin设置
@set PATH=%PATH%;D:\Cygwin\bin;

rem 这里是OpenJDK的设置啦
@set ALT_BOOTDIR=D:/JavaJDK/jdk1.6.0_34
@set ARCH_DATA_MODEL=64
@set ARCH=amd64
@set PLATFORM=windows
@set ALT_DROPS_DIR=D:/DiskF/OpenJDK/openjdk7_VS2010_x64/drops

rem 这两个变量要置空
@set JAVA_HOME=
@set CLASSPATH=

rem 个人爱好
@color 02
@title OpenJDK+VS2010

@cmd

10、运行run.bat

#测试配置:
make sanity
#没有错误的话:
make

我遇到的问题:
1、主要死到了MT和MD上,这个我修改了Makefile,一定要和FreeType保持一致
2、还有FreeType.dll,我编译的是个大Lib,所以Makefile里拷贝dll的语句要去掉
3、corba的字符集问题,要把Makefile里的ascii去掉,因为生成的注释有中文,显然要出错
4、EXE冲突,我的工具版本很多,估计一般人没这么多问题,最后改了PATH,Find改了名称
比如win的find和cygwin的find,Oracle的zip和cygwin的zip
同样,cygwin和(mingw、GnuSetup、GnuWin)的冲突,也要注意
5、还有一个,就是bat中的路径,除Path外尽量用/,因为linux下,\是转义用的
6、尝试了MinGW,发现不够给力啊

VC的链接顺序

CRT库在链接new, delete, DllMain这些符号的时候,使用的是弱外链接
MFC库同样也包含了new, delete, DllMain这几个符号,而MFC库必须在CRT库之前被链接才会成功。

如果link时出现了符号冲突,做下面的设置即可
project>properties>configuration properties>linker>input
在”Additional dependency”中依次增加 Nafxcwd.lib Libcmtd.lib
在add to “ignore specific library”中依次增加Nafxcwd.lib;Libcmtd.lib

VC服务程序调用远程资源

当VC服务程序调用远程资源时,经常返回路径不存在等问题
这是因为Windows中,服务程序以System用户登录,而不是桌面用户登录
这样就导致,虽然桌面程序已经映射网络资源,但System用户仍无法访问的问题
为了可以访问远程资源,可以调用API:WNetAddConnection2

BOOL AcessNetworkDrtive(CString szDevice,CString szDeviceName,CString szUsername,CString szPassword)
{
	DWORD dwRetVal;
	NETRESOURCE nr;

	memset(&nr, 0, sizeof (NETRESOURCE));
	nr.dwType = RESOURCETYPE_ANY;
	nr.lpLocalName = strDevice.GetBuffer(szDevice.GetLength());
	nr.lpRemoteName = szDeviceName.GetBuffer(szDeviceName.GetLength());
	nr.lpProvider = NULL;

	dwRetVal = WNetAddConnection2(&nr, szUsername, szUsername, CONNECT_UPDATE_PROFILE);

	if (dwRetVal != NO_ERROR)
	{
		CString cError;
		cError.Format(TEXT("[ERROR]WNetAddConnection2 Failed: %u\n"), dwRetVal);
		LogEvent(cError,TEXT("With remote name "),nr.lpRemoteName);
		return dwRetVal;
	}

	return 	dwRetVal;
}

用VC编译Nginx

1、安装Mysis和VC
2、用svn从Nginx取回源代码
3、调用下面的bat

@call "D:\Microsoft Visual Studio 9.0\VC\bin\vcvars32.bat"
@call "D:\GNUstep\msys.bat"
cmd

4、Config

./auto/configure --prefix= --sbin-path=nginx --with-cc=cl --with-cc-opt="" --without-http_rewrite_module --without-http_gzip_module

5、Make

nmake

创建进程API

Winexec
UINT WinExec(
LPCSTR lpCmdLine, 
UINT uCmdShow ); 

ShellExecute
HINSTANCE ShellExecute(
HWND hwnd, 
LPCTSTR lpOperation, 
LPCTSTR lpFile,
LPCTSTR lpParameters, 
LPCTSTR lpDirectory,
INT nShowCmd ); 

CreateProcess
BOOL CreateProcess(LPCTSTR lpApplicationName, 
LPTSTR lpCommandLine,
LPSECURITY_ATTRIBUTES lpProcessAttributes,
LPSECURITY_ATTRIBUTES lpThreadAttributes,
BOOL bInheritHandles,
DWORD dwCreationFlags,
LPVOID lpEnvironment,
LPCTSTR lpCurrentDirectory,
LPSTARTUPINFO lpStartupInfo, 
LPPROCESS_INFORMATION lpProcessInformation
); 

VC计算CString摘要

1、VC计算字符串MD5摘要

//输入:要计算摘要的字符串
//输出:128位MD5摘要
#include <wincrypt.h>
CString szResult;

CString CDigestDlg::CalcMD5(CString strContent)
{
  DWORD dwLength=0;
  BYTE* pbContent=NULL;

  dwLength = (DWORD)strContent.GetLength();
  pbContent = new BYTE[dwLength];
  memcpy(pbContent,strContent.GetBuffer(dwLength),dwLength);

  //计算MD5编码
  HCRYPTPROV hCryptProv; 
  HCRYPTHASH hHash; 
  BYTE byteMD5[16]; 
  DWORD dwHashLen=16;
  CString szResult;

  if(CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET)) 
  {
    if(CryptCreateHash(hCryptProv, CALG_MD5, 0, 0, &hHash)) 
    {
      if(CryptHashData(hHash, pbContent, dwLength, 0))
      {

        if(CryptGetHashParam(hHash, HP_HASHVAL, byteMD5, &dwHashLen, 0)) 
        {
          szResult.Format(TEXT("%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x"),
            byteMD5[0],byteMD5[1],byteMD5[2],byteMD5[3],byteMD5[4],byteMD5[5],byteMD5[6],byteMD5[7]
            ,byteMD5[8],byteMD5[9],byteMD5[10],byteMD5[11],byteMD5[12],byteMD5[13],byteMD5[14],byteMD5[15]);
        }
        else
        {
          szResult=TEXT("Error getting hash param");
        }

      }
      else
      {
        szResult=TEXT("Error hashing data");
      }
    }
    else
    {
      szResult=TEXT("Error creating hash");
    }
  }
  else
  {
    szResult=TEXT("Error acquiring context");
  }

  CryptDestroyHash(hHash); 
  CryptReleaseContext(hCryptProv, 0); 
  delete[] pbContent;
  pbContent=NULL;

  return szResult;
}

2、VC计算字符串SHA1摘要

//输入:要计算摘要的字符串
//输出:160位SHA1摘要
#include <wincrypt.h>
CString szResult;

CString CDigestDlg::CalcSHA1(CString strContent)
{
  DWORD dwLength=0;
  BYTE* pbContent=NULL;

  dwLength = (DWORD)strContent.GetLength();
  pbContent = new BYTE[dwLength];
  memcpy(pbContent,strContent.GetBuffer(dwLength),dwLength);

  //计算MD5编码
  HCRYPTPROV hCryptProv; 
  HCRYPTHASH hHash; 
  BYTE byteSHA1[20]; 
  DWORD dwHashLen=20;
  CString szResult;

  if(CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET)) 
  {
    if(CryptCreateHash(hCryptProv, CALG_SHA1, 0, 0, &hHash)) 
    {
      if(CryptHashData(hHash, pbContent, dwLength, 0))
      {

        if(CryptGetHashParam(hHash, HP_HASHVAL, byteSHA1, &dwHashLen, 0)) 
        {
          szResult.Format(TEXT("%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x"),
            byteSHA1[0],byteSHA1[1],byteSHA1[2],byteSHA1[3],byteSHA1[4],byteSHA1[5],byteSHA1[6],byteSHA1[7],
            byteSHA1[8],byteSHA1[9],byteSHA1[10],byteSHA1[11],byteSHA1[12],byteSHA1[13],byteSHA1[14],byteSHA1[15],
            byteSHA1[16],byteSHA1[17],byteSHA1[18],byteSHA1[19]);
        }
        else
        {
          szResult=TEXT("Error getting hash param");
        }

      }
      else
      {
        szResult=TEXT("Error hashing data");
      }
    }
    else
    {
      szResult=TEXT("Error creating hash");
    }
  }
  else
  {
    szResult=TEXT("Error acquiring context");
  }

  CryptDestroyHash(hHash); 
  CryptReleaseContext(hCryptProv, 0); 
  delete[] pbContent;
  pbContent=NULL;

  return szResult;
}