26

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

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

我有什么选择?

4

11 回答 11

32

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

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

// 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);
于 2012-01-01T19:50:59.740 回答
12

在阅读了关于这个线程的所有评论和上面提到的 johnnycoder 博客文章之后,我想出了一个解决方案:

  1. 将 ClickOnce 应用程序添加到 Startup 文件夹
  2. 卸载 ClickOnce 应用程序时自动删除启动项(重新启动或注销/登录后)
  3. 经过测试并在 Windows XP、Windows 7、Windows Server 2000/2003、Windows 8 上运行

我的解决方案

基本上,您的应用程序会将一个.bat文件写入启动文件夹,该文件夹会为您启动 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 文件是否存在),如果存在则启动它。否则,批处理文件会通过此处概述的方法自行删除。

现在您有了批处理文件,请对其进行测试。将其放在您的 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 步中的固定引号

于 2014-05-06T16:47:14.020 回答
5

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

正如@thijs 所建议的那样,您可以轻松绕过vista 的“安全性”。请参阅有关如何在 Windows 启动时运行 clickonce 应用程序的博文

于 2009-05-11T00:21:54.127 回答
2

好吧,有很多方法可以让您的应用程序在启动时启动,但是有一个清理问题。即使您使用启动注册表项并且它看起来不错,无论如何您应该清除所有添加到系统中的内容。你可以看看我的文章,我遇到了同样的清理问题并使用自动化和自定义卸载文件来解决问题。

于 2012-12-10T21:41:25.670 回答
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);
        }
于 2015-07-23T18:34:30.077 回答
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);
于 2015-08-08T10:40:09.163 回答
1

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

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

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

于 2008-12-30T23:27:52.110 回答
1

您可以在启动时将您的应用程序添加到适当的“运行”启动注册表项。然后,即使您的应用程序被删除时您无法删除它,它也不会造成任何伤害,并且没有人会看到损坏的引用。

于 2008-12-31T00:26:06.673 回答
1

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

于 2012-05-09T06:31:34.600 回答
0

出于某种原因,登录时 Windows 不会启动我的应用程序(“.appref-ms”文件)。所以,我想出了一个解决方案,其他人可能也会觉得有帮助。

第一次安装我的应用程序时(以及在我的应用程序启动时),我添加/验证我的应用程序当前位置是否string.Concat(Application.ExecutablePath, " ", "/startup")存在于注册表中"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run"。然后当应用程序启动时,我检查“/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自定义卸载解决方案来解决。希望这可以帮助...

于 2013-12-20T17:19:11.733 回答
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
于 2017-03-28T19:56:15.880 回答