I want to open a file in VS2017 with C++ by using fopen and relative path. But every try I got an error so I look at the absolute path of my relative input:
string ExePath() {
char buffer[MAX_PATH];
GetModuleFileName(NULL, buffer, MAX_PATH);
return buffer;
}
string AbsPath(string path) {
char buffer[MAX_PATH]; strcpy_s(buffer, path.c_str());
char buffer2[MAX_PATH];
GetFullPathName(buffer, MAX_PATH, buffer2, NULL);
return buffer2;
}
int main() {
cout << "Application\t " << ExePath() << "\n";
cout << "\\data.dat\t" << AbsPath(".\\data.dat") << "\n";
system("Pause");
}
I got the output:
Application C:\Users\User\source\repos\Project1\Debug\Project1.exe
\data.dat C:\Users\User\source\repos\Project1\Project1\data.dat
My Application is located in .\Debug\ and my relative path points to \Project1. Do I made an error?
Related
So I am trying to create a function to download a file with a variable address depending on the user with a string input using URLDownloadToFile() however it does not seem to actually download the file to the disk. It skips S_OK, E_OUTOFMEMORY and INET_E_DOWNLOAD_FAILURE to UNKNOWN_ERROR. Using GetLastError() returns 2, checking up online said that meant "Not Found". I'm not sure whether this was the website I was using or not (it's my own server with Node.JS using res.download(path, filename)). Hope for help, the code is below.
Just a note, everything is properly included as needed and the process (safely) runs with SE_DEBUG_NAME so it hopefully should not be a permission error.
// Convert String To Wide String
wstring S2WS(const string& str) {
int length;
int slength = (int)str.length() + 1;
length = MultiByteToWideChar(CP_ACP, 0, str.c_str(), slength, 0, 0);
wchar_t* buffer = new wchar_t[length];
MultiByteToWideChar(CP_ACP, 0, str.c_str(), slength, buffer, length);
wstring out(buffer);
delete[] buffer;
return out;
}
// Download File
int download(string url) {
wstring wUrl = S2WS(url);
LPCWSTR lUrl = wUrl.c_str();
TCHAR path[MAX_PATH];
GetCurrentDirectory(MAX_PATH, path);
HRESULT response = URLDownloadToFile(NULL, lUrl, path, 0, NULL);
if (response == S_OK) {
cout << "S_OK" << endl;
} else if (response == E_OUTOFMEMORY) {
cout << "E_OUTOFMEMORY" << endl;
} else if (response == INET_E_DOWNLOAD_FAILURE) {
cout << "INET_E_DOWNLOAD_FAILURE" << endl;
} else {
cout << "UNKNOWN_ERROR" << endl;
}
return 0;
}
// Example Usage
int main() {
download("http://somewebsite.com/files/textfile.txt");
}
From URLDownloadToFile, the path should be file path not a directory path. You could append some file name to the path variable and it should work.
TCHAR path[MAX_PATH];
GetCurrentDirectory(MAX_PATH, path);
wcscat_s(path, L"\\filename.txt");
I am trying to move the running EXE, but this gives access denied because of running state. I could use MoveFileEx(MOVEFILE_DELAY_UNTIL_REBOOT), but that only acts after rebooting.
Is there any way to do this without waiting for the reboot?
int _tmain(int argc, _TCHAR* argv[]){
WCHAR szFilepath[MAX_PATH];
std::wstring wFilepath;
std::wstring wFilename;
std::wstring wDestpath;
/* Get the current executable's full path */
wFilepath = std::wstring(szFilepath, GetModuleFileNameW(NULL, szFilepath, MAX_PATH));
std::wcout << L"filepath: " << wFilepath << std::endl;
/* Extract just the name */
wFilename = wFilepath.substr(wFilepath.find_last_of(L"\\/") + 1);
std::wcout << L"filename: " << wFilename << std::endl;
/* Set the destination folder path and file name */
wDestpath = L"D:\\" + wFilename;
std::wcout << L"dest path: " << wDestpath << std::endl;
// copys the file of your '.exe'
if (!CopyFileW(wFilepath.c_str(), wDestpath.c_str(), FALSE)) {
std::wcout << L"couldnt copy the file";
}
else {
std::wcout << L"copied";
}
return 0;
}
I am trying to create a program which copy itself while it is running to new location without keeping the orignal file location . once it is copied I got the file without extension , but how can I overcome this ?
int _tmain(int argc, _TCHAR* argv[])
{
TCHAR szFilepath[MAX_PATH];
TCHAR szFilename[MAX_PATH];
TCHAR szDestpath[MAX_PATH];
/* Get the current executable's full path */
GetModuleFileName(NULL, szFilepath, MAX_PATH);
std::wcout << "filepath: " << szFilepath << std::endl;
/* Extract just the name */
GetFileTitle(szFilepath, szFilename, MAX_PATH);
std::wcout << "filename: " << szFilename << std::endl;
//Set the destination folder path
_tcscpy(szDestpath, L"D:\\");
//Set the destination file path
_tcscat(szDestpath, szFilename);
std::wcout << "dest path: " << szDestpath << std::endl;
// copys the file of your '.exe'
if (!CopyFile(szFilepath, szDestpath, FALSE)) {
std::cout << "couldnt copy the file";
}
else {
std::cout << "copied";
}
return 0;
}
Per the documentation for GetFileTitle():
GetFileTitle returns the string that the system would use to display the file name to the user. The display name includes an extension only if that is the user's preference for displaying file names. This means that the returned string may not accurately identify the file if it is used in calls to file system functions.
You should be using a more suitable function to get the actual filename, such as PathFindFileName():
#include <windows.h>
#include <shlwapi.h>
#include <iostream>
int _tmain(int argc, _TCHAR* argv[])
{
WCHAR szFilepath[MAX_PATH];
LPWSTR lpszFilename;
WCHAR szDestpath[MAX_PATH];
/* Get the current executable's full path */
GetModuleFileNameW(NULL, szFilepath, MAX_PATH);
std::wcout << L"filepath: " << szFilepath << std::endl;
/* Extract just the name */
lpszFilename = PathFindFileNameW(szFilepath);
std::wcout << L"filename: " << lpszFilename << std::endl;
/* Set the destination folder path and file name */
PathCombineW(szDestpath, L"D:\\", lpszFilename);
std::wcout << L"dest path: " << szDestpath << std::endl;
// copys the file of your '.exe'
if (!CopyFileW(szFilepath, szDestpath, FALSE)) {
std::wcout << L"couldnt copy the file";
}
else {
std::wcout << L"copied";
}
return 0;
}
Or, you could simply parse the filename yourself using normal C++ string operations, eg:
#include <windows.h>
#include <iostream>
#include <string>
int _tmain(int argc, _TCHAR* argv[])
{
WCHAR szFilepath[MAX_PATH];
std::wstring wFilepath;
std::wstring wFilename;
std::wstring wDestpath;
/* Get the current executable's full path */
wFilepath = std::wstring(szFilepath, GetModuleFileNameW(NULL, szFilepath, MAX_PATH));
std::wcout << L"filepath: " << wFilepath << std::endl;
/* Extract just the name */
wFilename = wFilepath.substr(wFilepath.find_last_of(L"\\/")+1);
std::wcout << L"filename: " << wFilename << std::endl;
/* Set the destination folder path and file name */
wDestpath = L"D:\\" + wFilename;
std::wcout << L"dest path: " << wDestpath << std::endl;
// copys the file of your '.exe'
if (!CopyFileW(wFilepath.c_str(), wDestpath.c_str(), FALSE)) {
std::wcout << L"couldnt copy the file";
}
else {
std::wcout << L"copied";
}
return 0;
}
I found Get DLL path at runtime but I'm not sure what to use for the localFunc variable. I tried the filename of the DLL, I tried null and some other things, but the status returned was always 'File Not Found'.
From the MSDN:
lpModuleName [in, optional]
The name of the loaded module (either a .dll or .exe file), or an address in the module (if dwFlags is GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS).
So I assume they just mean the plain file name eg, "MyControl.dll" and not the path to file, since I do not know the path.
Edit: added the actual code:
char localFunc[MAX_PATH]
sprintf_s(localFunc, 52, "MyActiveXComponent.dll");
if (!GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, (LPCSTR) &localFunc, &hm))
{
int ret = GetLastError();
OutFile << L"GetModuleHandle returned " << ret << std::endl;
} else {
GetModuleFileNameA(hm, path, sizeof(path));
OutFile << L"Path of dll is:" << path << L"<" << std::endl;
}
Here's what I ended up with (performed both ways)
LPCWSTR anotherFunc = L"MyActiveXComponents.dll";
HMODULE hm2 = GetModuleHandle(anotherFunc); // get the handle to the module
LPWSTR anotherPath = new WCHAR[MAX_PATH];
GetModuleFileName(hm2, anotherPath, MAX_PATH); // get the full path
OutFile << L"Path of dll is:" << anotherPath << L"<" << std::endl;
Here's the other way.
char path[MAX_PATH];
HMODULE hm = NULL;
char localFunc[MAX_PATH] = {"MyActiveXComponents.dll"};
if (!GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, LPCSTR) &localFunc, &hm))
{
int ret = GetLastError();
OutFile << L"GetModuleHandle returned " << ret << std::endl;
} else {
GetModuleFileNameA(hm, path, sizeof(path));
OutFile << L"Path of dll is:" << path << L"<" << std::endl;
}
Thanks. I'm sure it is simple question.
Call GetModuleHandle() with the raw name like user32.dll or whatever the name of the DLL is. After you have the handle, call GetModuleFileName() to get the fully qualified name including path.
Has anyone used the FindFirstFile function to scan multiple files of the same type?
int main(int argc, char** argv){
if(argc != 3)
{
cout <<" Usage: Run [dir of images folder] [file format]" << endl;
cout <<" Example: Run \\imgs\\\\ .jpg " << endl;
return 0;
}
WIN32_FIND_DATA FindFileData;
HANDLE hFind;
string dir = argv[1]; // store user input dir
string type = argv[2]; // store user input file type
stringstream sst;
sst << dir << "*" << type;
string folderDir = sst.str();
sst.str("");
cout << "Scanning all " << type << " files in "<< dir << endl;
cout << folderDir << endl;
/* LOADING IMAGES IN FOLDER */
I tried folderDir.c_str() instead of "\imgs\*.jpg" but I can't make it work;
hFind = FindFirstFile("\imgs\\*.jpg", &FindFileData); //images must be in .vcxproj dir
if (hFind != INVALID_HANDLE_VALUE){
int i = 0;
do {
char loc[50] = "\imgs\\"; // Obvsly, I couldn't assign argv[1] here
images.push_back(imread(strcat(loc,FindFileData.cFileName))); //pushes images into vector
img_fname[i] = FindFileData.cFileName; // stores file names into string array
cout << "Successfully loaded " << FindFileData.cFileName << endl; //prints loaded file names
i++;
}while(FindNextFile(hFind, &FindFileData));
}
Also, may I ask help in assigning string dir to char loc[50] = "\imgs\\";?
If only char loc[50] = dir; is possible...
I tried strcpy(loc, dir.c_str()); after instantiating loc but it still failed. Gave me an error (Unrecognized or unsupported array type) in unknown function
i think, it should be only one backslash there:
"imgs\*.jpg" instead of "\imgs\\*.jpg".
this works fine for me ( and gives me the filelist ):
std::vector<std::string> readdir( const char * dmask )
{
std::vector<std::string> vec;
HANDLE hFind;
WIN32_FIND_DATA FindFileData;
if ((hFind = FindFirstFile(dmask, &FindFileData)) != INVALID_HANDLE_VALUE)
{
do {
vec.push_back( FindFileData.cFileName );
} while(FindNextFile(hFind, &FindFileData));
FindClose(hFind);
}
return vec;
}
std::vector<std::string> files = readdir("imgs\*.jpg");