31

类人猿同胞、睡莲和桨轮!

我正在使用 VS 2008 在 C#/.NET/WPF 中开发一个 Windows 桌面应用程序。该应用程序需要在 Vista 和 XP 机器上安装和运行。我正在使用安装程序/Windows 安装程序项目来安装该应用程序。

我的应用程序需要对 SQLCE 数据库文件 (.sdf) 和与我正在使用的第三方控件相关的一些其他数据库类型文件的读/修改/写访问权限。这些文件应在 PC 上的所有用户/登录名之间共享,其中任何一个都不需要成为管理员。当然,这意味着文件不能放在程序自己的安装目录中(就像在 Vista 到来之前经常发生的那样,是的,是的!)。

我原以为解决方案很简单。Vista 和 XP 都有用于此目的的共享应用程序数据文件夹。(Vista 中的“\ProgramData”,XP 中的“\Documents and Settings\All Users\Application Data”。) .NET Environment.GetFolderPath(SpecialFolder.CommonApplicationData) 调用可用于在给定 PC 上查找这些文件夹的路径,是的, 是的!

但我不知道如何将 shared-application-data 文件夹指定为安装项目中的目标。

Setup 项目提供了一个“Common Files”文件夹,但该文件夹用于共享程序组件(不是数据文件),通常位于“\Program Files”下,并且具有与“\Program files”中其他任何内容相同的安全限制,是的是的!

安装项目提供了一个“用户的应用程序数据”文件夹,但这是一个每个用户的文件夹,这正是我想要避免的,是的,是的!

是否可以从 VS 2008 安装项目以强大的跨 Windows 版本的方式将文件添加到 shared-app-data 文件夹?谁能告诉我怎么做?

4

7 回答 7

20

我已经通过其他来源了解了我的问题的答案,是的,是的!可悲的是,它并没有解决我的问题!是什么让我——一个固定鞋面?是的是的!

要将内容放在 VS2008 安装项目的 Common Application Data 文件夹的子目录中,您可以执行以下操作:

  1. 在解决方案资源管理器中右键单击您的设置项目,然后选择“查看 -> 文件系统”。

  2. 右键单击“目标机器上的文件系统”并选择“添加特殊文件夹 -> 自定义文件夹”。

  3. 将自定义文件夹重命名为“通用应用程序数据文件夹”。(这不是将用于生成文件夹的名称,它只是为了帮助您保持直截了当。)

  4. 将文件夹的 DefaultLocation 属性更改为“[CommonAppDataFolder][Manufacturer]\[ProductName]”。请注意与应用程序文件夹的 DefaultLocation 属性的相似之处,包括奇怪地使用单个反斜杠。

  5. 惊叹于可笑(但不可否认)的事实,即有一个名为“Property”的文件夹属性。

  6. 将文件夹的 Property 属性更改为“COMMONAPPDATAFOLDER”。

放置在“Common Application Data”文件夹中的数据文件将被复制到“\ProgramData\Manufacturer\ProductName”(在 Vista 上)或“\Documents and Settings\All Users\Application Data\Manufacturer\ProductName”(在 XP 上)。安装程序运行。

现在事实证明,在 Vista 下,非管理员无法对此处的文件进行修改/写入访问。因此,所有用户都可以阅读文件,但他们也可以在“\Program Files”中获得这些文件。那么,我想知道 Common Application Data 文件夹的意义是什么?

于 2008-10-01T20:02:58.470 回答
10

无需检查“启用 ClickOnce 安全设置”并选择“这是一个完全信任的应用程序”,可以使用安装项目的“安装”部分下的自定义操作来更改应用程序的 CommonAppDataDirectory 的权限。这是我所做的:

  1. 添加了一个自定义操作来调用正在安装的应用程序(或者您可以创建一个单独的程序/dll 并调用它)
  2. 将参数属性设置为“安装”
  3. 修改 Program.cs 中的 Main 以检查该 arg:

    static void Main(string[] args) { if (args != null && args.Length > 0 && args[0] == "Install") { ApplicationData.SetPermissions(); } else { // Execute app "normally" } }
  4. 编写了 SetPermissions 函数以编程方式更改权限

    public static void SetPermissions() { String path = GetPath(); try { // Create security idenifier for all users (WorldSid) SecurityIdentifier sid = new SecurityIdentifier(WellKnownSidType.WorldSid, null); DirectoryInfo di = new DirectoryInfo(path); DirectorySecurity ds = di.GetAccessControl(); // add a new file access rule w/ write/modify for all users to the directory security object
    ds.AddAccessRule(new FileSystemAccessRule(sid, FileSystemRights.Write | FileSystemRights.Modify, InheritanceFlags.ObjectInherit | InheritanceFlags.ContainerInherit, // all sub-dirs to inherit PropagationFlags.None, AccessControlType.Allow)); // Turn write and modify on // Apply the directory security to the directory di.SetAccessControl(ds); } catch (Exception ex) { MessageBox.Show(ex.Message); } }

由于安装程序以管理员权限运行,因此程序将能够更改权限。我在某处读到“启用 ClickOnce 安全性”可能会导致用户在应用程序启动时看到不需要的提示。如上所述进行操作将防止这种情况发生。我希望这可以帮助别人。我知道我可以从几天前看到这样的事情中受益!

于 2010-12-08T21:12:45.360 回答
6

我是这样解决的。我将数据库文件 (.sdf) 保存在与应用程序安装位置(应用程序文件夹)相同的文件夹中。在主项目属性窗口的安全选项卡上,我检查了“启用 ClickOnce 安全设置”并选择“这是一个完全信任的应用程序”,重建并运行设置。之后没有安全问题

我正在使用 Visual Studio 2008 和 Windows Vista

于 2009-01-29T04:05:43.120 回答
1

这对我使用 VS2005 有效,但我必须更改 DefaultLocation,我添加了一个“\”来分隔 CommonAppDataFolder。

[CommonAppDataFolder]\[Manufacturer]\[ProductName]

不知道这是否是一个错字,但莱曼确实提到了单个反斜杠的奇怪使用,但这似乎不正确。

于 2008-12-17T11:36:33.430 回答
1

我遇到过同样的问题。安装项目让用户可以选择“仅为当前用户”或“为所有用户:”安装应用程序。因此,数据库文件最终将位于当前用户或所有用户应用程序数据文件夹中。安装程序将必须在某处写入此信息,以便应用程序稍后在访问数据库时检索它。否则它怎么知道要查看哪个应用程序数据文件夹?

为了避免这个问题,我只想将数据库安装在 All Users/Application Data 文件夹中,无论应用程序是为一个用户还是为所有用户安装的。当然,我意识到两个用户无法在不覆盖彼此数据的情况下将应用程序安装在同一台计算机上。不过,这种可能性很小,我不想考虑。

我在这里得到的第一块拼图:

Form_Load(object sender, EventArgs e)
{
  // Set the db directory to the common app data folder
  AppDomain.CurrentDomain.SetData("DataDirectory", 
            System.Environment.GetFolderPath
           (System.Environment.SpecialFolder.CommonApplicationData));
}

现在我们需要确保数据源包含 DataDirectory 占位符。这件作品来自这里。在 DataSet 设计器中,找到 DataSet 的属性,打开 Connection 节点并编辑 ConnectionString 属性,如下所示:

Data Source=|DataDirectory|\YourDatabase.sdf

然后我按照上面 Lyman Enders Knowles 的说明,了解如何将 Common Application Data 文件夹添加到安装项目并将数据库文件放在该文件夹中。

然后我按照上面的 Ove 的建议,即我检查了“启用 ClickOnce 安全设置”并选择“这是一个完全信任的应用程序。

之后,应用程序在 Vista 上部署良好,并且数据库文件可以读写。

于 2009-04-12T13:22:57.703 回答
1

我喜欢下面的概念,一些东西取自上面

  1. 在解决方案资源管理器中右键单击您的设置项目,然后选择“查看 -> 文件系统”。

  2. 右键单击“目标机器上的文件系统”并选择“添加特殊文件夹 -> 自定义文件夹”。

  3. 将自定义文件夹重命名为“通用应用程序数据文件夹”。(这不是将用于生成文件夹的名称,它只是为了帮助您保持直截了当。)

  4. 将文件夹的 DefaultLocation 属性更改为“[CommonAppDataFolder][Manufacturer][ProductName]”。请注意与应用程序文件夹的 DefaultLocation 属性的相似之处,包括奇怪地使用单个反斜杠。

  5. 惊叹于可笑(但不可否认)的事实,即有一个名为“Property”的文件夹属性。满是狂犬病的宝宝,这玩意是谁想出来的?

  6. 将文件夹的 Property 属性更改为“COMMONAPPDATAFOLDER”。

string userAppData = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
string commonAppData = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData); 
于 2012-05-18T18:12:05.497 回答
0

我不确定这是否会对您的情况有所帮助。

但是,如果您将私有部分添加到应用程序的配置文件中

您可以指定额外的文件夹来签入您的应用程序。

如果您说的是您希望能够安装到机器上的其他文件夹中,那么这是一个问题。本质上,微软限制这些东西的全部原因是为了让恶意代码远离用户不知道他们正在安装什么的机器。

因此,如果您需要另一个目录,这将不起作用。此修复程序的作用是允许您指定在应用程序中搜索文件的位置......

于 2008-11-12T19:39:13.490 回答