我想使用该Wininet
功能InternetCheckConnection
检查机器何时连接到互联网并可以访问特定主机.问题是这个函数总是返回false,无论我放在它上面的URL.
在我们的程序中,每次需要发出HTTP请求时都会创建一个新线程,并且可以有多个线程同时运行。我遇到的问题是,如果我已经有两个线程正在运行,它们在InternetReadFile()
调用后循环读取HttpSendRequest()
,任何后续的调用尝试HttpSendRequest()
都会挂在该调用上,所以我最终会继续前面提到的两个线程从它们的连接中读取数据就可以了,但是第三个连接会一直阻塞,HttpSendRequest()
直到超时。
从我自己找到的情况来看,这似乎就是 wininet 的工作方式,正如HTTP 规范所建议的那样:“单用户客户端不应与任何服务器或代理保持超过 2 个连接。 ”
我见过各种程序处理对同一服务器的多个同时下载,但我想他们需要做很多额外的工作才能做到这一点,在管理各种连接或编写自己的 http 接口方面。
如果需要大量额外的复杂性来将其设置为处理两个以上的活动会话,那么我只需将其更改为一次仅处理一两个文件,而将其余文件留在队列中。然而,如果有一些低复杂性的方法允许一次超过两个(我想,我猜每次下载使用一个新进程可能会起作用,但会更混乱),那就更好了;无论如何,它不会同时下载超过 3-5 个,并且每次下载都是根据用户的请求进行的。我读到一些提到注册表黑客改变限制的内容,但这绝对不是我会做的事情。有任何想法吗?
使用WinINet
InternetGetCookie
和InternetSetCookie
函数,在应用程序中获取和设置cookie非常简单,从而通过Web请求WinINet
.
但是,到目前为止我找不到清除cookie的方法.
InternetSetCookie
使用空白数据(L""
或者NULL
)调用没有帮助(无论是否指定cookie名称都尝试过).
试了FindFirst/NextUrlCacheGroup
,DeleteUrlCacheGroup
和也FindFirst/NextUrlCacheEntry
,DeleteUrlCacheEntry
组合.仍然没有运气.
有任何想法吗?
我正在研究一个程序,它需要在加载之前检查页面是否存在(所以没有太多异国情调).
一切正常,但我无法让HttpQueryInfo返回页面的有效状态代码.返回的状态代码是:1875378224
产生问题的代码:
DWORD headerBuffSize = sizeof(DWORD);
DWORD statusCode;
//Check existance of page (for 404 error)
if(!HttpQueryInfo(hRequestHandle,
HTTP_QUERY_STATUS_CODE,
&statusCode,
&headerBuffSize,
NULL))
return 4;
if(statusCode == HTTP_STATUS_NOT_FOUND)
cout << "We got a 404 error" << endl;
cout << "Got Status code: " << statusCode << endl; //1875378224 everywhere
cout << "404 status code: " << HTTP_STATUS_NOT_FOUND << endl; //What it should be getting
Run Code Online (Sandbox Code Playgroud)
我不知道该怎么做; 我已将自己的代码与在线的几个示例进行了比较,看起来它应该可以工作,尽管我可能只是犯了一个愚蠢的错误.
谢谢!
基本上,我想将特定URL的内容(基本上只是字符串形式的HTML代码)下载到我的VB6 String变量中.但是,有一些条件.
我知道URLDownloadToFile函数 - 但是,这需要您将下载的文件/ HTML保存到磁盘上的文件位置,然后才能将其读入String变量,这对我来说不是一个选项,我不想这样做.
另一件事是,如果我需要使用外部库,它必须已经从XP及以后的所有版本的Windows附带,我不能使用我需要发送,打包和分发的控件或库,即使它是免费的,这不是一个选项,我不想这样做.因此,我不能使用MSINET.OCX(Internet传输)控件的.OpenURL()函数(它只是将内容返回到字符串中),因为它没有Windows.
有没有办法能够使用Windows API,URLMON或其他预先加载到Windows中或在Windows中附带的内容,或者完全在VB6(SP6)中执行此操作的方法?
如果是这样,我会很感激方向,因为即使经过一小时的谷歌搜索,我发现的唯一例子是对URLDownloadToFile的引用(需要在放入磁盘之前保存在磁盘上)和MsInet.OpenURL(需要我运送和分发MSINET.OCX,我不能也不想这样做.
当然必须有一种优雅的方式才能做到这一点?我可以在没有问题的VB.NET中做到这一点,但显然没有VB6中.NET框架的奢侈 - 任何想法?
更新:
我发现了这个:http://www.freevbcode.com/ShowCode.asp? ID = 1252然而它说显示的功能可能不会返回整个页面并链接到Microsoft错误报告或解释这个的kb文章.此外,我知道这是基于wininet.dll - 我想知道哪些版本的Windows WinInet.dll打包?Windows XP及更高版本?它是否附带Windows 7和/或Windows 8?
我用来下载wininet的一些函数文件:
Url := source_file;
destinationfilename := destination_file;
hInet := InternetOpen(PChar(application.title), INTERNET_OPEN_TYPE_PRECONFIG,
nil, nil, 0);
hFile := InternetOpenURL(hInet, PChar(Url), nil, 0,
INTERNET_FLAG_NO_CACHE_WRITE, 0);
if Assigned(hFile) then
begin
AssignFile(localFile, destinationfilename);
Rewrite(localFile, 1);
repeat
InternetReadFile(hFile, @Buffer, SizeOf(Buffer), bytesRead);
BlockWrite(localFile, Buffer, bytesRead);
current_size := current_size + bytesRead;
until (bytesRead = 0) OR (terminated = True);
CloseFile(localFile);
InternetCloseHandle(hFile);
end;
InternetCloseHandle(hInet);
Run Code Online (Sandbox Code Playgroud)
我试图确定下载速度,但得到一些奇怪的值:
...
repeat
QueryPerformanceFrequency(iCounterPerSec);
QueryPerformanceCounter(T1);
InternetReadFile(hFile, @Buffer, SizeOf(Buffer), bytesRead);
BlockWrite(localFile, Buffer, bytesRead);
current_size := current_size + bytesRead;
QueryPerformanceCounter(T2);
_speed := round((bytesRead / 1024) / ((T2 …
Run Code Online (Sandbox Code Playgroud) 我用这段代码下载小文件:
Var
ms:TMemoryStream;
begin
ms:=TMemoryStream.Create;
Idhttp1.get('http://mydomain.com/myfile.zip',ms);
ms.SaveToFile('myfile.zip');
ms.Free;
end;
Run Code Online (Sandbox Code Playgroud)
但是文件在存储到磁盘之前保存在RAM中,因此可能难以下载文件> 1Gb,例如.有没有办法按部件下载文件?或者我需要使用WinInet吗?提前致谢!
我们有一段代码可以在ftp服务器上传/下载和列出文件.它使用WinInet来处理FTP命令.它已经好几年了.但是,在Windows 8.1和带有IE 11的Windows 7中,相同的代码有时会返回错误12003.在ftp服务器日志中没有错误.
简单函数用于检查FTP响应中是否存在错误
bool IsLastErrorReallyAnError()
{
int err = GetLastError();
bool isError = true;
if (err == ERROR_INTERNET_EXTENDED_ERROR)
{
isError = false;
DWORD error, size = 0;
::InternetGetLastResponseInfo(&error, NULL, &size);
std::vector<wchar_t> response(size+1);
::InternetGetLastResponseInfo(&error, &response[0], &size);
utils::trace("Backup", "Checking FTP respose", &response[0]);
std::vector<std::wstring> lines;
boost::split(lines, std::wstring(&response[0]), boost::is_any_of(L"\n"));
for (auto it = lines.cbegin(); it != lines.cend(); ++it)
{
// If some response starts with 5?? then it is real error
if (boost::starts_with(*it,L"5"))
{
utils::trace("Backup", "Real FTP error", &((*it)[0]));
isError = true; …
Run Code Online (Sandbox Code Playgroud) 我用来URLDownloadToFile()
将图像从网络服务器下载到桌面上的目录中。如果我不想将图像保存到磁盘,而是想将它们读入内存(例如字节数组或 base64 字符串等),是否有类似的函数URLDownloadToFile()
可以实现此目的?
我正在从VBA加载一些旧的VB函数,并且大多数都已经更新到VB.NET,但是"wininet.dll"中的函数的函数声明似乎没有正确匹配.
我得到的错误是:
抛出异常:托管调试助手,'PInvokeStackImbalance':...
它的长短是声明的参数的长度需要是显式的,并且它与dll中的实际函数不匹配.
我看了这个,我可以通过删除支票来获得,但它会产生"堆栈不平衡",并且随着时间的推移最终会耗尽所有堆栈.此外,这些被称为"非托管"dll,并且已经在http://pinvoke.net上的PInvoke函数wiki上提出了一些声明.这个wiki确实有一些我正在使用的函数调用,但不是全部.其中一些我不得不猜测一些事情,但没有成功.
我从旧代码中复制的大部分更改都是从更改long
为int32
或integer
更改为IntPtr
旧代码中从未使用过的更改.我假设这会使所有整数大小正确(即16/32/64位),这可能是大多数问题所在.但是,有一种情况是改变long
了string()
,这看起来有点奇怪而且没有编译好.
那么,我如何实际查找dll中的函数长度并匹配API?
我查了几件事,但当我尝试在Visual Studio中添加对c:\ windows\system32\wininet.dll的引用到我的VB.NET项目时,它说我无法添加它.这似乎阻止我在Visual Studio中使用Object或Assembly浏览器.它似乎不是COM对象.这里有什么帮助?
作为参考,这是失败的旧代码:
Private Declare Function InternetOpen Lib "wininet.dll" Alias "InternetOpenA" ( _
ByVal Agent As String, ByVal AccessType As Long, ByVal ProxyName As String, _
ByVal ProxyBypass As String, ByVal Flags As Long) As Long
Private Declare Function InternetConnect Lib "wininet.dll" Alias "InternetConnectA" ( _
ByVal hInternetSession As Long, ByVal ServerName As String, ByVal ServerPort As …
Run Code Online (Sandbox Code Playgroud)