且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

从Windows注册表启动上启动应用程序时,返回的ClickOnce版本无法正常工作

更新时间:2023-01-25 20:35:06

我已经分离出的问题。我不会pretend理解的完全的ClickOnce的是如何工作的,但基本上,如果直接启动可执行文件,它不会跑的ClickOnce模式。这意味着它不会检查更新,并不会得到正确的版本号(因为它不是真正的网络部署)。

我迄今为止发现的***的解决办法就是指向的ClickOnce。preF-MS文件,而不是.exe文件。这个文件是像各种各样的快捷方式,并且是在开始菜单中。

这里的code我用得到我的应用程序的。preF-MS文件的位置:

 字符串allProgramsPath = Environment.GetFolderPath(Environment.SpecialFolder.Programs);
字符串shortcutPath = Path.Combine(allProgramsPath,注册表项目);
shortcutPath = Path.Combine(shortcutPath,注册表项目)+。preF-MS;
 

然后我再加上我的previous code设置在注册表中的位置。

I'm using the following code with System.Deployment to return the ClickOnce version of my .NET 3.5 C# application:

public string version
{
    get
    {
        System.Reflection.Assembly _assemblyInfo = System.Reflection.Assembly.GetExecutingAssembly();
        string ourVersion = string.Empty;

        if (System.Deployment.Application.ApplicationDeployment.IsNetworkDeployed)
        {
            ourVersion = System.Deployment.Application.ApplicationDeployment.CurrentDeployment.CurrentVersion.ToString();
        }
        else
        {
            if (_assemblyInfo != null)
            {
                ourVersion = _assemblyInfo.GetName().Version.ToString();
            }
        }
        return ourVersion;
    }
}

If I launch the application normally (from the Start menu, for example), this value is always returned correctly. However, if I start the application automatically with Windows using a registry key, the application returns the default hardcoded value of 1.0.0.0.

If I close the automatically-started application and re-open it manually, it then returns the correct ClickOnce version number again.

Any ideas on why this might be? Here is the code I'm using to set the registry key:

string keyName = "MyApp";
string assemblyLocation = Assembly.GetExecutingAssembly().Location;
Util.SetAutoStart(keyName, assemblyLocation);

And

public class Util
{
    private const string RUN_LOCATION = @"Software\Microsoft\Windows\CurrentVersion\Run";

    /// <summary>
    /// Sets the autostart value for the assembly.
    /// </summary>
    /// <param name="keyName">Registry Key Name</param>
    /// <param name="assemblyLocation">Assembly location (e.g. Assembly.GetExecutingAssembly().Location)</param>
    public static void SetAutoStart(string keyName, string assemblyLocation)
    {
        RegistryKey key = Registry.CurrentUser.CreateSubKey(RUN_LOCATION);
        key.SetValue(keyName, assemblyLocation);
    }

    /// <summary>
    /// Returns whether auto start is enabled.
    /// </summary>
    /// <param name="keyName">Registry Key Name</param>
    /// <param name="assemblyLocation">Assembly location (e.g. Assembly.GetExecutingAssembly().Location)</param>
    public static bool IsAutoStartEnabled(string keyName, string assemblyLocation)
    {
        RegistryKey key = Registry.CurrentUser.OpenSubKey(RUN_LOCATION);
        if (key == null)
            return false;

        string value = (string)key.GetValue(keyName);
        if (value == null)
            return false;

        return (value == assemblyLocation);
    }

    /// <summary>
    /// Unsets the autostart value for the assembly.
    /// </summary>
    /// <param name="keyName">Registry Key Name</param>
    public static void UnSetAutoStart(string keyName)
    {
        RegistryKey key = Registry.CurrentUser.CreateSubKey(RUN_LOCATION);
        key.DeleteValue(keyName);
    }
}

I've isolated the problem. I won't pretend to understand exactly how ClickOnce works, but basically, if you launch the executable file directly it won't run in "ClickOnce mode". This means it won't check for updates and won't get the correct version number (since it isn't actually network deployed).

The best solution I've found so far is to point to the ClickOnce .appref-ms file rather than the .exe file. This file is like a shortcut of sorts, and is in the start menu.

Here's the code I'm using to get the location of my app's .appref-ms file:

string allProgramsPath = Environment.GetFolderPath(Environment.SpecialFolder.Programs);
string shortcutPath = Path.Combine(allProgramsPath, keyName);
shortcutPath = Path.Combine(shortcutPath, keyName) + ".appref-ms";

And then I combine that with my previous code to set that location in the registry.