主頁 > .NET開發 > aardio + .NET 快速開發獨立 EXE 程式,可防 ILSpy 反編譯

aardio + .NET 快速開發獨立 EXE 程式,可防 ILSpy 反編譯

2022-09-09 06:00:25 .NET開發

? 簡介

aardio 可以非常方便地呼叫 .NET( 不需要任何復雜的步驟 ),

.NET 在 aardio 中很好用,系統自帶 .NET 組件以及各種開源 .NET 組件在 aardio 用戶中也很受歡迎,

aardio + .NET 生成的 EXE —— 可避免被 ILSpy 直接反編譯,

aardio 呼叫 .NET 示例:

//匯入 .NET 支持庫
import dotNet;
 
//匯入.NET 程式集
dotNet.import("System"); 

//呼叫類的靜態成員函式
var isValidHost = System.Uri.CheckHostName("www.aardio.com"); 

//構造 .NET 物件
var uri = System.Uri("https://www.aardio.com/test?q=aardio");

//讀或寫 .Net 物件的實體屬性
var host = uri.Host;

//呼叫 .Net 物件實體的成員函式
var hash = uri.GetHashCode();

aardio 語法與 JavaScript 接近,請參考:aardio 編程語言快速入門——語法速覽

aardio + .Net 開發對 .NET 版本沒有嚴格要求 —— 兼容流行 Windows 系統自帶的不同版本 .NET,不但可以呼叫系統自帶的大量 .NET 組件,也可以生成體積很小的 EXE 檔案,

Win7 自帶 .Net 3.5.1,支持 lambda

Win8 自帶 .Net 3.5.1 + .Net 4.5

Win10 自帶 .Net 4.6

Win10 1709 自帶 .Net 4.7.1 ,支持 ValueTuple

Win11 自帶 .NET 4.8

記憶體加載 .NET 程式集,生成獨立 EXE

aardio 提供 dotNet.reference() 函式 —— 可以方便地通過記憶體資料加載 .NET 程式集,這樣就可以生成獨立 EXE 程式,不再需要帶上一堆 DLL 檔案,

將記憶體資料系結為 .NET 程式集示例:

import dotNet;

dotNet.reference({
  ["test.mydll"] = $"\test.mydll.dll";
  ["test.core"] = $"\test.core.dll"; 
});

dotNet.reference() 的第 1 個引數指定程式集名稱,第 2 個引數指定實際要加載的程式集路徑或記憶體資料,aardio 代碼在檔案路徑前加 $ 號可將檔案資料編譯為二進制字串( 發布后不再需要原檔案 ),

然后就可以正常匯入記憶體程式集了,代碼如下:

dotNet.import("test.mydll");

上面的代碼匯入 .NET 程式集,然后再將 .NET 名字空間匯入 aardio ,dotNet.import() 函式的作用與下面的代碼相同:

//匯入 .NET 程式集
var assembly = dotNet.load("test.mydll"); 

//匯入 .NET 名字空間
assembly.import("test.mydll");

aardio 標準庫提供的 .NET 庫

aardio 標準庫中已經提供了一些 .NET 庫,例如 System ,呼叫示例:

//匯入 .NET 名空間
import System; 

//用 System 名字空間下面的類構造物件實體
var uri = System.Uri("https://www.aardio.com/test?q=aardio")

//讀或寫 .Net 物件的實體屬性
var host = uri.Host ;

aardio 代碼一般使用小駝峰命名風格,但 .NET 名字空間或類名一般會大寫首字母以示區別,

我們右鍵點 System ,在彈出選單內點擊「跳轉到定義」看一下 System 庫的源代碼,

 可以看到這個 Sytem 庫的關鍵代碼只有兩句:

import dotNet;
dotNet.import("System")

嵌入 .NET 視窗控制元件到 aardio 視窗

aardio 視窗嵌入 .NET DataGridView 控制元件范例的運行效果:

 首先要了解 .Net 的所有控制元件都應當放在 .Net 創建的視窗里(也就是 System.Windows.Forms.Form 物件),視窗是管理控制元件的容器,不能直接把控制元件單獨擰出來往 aardio 視窗里扔,

如果不想去弄個視窗,aardio 提供了一個更簡單的方法 ,例如把 .Net 的 DataGridView 控制元件直接嵌入 aardio 視窗:

import System.Windows.Forms;

var Forms = System.Windows.Forms; 
var dataGridView = Forms.CreateEmbed("DataGridView",winform.custom);

非常簡單,

好了,現在創建 DataTable 資料表,準備把他顯示到控制元件里,先創建資料列,重點看怎么指定列欄位使用的資料型別:

//添加資料列
var dataTable = System.Data.DataTable("DT"); 
dataTable.Columns.Add("名稱");//添加列
dataTable.Columns.Add("計數",System.Type.GetType("System.Double")); //添加指定資料型別的列
dataTable.Columns.Add("選擇",System.Type.GetType("System.Boolean")); //自動顯示復選框 

然后系結資料源到視圖:

//系結資料源到視圖
var dataView = System.Data.DataView(dataTable);
dataGridView.DataSource = dataView;
dataGridView.EditMode=2;

好吧,想再加一個下拉框嗎?!這個就略有些麻煩了,代碼如下:

//先移除自動生成的列
dataGridView.Columns.Remove("名稱"); 

//下面添加下拉框以替換上面移除的列
var cmbColumn = Forms.DataGridViewComboBoxColumn();
cmbColumn.Width = 120; 
cmbColumn.Name = "Name";
cmbColumn.DataPropertyName  = "名稱";//對應上面 dataTable 里的欄位名
cmbColumn.HeaderText = "名稱"; //顯示在列標題里的文本
 
//如果名稱與顯示值一樣,那直接給 cmbColumn.DataSource 賦值一個陣列就可以
//下面系結下拉候選框的資料源,上面的 DataPropertyName 才是真正要讀寫的資料值,
cmbColumn.DisplayMember = "Name";//下拉框顯示文本的屬性名
cmbColumn.ValueMember = "Value"; //下拉框選項值的屬性名
cmbColumn.DataSource = dotNet.createNameValueList(
  { "王五","張三"},
  { "WangWu","ZhangSan"}
);

//添加這個新的下拉框到資料視圖
dataGridView.Columns.Add(cmbColumn);

//移動到第一列
dataGridView.Columns.Item["Name"].DisplayIndex = 0;

然后添加下面的代碼回應 .NET 控制元件的事件:

//添加事件(event)
dataTable.ColumnChanged = function(sender,eventArgs){
  var columnName = eventArgs.Column.ColumnName;
  var value  =https://www.cnblogs.com/aardio/p/ eventArgs.Row.getItem(columnName);  
  winform.edit.print("已改變列:",columnName," 已變更值:",value);
}

然后讀寫資料:

//添加測驗資料
var row = dataTable.NewRow(); 
row.ItemArray = {"WangWu",123, true}
dataTable.Rows.Add(row);   

//讀取資料
winform.button.oncommand = function(id,event){ 
 
  for(i=1;dataTable.Rows.Count;1){ 
     var arr = dataTable.Rows[i].ItemArray; 
     winform.edit.print( arr[1] )  ; 
  } 
}

以上完整范例源代碼請參考 aardio 自帶范例:

aardio 范例 / 呼叫其他語言 / .Net / 控制元件視窗 / 嵌入控制元件

 

可以看到 aardio 自帶了大量呼叫 .NET 的范例,

在 aardio 中加載的 .NET 程式集如何除錯

用下面的代碼在 aardio 中加載 .NET 程式集的 pdb 除錯檔案:

dotNet.loadFile( "程式集路徑" ,"pdb 除錯檔案路徑" ); 

然后用 VS 附加運行的 aardio 行程就可以除錯了,懂 .NET 的都懂,這個不多說了,

用 aardio 在運行時編譯 C# 原始碼

直接看 aardio 代碼示例:

import dotNet; 

//創建 C# 語言編譯器
var compiler = dotNet.createCompiler("C#");

//DLL 程式集要提前引入,System.dll 默認已引入,注意這函式不支持記憶體 DLL
compiler.Reference("System.dll");

//設定待編譯C#原始碼( 注釋可賦值為字串,注釋標記首尾星號數目要一致 )
compiler.Source = /*** 
?> 
/*
如果 C# 代碼開始于 aardio 模板標記,則啟用 aardio 模板語法,
參考:《aardio 使用手冊 / aardio 語言 / 模板語法》
*/

namespace CSharpLibrary  
{  
    public class Object  
    {     
        <? if _WINXP { ?> 
        public string Test(){    
            return "Windows XP"; 
        }
        <? } else { ?> 
        public string Test(){    
            return "<?= win.version.name ?>"; 
        }
        <? } ?> 
    }   
} 
***/
import win.version;

//編譯并回傳程式集,可選在引數中指定輸出 DLL檔案,不指定則編譯為記憶體程式集,
var assembly = compiler.CompileOrFail(/*"/output.dll"*/);  

//匯入名字空間,也可以直接寫 compiler.import("CSharpLibrary"); 
assembly.import("CSharpLibrary");  

//使用 C# 撰寫的類構造物件實體 
var netObj = CSharpLibrary.Object();

//呼叫實時編譯的C#函式
var ret = netObj.Test(); 

import console;
console.log( ret );
console.pause();

注意 aardio 中的注釋可賦值為字串,因為 aardio 要求段注釋的首尾星號數目必須一致,所以不會與其他編程語言沖突,很適合用來放其他編程語言的源代碼,

上面的 compiler.Source 可以用一個字串指定 C# 原始碼,這個字串支持類似 PHP 的模板語法,所以我們可以用 aardio 代碼靈活地在運行時生態生成比較復雜的 C# 源代碼,然后再用 .NET 編譯為程式集,aardio 中的 dotNet.desktop 擴展庫就使用了這種技術用很少的代碼就實作了虛擬桌面管理支持庫,

默認可以將 C# 原始碼編譯為記憶體程式集,這樣很適合生成獨立 EXE 檔案,

注意在 aardio 中編譯 C#,呼叫的是 CLR,而 CLR 只有 2.0 / 4.0 的區別,運行時編譯也只支持這兩個版本的語法,例如安裝了 .Net 3.5 但沒有安裝 .Net 4.x ,那么 CLR 2.0 下編譯器不支持 var ,lambda 這些語法 (但是能運行編譯后的 DLL,可以事先用 VS 編譯 C# 代碼生成 DLL 程式集),

.NET 與 aardio 物件相互轉換規則

aardio 會自動處理型別轉換,呼叫 .NET 函式時如果引數型別不一致 —— aardio 也會盡最大可能地轉換引數型別,用起來還是比較輕松的,但簡單了解一下型別轉換規則和原理是有必要的,

所有原生 .NET 物件在 aardio 中分為兩類:

1、可自動轉換的簡單值型別

null值、數值、字串、列舉、 System.Drawing.Color 等簡單值型別,以及這些值型別的陣列可以直接交換,aardio 中的 buffer 在 .NET 中對應位元組陣列,

2、在 aardio 中存為 COM 物件的 .NET 物件

其他原生 .NET 物件在 aardio 存為 com.NETObject 物件(對應 .NET 中的 System.__ComObject 型別),其中有些特殊的 .NET 物件(例如 struct,ValueTuple),在傳入 aardio 時會封包為特殊的 DispatchableObject 物件,這些 .NET 物件在 aardio 中都會被封裝為 dotNet.object 物件,在 aardio 中使用沒有太大區別,

aardio 與 .NET 互動基于 COM 介面,所以遵守 aardio 的 COM 傳參基本規則:

aardio 中的整數傳入 .NET 默認為 int32,小數默認為 double 型別,aardio 數值陣列傳入 .NET 默認為 double 型別 COM 陣列,純字串陣列一律轉為 BSTR 陣列,其他陣列轉為 Variant 變體型別陣列,

.NET 中的 enum 列舉會自動轉換為 aardio 中的數值(雙向自動轉換),

.NET 中的 struct,tuple 由 .NET 物件 DispatchableObject 封包后再回傳 aardio ,

aardio 函式則自動轉換為委托、事件所需要的委托型別,

.NET 中的 System.IntPtr,System.UIntPtr 型別在 aardio 中會自動轉換為整數值,

aardio 中的指標型別(pointer)必須使用 tonumber() 函式轉換為數值才能傳入 .NET,

視窗句柄( HWND ) 在 aardio 以整數值表示,可以直接傳入 .NET,

System.Drawing.Color 在 aardio 則會自動轉換為 ARGB 格式的顏色數值,

呼叫 .NET 時 ARGB 格式的顏色數值也能自動轉換為 System.Drawing.Color 物件,

注意 GDI+ 使用 ARGB 格式顏色值,與 gdip庫,plus 控制元件等兼容,

aardio 提供以下函式創建指定靜態型別的 dotNet.object 物件:

dotNet.object(value,byRef) 轉換為 .Net 物件,

dotNet.byte(value,byRef) 轉換為 8 位整型數值,

dotNet.ubyte(value,byRef) 轉換為 8 位無符號整型數值,

dotNet.word(value,byRef) 轉換為 16 位整型數值,

dotNet.uword(value,byRef) 轉換為 16 位無符號整型數值,

dotNet.int(value,byRef) 轉換為 32 位整型數值,

dotNet.uint(value,byRef) 轉換為 32 位無符號整型數值,

dotNet.long(value,byRef) 轉換為 64 位整型數值,

dotNet.ulong(value,byRef) 轉換為 64 位無符號整型數值,

dotNet.float(value,byRef) 轉換為 32 位浮點數值,

dotNet.double(value,byRef) 轉換為 64 位浮點數值

以上函式會將引數 1 存為 .NET 物件并封包為 DispatchableObject 物件后再回傳 dotNet.object 物件,( 簡單的值型別也會轉換為 dotNet.object 物件 ),這可以讓 aardio 直接參考 .NET 中的物件,方便實作 ref,out 等輸出引數,

下面的 aardio 代碼演示了 dotNet.object 的用法:

import dotNet; 
var compiler = dotNet.createCompiler("C#");

//指定 C# 源代碼
compiler.Source = /***
namespace CSharpLibrary  
{  
    public class Object  
    {     
        public static void Test(ref double num,int [] arr){   
            num = 12.3;
            arr[0] = 56;
        }
    }   
} 
***/

//編譯程式集并匯入名字空間  
compiler.import("CSharpLibrary"); 

//創建 .Net 物件,啟用參考傳參, 
var num = dotNet.double(12.5,true);

//創建 .Net 陣列 
var arr = dotNet.int({1,2,3}); 

//呼叫 .NET 函式,
CSharpLibrary.Object.Test(num,arr); 

import console;

/*
dotNet.object 物件如果存盤的是陣列,
可用下標直接讀寫陣列成員,
*/
console.log( arr[1] ) 
 
/*
dotNet.object 物件如果存盤的是 Primitive,enum,string 型別
或這些型別的普通陣列,則可使用 Value 屬性讀寫原始值,
*/
console.log( num.Value ); 

//支持 tostring() 轉換為字串,tonumber() 轉換為數值,
console.log(tostring(num),tonumber(num)); 
console.pause();

下標

C# 中的 下標運算子[] 實際上會被自動轉換為訪問 Item[] 下標屬性,

先看 aardio 代碼示例:

import dotNet;  
var compiler = dotNet.createCompiler("C#");

compiler.Source = /****** 
using System;
using System.Collections.Generic;
namespace CSharpLibrary  
{ 
    public class TestClass
    {
        private Object [] values = new Object [] {1,2,3,4,5,6,7,8,9};
        public Object this [int index]
        {
            get  { return values[index]; }
            set  { values[index] = value; }
        }
        
        public Dictionary<string,string> dict = new Dictionary<string,string> ();
   }
} 
******/ 

//編譯并引入 C# 名字空間
compiler.import("CSharpLibrary"); 

//使用 C# 撰寫的類構造物件實體
var netObj = CSharpLibrary.TestClass(); 

//讀下標屬性,按 C# 規則起始下標為0,而非 aardio 中的起始下標為 1,
var item = netObj.Item[5];
var item = netObj.getItem(5); //這樣讀下標屬性也可以,支持多引數
var item = netObj.Item(5); //get 前綴可以省略

//寫下標屬性
netObj.Item[5]  = 123;
netObj.setItem(5); //這樣寫下標屬性也可以,支持多引數

//如果.NET 物件的下標為數值,允許省略 Item,但這時候起始下標為 1,
var item = netObj[6];
 
//也可以下面這樣賦值:
netObj[6] = 123; 

import console;
console.log(netObj[6]); 

//字典也可以這樣訪問
netObj.dict.Item["test"] = "abc";
console.log( netObj.dict.Item["test"] );

console.pause();

要點:

1、在 aardio 中需要用 Item[] 訪問 .NET 物件的 Item 屬性,這時候要注意起始下標為 0 ( 遵守 C# 規則 ),

2、如果下標為數值可以省略 Item 直接寫 [],但這時要起始下標為 1 (遵守 aardio 規則),

? 呼叫 UWP

用下面的 aardio 代碼創建支持呼叫 UWP 組件的 C# 編譯器:

import dotNet.uwpCompiler  
var uwpCompiler = dotNet.uwpCompiler( "\ocr.dll" )

可選在 dotNet.uwpCompiler 的第 2 個引數指定 Windows.winmd 的路徑,如果沒有指定 aardio 會自動到下面的目錄去查找最新版本 Windows 10 SDK 目錄( 需要事先安裝 ):

 C:\Program Files (x86)\Windows Kits\10\UnionMetadata 

然后在 SDK 目錄下查找 Windows.winmd,我們只是在編譯程式集時需要 Windows.winmd,運行時不需要它( 也不需要 Windows 10 SDK ),

例如 aardio 標準庫 dotNet.ocr 包含的 ocr.dll 就是用下面的代碼編譯的:

import dotNet.uwpCompiler  
var uwpCompiler = dotNet.uwpCompiler( "\ocr.dll" )

//啟用編譯優化
uwpCompiler.Parameters.CompilerOptions = "/optimize"
 
//設定待編譯C#原始碼
uwpCompiler.Source = /****** 
using System;
using System.Reflection; 
using System.Collections; 
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks; 
using Windows.Graphics.Imaging;
using Windows.Storage;
using Windows.Storage.Streams;
using System.Runtime.InteropServices;
using Windows.Media.Ocr;

namespace aardio  
{ 
    public class UwpOcrResult
    {
    
        public UwpOcrResult(OcrResult ocrRet)
        {
            ocrResult = ocrRet; 
        }
    
        public int LineCount()
        {
            return ocrResult.Lines.Count;
        }
    
        public string [] GetWords(int index)
        {
            ArrayList arr = new ArrayList();
            foreach (var word in ocrResult.Lines[index].Words)
            {
                arr.Add(word.Text);
            }
    
            return (string[])arr.ToArray(typeof(string));
        }
    
        public object GetWordRects(int index)
        {
            ArrayList arr = new ArrayList();
            foreach (var word in ocrResult.Lines[index].Words)
            {
                double[] rc = { word.BoundingRect.Left, word.BoundingRect.Top, word.BoundingRect.Right, word.BoundingRect.Bottom };  
                arr.Add(rc);
            }
    
            return (object)arr.ToArray(typeof(object));
        }
    
        private OcrResult ocrResult;
    
    }
    
    public class UwpOcrEngine  
    {
        public string [] AvailableRecognizerLanguages(){   
            ArrayList arr = new ArrayList();
            foreach (var lang in OcrEngine.AvailableRecognizerLanguages)
            {
                arr.Add(lang.LanguageTag);
            }
            return (string [])arr.ToArray(typeof( string));
        } 
          
        public object IsLanguageSupported( string name ){   
            Windows.Globalization.Language lang = new Windows.Globalization.Language(name);
            return OcrEngine.IsLanguageSupported(lang); 
        }
    
        public UwpOcrResult Recognize(byte[] imgBuffer, string language){   
            return new UwpOcrResult( RecognizeAsync(imgBuffer, language).GetAwaiter().GetResult() );
        }
    
        async Task<OcrResult> RecognizeAsync(byte[] imgBuffer, string language)
        { 
                var randomAccessStream = new InMemoryRandomAccessStream();
                var outputStream = randomAccessStream.GetOutputStreamAt(0);
                var dw = new DataWriter(outputStream);
                var task = new Task(() => dw.WriteBytes(imgBuffer));
                task.Start();
                await task;
                await dw.StoreAsync();
                await outputStream.FlushAsync();
    
                BitmapDecoder decoder = await BitmapDecoder.CreateAsync(randomAccessStream);
                SoftwareBitmap softwareBitmap = await decoder.GetSoftwareBitmapAsync(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Premultiplied);
                Windows.Globalization.Language lang = new Windows.Globalization.Language(language);
    
                OcrEngine engine = OcrEngine.TryCreateFromLanguage(lang);
                if (engine != null)
                {
                    OcrResult ocrResult = await engine.RecognizeAsync(softwareBitmap);
                    return ocrResult;
                }
    
                return null;
        }
    }   
} 
******/

//編譯并回傳程式集  
var assembly = uwpCompiler.CompileOrFail();

import console;
if(assembly) console.logPause("編譯成功",uwpCompiler.Parameters.OutputAssembly);

dotNet.ocr 支持庫的體積很小,可以生成獨立 EXE 檔案,呼叫代碼也非常簡潔,下面是呼叫 示例:

更多

aardio 提供的 .NET 范例非常多,更多功能請參考 aardio 自帶范例,如果大家有任何問題可以下面評論中留言,我會盡快解答,

轉載請註明出處,本文鏈接:https://www.uj5u.com/net/505918.html

標籤:C#

上一篇:過濾掉C中的注釋后回圈遍歷文本檔案

下一篇:aardio + .NET 快速開發獨立 EXE 程式,可防 ILSpy 反編譯

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • WebAPI簡介

    Web體系結構: 有三個核心:資源(resource),URL(統一資源識別符號)和表示 他們的關系是這樣的:一個資源由一個URL進行標識,HTTP客戶端使用URL定位資源,表示是從資源回傳資料,媒體型別是資源回傳的資料格式。 接下來我們說下HTTP. HTTP協議的系統是一種無狀態的方式,使用請求/ ......

    uj5u.com 2020-09-09 22:07:47 more
  • asp.net core 3.1 入口:Program.cs中的Main函式

    本文分析Program.cs 中Main()函式中代碼的運行順序分析asp.net core程式的啟動,重點不是剖析原始碼,而是理清程式開始時執行的順序。到呼叫了哪些實體,哪些法方。asp.net core 3.1 的程式入口在專案Program.cs檔案里,如下。ususing System; us ......

    uj5u.com 2020-09-09 22:07:49 more
  • asp.net網站作為websocket服務端的應用該如何寫

    最近被websocket的一個問題困擾了很久,有一個需求是在web網站中搭建websocket服務。客戶端通過網頁與服務器建立連接,然后服務器根據ip給客戶端網頁發送資訊。 其實,這個需求并不難,只是剛開始對websocket的內容不太了解。上網搜索了一下,有通過asp.net core 實作的、有 ......

    uj5u.com 2020-09-09 22:08:02 more
  • ASP.NET 開源匯入匯出庫Magicodes.IE Docker中使用

    Magicodes.IE在Docker中使用 更新歷史 2019.02.13 【Nuget】版本更新到2.0.2 【匯入】修復單列匯入的Bug,單元測驗“OneColumnImporter_Test”。問題見(https://github.com/dotnetcore/Magicodes.IE/is ......

    uj5u.com 2020-09-09 22:08:05 more
  • 在webform中使用ajax

    如果你用過Asp.net webform, 說明你也算是.NET 開發的老兵了。WEBform應該是2011 2013左右,當時還用visual studio 2005、 visual studio 2008。后來基本都用的是MVC。 如果是新開發的專案,估計沒人會用webform技術。但是有些舊版 ......

    uj5u.com 2020-09-09 22:08:50 more
  • iis添加asp.net網站,訪問提示:由于擴展配置問題而無法提供您請求的

    今天在iis服務器配置asp.net網站,遇到一個問題,記錄一下: 問題:由于擴展配置問題而無法提供您請求的頁面。如果該頁面是腳本,請添加處理程式。如果應下載檔案,請添加 MIME 映射。 WindowServer2012服務器,添加角色安裝完.netframework和iis之后,運行aspx頁面 ......

    uj5u.com 2020-09-09 22:10:00 more
  • WebAPI-處理架構

    帶著問題去思考,大家好! 問題1:HTTP請求和回傳相應的HTTP回應資訊之間發生了什么? 1:首先是最底層,托管層,位于WebAPI和底層HTTP堆疊之間 2:其次是 訊息處理程式管道層,這里比如日志和快取。OWIN的參考是將訊息處理程式管道的一些功能下移到堆疊下端的OWIN中間件了。 3:控制器處理 ......

    uj5u.com 2020-09-09 22:11:13 more
  • 微信門戶開發框架-使用指導說明書

    微信門戶應用管理系統,采用基于 MVC + Bootstrap + Ajax + Enterprise Library的技術路線,界面層采用Boostrap + Metronic組合的前端框架,資料訪問層支持Oracle、SQLServer、MySQL、PostgreSQL等資料庫。框架以MVC5,... ......

    uj5u.com 2020-09-09 22:15:18 more
  • WebAPI-HTTP編程模型

    帶著問題去思考,大家好!它是什么?它包含什么?它能干什么? 訊息 HTTP編程模型的核心就是訊息抽象,表示為:HttPRequestMessage,HttpResponseMessage.用于客戶端和服務端之間交換請求和回應訊息。 HttpMethod類包含了一組靜態屬性: private stat ......

    uj5u.com 2020-09-09 22:15:23 more
  • 部署WebApi隨筆

    一、跨域 NuGet參考Microsoft.AspNet.WebApi.Cors WebApiConfig.cs中配置: // Web API 配置和服務 config.EnableCors(new EnableCorsAttribute("*", "*", "*")); 二、清除默認回傳XML格式 ......

    uj5u.com 2020-09-09 22:15:48 more
最新发布
  • C#多執行緒學習(二) 如何操縱一個執行緒

    <a href="https://www.cnblogs.com/x-zhi/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/2943582/20220801082530.png" alt="" /></...

    uj5u.com 2023-04-19 09:17:20 more
  • C#多執行緒學習(二) 如何操縱一個執行緒

    C#多執行緒學習(二) 如何操縱一個執行緒 執行緒學習第一篇:C#多執行緒學習(一) 多執行緒的相關概念 下面我們就動手來創建一個執行緒,使用Thread類創建執行緒時,只需提供執行緒入口即可。(執行緒入口使程式知道該讓這個執行緒干什么事) 在C#中,執行緒入口是通過ThreadStart代理(delegate)來提供的 ......

    uj5u.com 2023-04-19 09:16:49 more
  • 記一次 .NET某醫療器械清洗系統 卡死分析

    <a href="https://www.cnblogs.com/huangxincheng/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/214741/20200614104537.png" alt="" /&g...

    uj5u.com 2023-04-18 08:39:04 more
  • 記一次 .NET某醫療器械清洗系統 卡死分析

    一:背景 1. 講故事 前段時間協助訓練營里的一位朋友分析了一個程式卡死的問題,回過頭來看這個案例比較經典,這篇稍微整理一下供后來者少踩坑吧。 二:WinDbg 分析 1. 為什么會卡死 因為是表單程式,理所當然就是看主執行緒此時正在做什么? 可以用 ~0s ; k 看一下便知。 0:000> k # ......

    uj5u.com 2023-04-18 08:33:10 more
  • SignalR, No Connection with that ID,IIS

    <a href="https://www.cnblogs.com/smartstar/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/u36196.jpg" alt="" /></a>...

    uj5u.com 2023-03-30 17:21:52 more
  • 一次對pool的誤用導致的.net頻繁gc的診斷分析

    <a href="https://www.cnblogs.com/dotnet-diagnostic/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/3115652/20230225090434.png" alt=""...

    uj5u.com 2023-03-28 10:15:33 more
  • 一次對pool的誤用導致的.net頻繁gc的診斷分析

    <a href="https://www.cnblogs.com/dotnet-diagnostic/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/3115652/20230225090434.png" alt=""...

    uj5u.com 2023-03-28 10:13:31 more
  • C#遍歷指定檔案夾中所有檔案的3種方法

    <a href="https://www.cnblogs.com/xbhp/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/957602/20230310105611.png" alt="" /></a&...

    uj5u.com 2023-03-27 14:46:55 more
  • C#/VB.NET:如何將PDF轉為PDF/A

    <a href="https://www.cnblogs.com/Carina-baby/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/2859233/20220427162558.png" alt="" />...

    uj5u.com 2023-03-27 14:46:35 more
  • 武裝你的WEBAPI-OData聚合查詢

    <a href="https://www.cnblogs.com/podolski/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/616093/20140323000327.png" alt="" /><...

    uj5u.com 2023-03-27 14:46:16 more