<WindowsAppSDKSelfContained Condition=”$(IsUnpackaged) == true”>true</WindowsAppSDKSelfContained>
<SelfContained Condition=”$(IsUnpackaged) == true”>true</SelfContained>

以上修改后,編譯出來的 exe 雙擊就可以打開了

托盤圖標(biāo)(右鍵點擊有 menu)

啟動時設(shè)置窗口不能改變大小,隱藏 titlebar, 讓 Webview 控件占滿整個窗口

這里要根據(jù)平臺不同實現(xiàn)不同了,windows 平臺采用 winAPI 調(diào)用,具體看工程代碼吧!

WebView

在 MainPage.xaml 添加控件

對應(yīng)的靜態(tài) html 等文件放在工程的 Resource\Raw 文件夾下 (整個文件夾里面默認(rèn)是作為內(nèi)嵌資源打包的,工程文件里面的如下配置起的作用)

<!– Raw Assets (also remove the “Resources\Raw” prefix) –>
<MauiAsset Include=”Resources\Raw\**” LogicalName=”%(RecursiveDir)%(Filename)%(Extension)” />

【重點】js 和 csharp 互相調(diào)用

這部分我找了很多資料,最終參考了這個 demo,然后改進(jìn)了下。

主要原理是:

js 的調(diào)用封裝如下:

// 調(diào)用csharp的方法封裝
export default class CsharpMethod {
constructor(command, data) {
this.RequestPrefix = “request_csharp_”;
this.ResponsePrefix = “response_csharp_”;
// 唯一
this.dataId = this.RequestPrefix + new Date.getTime;
// 調(diào)用csharp的命令
this.command = command;
// 參數(shù)
this.data = { command: command, data: !data ? : JSON.stringify(data), key: this.dataId }
}

// 調(diào)用csharp 返回promisecall {// 把data存儲到localstorage中 目的是讓csharp端獲取參數(shù)localStorage.setItem(this.dataId, this.utf8_to_b64(JSON.stringify(this.data)));let eventKey = this.dataId.replace(this.RequestPrefix, this.ResponsePrefix);let that = this;const promise = new Promise(function (resolve, reject) {const eventHandler = function (e) {window.removeEventListener(eventKey, eventHandler);let resp = e.newValue;if (resp) {// 從base64轉(zhuǎn)換let realData = that.b64_to_utf8(resp);if (realData.startsWith(err:)) {reject(realData.substr(4));} else {resolve(realData);}} else {reject(“unknown error :” + eventKey);}};// 注冊監(jiān)聽回調(diào)(csharp端處理完發(fā)起的)window.addEventListener(eventKey, eventHandler);});// 改變location 發(fā)送給csharp端window.location = “/api/” + this.dataId;return promise;}

// 轉(zhuǎn)成base64 解決中文亂碼utf8_to_b64(str) {return window.btoa(unescape(encodeURIComponent(str)));}// 從base64轉(zhuǎn)過來 解決中文亂碼b64_to_utf8(str) {return decodeURIComponent(escape(window.atob(str)));}

}

前端的使用方式

import CsharpMethod from ../../services/api

// 發(fā)起調(diào)用csharp的chat事件函數(shù)const method = new CsharpMethod(“chat”, {msg: message});method.call // call返回promise.then(data =>{// 拿到csharp端的返回后展示onMessageHandler({message: data,username: Robot,type: chat_message});}).catch(err => {alert(err);});

csharp 端的處理:

這么封裝后,js 和 csharp 的互相調(diào)用就很方便了。

chatgpt 的開放 api 調(diào)用

注冊好 chatgpt 后可以申請一個 APIKEY。

API 封裝:

public static async Task<CompletionsResponse> GetResponseDataAsync(string prompt){// Set up the API URL and API keystring apiUrl = “https://api.openai.com/v1/completions”;

// Get the request body JSONdecimal temperature = decimal.Parse(Setting.Temperature, CultureInfo.InvariantCulture);int maxTokens = int.Parse(Setting.MaxTokens, CultureInfo.InvariantCulture);string requestBodyJson = GetRequestBodyJson(prompt, temperature, maxTokens);

// Send the API request and get the response datareturn await SendApiRequestAsync(apiUrl, Setting.ApiKey, requestBodyJson);}

private static string GetRequestBodyJson(string prompt, decimal temperature, int maxTokens){// Set up the request bodyvar requestBody = new CompletionsRequestBody{Model = “text-davinci-003”,Prompt = prompt,Temperature = temperature,MaxTokens = maxTokens,TopP = 1.0m,FrequencyPenalty = 0.0m,PresencePenalty = 0.0m,N = 1,Stop = “[END]”,};

// Create a new JsonSerializerOptions object with the IgnoreNullValues and IgnoreReadOnlyProperties properties set to truevar serializerOptions = new JsonSerializerOptions{IgnoreNullValues = true,IgnoreReadOnlyProperties = true,};

// Serialize the request body to JSON using the JsonSerializer.Serialize method overload that takes a JsonSerializerOptions parameterreturn JsonSerializer.Serialize(requestBody, serializerOptions);}

private static async Task<CompletionsResponse> SendApiRequestAsync(string apiUrl, string apiKey, string requestBodyJson){// Create a new HttpClient for making the API requestusing HttpClient client = new HttpClient;

// Set the API key in the request headersclient.DefaultRequestHeaders.Add(“Authorization”, “Bearer ” + apiKey);

// Create a new StringContent object with the JSON payload and the correct content typeStringContent content = new StringContent(requestBodyJson, Encoding.UTF8, “application/json”);

// Send the API request and get the responseHttpResponseMessage response = await client.PostAsync(apiUrl, content);

// Deserialize the responsevar responseBody = await response.Content.ReadAsStringAsync;

// Return the response datareturn JsonSerializer.Deserialize<CompletionsResponse>(responseBody);}

調(diào)用方式

var reply = await ChatService.GetResponseDataAsync(xxxxxxxxxx);

在學(xué)習(xí) maui 的過程中,遇到問題我在 Microsoft Learn 提問,回答的效率很快,推薦大家試試看!

微軟最有價值專家(MVP)

微軟最有價值專家是微軟公司授予第三方技術(shù)專業(yè)人士的一個全球獎項。29年來,世界各地的技術(shù)社區(qū)領(lǐng)導(dǎo)者,因其在線上和線下的技術(shù)社區(qū)中分享專業(yè)知識和經(jīng)驗而獲得此獎項。

MVP是經(jīng)過嚴(yán)格挑選的專家團(tuán)隊,他們代表著技術(shù)最精湛且最具智慧的人,是對社區(qū)投入極大的熱情并樂于助人的專家。MVP致力于通過演講、論壇問答、創(chuàng)建網(wǎng)站、撰寫博客、分享視頻、開源項目、組織會議等方式來幫助他人,并最大程度地幫助微軟技術(shù)社區(qū)用戶使用 Microsoft 技術(shù)。

更多詳情請登錄官方網(wǎng)站:

https://mvp.microsoft.com/zh-cn

掃碼了解更多 MAUI 相關(guān)資料。

點擊「閱讀原文」了解 MAUI ~返回搜狐,查看更多


責(zé)任編輯:

不會自己注冊chagpt賬號或者太麻煩,可以直接購買一個成品chagpt賬號,直接使用!一人一號,獨立使用!直接購買聯(lián)系qq465693115 定制個人郵箱,非共享號碼實時幫你接收驗證碼,非??焖?

贊(0)
未經(jīng)允許不得轉(zhuǎn)載:揚州昇茂照明科技有限公司 » 使用 NET MAUI 開發(fā) ChatGPT 客戶端
分享到

相關(guān)推薦

登錄

找回密碼

注冊

手机看法国无码网站 | 91有色国产视频 | 99精品成人无码A片漫画 | 18精品久久久无码免费网站 | 少妇大叫太大太粗太爽了A片软件 | 成年人免费在线观看的视频 | 91青青草国产情侣 | 丰满人妻熟妇乱又伦精品凤鸣阁 | 国产老妇女婬片A级毛片 | 国产成人精品久久二区二区三区 | 亚洲熟妇无码Av无码www | 丁香草国际视频在线播放 | 久久亚洲国产精品无码一区 | 国产69精品久久久久熟女白洁老汉出租屋 | 91狠狠色综合久久久夜色撩人 | 国产精品久久7777777 | 少妇人妻一级A毛片无码九太网 | A√国产精品一级特成人午夜影院 | 嫩草视频在线观看 | 91综合区亚一洲线观看 | 波多野结衣219无码一区 | 久久久久久精久久ww | 国产一区二区无码AV在线 | 蜜臀久久99堂精品久久 | 欧美熟妇精品黑人巨大一二三区 | 亚洲欧洲无码色中文字幕在线 | 国内久久综合色欲啪 | 91麻豆精品A片国产在线观看 | 99久久精品国产一区二区野战 | 成人免费一区二区三区视频网站 | 一级a毛片免费看久久久久 精品一区二区三区日日av | 免费无码又爽又高潮又黄 | 国产毛片午夜福利 | 极品少妇XXXX精品少妇偷拍 | 巨乳黑丝袜少妇在线观看 | 亚洲一区二区三区在线 | 无码精品人妻一区二区三区动画 | 75精品福利导航 | 国产传媒一区二区三区高清视频 | 69精品视频一区二区在线观看 | 国产精品 色哟哟 |