简体   繁体   English

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

[英]32bit console application cannot be started in 64bit process written in c#

I see that quite similar topic has been discussed here but anyone has solved my problem so far. 我看到这里已经讨论了非常相似的主题,但是到目前为止,没有人解决了我的问题。

I have this assignment: 我有这个作业:

  1. I have .exe (32bit) utility to run with commands 我有.exe(32位)实用程序,可通过命令运行
  2. this utility will be started with windows service on 64bit platform 该实用程序将在64位平台上以Windows服务启动

I know that this is no possibility to run 32bit apps on 64bit process. 我知道这不可能在64位进程上运行32位应用程序。 Otherwise I found workaround by COM IPC communication. 否则,我通过COM IPC通信找到了解决方法。

So there is my solution: 所以有我的解决方案:

Interface declaration of COM library: COM库的接口声明:

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

Class implementing the interface: 实现接口的类:

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();
      }      
    }
  }
}

The code is build with no error and no warnings. 该代码的构建没有错误,也没有警告。 Then by regAsm.exe registered as COM. 然后通过regAsm.exe注册为COM。

Now I am trying to access to COM and call the method: 现在,我尝试访问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);

  }
}

And I got a problems: 我有一个问题:

  1. executing ends with exception: System.Runtime.InteropServices.COMException was unhandled, class is not registered HRESULT: 0x80040154 (REGDB_E_CLASSNOTREG)), when assembly is registered by regasm.exe with no error 执行结束,但异常:未处理System.Runtime.InteropServices.COMException,未注册类HRESULT:0x80040154(REGDB_E_CLASSNOTREG)),当程序集被regasm.exe注册且没有错误时
  2. I cannot add COM reference to project in VS via add reference wizard, it ends with error dialog window: "A reference to 'assemblyName' could not be added. The ActiveX type library 'libary path' was exported from a .net assembly and cannot be added as a reference. Add a reference to the .net assembly instead." 我无法通过添加引用向导将VS的COM引用添加到VS中,它以错误对话框窗口结尾:“无法添加对'assemblyName'的引用。ActiveX类型库'库路径'是从.net程序集导出的,无法被添加为参考。改为添加对.net程序集的参考。”

I tried a lot of solutions but I was unsuccessful ... thanks for help. 我尝试了很多解决方案,但未成功……感谢您的帮助。

It is not true that you can't run a 32-bit from a 64-bit process. 不能从64位进程运行 32位是不正确的。 You can not use a 32-bit DLL or COM-Control in a 64-bit process, but you can use Process.Start to start any process you want. 您不能在64位进程中使用 32位DLL或COM-Control,但是可以使用Process.Start启动所需的任何进程。

In your case it sounds like you don't even have to use the COM control you're describing (this causes more problems, even). 在您的情况下,听起来您甚至不必使用所描述的COM控件(这甚至会导致更多问题)。 Just do the following within your service (no matter whether 32- or 64-bit) and you're fine: 只需在您的服务中执行以下操作(无论是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();
}    

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM