1
votes

Hoping for some help here, as I am tearing my hair out!I'm using Visual Studio 2010.

I have an MFC C++ application to deploy. I have a config.ini file that I'd like referenced when the exe starts. At the moment the user cannot double click on a *.myfile and it open, because the application does not "start in" the application folder (where I am installing the ini file to), and so cannot find the ini. I've tried the following

  • I tried finding info on setting the "start in" folder for the &Open action, but cannot find anything.

  • I can't find any info on setting a registry value of the ini file at installation, since this would be a relative reference depending on the user's choice, and so this doesn't apply.

  • It is unmanaged so the C++/CLI app.config solution doesn't apply.

  • Using the Application Data folder, but this gives me the wrong path - I'm using Windows 7, this is probably why, but I want my deployment to work on Windows XP ++.

  • Reading the app path at start up (from here) (put this in CMyApp::InitInstance().

Code:

CString strPath;
TCHAR* pstrExePath = strPath.GetBuffer (MAX_PATH);
::GetModuleFileName (0, pstrExePath, MAX_PATH);
strPath.ReleaseBuffer();
int pos = strPath.ReverseFind('\\');
strPath = strPath.Left(pos);
strPath += "\\config.ini";

This is the closest, but in debug mode there is a weird "\.\" in the path invalidating it. I could use a #ifdebug but this is messy surely?

Really appreciate any help - thanks!


EDIT:

Using this:

TCHAR szPath[MAX_PATH];
if (SUCCEEDED(SHGetFolderPath(NULL, CSIDL_COMMON_APPDATA, NULL, 0, szPath)))
{
    MessageBox(NULL,szPath, "MyApp", MB_OK|MB_ICONWARNING);
}

I get: "C:\ProgramData" as the szPath. Maybe this is right for debug mode? Or the development machine?

1
Can you explain further how the Application Data folder is not working? This is the best place, as it will have write-access permissions and your program folder will not in Vista and 7. - Mark Ransom
Mark, thanks for replying. I've added more on the App Data folder problem. - Colin
C:\ProgramData is correct for Win7. It'll be different for XP. Edit: and the code you've used should get the different path under XP (i.e. the correct one :) - tinman
Is this the "Users Application Data Folder" in the File System (Setup)? Will it install as: "C:\ProgramData\[manufacturer]\[software]\\" under W7, and as appropriate under other Win OS? Thanks for all the help! - Colin
I don't use the VS deployment tool, but from reading the docs at msdn.microsoft.com/en-us/library/s2esdf4x.aspx I would say no. This is the "Common Application Data Folder", which is probably also the description of CSIDL_COMMON_APPDATA (Common Application Data). It should pick up the correct folder under XP as the installer will just use the same SHGetFolderPath() mechanism to get the correct path during deployment. - tinman

1 Answers

1
votes

Thanks for all the input and prompts. It helped me get to this solution. Hopefully it helps some others to have the info in one place. This solution is a very simple one and probably not for full commercial deployment!

  • In VS2010 in the FileSystem (Setup) put the config file in the User's Application Data Folder \ Productname
  • Set InstallAllUsers to false, so that you don't need conditionals on where your config file is located, based on the user's installation choice
  • In the InitInstance() function add something like the following:

[listbreaker]

TCHAR szPath[MAX_PATH] = {0};
if(SUCCEEDED(SHGetFolderPath(NULL, CSIDL_APPDATA|CSIDL_FLAG_CREATE,NULL,SHGFP_TYPE_CURRENT,szPath))) 
{
    PathAppend(szPath, "\\MyApp\\");
            // Can check to create the directory here
    //if (!PathFileExists(szPath))
    //  CreateDirectory(szPath, NULL);
    PathAppend(szPath, TEXT("MyApp.ini"));
            // can check to create default file here if removed by user
    //if (!PathFileExists(szPath))
        //g_ConfigData.write_default()  // be nice if it could write itself
    //MessageBox(NULL,szPath, "MyApp", MB_OK|MB_ICONWARNING);
}
if (!g_ConfigData.ReadData( szPath ) )
    MessageBox(NULL,"Configuration file cannot be read", "MyApp", MB_OK|MB_ICONWARNING);

Some useful links that really helped me on this are:

I'd appreciate any further help on this, as I'm sure there are more refined and flexible solutions (e.g. handling "All Users" choice on installation).