【问题标题】:How to store persistent User Connection Strings with .NET WPF Click-Once如何使用 .NET WPF Click-Once 存储持久的用户连接字符串
【发布时间】:2017-05-22 20:50:36
【问题描述】:

我们正在开发一个 Click-Once WPF Windows 应用程序,它可以从数据库中检索其所有数据。我实现了一个表单,用户可以在其中输入相应的数据,并使用 SqlConnectionStringBuilder 构建连接字符串,效果很好。

然后我们将连接字符串添加到 ConfigurationManager 使用

ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);

如果我们使用其他一些 ConfigurationUserLevel,应用程序会崩溃(我还不知道为什么,但我相信 Entity Framework Model 尝试加载连接字符串但没有找到它,因为文件未存储在正确的用户级别?)。现在,我们将连接字符串存储在一个单独的文件中,并将其加载到 App.config 中,这样我们就不必将其检入到版本控制中:

<connectionStrings configSource="connections.config"/>

我们不部署此文件,因为它包含我们自己的开发连接字符串。相反,我们为部署创建了一个空文件,其中将存储用户输入的连接字符串。这完全没问题。

我们的问题是,单击一次更新,文件将“丢失”。在配置文件中存储加密的持久每用户连接字符串的最佳方法是什么?或者我们应该完全切换到注册表?或者在 %APPDATA%/Local/Apps/2.0/...../ 文件夹之外的某个地方创建我们自己的加密文件并在初始化实体框架上下文时手动加载它?

【问题讨论】:

  • 如果应用程序崩溃,添加适当的日志记录。不要假设。使用单独的配置文件没有问题,只要将其存储在正确的文件夹中即可。所有这些事情都有很好的记录。
  • 如果您关心凭据,请不要使用它们。请改用 Windows 身份验证。操作系统和应用程序已经知道用户是谁。无需询问或存储用户名
  • 您好 Panagiotis,感谢您的建议。我们目前正在开发日志记录。
  • 问题是,我们不使用 Windows 身份验证,因为 Windows 帐户不一定对应数据库帐户。
  • 然后解决这个问题。拥有不同的帐户有什么意义?除非您希望允许多个用户使用相同的 Windows 帐户登录桌面但重新输入不同的数据库凭据 - 这在 2017 年用户切换需要几秒钟时没有多大意义

标签: c# .net wpf clickonce


【解决方案1】:

你可以去 MSDN 网站,它可能对你有帮助

https://msdn.microsoft.com/en-us/library/dd997001.aspx 在以下代码的帮助下,您需要根据您的要求修改此代码,希望这会有所帮助。

创建自定义 ClickOnce 应用程序安装程序

在 ClickOnce 应用程序中,添加对 System.Deployment 和 System.Windows.Forms 的引用。

向您的应用程序添加一个新类并指定任何名称。本演练使用名称 MyInstaller。

将以下 Imports 或 using 语句添加到新类的顶部。

using System.Deployment.Application;  
using System.Windows.Forms; 

将以下方法添加到您的类中。

这些方法调用 InPlaceHostingManager 方法来下载部署清单、声明适当的权限、请求用户安装权限,然后将应用程序下载并安装到 ClickOnce 缓存中。自定义安装程序可以指定 ClickOnce 应用程序是预先信任的,或者可以将信任决定推迟到 AssertApplicationRequirements 方法调用。此代码预先信任应用程序 注意:- 预信任分配的权限不能超过自定义安装程序代码的权限。

InPlaceHostingManager iphm = null;

    public void InstallApplication(string deployManifestUriStr)
    {
        try
        {
            Uri deploymentUri = new Uri(deployManifestUriStr);
            iphm = new InPlaceHostingManager(deploymentUri, false);
        }
        catch (UriFormatException uriEx)
        {
            MessageBox.Show("Cannot install the application: " + 
                "The deployment manifest URL supplied is not a valid URL. " +
                "Error: " + uriEx.Message);
            return;
        }
        catch (PlatformNotSupportedException platformEx)
        {
            MessageBox.Show("Cannot install the application: " + 
                "This program requires Windows XP or higher. " +
                "Error: " + platformEx.Message);
            return;
        }
        catch (ArgumentException argumentEx)
        {
            MessageBox.Show("Cannot install the application: " + 
                "The deployment manifest URL supplied is not a valid URL. " +
                "Error: " + argumentEx.Message);
            return;
        }

        iphm.GetManifestCompleted += new EventHandler<GetManifestCompletedEventArgs>(iphm_GetManifestCompleted);
        iphm.GetManifestAsync();
    }

    void iphm_GetManifestCompleted(object sender, GetManifestCompletedEventArgs e)
    {
        // Check for an error.
        if (e.Error != null)
        {
            // Cancel download and install.
            MessageBox.Show("Could not download manifest. Error: " + e.Error.Message);
            return;
        }

        // bool isFullTrust = CheckForFullTrust(e.ApplicationManifest);

        // Verify this application can be installed.
        try
        {
            // the true parameter allows InPlaceHostingManager
            // to grant the permissions requested in the applicaiton manifest.
            iphm.AssertApplicationRequirements(true) ; 
        }
        catch (Exception ex)
        {
            MessageBox.Show("An error occurred while verifying the application. " +
                "Error: " + ex.Message);
            return;
        }

        // Use the information from GetManifestCompleted() to confirm 
        // that the user wants to proceed.
        string appInfo = "Application Name: " + e.ProductName;
        appInfo += "\nVersion: " + e.Version;
        appInfo += "\nSupport/Help Requests: " + (e.SupportUri != null ?
            e.SupportUri.ToString() : "N/A");
        appInfo += "\n\nConfirmed that this application can run with its requested permissions.";
        // if (isFullTrust)
        // appInfo += "\n\nThis application requires full trust in order to run.";
        appInfo += "\n\nProceed with installation?";

        DialogResult dr = MessageBox.Show(appInfo, "Confirm Application Install",
            MessageBoxButtons.OKCancel, MessageBoxIcon.Question);
        if (dr != System.Windows.Forms.DialogResult.OK)
        {
            return;
        }

        // Download the deployment manifest. 
        iphm.DownloadProgressChanged += new EventHandler<DownloadProgressChangedEventArgs>(iphm_DownloadProgressChanged);
        iphm.DownloadApplicationCompleted += new EventHandler<DownloadApplicationCompletedEventArgs>(iphm_DownloadApplicationCompleted);

        try
        {
            // Usually this shouldn't throw an exception unless AssertApplicationRequirements() failed, 
            // or you did not call that method before calling this one.
            iphm.DownloadApplicationAsync();
        }
        catch (Exception downloadEx)
        {
            MessageBox.Show("Cannot initiate download of application. Error: " +
                downloadEx.Message);
            return;
        }
    }

    /*
    private bool CheckForFullTrust(XmlReader appManifest)
    {
        if (appManifest == null)
        {
            throw (new ArgumentNullException("appManifest cannot be null."));
        }

        XAttribute xaUnrestricted =
            XDocument.Load(appManifest)
                .Element("{urn:schemas-microsoft-com:asm.v1}assembly")
                .Element("{urn:schemas-microsoft-com:asm.v2}trustInfo")
                .Element("{urn:schemas-microsoft-com:asm.v2}security")
                .Element("{urn:schemas-microsoft-com:asm.v2}applicationRequestMinimum")
                .Element("{urn:schemas-microsoft-com:asm.v2}PermissionSet")
                .Attribute("Unrestricted"); // Attributes never have a namespace

        if (xaUnrestricted != null)
            if (xaUnrestricted.Value == "true")
                return true;

        return false;
    }
    */

    void iphm_DownloadApplicationCompleted(object sender, DownloadApplicationCompletedEventArgs e)
    {
        // Check for an error.
        if (e.Error != null)
        {
            // Cancel download and install.
            MessageBox.Show("Could not download and install application. Error: " + e.Error.Message);
            return;
        }

        // Inform the user that their application is ready for use. 
        MessageBox.Show("Application installed! You may now run it from the Start menu.");
    }

    void iphm_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
    {
        // you can show percentage of task completed using e.ProgressPercentage
    }

要尝试从您的代码安装,请调用 InstallApplication 方法。例如,如果您将您的类命名为 MyInstaller,您可以通过以下方式调用 InstallApplication。

MyInstaller installer = new MyInstaller();  
installer.InstallApplication(@"\\myServer\myShare\myApp.application");  
MessageBox.Show("Installer object created.");  

【讨论】:

  • 谢谢,这看起来很有帮助。我会调查一下!
猜你喜欢
  • 2010-10-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-31
  • 1970-01-01
  • 2012-08-13
  • 2011-12-08
  • 1970-01-01
相关资源
最近更新 更多