如何从 64 位应用程序连接到 windows phone 7
How to connect to windows phone 7 from a 64-bit application
我有一个 32 位程序(用 C++ 编写)可以连接到一些不同的设备,只要它是 32 位的就一切正常。但是,现在我需要将它构建为 64 位程序,但后来我遇到了 Windows Phone 7.
的一些问题
我发现我重建为 64 位的 dll(用 C# 编写)在这一行抛出异常:
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.0\Bin\ConMan2.dll" 的路径,所以我 registered that dll using regsvr32 但我仍然遇到相同的异常。
更新:
因为我可能需要创建一个解决方法而不是找到 ConMan2.dll 的 64 位版本,所以我 post 在这里提供了一些我当前的 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:\Program Files (x86)\Common Files\Microsoft Shared\Phone Tools\CoreCon 中实现.0\Bin\ConMan2.dll
该 DLL 没有 64 位版本。
而且您不能直接从 64 位进程使用 32 位 DLL。
有一个解决方法。您可以创建另一个项目,32 位 EXE,它将根据需要调用该 32 位 DLL,并实现任何 IPC 以与您的主要 64 位应用程序交互。
对于具体的IPC机制,如果你只需要调用一个比较长的task并等待它完成,command-like app + command-line arguments + exit code 就够了。
如果您需要发出很多调用,我会选择 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();
}
}
}
我有一个 32 位程序(用 C++ 编写)可以连接到一些不同的设备,只要它是 32 位的就一切正常。但是,现在我需要将它构建为 64 位程序,但后来我遇到了 Windows Phone 7.
的一些问题我发现我重建为 64 位的 dll(用 C# 编写)在这一行抛出异常:
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.0\Bin\ConMan2.dll" 的路径,所以我 registered that dll using regsvr32 但我仍然遇到相同的异常。
更新:
因为我可能需要创建一个解决方法而不是找到 ConMan2.dll 的 64 位版本,所以我 post 在这里提供了一些我当前的 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:\Program Files (x86)\Common Files\Microsoft Shared\Phone Tools\CoreCon 中实现.0\Bin\ConMan2.dll 该 DLL 没有 64 位版本。 而且您不能直接从 64 位进程使用 32 位 DLL。
有一个解决方法。您可以创建另一个项目,32 位 EXE,它将根据需要调用该 32 位 DLL,并实现任何 IPC 以与您的主要 64 位应用程序交互。 对于具体的IPC机制,如果你只需要调用一个比较长的task并等待它完成,command-like app + command-line arguments + exit code 就够了。
如果您需要发出很多调用,我会选择 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();
}
}
}