【问题标题】:How to connect to windows phone 7 from a 64-bit application如何从 64 位应用程序连接到 windows phone 7
【发布时间】:2016-02-07 06:54:38
【问题描述】:

我有一个 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\11.0\Bin\ConMan2.dll”的路径,所以我@ 987654322@ 但我仍然遇到同样的异常。

更新:

由于我可能需要创建一个解决方法而不是找到 64 位版本的 ConMan2.dll,如果有人可以向我展示可能的解决方法,我会在此处发布一些我当前的 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);
             ...
             ...           
        }
   }
}

【问题讨论】:

    标签: c# windows windows-phone-7 windows-phone 32bit-64bit


    【解决方案1】:

    CLSID = {349AB2E8-71B6-4069-AD9C-1170849DA64C} 的 COM 服务器在 C:\Program Files (x86)\Common Files\Microsoft Shared\Phone Tools\CoreCon\11.0\Bin\ConMan2.dll 中实现 该 DLL 没有 64 位版本。 而且您不能直接从 64 位进程中使用 32 位 DLL。

    有一个解决方法。您可以创建另一个项目,32 位 EXE,它会根据需要调用该 32 位 DLL,并实现任何 IPC 以与您的主 64 位应用程序交互。 对于具体的 IPC 机制,如果你只需要调用一个比较长的任务并等待它完成,类似命令的应用程序 + 命令行参数 + 退出代码可能对你来说足够了。

    如果您需要发出许多调用,我会选择 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++ 编写的,而我拥有的 DLL 是用 C# 编写的,这个 workaraound 仍然适合我吗?
    • 1 — 在整个文件系统中搜索,文件只在“Program Files (x86)”中
    • 2 - 它应该可以工作。您可以将该 DLL 编译为“任何 CPU”,将这些 InteropShared、YourService、iYourService 放入该 DLL,在运行时检查平台,如果它是 64 位,则启动 32 位主机进程并使用 WCF 调用服务通过 iYourService 代理,如果它是 32 位的,则创建一个 YourService 实例并在同一进程中直接与其交互。你会花一些时间处理不同的异常机制,但我这样做了,而且效果很好。
    • 再次感谢您的宝贵时间。不幸的是,由于我对 C#、COM 和 WCF 还很陌生,所以我不太明白你的意思。但是,如果您有时间向我展示应该如何实现该变通方法,我会使用我正在使用的非常短版本的 DLL 更新我的问题。
    • 你好。我现在确实有事情要做。我posted it in Code Review.
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-21
    • 1970-01-01
    • 2011-05-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多