32位控制台应用程序无法在用c#编写的64位进程中启动

时间:2012-12-03 11:42:13

标签: c# .net com com-interop

我看到这里讨论过非常相似的主题,但到目前为止,任何人都解决了我的问题。

我有这个任务:

  1. 我有.exe(32位)实用程序来运行命令
  2. 此实用程序将在64位平台上使用Windows服务启动
  3. 我知道在64位进程上运行32位应用程序是不可能的。否则我通过COM IPC通信找到了解决方法。

    所以有我的解决方案:

    COM库的接口声明:

    namespace Win32ConsoleAppWrapper
    {
      [GuidAttribute("5a6ab402-aa68-4d58-875c-fe26dea9c1cd"), ComVisible(true),
      InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
      interface IKDUCompessor
      {
        event ProcessStarted processStarted;
        void RunKDUCompress(string comm);
      }
    }
    

    实现界面的类:

    namespace Win32ConsoleAppWrapper
    {
    
      [GuidAttribute("a1f4eb1a-b276-4272-90e0-0eb26e4273e0"), ComVisible(true),
      ClassInterface(ClassInterfaceType.None)]
      public class KDUCompessor : IKDUCompessor
      {
        public static readonly string KDU_COMPRESS_LIBRARY_NAME = "kdu_compress.exe";
    
        public event ProcessStarted processStarted;
    
        public KDUCompessor() { }
    
        public void RunKDUCompress(string comm)
        {
          if(!File.Exists(KDU_COMPRESS_LIBRARY_NAME))
          {
            throw new FileNotFoundException(String.Format("File {0} could not be found. Please check the bin directory.", KDU_COMPRESS_LIBRARY_NAME));
          }
    
          ProcessStartInfo info = new ProcessStartInfo();
          info.CreateNoWindow = false;
          info.UseShellExecute = true;
          info.FileName = String.Concat(KDU_COMPRESS_LIBRARY_NAME);
          info.WindowStyle = ProcessWindowStyle.Hidden;
          info.Arguments = comm;
    
          // Start the process with the info we specified.
          // Call WaitForExit and then the using statement will close.
          using(Process exeProcess = Process.Start(info))
          {
            exeProcess.WaitForExit();
          }      
        }
      }
    }
    

    代码构建时没有错误,也没有警告。然后通过regAsm.exe注册为COM。

    现在我正在尝试访问COM并调用方法:

    public class MyClass
    {
    
    #region COM Interface and class declaration
    
    [
      ComImport(),
      Guid("5a6ab402-aa68-4d58-875c-fe26dea9c1cd"),
      InterfaceType(ComInterfaceType.InterfaceIsIUnknown)
    ]
    public interface IKDUCompessor
    {
      [PreserveSig]
      void RunKDUCompress(string comm);   
    
    }
    
    [
      ComImport,
      Guid("a1f4eb1a-b276-4272-90e0-0eb26e4273e0")
    ]
    public class KDUCompessor { }
    
    #endregion
    
    protected void CallCOM(_command)
    {
      if (IsCommandValid(_command))
      {
        // instance
        Type type = Type.GetTypeFromCLSID(new Guid("a1f4eb1a-b276-4272-90e0-0eb26e4273e0"));
        object o = Activator.CreateInstance(type);
        IKDUCompessor t = (IKDUCompessor)o;
        t.RunKDUCompress(_command);
    
      }
    }
    

    我遇到了问题:

    1. 执行以异常结束:System.Runtime.InteropServices.COMException未处理,类未注册HRESULT:0x80040154(REGDB_E_CLASSNOTREG)),当程序集由regasm.exe注册时没有错误
    2. 我无法通过添加引用向导向VS中的项目添加COM引用,它以错误对话框窗口结束:“无法添加对'assemblyName'的引用。从.net导出ActiveX类型库'libary path'程序集,不能作为参考添加。添加对.net程序集的引用。“
    3. 我尝试了很多解决方案,但我没有成功...感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

不能从64位进程运行 32位。您不能在64位进程中使用 32位DLL或COM-Control,但可以使用Process.Start启动任何所需的进程。

在你的情况下,听起来你甚至不必使用你正在描述的COM控件(这会导致更多问题,甚至)。只需在您的服务中执行以下操作(无论是32位还是64位),您就可以了:

if(!File.Exists(KDU_COMPRESS_LIBRARY_NAME))
{
    throw new FileNotFoundException(String.Format("File {0} could not be found. Please check the bin directory.", KDU_COMPRESS_LIBRARY_NAME));
}

ProcessStartInfo info = new ProcessStartInfo();
info.CreateNoWindow = false;
info.UseShellExecute = true;
info.FileName = String.Concat(KDU_COMPRESS_LIBRARY_NAME);
info.WindowStyle = ProcessWindowStyle.Hidden;
info.Arguments = comm;

// Start the process with the info we specified.
// Call WaitForExit and then the using statement will close.
using(Process exeProcess = Process.Start(info))
{
    exeProcess.WaitForExit();
}