草庐IT

c++ - Windows/C++ : how to use a COM dll which is not registered

coder 2023-11-11 原文

在我们的应用中,需要用到一个之前没有在系统中注册过的COM dll(即msdia100.dll)。

早些时候,我们刚刚通过以下代码调用其 DllRegisterServer 来调用 DLL:

// Register DIA DLL required by Breakpad
std::string diaLibPath = "msdia100";    
HMODULE diaLib = LoadLibrary(diaLibPath.c_str());
if( diaLib == NULL )
{
    errors << "Cannot load DLL " << diaLibPath << endl;
    return;
}

typedef HRESULT ( __stdcall * regServer_t )(void);

regServer_t regServer = (regServer_t)GetProcAddress(diaLib, "DllRegisterServer");
if( regServer == NULL )
{
    errors << "Cannot get method DllRegisterServer from " << diaLibPath << endl;
    FreeLibrary(diaLib);
    return;
}
if( regServer() != S_OK )
{
    errors << "Cannot call DllRegisterServer from " << diaLibPath << endl;
}
FreeLibrary(diaLib);

这在 Windows 7(也许还有 Vista,没试过)上不再有效,因为要调用此函数,它需要管理员权限。

这个问题的所有解决方案我都找到了获得这些管理员权限的地方。这对我们来说不是可行的解决方案,因为如果用户无法获得这些管理员权限,我们的应用程序也必须正常工作。

我们的应用程序突然需要一个注册此 DLL 的安装程序,这也不是解决方案。

那么,有哪些可能呢?我如何在没有管理员权限的情况下使用此 DLL?我是否必须重新编码 COM,无需先注册 DLL 即可工作?


我使用这个库的代码如下所示:

CComPtr<IDiaDataSource> data_source;
if (FAILED(data_source.CoCreateInstance(CLSID_DiaSource))) {
  fprintf(stderr, "CoCreateInstance CLSID_DiaSource failed "
          "(msdia80.dll unregistered?)\n");
  return false;
}

(顺便说一句,对于那些感兴趣的人:那是 Google Breakpad 的一部分。)

最佳答案

一个简单的方法是使用 LoadLibrary("msdia100.dll") 直接加载 DLL。然后使用 GetProcAddress("DllGetClassObject")。然后,您可以使用 IClassFactory 执行与 CoCreateInstance 等效的操作。

所以像下面这样。 (免责声明:我没有编译这个...)

HRESULT CoCreateDiaDataSource(CComPtr<IDiaDataSource>& data_source)
{
    HMODULE hmodule = LoadLibrary("MSDIA100");
    if (!hmodule)
        return HRESULT_FROM_WIN32(GetLastError()); // library not found

    BOOL (WINAPI*DllGetClassObject)(REFCLSID,REFIID,LPVOID*) =
        (BOOL(WINAPI*)(REFCLSID,REFIID,LPVOID*))GetProcAddress(hmodule, "DllGetClassObject");

    if (!DllGetClassObject) 
        return HRESULT_FROM_WIN32(GetLastError());

    CComPtr<IClassFactory> pClassFactory;
    HRESULT hr = DllGetClassObject(CLSID_DiaSource, IID_IClassFactory, &pClassFactory);
    if (FAILED(hr))
        return hr;

    hr = pClassFactory->CreateInstance(NULL, IID_IDiaDataSource, (void**)&data_source);
    if (FAILED(hr))
        return hr;

    return S_OK;
}

注意事项:

  1. 在 LoadLibrary 调用中,您可能必须提供路径。我不知道 MSDIA100.DLL 通常位于何处。

  2. 我不知道 MSDIA100.DLL 有什么作用。并非所有 COM DLL 都适用于此方法,特别是如果它们依赖于 COM 自由线程编码和类似的可怕东西。但是,根据我的经验,大多数 COM DLL 都是简单的单元线程并且工作正常。

关于c++ - Windows/C++ : how to use a COM dll which is not registered,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2466138/

有关c++ - Windows/C++ : how to use a COM dll which is not registered的更多相关文章

  1. ruby - 在 Ruby 程序执行时阻止 Windows 7 PC 进入休眠状态 - 2

    我需要在客户计算机上运行Ruby应用程序。通常需要几天才能完成(复制大备份文件)。问题是如果启用sleep,它会中断应用程序。否则,计算机将持续运行数周,直到我下次访问为止。有什么方法可以防止执行期间休眠并让Windows在执行后休眠吗?欢迎任何疯狂的想法;-) 最佳答案 Here建议使用SetThreadExecutionStateWinAPI函数,使应用程序能够通知系统它正在使用中,从而防止系统在应用程序运行时进入休眠状态或关闭显示。像这样的东西:require'Win32API'ES_AWAYMODE_REQUIRED=0x0

  2. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

    我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

  3. ruby - 在 Windows 机器上使用 Ruby 进行开发是否会适得其反? - 2

    这似乎非常适得其反,因为太多的gem会在window上破裂。我一直在处理很多mysql和ruby​​-mysqlgem问题(gem本身发生段错误,一个名为UnixSocket的类显然在Windows机器上不能正常工作,等等)。我只是在浪费时间吗?我应该转向不同的脚本语言吗? 最佳答案 我在Windows上使用Ruby的经验很少,但是当我开始使用Ruby时,我是在Windows上,我的总体印象是它不是Windows原生系统。因此,在主要使用Windows多年之后,开始使用Ruby促使我切换回原来的系统Unix,这次是Linux。Rub

  4. ruby - 使用 `+=` 和 `send` 方法 - 2

    如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:

  5. Vscode+Cmake配置并运行opencv环境(Windows和Ubuntu大同小异) - 2

    之前在培训新生的时候,windows环境下配置opencv环境一直教的都是网上主流的vsstudio配置属性表,但是这个似乎对新生来说难度略高(虽然个人觉得完全是他们自己的问题),加之暑假之后对cmake实在是爱不释手,且这样配置确实十分简单(其实都不需要配置),故斗胆妄言vscode下配置CV之法。其实极为简单,图比较多所以很长。如果你看此文还配不好,你应该思考一下是不是自己的问题。闲话少说,直接开始。0.CMkae简介有的人到大二了都不知道cmake是什么,我不说是谁。CMake是一个开源免费并且跨平台的构建工具,可以用简单的语句来描述所有平台的编译过程。它能够根据当前所在平台输出对应的m

  6. 深度学习部署:Windows安装pycocotools报错解决方法 - 2

    深度学习部署:Windows安装pycocotools报错解决方法1.pycocotools库的简介2.pycocotools安装的坑3.解决办法更多Ai资讯:公主号AiCharm本系列是作者在跑一些深度学习实例时,遇到的各种各样的问题及解决办法,希望能够帮助到大家。ERROR:Commanderroredoutwithexitstatus1:'D:\Anaconda3\python.exe'-u-c'importsys,setuptools,tokenize;sys.argv[0]='"'"'C:\\Users\\46653\\AppData\\Local\\Temp\\pip-instal

  7. ruby - 如何计算 Liquid 中的变量 +1 - 2

    我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我

  8. arrays - Ruby 数组 += vs 推送 - 2

    我有一个数组数组,想将元素附加到子数组。+=做我想做的,但我想了解为什么push不做。我期望的行为(并与+=一起工作):b=Array.new(3,[])b[0]+=["apple"]b[1]+=["orange"]b[2]+=["frog"]b=>[["苹果"],["橙子"],["Frog"]]通过推送,我将推送的元素附加到每个子数组(为什么?):a=Array.new(3,[])a[0].push("apple")a[1].push("orange")a[2].push("frog")a=>[[“苹果”、“橙子”、“Frog”]、[“苹果”、“橙子”、“Frog”]、[“苹果”、“

  9. ruby - 如何在 Ruby 中执行 Windows CLI 命令? - 2

    我在目录“C:\DocumentsandSettings\test.exe”中有一个文件,但是当我用单引号编写命令时`C:\DocumentsandSettings\test.exe(我无法在此框中显示),用于在Ruby中执行命令,我无法这样做,我收到的错误是找不到文件或目录。我尝试用“//”和“\”替换“\”,但似乎没有任何效果。我也使用过系统、IO.popen和exec命令,但所有的努力都是徒劳的。exec命令还使程序退出,这是我不想发生的。提前致谢。 最佳答案 反引号环境就像双引号,所以反斜杠用于转义。此外,Ruby会将空格解

  10. += 的 Ruby 方法 - 2

    有没有办法让Ruby能够做这样的事情?classPlane@moved=0@x=0defx+=(v)#thisiserror@x+=v@moved+=1enddefto_s"moved#{@moved}times,currentxis#{@x}"endendplane=Plane.newplane.x+=5plane.x+=10putsplane.to_s#moved2times,currentxis15 最佳答案 您不能在Ruby中覆盖复合赋值运算符。任务在内部处理。您应该覆盖+,而不是+=。plane.a+=b与plane.a=

随机推荐