use Windows API to set IE proxy
使用 Windows API 设置 IE 代理服务器
缘
最近折腾各种代理框架,需要设置 IE 代理服务器。了解有两种方式,注册表和API方式。
注册表方式使用时,偶尔会出现设置异常,无法成功的情况,所以想实验一下API的方式。
通过Google,查到了在 SysTutorials 上,ERIC MA 的一篇文章有相关实现。
因为原先的源代码是C++写的,编译后程序有点大,在原作者基础上用C语言稍微修改了下,控制下二进制大小。代码如下:
源代码
SetProxy.c
#include <stdio.h>
#include <windows.h>
#include <wininet.h>
BOOL SetConnectionOptions(LPCTSTR conn_name,LPCTSTR proxy_full_addr);
BOOL DisableConnectionProxy(LPCTSTR conn_name);
int main(int argc, char* argv[])
{
int nRetCode = 0;
//set proxy
if (argc<2) {
printf("SetProxy Usage:\n\n");
printf("Examples:\n");
printf("SetProxy.exe 10.1.1.1:8080 -- set proxy to 10.1.1.1:8080.\n" );
printf("SetProxy.exe \"\" -- disable proxy, set proxy to null.\n" );
printf("\n");
printf("Version 1.0.0\n");
printf("Author: Eric Ma <mazq.eric@gmail.com>.\n\n");
printf("Version 1.0.1\n");
printf("Editor: Nivrrex <nivrrex@gmail.com>.");
return 1;
}
const char *connection_name="";
char* proxy_addr=argv[1];
if (SetConnectionOptions(connection_name,proxy_addr)) {
char msg[100]="Proxy ";
if (strlen(proxy_addr)!=0) {
strcat(msg,"set to ");
strcat(msg,proxy_addr);
}
else {
DisableConnectionProxy(connection_name);
strcat(msg,"disabled");
}
printf("%s\n",msg);
}
return nRetCode;
}
BOOL SetConnectionOptions(LPCTSTR conn_name,LPCTSTR proxy_full_addr)
{
//conn_name: active connection name.
//proxy_full_addr : eg "210.78.22.87:8000"
INTERNET_PER_CONN_OPTION_LIST list;
BOOL bReturn;
DWORD dwBufSize = sizeof(list);
// Fill out list struct.
list.dwSize = sizeof(list);
// NULL == LAN, otherwise connectoid name.
list.pszConnection = conn_name;
// Set three options.
list.dwOptionCount = 2;//3;
list.pOptions = (INTERNET_PER_CONN_OPTION*) malloc (sizeof(INTERNET_PER_CONN_OPTION) * 2/*3*/);
// Make sure the memory was allocated.
if(NULL == list.pOptions)
{
// Return FALSE if the memory wasn't allocated.
OutputDebugString("failed to allocat memory in SetConnectionOptions()");
return FALSE;
}
// Set flags.
list.pOptions[0].dwOption = INTERNET_PER_CONN_FLAGS;
list.pOptions[0].Value.dwValue = PROXY_TYPE_DIRECT |
PROXY_TYPE_PROXY;
// Set proxy name.
list.pOptions[1].dwOption = INTERNET_PER_CONN_PROXY_SERVER;
list.pOptions[1].Value.pszValue = proxy_full_addr;//"http://proxy:80";
/*
// Set proxy override.
list.pOptions[2].dwOption = INTERNET_PER_CONN_PROXY_BYPASS;
list.pOptions[2].Value.pszValue = "local";
*/
// Set the options on the connection.
bReturn = InternetSetOption(NULL,
INTERNET_OPTION_PER_CONNECTION_OPTION, &list, dwBufSize);
// Free the allocated memory.
free(list.pOptions);
InternetSetOption(NULL, INTERNET_OPTION_SETTINGS_CHANGED, NULL, 0);
InternetSetOption(NULL, INTERNET_OPTION_REFRESH , NULL, 0);
return bReturn;
}
BOOL DisableConnectionProxy(LPCTSTR conn_name)
{
//conn_name: active connection name.
INTERNET_PER_CONN_OPTION_LIST list;
BOOL bReturn;
DWORD dwBufSize = sizeof(list);
// Fill out list struct.
list.dwSize = sizeof(list);
// NULL == LAN, otherwise connectoid name.
list.pszConnection = conn_name;
// Set three options.
list.dwOptionCount = 1;
list.pOptions = (INTERNET_PER_CONN_OPTION*) malloc (sizeof(INTERNET_PER_CONN_OPTION) * list.dwOptionCount);
// Make sure the memory was allocated.
if(NULL == list.pOptions)
{
// Return FALSE if the memory wasn't allocated.
OutputDebugString("failed to allocat memory in DisableConnectionProxy()");
return FALSE;
}
// Set flags.
list.pOptions[0].dwOption = INTERNET_PER_CONN_FLAGS;
list.pOptions[0].Value.dwValue = PROXY_TYPE_DIRECT ;
// Set the options on the connection.
bReturn = InternetSetOption(NULL,
INTERNET_OPTION_PER_CONNECTION_OPTION, &list, dwBufSize);
// Free the allocated memory.
free(list.pOptions);
InternetSetOption(NULL, INTERNET_OPTION_SETTINGS_CHANGED, NULL, 0);
InternetSetOption(NULL, INTERNET_OPTION_REFRESH , NULL, 0);
return bReturn;
}
编译步骤
原始程序是 32 位的,原作者用 VC 编译的,我是在 Debian11 下,用 mingw64 编译的,具体编译步骤如下:
i686-w64-mingw32-gcc SetProxy.c -lwininet -O2 -o setproxy.exe
i686-w64-mingw32-strip --strip-unneeded setproxy.exe
使用方式
setproxy.exe 127.0.0.1:1080 #设置代理服务器
setproxy.exe "" #取消代理服务器
结
比较注册表方式,用起来要稳定的多,就这样开心的用起来了~