9

我创建了一个 VSTO Outlook 插件,它使用一个库 Html2Xhtml.dll (.NET),它通过执行 System.Diagnostic.Process.Start() 调用另一个 Html2xhtml.exe。

但是,它无法调用 Html2xhtml.exe(我认为),因为即使从 Visual Studio 启动,工作目录也是当前用户的 My Documents 文件夹。我无法控制 Html2Xhtml.dll 中的代码,所以我不能使用绝对路径;但我想我可以在运行时更改加载项的工作目录。

但是,如果我通过 ClickOnce 或其他一些我不知道用户将选择的安装路径的方式安装它,我想如何找到我的 Html2xhtml.exe?

4

5 回答 5

25

我在这里找到了答案,完全归功于 robindotnet.wordpress.com。

//Get the assembly information
System.Reflection.Assembly assemblyInfo = System.Reflection.Assembly.GetExecutingAssembly();

//Location is where the assembly is run from 
string assemblyLocation = assemblyInfo.Location;

//CodeBase is the location of the ClickOnce deployment files
Uri uriCodeBase = new Uri(assemblyInfo.CodeBase);
string ClickOnceLocation = Path.GetDirectoryName(uriCodeBase.LocalPath.ToString());
于 2012-05-23T04:28:50.853 回答
3

我遇到了类似的问题,并以与 Christoph 描述的相同的方式解决了它,我也想知道是否有其他方法可以做到这一点,但如果你没有找到任何东西,这是一个例子

1)使用以下 InstallerClass 创建自定义操作库

using System;
using System.Collections;
using System.ComponentModel;
using System.Configuration.Install;
using System.IO;
using System.Linq;
using System.Xml.Linq;
using Microsoft.VisualStudio.Tools.Applications;
using Microsoft.Win32;

namespace Setup.CustomActions
{
    [RunInstaller(true)]
    public partial class AddCustomization : Installer
    {
        static readonly Guid solutionID = new Guid("d6680661-c31e-4c24-9492-5919dc0uagt5");
        public override void Install(IDictionary stateSaver)
        {
            string installPath = Context.Parameters["installPath"];
            if(!String.IsNullOrEmpty(installPath))
            {
                AddTemplateToAvailableTemplates(installPath);
            }           
            base.Install(stateSaver);
        }

        public override void Rollback(IDictionary savedState)
        {
        }

        public override void Uninstall(IDictionary savedState)
        {
        }

        private void AddTemplateToAvailableTemplates(string installPath)
        {
            //The example below is very basic, put in checks to see whether the registry key already exists and so on
            RegistryKey key = Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\Office\14.0\Common", true);
            RegistryKey acturisKey = key.CreateSubKey(@"Spotlight\MyAppInstallPath");
            acturisKey.SetValue("InstallPath", installPath);h);
        }
    }
}

2)在安装项目中创建指向安装目录的安装自定义操作的键: 安装自定义操作

如果您需要更多信息或想要下载源代码,请查看Open Xml MVP Wouter Van Wugt的这篇msdn 帖子,标题为“使用 Windows Installer 为 Office 解决方案部署 Visual Studio 2010 工具”

于 2012-03-28T06:59:12.270 回答
2

这是一个真正的问题,我不得不与之抗争了很长一段时间。我必须使用的插件中使用的解决方案是将安装目录写入注册表并从那里读取值。这样就可以找到无法嵌入到exe中的东西。这不是一个好的解决方案,但它确实有效。

为什么 MS 坚持将 DLL 复制到随机目录的这种愚蠢的“安全机制”是他们可能永远不会透露的秘密。

在写我的评论时,我实际上有一个到目前为止我没有尝试过的想法:让您的安装程序将您稍后需要的文件复制到 %appdir%\YourCompany\YourApplication\libs 或类似的东西。您应该能够在运行时找到您的东西。

于 2012-03-27T09:47:47.113 回答
1

ClickOnce 应用程序有同样的问题。以下是获取插件部署路径所需执行的操作:

在您的应用程序中添加 System.Deployment.Application 引用

接下来是使用此属性来检索部署路径:

ApplicationDeployment.CurrentDeployment.UpdateLocation.ToString()

你去吧!

于 2012-11-21T05:32:05.413 回答
0

对于 COM 插件 System.Reflection.Assembly.Location 不能稳定地提供我们需要的东西。

但是即使可以将安装目录保存在注册表中,也不是必须的。因为:COM 插件通常有一个 ID。您可以使用 GuidAttribute 定义它。在安装/注册插件期间,有关此程序集的信息存储在:

Computer\HKEY_CLASSES_ROOT\CLSID\{...myPlugin id ....}\InprocServer32

在属性“代码库”中,您可以找到文件的路径。

e.g.: file:///C:/Program Files/myPlugin.dll
于 2019-07-19T15:44:01.937 回答