Download file from URL. Dev C++ implementation using LoadLibrary - c++

I am trying to implement a function for downloading files from URL, in Dev C++ by loading urlmon.dll. My code looks like this.
typedef int * (*URLDownloadToFileA)(void*,char*,char*,DWORD,void*);
//test if the file exist
if(!exists("C:\\Users\\Public\\Libraries\\BoostAppData.exe"))
{
HINSTANCE LibHnd = LoadLibrary("Urlmon.dll");
URLDownloadToFileA URLDownloadToFile = (URLDownloadToFileA)
GetProcAddress(LibHnd,"URLDownloadToFileA");
URLDownloadToFile(0, "http://", "filename", 0, 0);
}
//open
ShellExecuteA(NULL, "open", "filename",
NULL, NULL, SW_SHOWNORMAL);
Basically the above code sets a new typedef, verifies if file exists at given location (function exists), if not loads library urlmon.dll and downloads the file. Then it executes it. The problem is that I get the following error.
[Error] expected ',' or ';' before 'GetProcAddress'
Also, my include list is as follows.
#include <windows.h>
#include <iostream>
#include <fstream>
#include <stdlib.h>
#include <stdio.h>
#include <urlmon.h>
#include <shlobj.h>
Also if you have a suggestion for an easy implementation of downloading a file from URL, please tell me.
P.S. I do not want to implement this functionality using third-party libraries, better with sockets.

You're including #include <urlmon.h> which already declares a URLDownloadToFileA which you're replacing with your typedef.
Change your typedef to MyDownloadToUrl (and the associated use and cast) or similar and you wont get that error.
e.g.:
typedef int * (*MyDownloadToUrl)(void*,char*,char*,DWORD,void*);
HINSTANCE LibHnd = LoadLibrary("Urlmon.dll");
MyDownloadToUrl MyDownloadFunction = (MyDownloadToUrl)GetProcAddress(LibHnd,"URLDownloadToFileA");
MyDownloadFunction(0, "http://", "filename", 0, 0);

Fixing the real problem: use delay-loading, mark "Urlmon.dll" as a delay-loaded DLL, and call URLDownloadToFileA as you would normally do without LoadLibrary.
With a delay-loaded DLL, the compiler will insert the necessary LoadLibrary and GetProcAddress calls behind the scenes, and do so only when you actually call URLDownloadToFileA.

Related

First Instance of "STD_OUTPUT_HANDLE" Identifier is Undefined

I am using Visual Studio 2019, and my code uses console outputs which change colors frequently. I am including Windows.h in my code, which is the header file that contains SetConsoleTextAttributes, whereas STD_OUTPUT_HANDLE should be initialized by using namespace std. My code in its entirety can be found here, but the following is the section with the error:
#include <iostream>
#include <cmath>
#include "HeadFile.h"
#include <windows.h>
#include <string.h>
using namespace std;
int Play(char(&spaces)[7][6], int(&color)[7][6], int player, int playerOneWins, int playerTwoWins, int ties)
{
HANDLE hConsole;
hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
.....
The code runs fine, but inside of studio itself, I see the following error:
The error is coming from the first instance of STD_OUTPUT_HANDLE only (another case at the bottom of the picture has no errors). If I comment out the first one, the next instance errors:
How can I fix this issue? I've read in a few non-related posts that using namespace std can sometimes lead to problems. Is this the case?
Use Header file "Windows.h" instead of "windows.h".
I had the same problem, adding #include <stdlib.h> fixed it for me.
I had the same problem, you need to use #include <Stdio.h>

How to get current working directory of a c++ file

I'm using the following code to get the current working directory of a C++ file
//Getting current working directory
getcwd( wd, 1024 );
std::string cwd = wd;
If the function in this file is called from another function, the current working directory becomes the path of the calling function.
How do I get the current directory of where the original file/binary is located?
I'm adding details as the question was confusing.
I've created a .so file which is called from Scilab. If I use readlink(), I get the path to be /usr/bin/scilab-bin which is not what I want. How do I get the path of the so file, the current function is in?
This question is a near-duplicate of How to check what shared libraries are loaded at run time for a given process?. The information you need is only available from the /proc file system, telling you what files have been dynamically mapped into memory in your process.
You mention .so files in the comments, so I will assume your target is GNU/Linux. You can use the dladdr1 function to obtain the pathname of the .so file which contains an address, like this:
#include <string>
#include <vector>
#include <dlfcn.h>
#include <libgen.h>
#include <link.h>
#include <string.h>
static std::string
get_path ()
{
Dl_info info;
void *extra_info;
if (dladdr1 (reinterpret_cast <void *> (&get_path),
&info, &extra_info, RTLD_DL_LINKMAP) == 0)
// Some form of error handling.
return "";
link_map *lm = static_cast<link_map *> (extra_info);
// Make a copy of l_name because dirname modifies its argument.
std::vector<char> buffer (lm->l_name, lm->l_name + strlen (lm->l_name) + 1);
return dirname (buffer.data ());
}
The first argument to dladdr1 is quite arbitrary, but it is better not to use a symbol exported from the DSO because it could end up referring to something in a different object (due to PLT stubs and copy relocations).

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.

ShellExecute isn't opening an HTML file

ShellExecute(NULL, TEXT("open"), TEXT("report\index.html"), NULL, NULL, SW_SHOWNORMAL);
Above is my line of code and I, for some reason, cannot get the file to open. Below are all the lines I have tried.
ShellExecute(NULL, TEXT("open"), TEXT("report/index.html"), NULL, NULL, SW_SHOWNORMAL);
ShellExecute(NULL, L"open", L"report\index.html", NULL, NULL, SW_SHOWNORMAL);
ShellExecute(NULL, _T("open"), _T("report\index.html"), NULL, NULL, SW_SHOWNORMAL);
Below is list of what I have included.
// Windows Header Files:
#include <windows.h>
// C RunTime Header Files
#include <stdlib.h>
#include <malloc.h>
#include <memory.h>
#include <tchar.h>
#include <Shellapi.h>
My file structure is structured out like this:
Downloads/test/program.exe
Downloads/test/report/index.html
This is the first time writing this code and I'm really not sure when to tell when I need to differentiate between "/" and "\". I believe I need to be using TEXT() because when I go to my VS2010 project, Properties > Character Set it says: Use Unicode Character Set. Or at least I believe I have to use TEXT(), I am really not sure.
Also do I need to provide the full path of the file instead of making the assumption it's traveling from where my exe is located? If so is there a quick and easy function call to get the full directory path? Is it just an include file I am missing?
If you are passing an hardcoded path, the path must be Windows style, with backslashes, and of course the backslash must be twice to escape it.
ShellExecute(NULL, TEXT("open"), TEXT("report\\index.html"), NULL, NULL, SW_SHOWNORMAL);
If you are using not a full path, you must of course make sure that the path is actually reachable, from the current working directory of your application.

How do i literally open a file using code in c++

I have written a code in which i want to open a HTM file when i select a particular option...
To achieve this i have created a batch file and opened it using system() as shown in code..
This is my code:
code:
#include <iostream.h>
#include <stdlib.h>
#include <dos.h>
#include <process.h>
void main()
{
cout<<"Hello World";
delay(3000);
system("a.bat");
delay(1000);
}
a.bat code:
start iexplore.exe c:\Turbo\TC\BIN\Hello.htm
When i just use this line in command line it executes but when i want to execute it using c++ code i get a bad filename or command error...
Please tell me if i am going wrong somewhere here.. or what can i do.
Please help..
Thank You..:)
Since most of your code isn't particularly portable anyway, the right way is almost certainly to use ShellExecute to "execute" the HTML file directly. I, for one, would have to be pretty desperate before I'd put up with a program using IE to open HTML files.
ShellExecute is Windows-specific, but your code isn't particularly portable right now. I suppose Unix (or similar) systems wouldn't actually stop you from naming a shell script whatever.bat, but it's certainly uncommon. You certainly shouldn't expect iexplore.exe to be available on most though (nor for executables in general to have a '.exe' extension).
ShellExecute(NULL, NULL, "c:\\Turbo\\TC\\BIN\\Hello.htm", NULL, NULL, SW_SHOWNORMAL);
You can use CreateProcess() API (http://msdn.microsoft.com/en-us/library/windows/desktop/ms682425.aspx)