最近因為工作需要,客戶那邊工程師使用的是JAVA語言開發的程式,我們這邊平臺中是用C#語言開發的,因為有些操作必須統一,所以我在網上查詢解決方法,自己也實踐過,在這裡做個筆記吧,分享一下。
一、使用C#編寫com元件
開發環境 :VS2017
1、新建工程:CalcTest(類庫專案,根據自己喜好需要取工程名,框架我這裡使用的是:.NET Framework 4 ,你可以根據自己的來選。 (注:下面紅色框和箭頭和需要注意的地方)
2、右鍵專案屬性,點選專案屬性,看到下面這個介面,點選紅色框框"程式集資訊,使程式集com可見,打上勾,如下圖所示
程式集中其他資訊可以根據個人喜好可寫可不寫。
3、選擇生成看到以下介面,平臺目標選擇:X64, 為COM互操作註冊(C) 勾上,如下圖操作。
4、接下來是設定強簽名,要以管理員的身份執行
①.找到Visual Studio Command Prompt (VS2017 開發人員命令提示)
輸入命令:sn -k D:/CalcComkey.snk
這裡我生成的CalcComkey.snk 檔案放在D盤,注意選擇你自己的儲存路徑。
VS2017 開發人員命令提示工具的路徑是安裝VS2017 路徑下,你可以自己找一下,每個人安裝位置不一樣。
比如我的是 : C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Visual Studio 2017\Visual Studio Tools
5、在簽名 標籤中選中 為程式集簽名,選擇剛剛生成的強名稱檔案CalcComkey.snk 。
6、建立GUID
通過點選工具 => 建立GUID => 選擇4 => New Guid => copy => 替換下面 C#程式碼中的兩個 GUID 值
建立GUID,新建複製,貼上到程式碼中去就可以,把程式碼中那兩個都替換掉。
using System; using System.Collections.Generic; using System.Linq; using System.Runtime.InteropServices; using System.Text; namespace CalcTest { [Guid("68E2A6FD-F437-4107-A6DB-E78714EC8D8B")] //GUID值 interface ICalc { [DispId(1)] int Add(int a, int b); //返回的int值,與需要呼叫的類的方法名一致。 } [Guid("60D60EE5-EAF3-482C-BE33-DED6BE635111"), ClassInterface(ClassInterfaceType.None)] //GUID值 public class Calc : ICalc //類名,介面名 ,必須定義介面 { public Calc() { } //定義具有兩個引數的方法,返回計算結果。根據各自需要定義。 public int Add(int a, int b) { return a+b; } } }
7、編譯生成程式,Debug目錄中會生成 CalcTest.dll 和CalcTest.tlb。
二、java呼叫C#編寫com元件
一、準備工作
1、剛剛上文中我們生成的兩個檔案,CalcTest.dll 、 CalcTest.tlb,先儲存起來,一會兒會用到。
名稱空間為:CalcTest、類名為:Calc
2、jacob下載,可以自主下載,這裡提供一個,下面是百度網盤的地址和提取碼:
連結:https://pan.baidu.com/s/1U_2NDpQvmScSB9_fICW9Ig
提取碼:s60u
二、實現步驟
1、將CalcTest.dll、CalcTest.tlb複製到JAVA開發環境中,JAVA環境中需要安裝對應版本的.net framework
注:JAVA開發環境指JDK下的bin目錄,我的是win7的系統,預設就安裝了.NET Framework 4.0
2、在JAVA開發環境中註冊新生成的com元件,在客戶環境中,通過regasm.exe註冊com元件。
Regasm.exe預設安裝路徑為:C:\Windows\Microsoft.NET\Framework\v2.0.50727
注:因為上面我們選擇的是X64平臺,因此框架是選擇Framework64,路徑為:
C:\Windows\Microsoft.NET\Framework64\v4.0.30319
還有步驟1的意思就是,把CalcTest.dll、CalcTest.tlb複製到這個路徑下面C:\Windows\Microsoft.NET\Framework64\v4.0.30319
注:圖片中的InvokeTest.dll和Invoke.tlb就是我們上文的CalcTest.dll、CalcTest.tlb
①、按下win+R,輸入cmd進入控制皮膚
②、輸入 cd C:\Windows\Microsoft.NET\Framework64\v4.0.30319
③、接下來,手動註冊COM方法:執行命令(管理員身份執行)
④、regasm CalcTest.DLL /CalcTest.tlb
出現以下介面說明註冊成功:
注:圖片中的InvokeTest.dll和Invoke.tlb就是我們上文的CalcTest.dll、CalcTest.tlb
3、強簽名的dll檔案新增到快取中
1、首先找到gacutil,路徑為:C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.6.1 Tools
注:也有可能在這裡路徑下面找不到gacutil,那麼就去下載一個或者找一下其他地方的複製過來,我一開始就沒有這個bin資料夾,從其他地方拷貝過來的。
注:圖片中的InvokeTest.dll和Invoke.tlb就是我們上文的CalcTest.dll、CalcTest.tlb
2、接下來就是要將dll新增到快取中
①、按下win+R,輸入cmd進入控制皮膚
②、輸入
cd C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.6.1 Tools
③、執行命令: 執行這個命令需要InvokeTest.DLL 具有強名稱
gacutil -i C:\Program Files\Java\jdk1.8.0_181\bin\InvokeTest.DLL
注:上面這個路徑因人而異,找到你自己jdk的存放路徑,把InvokeTest.dll、InvokeTest.tlb放到bin資料夾下面。
注:圖片中的InvokeTest.dll和Invoke.tlb就是我們上文的CalcTest.dll、CalcTest.tlb
Ok,dll新增到快取中的操作就完成了,看到以下介面就說明成功新增了
或者
4、檢視登錄檔regedit,HKEY_CLASSES_ROOT中是否有InvokeTest.MyMd5 項,如果有說明註冊COM成功。如果沒有,請重新註冊。重複上面過程。
檢視登錄檔,不知道怎麼操作的,下面連結可以開啟看,或者自己上網查。
https://jingyan.baidu.com/article/295430f10e5cc80c7e00500d.html
看到以下介面說明註冊成功了
注:圖片中的InvokeTest.MyMd5就是我們上文的CalcTest.Calc,因為節省時間,我上文給大家演示了一遍,下面這個是按照我實踐過的例子貼的經驗,
三、Java專案呼叫
1、新建專案,引用jacob.jar
2、實現,直接貼程式碼
package test; //=================導包======================= import com.jacob.activeX.ActiveXComponent; import com.jacob.com.ComThread; import com.jacob.com.Dispatch; import com.jacob.com.Variant; //=================導包======================= public class main { public static void main(String[] args) { // TODO Auto-generated method stub try { ComThread.InitSTA(); ActiveXComponent dotnetCom = null; //需要呼叫的C#程式碼中的名稱空間名和類名。 dotnetCom = new ActiveXComponent("CalcTest.Calc"); //需要呼叫的方法名和引數值 Variant var = Dispatch.call(dotnetCom,"Add",1,2); String str2 = var2.toString(); //返回需要的字串 System.out.println(str2.toString());//列印結果,結果等於3 } catch (Exception ex) { ex.printStackTrace(); }
finally { ComThread.Release(); } } }
宣告:下面操作主要分為兩部分,第一部分使用C#編寫com為了寫這篇文章我是新建的操作demo,
第二部分java呼叫c#編寫的com元件,因為是工作時的demo,因為當時有給客戶寫了使用說明,在這裡拿一些截圖出來用一下,為了節省時間,我就不再操作一遍了,如有不理解的可以留言。
ok,對於整個操作過程就分享到這裡了,如果有不理解的,或者我有講的不對的請幫忙指出,謝謝。