使用 C# 访问系统目录

Posted

技术标签:

【中文标题】使用 C# 访问系统目录【英文标题】:Access to system directories using C# 【发布时间】:2019-05-29 03:47:28 【问题描述】:

我有一个包含本地数据库的程序 当我从非系统目录运行它时它工作正常,但是当我从系统目录(如程序文件目录)运行它时,我无法访问我的数据库 我正在使用 c# wpf 。不知道如何访问我的数据库:/

我使用实体数据模型,该模型与应用程序目录中的数据库一起使用(这将在程序文件目录中,就像我安装的每个其他应用程序一样,例如 Adob​​e 应用程序 MS Office 等)他们如何访问他们的程序文件目录中的数据没有得到用户的任何许可?!!! :((

【问题讨论】:

以管理员身份运行程序/Visual Studio? 您不应将数据存储在程序文件文件夹中。使用类似:Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) 并将数据存储在那里。 @Compufreak 我不能强制每个用户以管理员身份运行程序,问题是我希望程序授予访问权限,或者至少要求用户手动授予它一次 @Kevin 是的,肯定可以解决问题,但我使用的是实体数据模型,它与应用程序目录中的数据库一起使用 :(( ...我正在使用存储过程伙计跨度> 【参考方案1】:

您不应将程序数据保存在您的程序应用程序文件夹中,因为在不更改用户权限或使用管理权限的情况下您无权访问它。你应该使用Environment.SpecialFolder。

例如

Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\YourApplication"

这也是例如Adobe Flash 或 MS Office 正在使用。

【讨论】:

谢谢,但我怎样才能创建一个实体模型,它与我的数据库一起工作在与我的程序文件夹不同的文件夹中?目前我有一个 EDM,它正在与我的程序文件夹中的数据库一起使用我如何更改它的连接字符串?!在运行时有可能吗? 或者当我无权复制数据库时,如何将数据库复制到那个特殊文件夹中……在客户端机器上安装程序时,是否可以将其放置在那里?我正在使用 InstallShield 部署我的程序 这取决于您使用的数据库类型,您应该阅读如何为您的实体框架版本配置连接字符串,可能就像提到的here。 是的,这就是我要找的。但最后一件事是我可以在 app.config 中使用动态连接字符串而不是静态连接字符串吗? Bcz 我不知道在 xaml 文件中使用客户端计算机上的 applicationData 文件夹的用户名是什么!也许是绑定或……?我使用本地 sql db 文件 (mdf) btw 我通常只使用 EFCore,而不是 EF,所以我不知道,抱歉 - 这听起来你应该在另一个问题中问它,因为它与你最初的问题没有真正的关系。【参考方案2】:

我将此作为回答发布,因为我还不能发表评论,但是我会检查以下内容:

权限,如果程序由其他用户运行,可能会导致问题 路径,确保它们不是相对的

但是没有代码就很难分辨

【讨论】:

谢谢 bruh,但我怎么知道这个用户是管理员?还是其他用户?或者我怎样才能知道他们以管理员身份运行我的程序?【参考方案3】:

如果没有错误消息,很难猜出您的问题是什么。

我的猜测:您需要管理员权限才能写信给C:\Program Files

您的程序更改的数据(文件或数据库)不应包含在此目录中!

这是一种安全机制,可保护您的程序(不仅是您创建的程序)不被其他用户更改。

【讨论】:

【参考方案4】:

编辑:这里是使用应用数据文件夹的代码

public partial class MainWindow : Window

    public MainWindow()
    
        InitializeComponent();
        GetDB();
    

    void GetDB1()
    
        var DBFile = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "DB1");
        var con = new System.Data.SQLite.SQLiteConnection($"Data Source=DBFile.sqlite;Version=3;");
        con.Open();
        string sql = "Select 1 as col1";
        var command = new System.Data.SQLite.SQLiteCommand(sql, con);
        var reader = command.ExecuteReader();
        while (reader.Read())
            Console.WriteLine("col1: " + reader["col1"]);
    

只需在窗口上检查您的文件夹权限,就像在图片中一样


更多详情

1。软件

软件是告诉计算机如何工作的数据或计算机指令的集合

为简单起见,主要有两种类型

操作系统软件

应用软件

2。操作系统软件

操作系统 (OS) 是管理计算机硬件和软件资源并为计算机程序提供通用服务的系统软件。

3。目录结构

在计算中,目录结构是操作系统的文件系统及其文件向用户显示的方式。文件通常以分层树结构显示。

4。 Windows 10 [用户名]\AppData

此文件夹存储每个用户的应用程序数据和设置。该文件夹包含三个子文件夹:Roaming、Local 和 LocalLow。漫游用于漫游配置文件的基于网络的登录。当用户登录时,漫游中保存的数据将同步到计算机。 Local 和 LocalLow 不与联网计算机同步

5。指南:存储和检索设置和其他应用数据

应用数据是特定于特定应用的可变数据。它包括运行时状态、用户首选项和其他设置。

应用数据不同于用户数据,用户在使用应用时创建和管理的数据。用户数据包括文档或媒体文件、电子邮件或通信记录,或保存用户创建的内容的数据库记录。用户数据可能对不止一个应用程序有用或有意义。

通常,这是用户希望作为独立于应用程序本身的实体(例如文档)来操作或传输的数据。

-关于应用数据的重要说明:应用数据的生命周期与应用的生命周期相关。如果应用程序被删除,所有应用程序数据将因此丢失。不要使用应用数据来存储用户数据或用户可能认为有价值且不可替代的任何内容。我们建议使用用户的库和 Microsoft OneDrive 来存储此类信息。应用数据非常适合存储特定于应用的用户偏好、设置和收藏夹。

6.访问控制

访问控制是指控制谁可以访问操作系统 (OS) 中的文件(资源)的安全功能。

7.操作系统与应用软件的关系是什么

所有应用程序都调用操作系统 (OS) 上的访问控制函数来访问特定资源或控制对应用程序提供的资源的访问。

所以你的应用需要你作为一个可以控制操作系统的用户向操作系统请求文件夹权限

所以你需要C#代码+操作系统权限

8。如何应用这些概念

8.1.以管理员身份运行,因为他们有访问权限 8.2。检查App所在的文件夹 8.3。为当前用户添加文件夹权限

8.1。以管理员身份运行,因为他们有访问权限

8.1.1 如何

8.1.2 为什么

8.1.3 为什么不

Why you shouldn’t run as admin… – Aaron Margosis' Non-Admin, App-Compat and Sysinternals WebLog

如果恰好编写了漏洞利用程序,因此它需要管理员权限(就像许多人一样),只需以用户身份运行就会停止它的死机。但如果您以管理员身份运行,则漏洞利用可以:

安装内核模式 rootkit 和/或键盘记录器(几乎无法检测到) 安装和启动服务 安装 ActiveX 控件,包括 IE 和 shell 插件(常见于间谍软件和广告软件) 访问属于其他用户的数据 导致代码在任何其他人登录时运行(包括捕获输入到 Ctrl-Alt-Del 登录对话框的密码) 用木马替换操作系统和其他程序文件 访问 LSA 机密,包括其他敏感帐户信息,可能包括域帐户的帐户信息 禁用/卸载防病毒软件 在事件日志中掩盖其踪迹 使您的机器无法启动 如果您的帐户是网络上其他计算机的管理员,则恶意软件也会获得对这些计算机的管理员控制权 还有更多

8.2。检查App所在的文件夹

8.3。为当前用户添加文件夹权限

参考。

https://docs.microsoft.com/en-us/windows/uwp/design/app-settings/store-and-retrieve-app-data https://docs.microsoft.com/en-us/windows/desktop/SecAuthZ/access-control https://en.wikipedia.org/wiki/Software https://en.wikipedia.org/wiki/Directory_structure

【讨论】:

哇,这么划算! 老兄!哇...感谢您的回答,但我不能强迫用户做所有这些事情!我需要我的程序像我们在机器上安装的任何其他应用程序一样工作,并且它们可以正常工作,而无需获得用户的任何许可或让用户执行这些操作!我需要我的程序自己获得访问权限,或者至少向用户询问一次权限。再次感谢男人 @Mahdi.KH 您如何部署应用程序? MS SETUP , Onclicke 或 jsut 通过 USB 复制文件? @MohamedElrashid 我正在使用 installShield -> 基本 MSI 项目 @Mahdi.KH 检查sql代码还是使用实体框架

以上是关于使用 C# 访问系统目录的主要内容,如果未能解决你的问题,请参考以下文章

C#获取当前系统磁盘符系统目录桌面等

c# 枚举安卓系统中所有目录及文件名

如何使用Java API访问HDFS为目录设置配额

使用 c# 从另一个域访问远程目录

使用 C# 创建目录时访问被拒绝

C#插件系统设计