Download URL File from Direct Download URL? | C++ - c++

So basically i'm trying to Download a File from a URL (NOT FROM A HTML/PHP) from a direct download link, example: https://cdn.discordapp.com/attachments/0/0/file.txt. I want my program to download a certain file from a direct download link in the same directory where the application was ran, i know this is possible in C# using WebClient.DownloadFile but I'm not exactly sure on how to use something similar in C++. If you could help that would be amazing, thank you and have a great day.

In my opinion, you could use URLDownloadToFile to download files from the url.
I opened the link you gave but the webpage reported an error and did not find any txt. Therefore, you could refer to the following example:
#include <iostream>
#include <urlmon.h>
#pragma comment(lib,"urlmon.lib")
using namespace std;
int main()
{
HRESULT hr = URLDownloadToFile(0, L"http://pic104.nipic.com/file/20160715/6171480_185807154956_2.jpg", L"D:\\testfolder\\sky.jpg", 0, NULL);
if (hr == S_OK)
{
cout << "ok" << endl;
}
return 0;
}
Of course, you could use the third-party library, such as libcurl.

Related

Stopping an exe file from being run C++

I am creating an application to manage other applications or exe files on a user's computer, and stop them from accessing them at certain times (like ColdTurkey's application blocking feature).
The way I am trying to do this has not been working so far - I attempted to do this by opening the file dwShareMode set to 0 using the CreateFile function. This seems to work for files such as text files and does not allow the file to be opened, however this is not the case if I try and do this same approach on exe files, and the user is free to open the file.
I assume that exe files are not 'read' in the same way by Windows as a text file is read by notepad and that that means setting the dwShareMode to 0 does not affect it being opened, however I do not know what the difference between these are. Any help would be appreciated.
Code here (for the text file):
#include <windows.h>
#include <string>
#include <iostream>
using namespace std;
int main()
{
HANDLE test;
test = CreateFile("test.txt",
GENERIC_WRITE,
0,
NULL,
CREATE_NEW,
FILE_ATTRIBUTE_NORMAL,
NULL);
cout << "press enter to stop blocking application: ";
string b;
getline(cin, b);
cout << endl;
CloseHandle(test);
return 0;
}
Your code works fine for me to block execution of the file. You do need to specify OPEN_EXISTING instead of CREATE_NEW (because you're not trying to create a new file here).
Not a windows expert -- I'm used to Unix/Linux and use the Cygwin package so I can program "in Unix" on my Windows desktop -- but it looks to me like you need to set the lpSecurityAttributes parameter, the one that comes after dwShareMode.
I think the following page might be helpful:
https://msdn.microsoft.com/en-us/library/windows/desktop/aa364399(v=vs.85).aspx

Getting created, last accessed and last modified times from locked files in C++

I am currently trying to fix a bug on a legacy application code in which it uses basically GetFileTime function to retrieve file information through a HANDLE obtained by using CreateFileW function.
Problem arises when it attempts to work with files that are already opened by other processes like *.ldf and *.mdf files which are opened by SQL Server. An error is thrown when trying to get the file HANDLE.
As an alternative, I noticed that boost library is being used as a dependency in the project so I found the following code sample working:
#include <boost/filesystem.hpp>
using namespace boost::filesystem;
path filePath("path/to/the/file.ext");
std::cout << file_size(filePath) << "\n"; // Getting file size
std::cout << last_write_time(filePath) << "\n"; // Getting write/modified time
Using that piece of code we get the file size and the last write time. However, I still need the created and last accessed times. Any ideas how can I achieve it?
Boost FileSystem doesn't seem to support retrieving the creation/last accessed times for a file.
Under the circumstances, I'd probably use FindFirstFile (and FindClose) to get the information you want:
WIN32_FIND_DATA GetFileInfo(char const *path) {
WIN32_FIND_DATA data;
HANDLE h;
h = FindFirstFile(path, &data);
FindClose(h);
return data;
}
This doesn't require opening the file, so it can retrieve data about a file, even if that file is currently open in another process.

C++, download file in directory

So I have this simple code to download a file from an url opening the browser
#include <iostream>
#include<Windows.h>
#include<string>
using namespace std;
int main()
{
string dwnld_URL = "http://www.url.com/downloadpage";
ShellExecuteA(NULL, "open", dwnld_URL.c_str(), NULL, NULL, SW_SHOWNORMAL);
return 0;
}
But I want the file to go in the current directory instead of going in the default download folder. Is there any way I can do this?
if you're on windows, you can use
#include <iostream>
#include<Windows.h>
#include<string>
#pragma comment(lib, "urlmon.lib")
using namespace std;
int main()
{
string dwnld_URL = "http://www.url.com/downloadpage/filename.txt";
string savepath = "C:\\tmp\\filename.txt";
URLDownloadToFile(NULL, dwnld_URL.c_str(), savepath.c_str(), 0, NULL);
return 0;
}
Read more about HTTP and URLs first.
You want some HTTP client library; you could consider libcurl, but both Qt and POCO have some functions for HTTP client. And probably Windows might have some specific functions around that.
All three libcurl, Qt, POCO are free software libraries, and can run also on Linux and POSIX systems.
If you need an HTTP server library (which does not seem the case), you could find some also (e.g. Wt, libonion, ...)
Regarding your comment (which should have gone into your question) "but how can I know"?, an intuition could be, for remote data access, to focus on protocols.
Whatever library (or framework) you are using, you'll need to spend many hours or days to study it and read its documentation and tutorials.

Best method copying folders in C++ on Windows 7

I am working on a simple program to copy all files in folders from one drive to another using C++. Using the Windows API function CopyFile(). I have used the following code:
#include <iostream>
#include <windows.h>
int main()
{
std::cout << "File Copier Version 1";
CopyFile("U:\\whateverfile.file","U:\\whateverfile2.file",0);
return 0;
}
What is the best way to handle copying an entire directory and all the files in it? Any other advice on this? Problems I may encounter?
If you wish to do it on Windows with progress display and other features, without putting too much effort into it, look up IFileOperation::CopyItem. However, it requires Vista or later.

Please help: Legacy database programming in Visual C++ with ADODB

I am maintaining a legacy codebase and need to write a small console application in Visual C++ 6 that accesses a SQL Server database via ADODB. I am an experienced C/C++ developer, but haven't spent much time with MS C++, which as far as I can tell is totally different than g++ and chock full of nonstandard language extensions.
Whenever I try to follow a tutorial on the web, I get a zillion errors. It doesn't recognize a whole bunch of identifiers (e.g. CComPtr, HRESULT, _RecordsetPtr, etc.) and I'm pretty sure the problem is I'm somehow setting up my project wrong. I have tried basically every console app AppWizard available, and none will make the demo code I found work.
Can someone explain to me how I set up a Visual C++ 6 application that can, for example, do a count(*) from a DB table? I am thinking my problem has something to do with non properly including various ATL or whatever libraries that ADODB depends on... I've figured out how to #import msado15.dll but still no dice.
Please help!!! Thanks in advance,
Jason
UPDATE: have now gotten it to compile, but am getting a "Debug Assertion Failed" when I try to open my ADO connection. It comes from atlbase.h line 474 and the assertion is "p != 0".
UPDATE 2: Here's my code
#import "C:\Program Files\Common Files\System\ADO\msdo15.tlb" no_namespace rename("EOF","A_EOF")
#include "stdafx.h"
#include <objbase.h>
#include <initguid.h>
#include <comdef.h>
#include <atlbase.h>
#include <adoid.h>
#include <adoint.h>
int main(int argc, char* argv[])
{
HRESULT hr;
CComPtr<ADORecordset> m_pSet;
CComPtr<ADOConnection> m_pConn;
char ret[128];
CComBSTR connstr = (CComBSTR) "driver=SQL Server;server=SQL1;uid=ffffddddd;pwd=aaaasss;database=MyDB";
CoCreateInstance(CLSID_CADOConnection, NULL, CLSCTX_INPROC_SERVER, IID_IADOConnection, (LPVOID *) &m_pConn);
CoCreateInstance(CLSID_CADORecordset, NULL, CLSCTX_INPROC_SERVER, IID_IADORecordset, (LPVOID *) &m_pSet);
printf("Here %d!\n", (int) &m_pConn);
m_pConn->Open(connstr, (CComBSTR) "", (CComBSTR) "", adOpenUnspecified);
//m_pConn->ConnectionString = connstr;
//m_pConn->Open("","","",NULL);
printf("Here!\n");
m_pSet->Open(CComVariant((CComBSTR) "SELECT COUNT(*) AS Cnt FROM VARIANCESWAP_INDIC"), CComVariant(m_pConn), adOpenKeyset, adLockOptimistic, adCmdText);
CComPtr<ADOFields> pFields = NULL;
m_pSet->get_Fields(&pFields);
CComPtr<ADOField> cnt = NULL;
pFields->get_Item(CComVariant(0), &cnt);
CComVariant dbValue;
cnt->get_Value(&dbValue);
sprintf(ret, "%S", dbValue.bstrVal);
if(m_pSet != NULL) m_pSet->Close();
if(m_pConn != NULL) m_pConn->Close();
printf("Hello World!\n");
return 0;
}
If you're not getting a definition for HRESULT then you probably have not #included <windows.h>.
Google is your friend. Search for missing types and generally some kind soul, or MSDN, will tell you what file you need to include in your program to get it working.
Make sure you check the HRESULT return values from your function calls, specifically the CoCreateInstance calls here. I suspect they are failing because it looks like you haven't called CoInitialize, but check what error code you get.
You haven't initialized COM.
Also, you are not checking the return values of COM calls like CoCreateInstance or Open. You are supposed to check the result of each COM call.
Suggested reading
Using ADO with Microsoft Visual
C++
KB183606 ActiveX Data
Objects (ADO) Frequently Asked
Questions