C# 创建具有依赖项的应用程序的快捷方式

C# 创建具有依赖项的应用程序的快捷方式,c#,wpf,windows,shortcut,C#,Wpf,Windows,Shortcut,我正在尝试让我的应用程序在桌面上创建快捷方式。原因是因为我的应用程序有一些依赖项,比如外部DLL和其他,我更喜欢将它放在一个文件夹中,在桌面上有一个快捷方式,而不是将所有文件放在桌面上或包含所有内容的文件夹中 这是我第一次尝试这个。我认为这很简单,如果我的问题有点离题,我真的很抱歉。 我的简单代码如下所示: string checkDesktopDir = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);

我正在尝试让我的应用程序在桌面上创建快捷方式。原因是因为我的应用程序有一些依赖项,比如外部DLL和其他,我更喜欢将它放在一个文件夹中,在桌面上有一个快捷方式,而不是将所有文件放在桌面上或包含所有内容的文件夹中

这是我第一次尝试这个。我认为这很简单,如果我的问题有点离题,我真的很抱歉。 我的简单代码如下所示:

string checkDesktopDir = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);
if (!File.Exists(checkDesktopDir + "\\My app.url"))
    {
        ShortCutWithDependencies("My app");
    }   
private void ShortCutWithDependencies(string sAppName)
    {
        string deskDir = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);

        using (StreamWriter writer = new StreamWriter(deskDir + "\\" + sAppName + ".url"))
        {
            string app = Assembly.GetExecutingAssembly().Location;
            MessageBox.Show(app);
            writer.WriteLine("[InternetShortcut]");
            writer.WriteLine("URL=" + app);
            writer.WriteLine("IconIndex=0");
            string icon = app.Replace('\\', '/');
            writer.WriteLine("IconFile=" + icon);
            writer.Flush();
        }
    }
然而,我的应用程序永远不会工作。一旦它到达零件,它将需要依赖项来继续,它将崩溃。更具体地说,当我使用通过
DLLImport
导入的方法(如bass.dll方法)时,它只会崩溃。当然,我在输出中看不到任何东西,因为快捷方式是编译的.exe

所以我的问题是,;如何创建应用程序的完整快捷方式

编辑:更新dllimport的示例

        [DllImport("bass.dll")]
        public static extern bool BASS_Start();
        [DllImport("bass.dll")]
        public static extern bool BASS_Init(int device, uint freq, uint flag,
             IntPtr hParent, uint guid);

        if (mp3ToPlay != string.Empty)
                            {
                                BASS_Start();
                                BASS_Init(-1, 44100, 0, IntPtr.Zero, 0);
                                BassHandle = BASS_StreamCreateFile(false, mp3ToPlay, 0, 0, 0x20000);
                                BASS_ChannelPlay(BassHandle, false);
                                PlayBackLength = BASS_ChannelGetLength(BassHandle, 0);
                                PlayBack = true;
                            }
现在我相信这就是问题所在。不过我不确定。外部dll(bass.dll、Newtonsoft.Json.dll和Spotify.dll)将
Copy to output directory
设置为
Copy always
,并将其复制。.exe将正常运行,手动创建并发送到桌面的快捷方式也将正常运行

编辑:使用Federico的示例更新2 现在这将起作用:

private void CreateShortcut()
        {
            object shDesktop = "Desktop";
            WshShell shell = new WshShell();
            string shortcutAddress = (string)shell.SpecialFolders.Item(ref shDesktop) + @"\iBlock.lnk";
            IWshShortcut shortcut = (IWshShortcut)shell.CreateShortcut(shortcutAddress);
            shortcut.Description = "New shortcut for a iBlock";
            shortcut.Hotkey = "Ctrl+Shift+N";
            shortcut.TargetPath = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory) + @"\iBlock\iBlock.exe";
            shortcut.Save();
        }
然而,这里有一个小故障。 这是我代码的一部分

public string mp3Path = Directory.GetCurrentDirectory() + "\\mp3Directory";

if (!System.IO.File.Exists(mp3Path))
            {
                Directory.CreateDirectory(mp3Path);
            }

将其更改为AppDomain.CurrentDomain.BaseDirectory将很容易解决此问题。

请尝试使用本机COM Windows API创建快捷方式,如以下回答所述:

首先,项目>添加引用>COM>Windows脚本主机对象模型

using IWshRuntimeLibrary;

private void CreateShortcut()
{
    object shDesktop = (object)"Desktop";
    WshShell shell = new WshShell();
    string shortcutAddress = (string)shell.SpecialFolders.Item(ref shDesktop) + @"\Notepad.lnk";
    IWshShortcut shortcut = (IWshShortcut)shell.CreateShortcut(shortcutAddress);
    shortcut.Description = "New shortcut for a Notepad";
    shortcut.Hotkey = "Ctrl+Shift+N";
    shortcut.TargetPath = Environment.GetFolderPath(Environment.SpecialFolders.System) + @"\notepad.exe";
    shortcut.Save();
}
[编辑1]在
目录之后更新。GetCurrentDirectory()
问题:

从:
中,当前目录与启动进程的原始目录不同。

您期望的目录与通过
directory.GetCurrentDirectory()
返回的目录不同,因为当您使用快捷方式(桌面)时,实际上是从不同的目录启动进程
Directory.GetCurrentDirectory()
返回当前的工作目录,如果通过打开.exe文件启动程序集,则该目录与程序集相同,但如果从.lnk文件启动程序集,则它是快捷目录


在您的场景中,我会使用
Assembly.GetExecutingAssembly().Location
(查看此答案了解更多信息:)

如果我理解正确,听起来您最好只为应用程序制作一个安装程序。您可以通过VisualStudio来实现这一点,它几乎可以为您实现过程的自动化。此外,您可以尝试将程序设置为具有依赖项的ClickOnce应用程序。我个人会选择后者


我意识到这不是一个特别彻底的答案,但我觉得这个问题有点不清楚。

不清楚问题是什么。这些依赖项位于哪里?如何加载它们?它们是外部DLL。我通过德林波特给他们打电话。有些位于“应用程序”位置,而另一些位于同一位置的子文件夹中。@user2530266我想,如果您手动创建快捷方式并尝试运行它,您将有相同的行为。您能否确切说明如何将DllImport与不起作用的依赖项dll一起使用?您必须停止猜测该问题。每个.NET程序员最终都会发现,为AppDomain.CurrentDomain.UnhandledException编写事件处理程序不是可选的。我会选择AppDomain.CurrentDomain.BaseDirectory