9

我已经阅读了无数关于这个主题的帖子,但无法将我的大脑包裹在整个事情上。我有一个旧的 VB6 应用程序,它曾经安装在根目录的文件夹中。在该文件夹中有子文件夹:用于访问数据库的
\data子文件夹
\quotes将存储用户生成的 Word 文档的子文件夹和 \backup我的程序定期备份 mdb 的副本的位置

它工作得很好,生活很简单。现在,当我们尝试在 Windows 7 和 Windows 8 上安装时,程序会安装到程序文件 (x86) 文件夹中。程序运行良好,但所有数据库更新和 word 文件都存储在 users 文件夹中的虚拟存储中,这不是我们想要的。

我知道为什么会发生这种情况,并且我知道我需要修改我的程序以适应 Windows 7/8。有人可以就以下操作给我一个明确的解释/建议:

我知道“用户”下的 appdata 文件夹是存储数据库/word 文件/备份的推荐位置。但是,在我隐藏的系统上,我希望用户可以轻松访问它(不隐藏),所以我在想 MyDocuments 文件夹?

我读过这个帖子:我应该在哪里存储应用程序特定的设置?这让我对如何在代码中找到文件/位置有了一些了解,尽管目前尚不清楚如何找到 MyDocuments。 任何人都可以帮忙吗?

这是我变得更加困惑的地方。如果我想使用 MyDocuments\CompanyName 之类的东西,甚至是上面链接中提到的 Appdata 文件夹, 我如何告诉包/部署向导将 mdb 文件和上面提到的文件夹安装到这个特定文件夹中? 我可以使用 PDW 中的 Appdata 或 MyDocuments 文件夹的宏吗?我在 XP 机器上,所以我的路径与 Windows 7/8 机器不同。

任何帮助/见解将不胜感激。

4

2 回答 2

7

我知道为什么会发生这种情况,并且我知道我需要修改我的程序以适应 Windows 7/8。

好,那我会尽量不打死马(虽然这是我经常喜欢给一个很好的鞭打,因为很多人误解它)。我只想指出,即使在旧版本的 Windows 上,您的程序也能正常运行,这是一个潜在错误的幸运结果。“Program Files”文件夹从来都不是可写的。您不只是在解决较新版本的 Windows 的一些愚蠢的“问题”。这是从一开始就应该做的事情。

我知道“用户”下的 appdata 文件夹是存储数据库/word 文件/备份的推荐位置。但是,在我隐藏的系统上,我希望用户可以轻松访问它(不隐藏),所以我在想 MyDocuments 文件夹?

我知道这很复杂,所以让我看看是否可以尝试使其尽可能简单……

应用程序数据”文件夹用于存储供您的应用程序内部使用的数据,而不是供用户直接查看或操作的数据。

我的文档”文件夹用于存放用户应该能够看到和直接操作的所有内容;换句话说,用户数据而不是应用程序数据。

然后还有这两种文件夹类型的每个用户和全局变体。在“应用程序数据”的情况下,每个用户的变体进一步细分为本地(仅保留在本地计算机上)和漫游(跟随用户帐户到她登录的网络上的任何计算机)。

因此,如果您希望文件“易于用户访问”,那么您绝对应该使用“我的文档”文件夹。这就是它的用途——用户文档。

存在所有这些复杂规则的原因是,微软和 Adob​​e 等流行供应商的行为不端的应用程序有(有?)倾向于将垃圾转储到用户的“我的文档”文件夹中,用户从未打算与之交互的东西直接地。然后,用户将打开他们的文档文件夹并看到一堆他们从未放在那里的东西。“这些都是什么东西?这些不是我的。我的文件呢?” 上周我更新她的电脑时,我妈妈刚刚问过我这个问题。

目前尚不清楚如何找到 MyDocuments。任何人都可以帮忙吗?

从VB 6?简单的方法是BobMark在您查看的问题中建议的方法。这涉及创建一个 Shell 对象并查询它以获取您感兴趣的文件夹的位置。

缺少的部分是与“我的文档”文件夹对应的常量。您将在此处找到完整的常量列表。您想要的名称ssfPERSONAL(因为在过去创建此 API 时,Windows 不那么友好,并且尚未发明“我的文档”名称),其值为&H05. 所以代码看起来像:

Const ssfPERSONAL = &H05

Dim strMyDocsPath As String
strMyDocsPath = CreateObject("Shell.Application").NameSpace(ssfPERSONAL).Self.Path

如果我想使用 MyDocuments\CompanyName 之类的东西,甚至是上面链接中提到的 Appdata 文件夹,我如何告诉包/部署向导将 mdb 文件和上面提到的文件夹安装到这个特定文件夹中?我可以使用 PDW 中的 Appdata 或 MyDocuments 文件夹的宏吗?

Bob 在他的回答中没有涵盖的内容不多,除了建议您在更新此 VB 应用程序时,您还可以考虑放弃过时的 PDW 以支持更好的安装程序。

就个人而言,我是Inno Setup的忠实粉丝它是一个免费的 Windows 应用程序安装实用程序,它提供的功能比你能动摇的还要多。它适用于 VB 6 应用程序。我自己为此使用了很多次。我认为它相当容易使用,至少对于基础来说是这样。它支持各种高级自定义,如果您没有通过阅读文档来很好地学习,其中一些可能会很棘手,但这一切都非常可行。我什至偶然发现了编写 Delphi 代码来自定义 Inno Setup 项目的方式!

在 Inno Setup 中,您可以使用预定义的常量之一访问系统文件夹的路径。例如,{userdocs}{commondocs}。这些工作很像 PDW 中的宏(如果不完全像,那已经很长时间了)。

当然,这仍然不能解决 Bob 正确指出的问题:用户的“我的文档”文件夹的概念对于安装程序并没有多大意义。当然,您可以访问全局(公共)“我的文档”文件夹,因为它在所有用户之间共享,但这可能不是您想要的。安装程序应该能够由任何具有足够权限的用户运行,实际上这通常是一个管理员帐户,不同于用于运行应用程序的常规用户帐户。您不能在设置期间假设特定的用户帐户,您的设计必须考虑到这一点。

在我看来,“模板”方法对您来说是个好方法。用于设置新用户帐户的完整文件集可以存储在“Program Files”文件夹中。这实际上是一个很好的地方,因为它在那里得到了很好的保护,不会被错误修改,而且你只会阅读从中可以保证您拥有必要的权限。当应用程序在新用户帐户下首次启动时,它可以检测到这一事实并提供设置新用户帐户以与应用程序一起使用。此时,您知道您在正确的用户帐户下运行,因此您可以使用上面的代码查询该用户的“我的文档”文件夹的位置。将所需的文件夹结构全部设置在“程序文件”中应用程序文件夹的子目录中,设置新用户帐户就像复制该文件夹一样简单。如果您需要从用户那里收集信息或提供自定义选项,您可以编写一个小的“首次运行向导”。

于 2013-03-20T21:58:07.890 回答
4

我知道“用户”下的 appdata 文件夹是存储数据库/word 文件/备份的推荐位置。但是,在我隐藏的系统上,我希望用户可以轻松访问它(不隐藏),所以我在想 MyDocuments 文件夹?

这两个都是每个用户数据的位置。因此,您的安装程序不能在此处放置任何内容,因为在正常情况下,它甚至不会在目标运行时用户下运行,并且不知道该数据的目标是哪一个。

相反,您需要决定哪些文件是每台计算机的,哪些是每用户的。任何每用户文件都应由您的应用程序在“首次运行”时创建或复制,它通常应通过检查每用户应用程序文件夹中是否存在每用户 INI 文件来检测(它还需要创建)在 LocalAppData 下。

每台机器的文件进入安装程序在 ProgramData (CommonAppData) 下创建的文件夹。在大多数情况下,您的安装程序不仅需要创建此“公司/应用程序”子文件夹,还需要在文件夹上设置安全性,以允许用户对放置在那里的项目具有所需的访问权限。然后安装程序可以将任何已部署的每台机器数据(如设置文件、MDB 等)放入此文件夹。

一个例外可能是您的首次运行操作复制到用户配置文件中的每台机器“模板”文件,或在应用程序生命周期内只读的其他数据。这些仍然可以转储到 EXE 旁边的 Program Files 子文件夹中(或子文件夹等)。

PDW 太旧太原始,无法完成所有所需的安装活动。这并不意味着您不能破解 setup1.vbp(通过安装 VB6 和 PDW 提供)来进行自定义 setup1。但通常这不值得麻烦,因为您无法扩展 PDW 的“向导”以拥有新屏幕并接受新信息。

随着 Windows Installer 在 1998 年问世,Microsoft 发布了一个名为 Visual Studio 6.0 Installer 1.0(以及一年后的 1.1)的免费更新工具来补充/替换 PDW。

Microsoft 不再托管包含 VSI 1.1 的两个下载文件,尽管您可能仍会找到由 3rd 方托管的副本(尽管病毒扫描类似)。

您还可以在更新版本的 Visual Studio 中使用 Installer 项目类型(尽管我相信他们从 VS 2012 开始使用它)。还有诸如 WiX 工具套件和基于第 3 方安装程序的工具之类的东西。

但即使使用 VSI 1.1,您也会发现许多需要让您的包执行的操作无法在 VSI 1.1 中指定,这意味着您必须对 MSI 数据库进行一些构建后的调整。您可以使用 Installer SDK 中的 Orca 或通过使用 Windows Installer 的自动化界面进行这些构建后编辑的 WSH 脚本来执行此操作。

我读过这个帖子:我应该在哪里存储应用程序特定的设置?这让我对如何在代码中找到文件/位置有了一些了解,尽管目前尚不清楚如何找到 MyDocuments。任何人都可以帮忙吗?

您可以通过其自动化接口或 API 调用使用 Shell 操作。该位置是通过 、 或 常量请求的ssfPERSONALCSIDL_PERSONAL具体FOLDERID_Documents取决于您决定进行哪个调用来获取它。

于 2013-03-20T21:18:35.790 回答