如何从64位应用程序连接到Windows Phone 7
我有一个32位程序(用C++编写),可以连接到一些不同的设备,只要它是32位的一切正常。然而,现在我需要将它构建为64位程序,但随后我遇到了Windows Phone 7的一些问题。如何从64位应用程序连接到Windows Phone 7
我发现一个dll(用C#编写),我重建为64位引发异常在这条线:
MultiTargetingConnectivity connectivity = new MultiTargetingConnectivity(CultureInfo.CurrentUICulture.LCID);
唯一的例外是:
An unhandled exception of type 'Microsoft.SmartDevice.Connectivity.DatastoreException' occurred in Microsoft.SmartDevice.Connectivity.dll
Additional information: Retrieving the COM class factory for component with CLSID {349AB2E8-71B6-4069-AD9C-1170849DA64C} failed due to the following error: 80040154 Class not registered (Exception from HRESULT: 0x80040154 (REGDB_E_CLASSNOTREG)).
(例如,如果我尝试运行this example program工作在32位,但抛出的64位是例外,在同一行)
当我在注册表中搜索该CLSID时,我找到了一个“C:\ Program Files(x86)\ Common Files \ Microsoft Shared \ Phone Tools \ CoreCon \ 11.0 \ Bin \ ConMan2.dll”的路径,所以我registered that dll using regsvr32我仍然得到相同的例外。
UPDATE:
因为我可能需要创建一个解决办法,而不是寻找ConMan2.dll 64位版本的,我发表一点我在这里的当前的dll的,如果有人能告诉我一个可能的解决方法,使它可以在32位和64位上工作。
namespace WP7DLL
{
// Interface declaration.
[Guid("11111111-1111-1111-1111-111111111111")]
public interface IWP7DLL
{
int GetStatus();
};
[ClassInterface(ClassInterfaceType.None)]
[Guid("22222222-2222-2222-2222-222222222222")]
public class WP7DLL : IWP7DLL
{
public WP7DLL() { }
public int GetStatus()
{
//Line that gives an exception in 64 bit
MultiTargetingConnectivity connectivity = new MultiTargetingConnectivity(CultureInfo.CurrentUICulture.LCID);
...
...
}
}
}
与CLSID = {349AB2E8-71B6-4069-AD9C-1170849DA64C} COM服务器用C实现的:\程序文件(x86)\ Common Files文件\ Microsoft共享\手机工具\ CoreCon \ 11.0 \斌\ ConMan2.dll 该DLL没有64位版本。 而且你不能直接从64位进程使用32位DLL。
有一个解决方法。您可以创建另一个项目,即32位EXE,然后根据需要调用该32位DLL,并实现任何IPC以与主要的64位应用程序进行交互。 对于特定的IPC机制,如果您只需要调用一个相对较长的任务并等待它完成,那么类似命令的app +命令行参数+退出代码对我来说就足够了。
如果您需要发出很多呼叫,我会选择WCF通过命名管道传输。如果你选择这种方式,下面是一些实现.EXE的示例代码。
/// <summary>The class from the shared assembly that defines WCF endpoint, and named events</summary>
public static class InteropShared
{
// Host signals it's ready and listening. Replace the zero GUID with a new one
public static readonly EventWaitHandle eventHostReady = new EventWaitHandle(false, EventResetMode.AutoReset, @"{00000000-0000-0000-0000-000000000000}");
// Client asks the host to quit. Replace the zero GUID with a new one
public static readonly EventWaitHandle eventHostShouldStop = new EventWaitHandle(false, EventResetMode.AutoReset, @"{00000000-0000-0000-0000-000000000000}");
const string pipeBaseAddress = @"net.pipe://localhost";
/// <summary>Pipe name</summary>
// Replace the zero GUID with a new one.
public const string pipeName = @"00000000-0000-0000-0000-000000000000";
/// <summary>Base addresses for the hosted service.</summary>
public static Uri baseAddress { get { return new Uri(pipeBaseAddress); } }
/// <summary>Complete address of the named pipe endpoint.</summary>
public static Uri endpointAddress { get { return new Uri(pipeBaseAddress + '/' + pipeName); } }
}
static class Program
{
/// <summary>The main entry point for the application.</summary>
[STAThread]
static void Main()
{
// The class implementing iYourService interface that calls that 32-bit DLL
YourService singletoneInstance = new YourService();
using(ServiceHost host = new ServiceHost(singletoneInstance, InteropShared.baseAddress))
{
// iYourService = [ServiceContract]-marked interface from the shared assembly
host.AddServiceEndpoint(typeof(iYourService), new NetNamedPipeBinding(), InteropShared.pipeName);
host.Open();
InteropShared.eventHostReady.Set();
// Wait for quit request
InteropShared.eventHostShouldStop.WaitOne();
host.Close();
}
}
}
谢谢你的回答。我有一些疑问。首先,你是怎么知道ConMan2.dll在64位版本中不存在的?第二,在前面的问题中我没有提到它,但是我的程序是用C++编写的,而且我用C#编写的DLL,这种工作方式仍然适合我吗? – Olppah
1 - 在整个文件系统中搜索,该文件只在“Program Files(x86)” – Soonts
2 - 它应该工作。您可以将该DLL编译为“任何CPU”,将这些InteropShared,YourService,iYourService放入该DLL,在运行时检查平台,如果它是64位,则启动32位主机进程并使用WCF调用该服务通过iYourService代理,如果它是32位,则创建YourService的一个实例并在同一个进程中直接与它进行交互。你会花一些时间处理不同的异常机制,但我做到了,并且它工作正常。 – Soonts