I'm creating a dll on c++. It is a Visual Studio project. The dll reads some data from ini file. I have decided to use GetPrivateProfileString function. It works almost completely. It does not see file in current directory. How can I provide this parameter (variable called path)?
How can I pass last parameter (path)
Code:
LPCTSTR path = L"\\test.ini";
TCHAR protocolChar[32];
int a = GetPrivateProfileString(_T("Connection"), _T("Protocol"), _T(""), protocolChar, 32, path);
String from test.ini:
[Connection]
Protocol = HTTP
I also tried this:
LPCTSTR path = L"test.ini";
But it did not help me
LPCTSTR path = _T(".\\test.ini");
. symbolises current directory. Hope this will work for you.
WCHAR cfg_IniName[256];
GetCurrentDirectory (MAX_PATH, cfg_IniName );
wcscat ( cfg_IniName, L"\\test.ini" );
way to get full path
Related
Well, the title say which is my problem
my .cpp code is:
GetPrivateProfileString("Server","MainDns","ServerDns",
g_DataBaseDns,sizeof(g_DataBaseDns),".\\Server.ini");
when I use:
GetPrivateProfileString("Server","MainDns","ServerDns",
g_DataBaseDns,sizeof(g_DataBaseDns),"..\\Server.ini");
and Put the ini file in the back folder: works normally!
What am I doing wrong?
You need to first call GetFullPathName() to obtain an absolute path, which is required according to the documentation for GetPrivateProfileString():
The name of the initialization file. If this parameter does not contain a full path to the file, the system searches for the file in the Windows directory.
For example:
TCHAR sAbsolutePathBuffer[2048] = _T("");
if (GetFullPathName(TEXT("Server.ini"), sizeof(sAbsolutePathBuffer)/sizeof(TCHAR), sAbsolutePathBuffer, NULL))
{
GetPrivateProfileString(TEXT("Server"), TEXT("MainDns"), TEXT("ServerDns"),
g_DataBaseDns, sizeof(g_DataBaseDns), sAbsolutePathBuffer);
}
I could swear to god that the code below used to work a week ago. I can tell that because the software I develop depends on it.
This code chunk is supposed to open an html page from a local HDD using IE:
(These strings are not hardcoded in my actual example. What it does is this -- it escapes the path to the local html file and adds file:/// in front.)
LPCTSTR m_strBrowser = L"C:\\Program Files (x86)\\Internet Explorer\\iexplore.exe";
LPCTSTR addr2 = L"\"file:///C%3a%5cUsers%5cUserName%5cAppData%5cLocal%5cTemp%5cReport_View.htm\"";
ShellExecute(hMain, NULL, m_strBrowser, addr2, NULL, SW_SHOWNORMAL);
But what I get when I test it today is just the home page in IE.
Any idea what is wrong here?
PS. The Report_View.htm file exists in the file system.
PS2. If I copy and paste the escaped URL into Chrome or FF, it opens just fine.
Well, evidently they made some changes to the IE and now the file protocol URL can no longer contain arbitrary escaping. From my experience, the only way to make it work with IE is by getting the file protocol path by calling the UrlCreateFromPath API:
//You get this path from Registry
LPCTSTR m_strBrowser = L"C:\\Program Files (x86)\\Internet Explorer\\iexplore.exe";
LPCTSTR addr2 = L"C:\\Users\\UserName\\AppData\\Local\\Temp\\Report_View.htm";
DWORD dwSz_buff_addr2 = INTERNET_MAX_URL_LENGTH;
TCHAR buff_addr2[INTERNET_MAX_URL_LENGTH];
if(SUCCEEDED(UrlCreateFromPath(addr2, buff_addr2, &dwSz_buff_addr2, NULL))
{
ShellExecute(hMain, NULL, m_strBrowser, buff_addr2, NULL, SW_SHOWNORMAL);
}
Also I'm not sure the parameter should be quoted in itself (it doesn't have space characters anyway), also not sure about the escaping.
Try:
LPCTSTR addr2 = L"file:///C|/Users/UserName/AppData/Local/Temp/Report_View.htm";
I am attempting to open a .chm file(A windows help file) at a specific page/topic by using a system call in C++.
I can successfully open the .chm file to the start page through the following code, but how can I open a .chm file to a specific page/topic inside the help file?
system("start c:/help/myhelp.chm");
PS: I know system is evil/discouraged but the system part is not really relevant its the command line arguments I pass with the .chm file(that will specify what page I want to open) that I am trying to determine.
Ok the arguments are like so:
system(" /Q /E:ON /C HH.EXE ms-its:myChm.chm::myPageName.htm");
There is an API in the Windows SDK called HtmlHelp in the HtmlHelp.h file. You can call like so:
HtmlHelp(GetDesktopWindow(), L"C:\\helpfile\\::/helptopic.html", HH_DISPLAY_TOPIC, NULL);
The Microsoft Docs - HtmlHelpA function provides more information about the function. HtmlHelp() will normally resolve to HtmlHelpA() or HtmlHelpW() depending on whether Unicode compiler option is set or not.
See as well Microsoft Docs - HTML Help API Overview.
Another option - use ShellExecute. The Microsoft help is not easy to use. This approach is much easier and in line with your question. Here is a quick routine to open a help file and pass an ID number. I have just set up some simple char’s so you can see what is going on:
void DisplayHelpTopic(int Topic)
{
// The .chm file usually has the same name as the application - if you don’t want to hardcode it...
char *CmndLine = GetCommandLine(); // Gets the command the program started with.
char Dir[255];
GetCurrentDirectory (255, Dir);
char str1[75] = "\0"; // Work string
strncat(str1, CmndLine, (strstr(CmndLine, ".exe") - CmndLine)); // Pull out the first parameter in the command line (should be the executable name) w/out the .exe
char AppName[50] = "\0";
strcpy(AppName, strrchr(str1, '\\')); // Get just the name of the executable, keeping the '\' in front for later when it is appended to the directory
char parms[300];
// Build the parameter string which includes the topic number and the fully qualified .chm application name
sprintf(parms,_T("-mapid %d ms-its:%s%s.chm"), Topic, Dir, AppName);
// Shell out, using My Window handle, specifying the Microsoft help utility, hh.exe, as the 'noun' and passing the parameter string we build above
// NOTE: The full command string will look like this:
// hh.exe -mapid 0 ms-its:C:\\Programs\\Application\\HelpFile.chm
HINSTANCE retval = ShellExecute(MyHndl, _T("open"), _T("hh.exe"), parms, NULL, SW_SHOW);
}
The topics are numbered within your .chm file. I set up a #define for each topic so if I had to change the .chm file I could just change the include file to match and not have to worry about searching through the code for hardcoded values.
Suppose that I have a dll called it MyDll.dll
It is in the d:\MyWorks\MyDll.dll [it is directshow dll]
I want to get path of its location from inside the MyDll code.
I used boost for this: FileSystem
string path = "";
boost::filesystem::path full_path( boost::filesystem::current_path() );
path = full_path.string();
But this give me its execution path, which is C:\Windows\system32, and not its location path which is d:\MyWorks\MyDll.dll.
How can I get a dll's location inside the same dll?
Update: By Get Module:
TCHAR path[2048];
GetModuleFileName( NULL, path, 2048 );
ostringstream file;
file << path ;
string const pathString =file.str();
cout << "Path: " << pathString << endl;
Gives me just hex-like string : 0049EA95....
In your DllMain you receive an HINSTANCE parameter; that is actually the HMODULE of your dll, that you can use with GetModuleFileName to retrieve the fully-qualified path of your dll. To get just the directory that contains it you just have to remove the file name (you can do that with boost::filesystem, with shell path functions as well as just with a strrchr).
Your problem is trying to see a Unicode string on an Ansi console output window. If you really want to see the result, you need to cast your strings to Ansi (with some loss of course) or you can directly use;
char path[2048];
GetModuleFileNameA(NULL, path, 2048);
cout << path;
If you want to use Unicode, use TCHAR and GetModuleFileNameW (or GetModuleFileName since your application is in unicode mode) but don't try to output to console window without casting to Ansi.
You can use GetModuleFileName in order to get the full path of a module.
The first argument is a handle to the required module. If this parameter is NULL, GetModuleFileName retrieves the path of the executable file of the current process.
If you want the path to other module, you may use GetModuleHandle to get a handle. For example:
TCHAR path[_MAX_PATH+1];
GetModuleFileName(GetModuleHandle(_T("MyDll.dll")), path, sizeof(path)/sizeof(path[0]));
TCHAR s[MAX_PATH+1];
GetModuleFileName(hInstance, s, _countof(s));
where hInstance is a parameter of DllMain. Despite the name, it returns the full path.
I know that GetCurrentDirectory() and SetCurrentDirectory() functions exist on the MFC framework, but I don't have a CFtpConnection object in my application. I have a simple CWinApp-derived class, and I would like to retrieve its working directory upon program startup. What's the easiest method to achieve this goal? Thanks in advance for the advices.
GetCurrentDirectory is a simple Win32 API function, so just call it like this:
TCHAR currentDir[MAX_PATH];
GetCurrentDirectory( MAX_PATH, currentDir );
I assume you are trying to get the directory where your .exe file is located instead of the current directory. This directory can be different from the current directory.
TCHAR buff[MAX_PATH];
memset(buff, 0, MAX_PATH);
::GetModuleFileName(NULL,buff,sizeof(buff));
CString strFolder = buff;
strFolder = strFolder.Left(strFolder.ReverseFind(_T('\\'))+1);