views:

143

answers:

1

I'm using Inno for an installer, and I want to associate a file type with my app:

Root: HKCR; Subkey: ".rpl"; ValueType: string; ValueName: ""; ValueData: "MyReplay"; Flags: uninsdeletevalue;
Root: HKCR; Subkey: "MyReplay"; ValueType: string; ValueName: ""; ValueData: "Replay File"; Flags: uninsdeletekey;
Root: HKCR; Subkey: "MyReplay\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\bin\MyApp.ico,0"; Flags: uninsdeletekey;
Root: HKCR; Subkey: "MyReplay\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\bin\MyApp.exe"" ""%1"""; Flags: uninsdeletekey;

Right now, double-clicking a .rpl file launches the app, but the working dir appears to be where the .rpl file is located, so the app crashes as it can't load any data. Is it posible to set the registry to control the start/working dir for file associations as well as the app that is launched? Or does my app itself need to be able to work around this?

The point is I always want my EXE to run from e.g. c:\Programs\MyApp. If you click a shortcut or run it manually this is fine. The only exception I can find is when you double click on a file of a type associated with the app, Windows sets the working dir of the EXE to the location of that file.

The problem behind all this is I have a development build on my PC, and I also install the released version as a normal user would. I need to be able to run the dev version without it going to the registry and finding paths to the installed production version's files.

+1  A: 

Even if there is a way to have a different working directory for your application specified in the registry - you should really fix this in the application. The reason is that there are multiple ways to open a data file with your application, and you simply can't fix it for all of them. Consider

D:\> c:\Programs\MyApp\MyApp.exe \\public\foo\data.ext

where a program is started with the name of the file (as UNC path) to open as a parameter, executed in a completely different directory. I do stuff like that regularly, and I expect applications to work under these circumstances.

Note that setting the working directory to the application root path first thing after start isn't a good idea either, as then relative paths will be wrong. A proper solution means changing the application in a way that it works correctly from whatever the current working directory happens to be, by using fully qualified paths internally.

Edit:

You comment

But then this means my app is totally dependent on the registry. Which is a pain for development testing, if every time I run my dev build it goes and loads all the files for the installed version

but that isn't necessarily so. You can read the path to the currently running executable, by using the GetModuleFileName() function or its equivalent wrapper in the GUI library (like Application.ExeName in Delphi). Setting the working directory from that path is easy, I just don't think it is a good idea, as changing the working directory breaks relative paths the user may expect to work. It isn't really true that

Windows runs the EXE from the location of the file you double-click. This seems to be the exceptional case, in other cases the EXE always runs from where I expect.

because there can be many ways how the application can be executed with a different working directory than the path to the executable itself. A well-behaved program doesn't make the assumption that these are equal. It makes using the application in scripts or from the command line so much harder.

mghie
But then this means my app is totally dependent on the registry. Which is a pain for development testing, if every time I run my dev build it goes and loads all the files for the installed version.
John
"D:\> c:\Programs\MyApp\MyApp.exe \\public\foo\data.ext" - I don't see the issue here. The point is I _always_ want my EXE to run from c:\Programs\MyApp\. Loading the external file is fine, the problem is when you associate a file type, Windows runs the EXE from the location of the file you double-click. This seems to be the exceptional case, in other cases the EXE always runs from where I expect.
John
This is a windows GUI app. I can only see two use-cases - you double-click the shortcut, or you double-click an associated file and Windows launches the app.
John
John, mghie is expressing that in the case he described, the working directory will be "D:\", not the application directory. The correct way to handle this **is** to use Win32 APIs (e.g. GetModuleFileName) to identify the module's path at runtime - not to rely on the current working directory, which can never be guaranteed to be what you want to it be. Also it should be noted that the current working directory can change during the lifetime of your process (for instance, due to invoking common file dialogs.)For details, see http://msdn.microsoft.com/library/ms683197.aspx
hemp
@John: I do a lot of stuff on the command line, and for me there simply isn't a difference between a GUI and a non-GUI app. I can start both from the command line, and I do. Your users **will** find ways to use your application that you didn't think of. Your not being able to control what the working directory is is just a part of that.
mghie
how often do you decide to run MSWord from the command-line? My users are not developers or even experienced PC users, they will install the app and run it. Of course technically you could break it by going to c: in a command prompt and typing "program files\myapp\myapp.exe" but it's not a required use-case...
John
@John: Then you should be totally fine with setting the working directory immediately at program start, problem solved.
mghie
I guess, but it seems ugly. I'd hoped I could tell Windows to set the working dir for me when launching the associated app for a file.
John