我发现了一篇关于如何通过调用来提升用C++编写的COM对象
的文章CoCreateInstanceAsAdmin.但是我无法找到或做的是将.NET(c#)应用程序的一个组件实现为COM对象,然后调用该对象来执行需要UAC提升的任务.MSDN将此文档记录为管理COM对象模型.
我知道以管理员身份启动应用程序(或其他应用程序)是可行且非常容易的,以便在单独的过程中执行任务(例如参见Daniel Moth的帖子,但我正在寻找的是一种方式从同一个未提升的.NET可执行文件中做所有事情.当然,这样做会在新进程中生成COM对象,但是由于透明的编组,.NET COM对象的调用者不应该(也是很多)意识到这一点.
关于如何使用C#,C#项目,通过CoCreateInstanceAsAdminAPI 实现C#编写的COM对象的任何想法都会非常有用.所以我真的很想学习如何在C#中编写COM对象,然后我可以通过COM高程API从C#调用它.
不要紧,升高的COM对象是否在同一进程中运行.我只是不想要提升整个应用程序; 我想要提升将执行代码的COM对象.如果我能写出一些东西:
// in a dedicated assembly, marked with the following attributes:
[assembly: ComVisible (true)]
[assembly: Guid ("....")]
public class ElevatedClass
{
public void X() { /* do something */ }
}
Run Code Online (Sandbox Code Playgroud)
然后让我的主应用程序ElevatedClass通过CoCreateInstanceAsAdmin调用实现.但也许我只是在做梦.
我们有一些动态HTML页面,其中包含一个<OBJECT>实例化ActiveX控件的标记.然后,用户可以导航到另一页面,该页面包含<OBJECT>指向较新版本的ActiveX控件的标签.
IE将在第二页上下载并安装新的ActiveX,这就是那个页面的用途.问题是,由于IE在第一页上加载了ActiveX,它现在将强制用户重新启动,然后才能完全安装下载的ActiveX,因为它正由进程(IE)使用.
在普通容器中,我只是在尝试升级之前卸载ActiveX.有没有办法迫使IE这样做?如果可以做到这一点,那么浏览一个不使用控件的页面是可以接受的.
编辑:
需要ActiveX本身执行某些操作的解决方案不能简单地工作,因为问题是当IE开始安装新版本的ActiveX时,ActiveX仍在内存中.我想要做的是在IE启动该过程时不要在内存中使用ActiveX,所以显然我不能依赖ActiveX控件本身的任何东西.
我有一个引用VB6 DLL的C#应用程序.当我将C#中的null传递给VB6 dll函数时,null在VB6中被转换为值Empty(value),而不是Nothing(object).例如:
// function in vb6 dll that referenced by c# app
Public Sub TestFunc(ByVal oValue As Variant)
{
...
if oValue is Nothing then
set oValue = someObject
end if
...
}
// main c# code
private void Form1_Load(object sender, EventArgs e)
{
object testObject = new object();
testObject = null;
TestFunc(testObject);
}
Run Code Online (Sandbox Code Playgroud)
当我传递一个对象(非null)时,它将作为对象传递给VB6.但是当null传递给vb6时,它变为值类型为Empty,而不是对象类型Nothing.谁知道为什么?无论如何,当从c#app传递时,我可以强制null为VB6中的Nothing吗?
非常感谢.
我正在尝试使用Python中的COM对象(win32com)来自动化进程,但是我没有得到预期的结果......是否有工具来探索/测试COM对象而无需编写特定的程序?我的意思是,是否存在允许例如实例化COM对象并调用其方法的东西?
(基本上我试图找出我的意外结果是否是win32com的错,我想避免安装Visual Studio来编写C#应用程序)
我从System.Thread.Timer线程池得到了这个(上面标题中的错误)所以我有我的TimerWrapper包装System.Thread.Timer将实际执行移动到System.Thread.ThreadPool我仍然得到它我将它移动一个新的线程(回调).Start(),我仍然得到它.当我把它放在一个全新的线程上时,如何调度输入同步调用?
这是一个非常小的原型应用程序,其中我所做的就是触发一个正在执行此操作的计时器...
IEnumerable swc = SHDocVw.ShellWindows()
HashSet<WindowInfo> windows = new HashSet<WindowInfo>();
foreach (SHDocVw.InternetExplorer ie in swc)
{
if (!ie.FullName.ToLower().Contains("iexplore.exe"))
continue;
IntPtr hwnd;
IEPlugin.IOleWindow window = ie.Document as IEPlugin.IOleWindow;
window.GetWindow(out hwnd);
WindowInfo info = new WindowInfo();
info.handle = hwnd;
info.extraInfo = ie;
windows.Add(info);
}
Run Code Online (Sandbox Code Playgroud) 我在一本关于WCF的书中遇到过这一行:
...用于编写COM组件的语言(例如C++和Visual Basic)最好是面向对象的,但不是面向组件的......
两者有什么区别?
我使用的是进程外COM服务器(使用DECLARE_CLASSFACTORY_SINGLETON实现的COM单例"引擎"),它在STA(CComSingleThreadModel,_ATL_APARTMENT_THREADED)中工作.
COM服务器客户端:
BHO定期调用Engine :: dispatchEvent,Engine调用ActiveScript的JavaScript函数.这种架构非常有效,直到我同时打开两个BHO.
如果我打开两个BHO,当我调用ActiveScript函数(使用IDispatch/Invoke)时会发生卡住.我没有创建任何额外的线程.
一些说明:
调用堆栈:
> ntdll.dll!_ZwWaitForMultipleObjects@20() + 0x15 bytes
ntdll.dll!_ZwWaitForMultipleObjects@20() + 0x15 bytes
KernelBase.dll!_WaitForMultipleObjectsEx@20() + 0x100 bytes
kernel32.dll!_WaitForMultipleObjectsExImplementation@20() + 0x8e bytes
user32.dll!_RealMsgWaitForMultipleObjectsEx@20() + 0xe2 bytes
ole32.dll!CCliModalLoop::BlockFn(void * * ahEvent, unsigned long cEvents, unsigned long * lpdwSignaled) Line 1222 C++
ole32.dll!ModalLoop(CMessageCall * pcall) Line 211 C++
ole32.dll!ThreadSendReceive(CMessageCall * pCall) Line 4979 C++
ole32.dll!CRpcChannelBuffer::SwitchAptAndDispatchCall(CMessageCall * * ppCall) Line 4454 + 0x6 bytes C++
ole32.dll!CRpcChannelBuffer::SendReceive2(tagRPCOLEMESSAGE * pMessage, unsigned long * pstatus) Line 4076 C++ …Run Code Online (Sandbox Code Playgroud) 在64位计算机上从Visual Studio 2012运行应用程序,显示以下错误消息:
检索具有CLSID {F2D4F4E5-EEA1-46FF-A83B-A270C92DAE4B}的组件的COM类工厂由于以下错误而失败:80040154未注册类(HRESULT异常:0x80040154(REGDB_E_CLASSNOTREG))
我在visualstudio中使用Inventor packandgo dll库.
任何人都知道错误是什么?