Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537
沒有想過在Windows 10上直接安裝和運行Xbox主機游戲?這樣的愿望似乎并非遙不可及。
微軟密謀大動作
可能Windows Insider快速通道的會員已經注意到,最近發布的兩版預覽系統中,微軟號稱對游戲進行了深入優化,不過感受的方式是鼓勵用戶從微軟商店下載《腐爛國度(State of Decay)》這款游戲。微軟并未明確列出對Windows 10玩游戲到底做了哪些具體修改,整套操作有些詭異。
資深記者Brad Sams發現了一些蛛絲馬跡,顯然微軟是要進一步拉近Xbox One和Win10 PC之間的距離。比如游戲雖然是從商店下載,但連接的是Xbox文件服務器;再比如游戲安裝包未XVC格式,這是微軟自2013年以來一直描述Xbox One平臺游戲的專屬格式,而在19H1上,借助PowerShell命令就能導入了。
再結合一些已經出現的源代碼,有理由猜測微軟正密謀大動作,或許就是要把Windows 10和Xbox One游戲不加修飾地直接打通。
不過坦率來說,Xbox平臺的主機獨占游戲除了《光環》就幾乎沒有可圈可點的了,微軟葫蘆里到底賣的什么藥呢?
微軟Win10 Lite OS主界面曝光
除了打通內部的關聯性外,微軟多年來一直試圖阻止Chromebook快速的市場份額增長。最開始,微軟曾試圖盡可能優化Windows,允許它(在某種程度上)運行在廉價的基于Atom的平板電腦和筆記本電腦上。微軟后來發布了Windows 10 S,它無法運行傳統的Windows應用程序。現在,通過開發一個全新的輕量級操作系統——Lite OS,微軟似乎更進一步。
據報道,Lite OS代號為“Santorini”,基于Windows Core OS,這是Windows的模塊化版本,將丟棄傳統組件以更好地適應新的設備外形。外媒Petri的編輯Brad Sams聲稱已經親眼看過這款新的Lite操作系統,上圖是該系統主界面的視覺效果圖,其界面看起來類似于Chrome OS的應用程序抽屜。
與傳統的Windows 10相比,Lite OS具有更簡單的UI,同時保留一些熟悉的元素。底部任務欄顯然取消了系統托盤,而“開始”菜單也會看起來不同,不再有活動磁貼。但是,文件資源管理器和窗口應用程序等經典Windows功能仍然存在。
據報道,微軟正在“積極工作”以完成Lite OS。與Windows 10 S非常相似,Lite OS只能運行通用Windows平臺(UWP)應用程序和漸進式Web應用程序。
外媒稱,預計微軟將在春季開始提及這款操作系統,可能是在5月份的Build大會上,但更重要的是,該公司將在今年夏天開始為該系統進行更廣泛的測試。
小獅子最喜歡的雞腿 分割線
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
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 庫,例如 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")
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=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 程序集的 pdb 調試文件:
dotNet.loadFile( "程序集路徑" ,"pdb 調試文件路徑" );
然后用 VS 附加運行的 aardio 進程就可以調試了,懂 .NET 的都懂,這個不多說了。
直接看 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 程序集)。
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 規則)。
用下面的 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\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 自帶范例,如果大家有任何問題可以下面評論中留言,我會盡快解答。
軟昨日向Windows Insider計劃的Release Preview通道用戶推送Windows 10 KB4505903 (Build 18362.266),其引入一項變化:當用戶同時擁有Edge Dev/Canary通道版本時,經典的老版Edge瀏覽器將被隱藏,無論是在開始菜單和Windows全局搜索中都無法找到。
不過用戶仍然可以通過在運行中輸入“microsoft-edge”開啟老版Edge瀏覽器。外媒記者已經在五臺更新Build 18362.266)的設備中驗證了這一改變。
這一改變僅對 Release Preview Ring Insider會員生效,至于其是否會在Windows 10 2019五月更新中應用,目前仍需觀察。
Windows 10 20H1
此外值得一提的是,Windows 10 20H1 預覽更新后,也包含了一些新的源碼,用戶發現,最新版本的Edge dev/canary被安裝時. 源碼新增了HideUwpEdgeFromAppListIfWin32EdgePresent,用于將舊版本Edge隱藏。
*請認真填寫需求信息,我們會在24小時內與您取得聯系。