在C++中使用COM时,字符串通常是BSTR数据类型.有人可以使用BSTR包装器CComBSTR或MS CString.但是因为我不能在MinGW编译器中使用ATL或MFC,是否有标准代码片段转换BSTR为std::string(或std::wstring),反之亦然?
是否还有一些BSTR类似的非MS包装CComBSTR?
感谢所有以任何方式帮助过我的人!仅仅因为没有人解决过BSTR和之间的转换问题std::string,我想在此提供一些关于如何做到这一点的线索.
下面是我用转换的功能BSTR,以std::string及std::string对BSTR分别为:
std::string ConvertBSTRToMBS(BSTR bstr)
{
int wslen = ::SysStringLen(bstr);
return ConvertWCSToMBS((wchar_t*)bstr, wslen);
}
std::string ConvertWCSToMBS(const wchar_t* pstr, long wslen)
{
int len = ::WideCharToMultiByte(CP_ACP, 0, pstr, wslen, NULL, 0, NULL, NULL);
std::string dblstr(len, '\0');
len = ::WideCharToMultiByte(CP_ACP, 0 /* no flags */,
pstr, wslen /* not …Run Code Online (Sandbox Code Playgroud) 我知道如何注册dll但是我从来没有真正确定我为什么要这样做,或者在什么条件下必须注册dll.有人可以向我解释或指出一些文件吗?
我正在尝试在C#中构建一个小应用程序,它应该启动/停止IIS Express工作进程.为此,我想使用MSDN上记录的官方"IIS Express API":http://msdn.microsoft.com/en-us/library/gg418415.aspx
据我所知,API仅(仅)基于COM接口.为了使用这个COM接口,我通过Add Reference - > COM - >"IIS Installed Versions Manager Interface"在VS2010中添加了对COM库的引用:

到目前为止一切都很好,但下一步是什么?有一个IIISExprProcessUtility可用的接口,包括启动/停止IIS进程的两个"方法".我是否必须编写一个实现此接口的类?
public class test : IISVersionManagerLibrary.IIISExprProcessUtility
{
public string ConstructCommandLine(string bstrSite, string bstrApplication, string bstrApplicationPool, string bstrConfigPath)
{
throw new NotImplementedException();
}
public uint GetRunningProcessForSite(string bstrSite, string bstrApplication, string bstrApplicationPool, string bstrConfigPath)
{
throw new NotImplementedException();
}
public void StopProcess(uint dwPid)
{
throw new NotImplementedException();
}
}
Run Code Online (Sandbox Code Playgroud)
如您所见,我不是一名专业开发人员.有人能指出我正确的方向.任何帮助是极大的赞赏.
更新1: 根据建议,我尝试了下面的代码,但遗憾的是它不起作用:
好的,它可以实例化但我看不到如何使用这个对象...


IISVersionManagerLibrary.IIISExpressProcessUtility test3 = (IISVersionManagerLibrary.IIISExpressProcessUtility) Activator.CreateInstance(Type.GetTypeFromCLSID(new Guid("5A081F08-E4FA-45CC-A8EA-5C8A7B51727C")));
Exception: Retrieving the …Run Code Online (Sandbox Code Playgroud) 我遇到基于COM的客户端 - 服务器设置问题.COM服务器使用C#(.NET 4.0)编写,并作为(注册的)本地服务器运行.
根据连接到服务器的应用程序,其他客户端将收到服务器执行失败(HRESULT异常:0x80080005(CO_E_SERVER_EXEC_FAILURE)
这里解释了潜在的问题(在COM部分是完整性感知的部分).我理解它的方式,是由于提升的应用程序创建具有更高完整性级别的服务器这一事实.当另一个未提升的应用程序连接时,不允许连接到同一个实例.当非提升的应用程序创建进程时,在提升的应用程序连接之后也会发生同样的情况.
我试图实现页面上描述的解决方案:修改注册表以设置应允许所有客户端连接的安全描述符.在C++中有一个代码示例,但这在.NET中实际上是相同的:
// Security Descriptor with NO_EXECUTE_UP
var sd = new RawSecurityDescriptor("O:BAG:BAD:(A;;0xb;;;WD)S:(ML;;NX;;;LW)");
byte[] securityDescriptor = new Byte[sd.BinaryLength];
sd.GetBinaryForm(securityDescriptor, 0);
RegistryKey key = Registry.ClassesRoot.OpenSubKey("AppID\\{APP-ID-GUID}", true);
if (key == null)
{
key = Registry.ClassesRoot.CreateSubKey("AppID\\{APP-ID-GUID}");
}
using (key)
{
key.SetValue("LaunchPermission", securityDescriptor, RegistryValueKind.Binary);
}
Run Code Online (Sandbox Code Playgroud)
但是,这没有达到预期的效果.当第二个客户端尝试创建相关对象的实例时,Windows会尝试启动COM服务器的单独实例,但服务器会阻止两个实例作为同一用户运行.鉴于我设置的权限,我不希望第一个实例启动第二个实例.
由于其中一个客户端应用程序在Medium IL中运行,而另一个客户端应用程序在High IL中运行,因此我还在强制标签上尝试了变体,例如:
O:BAG:BAD:(A;;0xb;;;WD)S:(ML;;NX;;;ME)
O:BAG:BAD:(A;;0xb;;;WD)S:(ML;;NX;;;LW)(ML;;NX;;;ME)(ML;;NX;;;HI)
Run Code Online (Sandbox Code Playgroud)
我也尝试ROTFlags按照页面上的建议将注册表项设置为0x1(ROTFLAGS_ALLOWANYCLIENT),但行为仍然没有变化.
我已经确定LaunchPermission注册表值正在以某种方式使用.我无法发现使用Process Monitor读取它的位置,但是当我使用该dcomcnfg.exe工具设置相同的密钥时,我可以通过拒绝启动权限来强制服务器加载失败.
我想指出我的服务器进程不需要提升.如何使提升和非提升的进程都能够连接到单个服务器实例?
更新: XE2 Update 2修复了下面描述的错误.
下面的程序,从真实程序中减少,在XE2中失败.这是从2010年开始的回归.我没有XE可以测试,但我希望程序在XE上运行正常(感谢Primož确认代码在XE上正常运行).
program COMbug;
{$APPTYPE CONSOLE}
uses
SysUtils, Variants, Windows, Excel2000;
var
Excel: TExcelApplication;
Book: ExcelWorkbook;
Sheet: ExcelWorksheet;
UsedRange: ExcelRange;
Row, Col: Integer;
v: Variant;
begin
Excel := TExcelApplication.Create(nil);
try
Excel.Visible[LOCALE_USER_DEFAULT] := True;
Book := Excel.Workbooks.Add(EmptyParam, LOCALE_USER_DEFAULT) as ExcelWorkbook;
Sheet := Book.Worksheets.Add(EmptyParam, EmptyParam, 1, EmptyParam, LOCALE_USER_DEFAULT) as ExcelWorksheet;
Sheet.Cells.Item[1,1].Value := 1.0;
Sheet.Cells.Item[2,2].Value := 1.0;
UsedRange := Sheet.UsedRange[LOCALE_USER_DEFAULT] as ExcelRange;
for Row := 1 to UsedRange.Rows.Count do begin
for Col := 1 to UsedRange.Columns.Count do begin
v := …Run Code Online (Sandbox Code Playgroud) 我创建了一个COM +域分区,然后将其映射到Windows 2008服务器计算机并将COM +应用程序导入其中.
我尝试使用以下C#代码远程激活服务器上该特定分区的对象:
//partition guid
Guid guidMyPartition = new Guid("41E90F3E-56C1-4633-81C3-6E8BAC8BDD70");
//parition moniker
string uri= "partition:{" + guidMyPartition + "}/new:MyObject";
Type t = Type.GetTypeFromProgID("MyObject", "MyServer");
MyObject obj = (MyObject)Activator.GetObject(t, uri);
Run Code Online (Sandbox Code Playgroud)
但是我得到了这个例外:
无法创建通道接收器以连接到URL'分区:{41e90f3e-56c1-4633-81c3-6e8bac8bdd70}/new:MyObject'.可能尚未注册适当的频道.
有谁知道如何实现这样的激活?
我可以使用以下脚本启动Excel.但是在ghci(7.4.1)中,当我运行它时会出现分段错误.
我不知道从哪里开始搜索.如果删除该行,我没有此错误
workSheets <- workBook # propertyGet_0 "Worksheets"
Run Code Online (Sandbox Code Playgroud)
这是代码.可能是我忘记了什么.我在这里阅读了com.hs的源代码,但它没有给我任何线索.
import System.Win32.Com
import System.Win32.Com.Automation
--
-- createObjectExcel
-- coming from Automation.hs and com.hs
--
iidIDispatch_unsafe = mkIID "{00020400-0000-0000-C000-000000000046}"
createObjExl :: IO (IDispatch ())
createObjExl = do
clsidExcel <- clsidFromProgID "Excel.Application"
pExl <- coCreateInstance clsidExcel Nothing LocalProcess iidIDispatch_unsafe
return pExl
fichierTest2 = "E:/Programmation/haskell/Com/qos1.xls"
main = coRun $ do
pExl <- createObjExl
workBooks <- pExl # propertyGet_0 "Workbooks"
workBook <- workBooks # propertyGet_1 "Open" fichierTest2
workSheets <- workBook # propertyGet_0 "Worksheets" …Run Code Online (Sandbox Code Playgroud) 我使用Visual Studio 2010(.NET 4).我需要创建一个COM对象(在C#中)并且不知道如何开始(使用什么类型的项目等).
这似乎是一个常见的问题,虽然我无法在SO上找到它.
我应该在我的应用程序中使用哪个版本的MSXML,更重要的是,我该如何决定?
有MSXML3,4,5和6.
我最近在使用MSXML v4的call-wcf-service-by-vbscript中发布了一些代码.AnthonyWJones发布我不应该使用4,而是使用3或6,但可能是3.当然不是v5!
为什么?我想更多地了解选择在我的应用中使用的MSXML版本的标准.
奖金问题:有没有人总结过各种版本的MSXML随时间的差异?
截至目前的摘要:
我有一些COM组件,我从一些c#dll调用.
我还有一个使用该.dll的winforms应用程序.
当我关闭应用程序时,我得到以下异常:
无法使用已与其基础RCW分离的COM对象.
堆栈跟踪显示此异常来自.dll中的析构函数.我实现了这个析构函数来调用COM中的一些清理方法.
为什么会这样?如何最好地解决它?
com ×10
c# ×4
windows ×2
.net ×1
activation ×1
c#-4.0 ×1
c++ ×1
com-interop ×1
delphi ×1
delphi-xe2 ×1
dll ×1
excel ×1
haskell ×1
iis ×1
iis-express ×1
interop ×1
moniker ×1
msxml ×1
ole ×1
scripting ×1
string ×1
uac ×1
visual-c++ ×1
winforms ×1