设置注册表以控制将文件类型与应用程序关联时的工作目录
我使用 Inno 作为安装程序,并且想要将文件类型与我的应用程序关联:
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;
现在,双击 .rpl 文件会启动该应用程序,但工作目录似乎是 .rpl 文件所在的位置,因此应用程序崩溃,因为它无法加载任何数据。 是否可以设置注册表来控制文件关联的启动/工作目录以及启动的应用程序?或者我的应用程序本身是否需要能够解决这个问题?
关键是我总是希望我的 EXE 从 c:\Programs\MyApp 运行。如果您单击快捷方式或手动运行它,那就没问题。我发现的唯一例外是,当您双击与应用程序关联的类型的文件时,Windows 会将 EXE 的工作目录设置为该文件的位置。
这一切背后的问题是我的电脑上有一个开发版本,并且我还像普通用户一样安装发布版本。我需要能够运行开发版本,而无需访问注册表并查找已安装生产版本文件的路径。
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
即使有办法为注册表中指定的应用程序指定不同的工作目录 - 您确实应该在应用程序中修复此问题。原因是有多种方法可以使用您的应用程序打开数据文件,并且您根本无法修复所有这些方法。考虑
其中程序以要作为参数打开的文件名(作为 UNC 路径)启动,在完全不同的目录中执行。我经常做这样的事情,我希望应用程序能够在这些情况下工作。
请注意,启动后首先将工作目录设置为应用程序根路径也不是一个好主意,因为这样相对路径将是错误的。正确的解决方案意味着通过在内部使用完全限定的路径,以无论当前工作目录是什么都可以正确工作的方式更改应用程序。
编辑:
您发表评论
,但事实并非如此。您可以使用
GetModuleFileName()
函数或其在 GUI 库中的等效包装器(如 Delphi 中的Application.ExeName
)。从该路径设置工作目录很容易,我只是认为这不是一个好主意,因为更改工作目录会破坏用户可能期望工作的相对路径。这不是真的因为可以通过多种方式使用与可执行文件本身的路径不同的工作目录来执行应用程序。一个行为良好的程序不会假设它们是相等的。它使得在脚本中或从命令行使用该应用程序变得更加困难。
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
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 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 (likeApplication.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 thatbecause 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.