如何在启动时运行Click-once部署的应用程序?

时间:2008-12-30 23:17:54

标签: .net clickonce startup

如何使Click-once部署的应用程序运行启动?

我通过搜索找到的最佳选项是将应用程序上的发布者设置为启动,因此“开始”菜单快捷方式将放在“启动”文件夹中,但这似乎是一个巨大的黑客,我希望有一个开始人们可以找到的菜单图标。

我有哪些选择?

11 个答案:

答案 0 :(得分:25)

我觉得将您的应用程序添加到启动文件夹是不专业的。我强烈建议使用启动注册表项来启动您的应用程序。

与此主题的许多材料相反,设置一个键以启动应用程序一次点击并且不需要设置其他快捷方式非常简单。您只需使用在安装时创建的快捷方式:

// The path to the key where Windows looks for startup applications
RegistryKey rkApp = Registry.CurrentUser.OpenSubKey(
                    @"SOFTWARE\Microsoft\Windows\CurrentVersion\Run", true);

//Path to launch shortcut
string startPath = Environment.GetFolderPath(Environment.SpecialFolder.Programs) 
                   + @"\YourPublisher\YourSuite\YourProduct.appref-ms";

rkApp.SetValue("YourProduct", startPath);

答案 1 :(得分:12)

在阅读了该主题和johnnycoder blog post mentioned above的所有评论之后,我想出了一个解决方案:

  1. 将ClickOnce应用添加到“启动”文件夹
  2. 卸载ClickOnce应用程序时(自动重启或注销/登录后)自动删除启动项目
  3. 经过测试,适用于Windows XP,Windows 7,Windows Server 2000/2003,Windows 8
  4. 我的解决方案

    基本上,您的应用会将.bat文件写入Startup文件夹,为您启动ClickOnce应用。 .bat文件足够智能,可以检测应用程序是否已卸载,如果无法找到ClickOnce应用程序,则会自行删除。

    第1步

    获取批处理文件。将PUBLISHER_NAME和APPLICATION_NAME替换为正确的值。您可以通过安装ClickOnce应用程序找到它们,然后按照文件系统上的路径进行操作:

    @echo off
    
    IF EXIST "%appdata%\Microsoft\Windows\Start Menu\Programs\PUBLISHER_NAME\APPLICATION_NAME.appref-ms" (
    "%appdata%\Microsoft\Windows\Start Menu\Programs\PUBLISHER_NAME\APPLICATION_NAME.appref-ms"
    ) ELSE (start /b "" cmd /c del "%~f0"&exit /b)
    

    批处理文件将检查您的ClickOnce应用程序是否已安装(通过查看appref-ms文件是否存在)并启动它(如果存在)。否则,批处理文件将通过方法outlined here删除自身。

    现在您已拥有批处理文件,请将其测试出来。将其放在Startup文件夹中,以确保它在登录时启动您的应用程序。

    第2步

    现在,在您的应用程序的代码中,您需要将此批处理文件写入Startup文件夹。下面是在C#中使用上面的批处理文件的示例(请注意,有一些转义,环境变量voodoo正在发生):

    string[] mystrings = new string[] { @"@echo off
    
    IF EXIST ""%appdata%\Microsoft\Windows\Start Menu\Programs\PUBLISHER_NAME\APPLICATION_NAME.appref-ms"" (
    ""%appdata%\Microsoft\Windows\Start Menu\Programs\PUBLISHER_NAME\APPLICATION_NAME.appref-ms""
    ) ELSE (start /b """" cmd /c del ""%~f0""&exit /b)"};
    
    string fullPath = "%appdata%\\Microsoft\\Windows\\Start Menu\\Programs\\Startup\\StartMyClickOnceApp.bat";
    
    //Expands the %appdata% path and writes the file to the Startup folder
    System.IO.File.WriteAllLines(Environment.ExpandEnvironmentVariables(fullPath), mystrings);
    

    你有它。欢迎评论/改进。

    编辑:修正了第2步中的引号

答案 2 :(得分:5)

不幸的是,所有这些技巧都不适用于Vista。由于某种原因,Vista会在启动时阻止这些程序。

正如@thijs所建议的那样,你可以轻松地绕过vista的“安全性”。请参阅how to run clickonce apps on windows startup上的博客帖子。

答案 3 :(得分:2)

有很多方法可以让你的应用程序在启动时启动,但是有一个清理问题。即使您使用启动注册表项并且它看起来很好,无论如何您应该清除添加到系统中的所有内容。 You can take a look on my article, I faced same clean up problem and used automation and cutom uninstall file to solve issue.

答案 4 :(得分:2)

感谢DiscDev和dbenham。解决方案很有效。只是想根据dbenham的最新信息分享更新的工作代码。

 const string fullPathEnvVar =
            "%appdata%\\Microsoft\\Windows\\Start Menu\\Programs\\Startup\\StartMyClickOnceApp.bat";
 //Expands the %appdata% path
 string fullPath = Environment.ExpandEnvironmentVariables(fullPathEnvVar);

if (!File.Exists(fullPath))
        {
            string[] mystrings =
            {
                @"@echo off 
if exist ""%appdata%\Microsoft\Windows\Start Menu\Programs\<PublisherName>\<ApplicationName>.appref-ms"" (
""%appdata%\Microsoft\Windows\Start Menu\Programs\<PublisherName>\<ApplicationName>.appref-ms""
) else (
(goto) 2>nul & del ""%~f0""
)"
            };
            //write the file to the Startup folder
            File.WriteAllLines(fullPath, mystrings);
        }

答案 5 :(得分:2)

首先感谢Discdev的回答。为了使这个与ÅÄÖ和其他特殊字符一起使用,这个修改为我做了,使用UTF-8一个不同的代码页,没有BOM。

string[] mystrings = new string[] { "chcp 65001", @"IF EXIST ""%appdata%\Microsoft\Windows\Start Menu\Programs\<Publisher>\<App_Name>.appref-ms"" (""%appdata%\Microsoft\Windows\Start Menu\Programs\<Publisher>\<App_Name>.appref-ms"") ELSE (start /b """" cmd /c del ""%~f0""&exit /b)" };
string fullPath = "%appdata%\\Microsoft\\Windows\\Start Menu\\Programs\\Startup\\StartErrandDynamicMenu.bat";
System.Text.Encoding utf8WithoutBOM = new System.Text.UTF8Encoding(false);
System.IO.File.WriteAllLines(Environment.ExpandEnvironmentVariables(fullPath), mystrings, utf8WithoutBOM);

答案 6 :(得分:1)

就实际启动应用程序在启动时启动而言,在启动文件夹中添加链接是最好的选择。或者如果不是启动文件夹,则启动reg键。

一种解决方法是不让Icon处于正常位置的方法是让应用程序在Application启动时将自己的链接放入启动文件夹中。 ClickOnce应用程序将在首次安装时运行。应用程序可以使用此启动将链接放在Startup文件夹中。现在链接将在两个地方,你应该是金色的。

虽然现在删除ClickOnce应用程序将不再实际删除它,但存在问题。 ClickOnce不会跟踪添加的手动链接,因此每当有人卸载您的应用并重新启动时,它都会重新安装。我会开始考虑该程序表现不佳:(。

答案 7 :(得分:1)

您可以在启动时将您的应用添加到相应的“运行”启动注册表项。然后,即使你的应用程序被删除时你无法删除它,它也不会伤害任何东西,没有人会看到破坏的参考。

答案 8 :(得分:1)

如果它帮助其他人仍然在寻找解决方案,那么评论方式可以在底部http://johnnycoder.com/blog/2009/02/24/clickonce-run-at-startup/建议设置ClickOnce发布选项(在VS.Net 2010中的项目属性,发布屏幕和选项)发布者名称设置为启动和套件名称留空。这确实让我在Windows 7上的程序快捷方式进入启动文件夹。我不知道Windows的其他版本是做什么的。

答案 9 :(得分:0)

出于某种原因,Windows登录时无法启动我的应用程序(“.appref-ms”文件)。因此,我想出了一个其他人可能也会发现有用的解决方案。

首次安装我的应用程序时(以及启动我的应用程序时),我添加/验证我的应用程序当前位置string.Concat(Application.ExecutablePath, " ", "/startup")是否存在于注册表"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run"中。当应用程序启动时,我检查args是否为“/ startup”,如果存在,请执行以下代码。

var startMenuFile = Path.Combine("Programs", Company, Product + ".appref-ms");
var startMenuFolder = Environment.GetFolderPath(Environment.SpecialFolder.StartMenu);
var fileName = Path.Combine(startMenuFolder, startMenuFile);

if (File.Exists(fileName))
{
    Process.Start(fileName);
    return;
}

// Log that for some reason, the application doesn't exist.

这对我很有用。但是,如果只是在没有Application.ExecutablePath争论的情况下将"/startup"值添加到注册表,则应用程序将在Windows启动时启动,但不会在“单击一次”应用程序的上下文中启动。这不允许您访问ApplicationDeployment.CurrentDeployment。虽然这很好用但仍然存在这样的问题,即当我的应用程序被卸载时,注册表设置不会被删除。可以使用@Ivan Leonenko自定义卸载解决方案来解决此问题。希望这会有所帮助...

答案 10 :(得分:0)

我做这个并为我工作

 Sub AddToStartup()
    If My.Application.IsNetworkDeployed Then


        Dim str As String = My.Application.Deployment.UpdatedApplicationFullName.ToString

        Dim saida As String = ""

        For i As Integer = 0 To str.Split(",").Length

            If Not saida.Contains("msil") Then
                saida += str.Split(",")(i) & ", "
            End If
        Next

        If saida.Contains("msil") Then
            saida = saida.Substring(0, saida.Length - 2)
        End If

        Dim name As String = My.Application.Info.Title
        Dim file As String = Path.Combine(My.Application.Info.DirectoryPath, name & ".appref-ms")
        My.Computer.FileSystem.WriteAllText(file, saida, False)

        Dim reg As RegistryKey = Registry.CurrentUser.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", True)
        reg.SetValue(name, file)

    End If


End Sub