c++ - 如何将静态库捆绑到 NSIS 插件中
问题描述
我是 NSIS 和 C++ 的新手。我编写了一个 NSIS 插件来检查带有 VS2010 的 http 请求的许可证。但该插件仅适用于安装了 VS2010 的计算机。我猜原因是像“ws2_32.lib”这样的库没有捆绑在包中。我希望带有此插件的安装包可以在未安装 C++ 的计算机上运行。有什么想法可以解决吗?
非常感谢。这是我的代码。
// dllmain.cpp : Defines the entry point for the DLL application.
#include "stdafx.h"
#include <WinSock2.h>
#include <iostream>
#include <stdlib.h>
using namespace std;
#include <string.h>
#include <stdio.h>
#include "./../nsis/pluginapi.h"
#include <windows.h>
#include <Wincrypt.h>
#pragma comment(lib,"crypt32")
#pragma comment(lib,"./../nsis/pluginapi-x86-unicode.lib")
#pragma comment(lib, "ws2_32.lib")
void __declspec(dllexport) myFunction(HWND hwndParent, int string_size,
TCHAR *variables, stack_t **stacktop,
extra_parameters *extra)
{
g_hwndParent = hwndParent;
EXDLL_INIT();
//读取输入参数
WCHAR szComponent[256];
popstring(szComponent);
//打印参数
WCHAR buf[1024];
//这里能正确打印出来自NSIS的中文信息。
//wsprintf(buf, L"kagula $0=[%s][szComponent]\n", szComponent);
//MessageBoxW(g_hwndParent, buf, 0, MB_OK);
WCHAR urlComponent[256];
popstring(urlComponent);
//wsprintf(buf, L"kagula $0=[%s][urlComponent]\n", urlComponent);
//MessageBoxW(g_hwndParent, buf, 0, MB_OK);
WCHAR ipComponent[256];
popstring(ipComponent);
WCHAR portComponent[256];
popstring(portComponent);
//准备返回参考
int len = (int)wcslen(szComponent);
int input_len = (int)wcslen(szComponent);
//printf("%d\n", input_len);
//char server_id[256];
//for (int i = 0; i <
char* server_id = wchar2char(szComponent);
printf("%d\n", strlen(server_id));
//char* server_id = new char(256);
//for (int i = 0; i < input_len; i++) {
// server_id[i] = szComponent[i];
//}
//to_narrow(szComponent, server_id, 256);
printf("serid %s", server_id);
//打印参数
char* ret = ""; // 返回Http Response
try
{
// 开始进行socket初始化
WSADATA wData;
::WSAStartup(MAKEWORD(2, 2), &wData);
SOCKET clientSocket = socket(AF_INET, 1, 0);
struct sockaddr_in ServerAddr = {0};
char* m_ip = wchar2char(ipComponent);
int m_port = atoi(wchar2char(portComponent));
char* req = wchar2char(urlComponent);
WCHAR bufchar[3069];
//这里能正确打印出来自NSIS的中文信息。
//wsprintf(bufchar, L"kagula $0=[%s][server_id]\n", char2wchar(server_id));
//MessageBoxW(g_hwndParent, bufchar, 0, MB_OK);
printf("req %s", req);
char* urlSend = (char*) malloc(strlen(req) + strlen(server_id));
strcpy(urlSend, req);
strcat(urlSend, server_id);
//strcat(req, server_id);
printf("req %s", req);
ServerAddr.sin_addr.s_addr = inet_addr(m_ip);
ServerAddr.sin_port = htons(m_port);
ServerAddr.sin_family = AF_INET;
int errNo = connect(clientSocket, (sockaddr*)&ServerAddr, sizeof(ServerAddr));
printf("errNo connect %d \n", errNo);
if(errNo == 0)
{
// "GET /[req] HTTP/1.1\r\n"
// "Connection:Keep-Alive\r\n"
// "Accept-Encoding:gzip, deflate\r\n"
// "Accept-Language:zh-CN,en,*\r\n"
// "User-Agent:Mozilla/5.0\r\n\r\n";
char* cookie = " HTTP/1.1\r\nCookie:16888\r\n\r\n";
// strSend = "GET " + req + strSend;
char* gp = "GET ";
char* strSend = (char*) malloc(strlen(gp) + strlen(cookie) + strlen(urlSend));
strcpy(strSend, gp);
strcat(strSend, urlSend);
strcat(strSend, cookie);
// 发送
errNo = send(clientSocket, strSend, strlen(strSend), 0);
if(errNo > 0)
{
//cout << "发送成功" << endl;
}
else
{
//std::cout << "errNo:" << errNo << std::endl;
printf("errNo:");
// return ret;
}
// 接收
char bufRecv[3069] = {0};
errNo = recv(clientSocket, bufRecv, 3069, 0);
if(errNo > 0)
{
ret = bufRecv;// 如果接收成功,则返回接收的数据内容
}
else
{
// std::cout << "errNo:" << errNo << std::endl;
printf("errNo:");
// return ret;
}
}
else
{
errNo = WSAGetLastError();
// std::cout << "errNo:" << errNo << std::endl;
printf("errNo:");
printf(errNo + "");
}
// socket环境清理
::WSACleanup();
}
catch (...)
{
// return "";
}
printf(ret);
// push back on the stack
TCHAR * tchar;
char* ok_str = "ServerId is OK";
if(strstr(ret, ok_str) == NULL) {
tchar = _T("0");
} else {
tchar = _T("1");
}
for (int i = 0; i < len; ++i) {
printf("%d", i);
szComponent[i] += 1;
}
pushstring(tchar);
}
解决方案
我猜原因是像“ws2_32.lib”这样的库没有捆绑在包中。
不,那个东西只被 Visual C++ 链接器使用。在运行时,对应的 DLL 取自C:\Windows\System32\ws2_32.dll
最可能的原因是 C 和 C++ 运行时 DLL。默认情况下,Visual Studio C++ 项目使用到这些库的动态链接。对于安装程序插件,修复的一个好方法是切换到静态 C++ 运行时。右键单击项目,配置属性,C/C++,代码生成,将“运行时库”设置更改Multi-threaded Debug (/MTd)
为调试配置和Multi-threaded (/MT)
发布配置。
PS 我会推荐用于 HTTP 网络的更高级别的库,例如 WinHTTP 或 WinINet。现代互联网已经从http迁移到https。
推荐阅读
- iis - 为什么绝对路径省略http协议?
- python - Pygame - 无法将整个文本放在不同的行中
- python - 如何在if语句中定义一个单词的变量
- powerbi - dax 总结和标量错误的问题
- java - 有没有办法检测用户是否在whatsapp/messenger上成功发送/分享我的应用链接?
- java - 使上传方法返回字符串“上传的文件url”
- tensorflow - Tensorflow Serving:张量维度在服务时发生变化
- php - laravel 重定向路由多个旧的 slug 到新的
- node.js - readFileSync 不将 URL 读取为文件
- javascript - 如何使用 replace() 从字符串中删除逗号和 None