electron 总结

前言

有一个web项目需要用客户端来包装一下 项目的主要业务都在服务器上 所以项目的大多数功能都用url 地址来访问; 客户端登陆界面在本地 打包客户端的本地登陆界面 做为登陆入口;

electron 开发中 有一个概念需要理解 我暂且叫主进程吗 main,  这个进程的控制 在项目的 配置 package.json  的main 字段中定义;

main.js 作为electron 控制的后端入口, 基本的主要控制都是在这个文件里面定义  eletron 控制系统 的接口很多也在这里面定义,详细可以查看官方API 文档;

{
"name": "linksame",
"version": "1.0.4",
"description": "邻盛管家客户端",
"main": "main.js", // 主进程控制定义
"scripts": {
"start": "electron .",
"dist": "electron-builder -wm",
"build": "electron-builder",
"test": "echo \"Error: no test specified\" && exit 1"
},

模块

使用到的nodejs 模块:


"electron-main-notification": "^1.0.1", // 右下角消息提醒 组件
"electron-notify": "^0.1.0",// 消息提醒组件
"electron-packager": "^10.1.2",// 项目打包 组件 打包为独立的绿色运行程序
"electron-squirrel-startup": "^1.0.0",// 升级包工具 用处不详
"electron-updater": "^2.20.1",// 一个不错的升级包 制作组件 我们用它做的升级包 提醒
"gulp": "^3.9.1", // 工具链工具 本地开发
"nedb": "^1.8.0",// 一个数据库组件 对象性质 nodejs
"request": "^2.83.0" // 一个请求库

项目用到 eletron 主要的模块 说明

const electron = require('electron') //
//import { autoUpdater } from "electron-updater"
const autoUpdater=require('electron-updater').autoUpdater // 升级包检测 不同于官方默认的那个
autoUpdater.autoDownload = false // 配置取消自动下载
// Module to control application life.
const app = electron.app // 项目基础控制
// Module to create native browser window.
const BrowserWindow = electron.BrowserWindow // 开窗口控制
const BrowserView = electron.BrowserView // 窗口控制另外一种方式
const dialog = electron.dialog // 系统弹出地址框
const Tray = electron.Tray // 右下角任务栏
const Menu = electron.Menu //右下角任务栏 菜单控制
const Notification = electron.Notification // 消息提醒
const window = electron.window
const ipcMain = require('electron').ipcMain // 重点 主进程通信专用 发通道信息 监听通道
const ipcRenderer = require('electron').ipcRenderer // 重点 子窗口 通信专用 可以在子窗口中 和 主进程通信
//const storage = require('electron-json-storage')
const {shell} = require('electron') // electron 基础功能接口 例如 打开浏览器网页 ; 打开文件 运行程序等等;
const notify = require('electron-main-notification') // 也是一个消息对话框
const {session} = require('electron') // seesion cookie 控制
const fs = require('fs'); // nodejs 模块 文件文本操作等等 io
const nedb = require('nedb'); // 数据库 一个nodejs 中可以用的数据库

通信

const ipcMain = require('electron').ipcMain // 重点 主进程通信专用 发通道信息 监听通道

const ipcRenderer = require('electron').ipcRenderer // 重点 子窗口 通信专用 可以在子窗口中 和 主进程通信

// 例如 主穿裤中监听 界面发来的命令 主进程中执行相应操作

ipcMain.on('window-min',function(){

mainWindow.minimize();

})

// 主进程发起送消息 其他页面会收到数据domianObj

mainWindow.webContents.send('islogin',domainObj)

本地数据库

打包

npm run build

升级包制作

参考 :https://www.electron.build/auto-update

const autoUpdater=require('electron-updater').autoUpdater // 升级包检查模块 包含检查升级包 下载 安装等接口封装 都在里面

autoUpdater.setFeedURL('http://www.linksame.com/release/');

升级包检测 比较

app.getVersion() // 系统当前版本

// 检查升级包接口 返回 Promise 对象

let checkinfo=autoUpdater.checkForUpdates();

//console.log('checkinfo:',checkinfo)

checkinfo.then(function(data){

console.log('datav:::',data.versionInfo.version)

console.log('datav2:::',data)

// 返回的data 为网络上版本最新版信息 可获取系统版本号 和 最新版本好比较 确定要部要升级

if(data.versionInfo.version!=app.getVersion()){

updateHandle();

//const UpdateInfo=require('electron-updater').UpdateInfo

//console.log('UpdateInfo:',)

}

})

Promise 应用 对象

异步变成 新规范 一些功能中用到了 例如 autoUpdater 升级管理 模块的的一些接口 就是 该类型

参考

升级参考

main.js 参考

项目组控制 介绍说明


if (require('electron-squirrel-startup')) return;
const electron = require('electron')
//import { autoUpdater } from "electron-updater"
const autoUpdater=require('electron-updater').autoUpdater
autoUpdater.autoDownload = false // 配置取消自动下载
// Module to control application life.
const app = electron.app
// Module to create native browser window.
const BrowserWindow = electron.BrowserWindow
const BrowserView = electron.BrowserView
const dialog = electron.dialog
const Tray = electron.Tray
const Menu = electron.Menu
const Notification = electron.Notification
const window = electron.window
const ipcMain = require('electron').ipcMain
const ipcRenderer = require('electron').ipcRenderer
//const storage = require('electron-json-storage')
const {shell} = require('electron')
const notify = require('electron-main-notification')
const {session} = require('electron')
const fs = require('fs');
const nedb = require('nedb'); // 数据库 const path = require('path')
const url = require('url') const icologo=__dirname+'\\ioc\\ls.ico'
// 域名
const domain="http://www.linksame.com";
const loginpath=domain+"/index.php?app=Core&m=Pcdlogin&network=1&ip=0"
const request = require('request')
// 判断网络配置
const options = {
       method: 'post',
url:domain+'/release/network.json',
form: "content",
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
}; const message={
error:'check version error',
checking:'check updateing ......',
updateAva:'find a New Version,downloading ......',
updateNotAva:'now it New best',
};
const os = require('os'); // init obj
let mainWindow
let tray = null
const app_data=app.getPath('userData')
console.log('app_data',app_data) // 设置共享运行目录
global.linksame = {
runpath: app_data
} // 实例化连接对象(不带参数默认为内存数据库) const db = new nedb({
filename: path.join(app_data,'\\Cache\\downloadfile.db'),
autoload: true
});
let date=new Date(); const initobj={
width:1024,
height:760,
} function createWindow() {
// Create the browser window.
mainWindow = new BrowserWindow({
width: 712,
height: 588,
icon:icologo,
title:'邻盛企业管家',
frame: false,
transparent: true,
webPreferences:{
nodeIntegration:true,
nodeIntegrationInWorker:true,
}
}) //Menu.setApplicationMenu(null); const mainindex = path.join('file://', __dirname, 'index.html')
mainWindow.loadURL(mainindex) mainWindow.once('ready-to-show', () => {
mainWindow.show()
}) // Open the DevTools.
// mainWindow.webContents.openDevTools() // Emitted when the window is closed.
mainWindow.on('closed', function() { mainWindow = null
}) //捕获新打开窗口事件 定制新窗口
mainWindow.webContents.on('new-window', (event, url) => {
event.preventDefault()
const win = new BrowserWindow({
width: 1024,
height: 760,
icon:__dirname+'./ioc/ls.ico',
title:'邻盛企业管家',
frame: false,
transparent: true,
backgroundColor:'#4385F4', }) win.once('ready-to-show', () => win.show())
win.loadURL(url)
//event.newGuest = win console.log('windowID:',win.id) ipcMain.on('sub-close',function(d){
console.log('d',d)
win.hide()
}) }) // download mainWindow.webContents.session.on('will-download', (event, item, webContents) => {
// Set the save path, making Electron not to prompt a save dialog. item.on('updated', (event, state) => { if (state === 'interrupted') {
console.log('Download is interrupted but can be resumed')
} else if (state === 'progressing') {
// set loading progressBar
mainWindow.setProgressBar(item.getReceivedBytes() / item.getTotalBytes()); if (item.isPaused()) {
console.log('Download is paused')
} else { if(Math.ceil(item.getReceivedBytes()/1024/1024)===1){
let title='稍等 正在下载';
let body= item.getSavePath();
let ico=getico(item.getSavePath());
notifly(title,body,ico)
} let download = `Received bytes: ${Math.ceil(item.getReceivedBytes()/1024/1024)} M / ${Math.ceil(item.getTotalBytes()/1024/1024)}M` console.log(`Received bytes: ${Math.ceil(item.getReceivedBytes()/1024/1024)} M / ${Math.ceil(item.getTotalBytes()/1024/1024)}M`)
}
}
})
item.once('done', (event, state) => { if (state === 'completed') {
const filepath=item.getSavePath();
var arr = filepath.split('\\');
let filename=arr[arr.length-1]; let title=filename+' 下载完成!';
let body= item.getSavePath()+' 打开';
let ico=getico(item.getSavePath()); //notifly(title,body,ico)
notiflyclick(title,body,function(){ shell.openItem(filepath) })
console.log('Download successfully') db.insert({
name: filename,
path:item.getSavePath(),
datetime:date.toLocaleDateString(),
sizes:Math.ceil(item.getTotalBytes()/1024/1024),
}, (err, ret) => {
console.log('insert successfully',err,ret)
}); } else {
console.log(`Download failed: ${state}`)
}
}) }) // 任务栏图标菜单 A
tray = new Tray(icologo)
const contextMenu = Menu.buildFromTemplate([{
label: '帮助中心',
type: 'normal',
icon: __dirname+'\\ioc\\help.png',
click: function() {
shell.openExternal('http://help.linksame.com/')
}
},
{ label: '官网', type: 'normal', icon: __dirname+'\\ioc\\web.png',click:function(){
shell.openExternal('http://www.linksame.com')
}},
{ label: '移动端', type: 'normal', icon:__dirname+'\\ioc\\phone.png',click:function(){
//shell.openExternal('http://www.linksame.com/index.php?app=Core&m=V7&a=download') const modalPath = path.join('file://', __dirname, 'qcode.html')
//let win = new BrowserWindow({ width: 705, height: 250,resizable:false,autoHideMenuBar:true,type: 'desktop', icon: './ioc/download2.png' })
let win = new BrowserWindow({
title:'移动设备软件下载',
width: 250,
height: 250,
autoHideMenuBar:true,
type: 'desktop',
icon:__dirname+'\\ioc\\phone.png',
resizable:false,
maximizable:false, })
//win.setApplicationMenu(null);
win.on('close', function() { win = null })
win.loadURL(modalPath)
win.show() } },
{
label: '下载管理',
type: 'normal',
icon:__dirname+'\\ioc\\down.png',
click: function() {
const modalPath = path.join('file://', __dirname, 'download.html')
//let win = new BrowserWindow({ width: 705, height: 250,resizable:false,autoHideMenuBar:true,type: 'desktop', icon: './ioc/download2.png' })
let win = new BrowserWindow({
width: 705,
height: 250,
autoHideMenuBar:true,
type: 'desktop',
icon: __dirname+'\\ioc\\download2.png',
resizable:false,
maximizable:false,
})
//win.setApplicationMenu(null);
win.on('close', function() { win = null })
win.loadURL(modalPath)
win.show()
}
},
{
label: '设置',
type: 'submenu',
icon:__dirname+'\\ioc\\setting.png',
submenu: [
{ label: '开机启动', type: 'normal', icon:__dirname+'\\ioc\\sysset.png' },
{ label: '更新缓存', type: 'normal', icon:__dirname+'\\ioc\\clear-2.png',click:function(){
let cachepath=app_data+'/Cache'
let dir=fs.readdir(cachepath,(err,file)=>{ for(v in file){
console.log('file',v)
let rmnum=shell.moveItemToTrash(path.join(cachepath,file[v]))
console.log('remove',rmnum)
}
notifly('缓存清理','缓存清理完成!',__dirname+'\\ioc\\ok.png') })
}}, ]
},
{ label: '升级', type: 'normal', icon: __dirname+'\\ioc\\upgrate.png',click:function(){
updateHandle();
} },
{ label: '注销', type: 'normal', icon: __dirname+'\\ioc\\zx.png', role: 'close',click:function(){ // console.log('siht',console.log(ses.getUserAgent()))
// 查询与指定 url 相关的所有 cookies. /*session.defaultSession.cookies.remove('http://www.linksame.com','sns_shell',function(cookies) {
console.log('remove~~~~')
});*/
session.defaultSession.cookies.get({url:domain}, function(error, cookies) { let domainObj=cookies
for (var i in domainObj){
console.log(i,':',domainObj[i])
session.defaultSession.cookies.remove(domain,domainObj[i].name, function(data) {
console.log('remove',data);
}); }
//console.log('ddd',domainObj)
}); let newobj=session.defaultSession.cookies.get({ url : domain }, function(error, cookies) {
console.log('login out coockie:',newobj)
}); app.quit();
//session.cookies.remove("http://www.linksame.com", name, callback) }},
{ label: '退出', type: 'normal', icon:__dirname+'\\ioc\\loginout.png', role: 'close',click:function(){
const dopt={
type:'question',
title:'你确定要退出吗?',
buttons:['确定','取消'],
defaultId:1,
message:'退出后 会关闭邻盛企业管家。',
//icon:'./ioc/ls.ico',
noLink:true,
}
dialog.showMessageBox(dopt,function(e){
console.log('e:',e)
if(e==0){
app.quit();
}else{
console.log('nat close')
}
//
}) }}
])
tray.setToolTip('邻盛企业管家 你的企业好帮手!')
tray.setContextMenu(contextMenu) } // This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.on('ready', createWindow) // Quit when all windows are closed.
app.on('window-all-closed', function() {
// On OS X it is common for applications and their menu bar
// to stay active until the user quits explicitly with Cmd + Q
if (process.platform !== 'darwin') {
app.quit()
}
}) app.on('activate', function() {
// On OS X it's common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (mainWindow === null) {
createWindow()
}
}) //登录窗口最小化
ipcMain.on('window-min',function(){
mainWindow.minimize();
}) //重新设置大小
ipcMain.on('window-reset',function(){
console.log(initobj.width, initobj.height) mainWindow.setSize(initobj.width, initobj.height)
mainWindow.center()
}) //登录窗口最大化
ipcMain.on('window-max',function(data){ console.log('data',data) if(mainWindow.isMaximized()){
mainWindow.restore();
}else{
mainWindow.maximize();
}
}) ipcMain.on('window-close',function(){
mainWindow.close();
}) // 检查登陆
ipcMain.on('islogin',function(){
session.defaultSession.cookies.get({url:domain,name:'sns_username'}, function(error, cookies) {
let domainObj=cookies
// console.log('ddd',domainObj[0].value)
mainWindow.webContents.send('islogin',domainObj)
});
})
// 检查网络
ipcMain.on('testNetwork',function(){
request(options, function (err, res, body) {
if (err) {
console.log(err)
}else {
mainWindow.webContents.send('testNetwork',body)
}
})
})
// 注销登陆
ipcMain.on('loginout',function(){
session.defaultSession.cookies.get({url:domain}, function(error, cookies) { let domainObj=cookies
for (var i in domainObj){
console.log(i,':',domainObj[i])
session.defaultSession.cookies.remove(domain,domainObj[i].name, function(data) {
console.log('remove',data);
}); }
//console.log('ddd',domainObj)
});
//app.quit();
//mainWindow.loadURL(loginpath)
}) // 消息通知 函数
function notifly(title,body,ico){
const opt = {
icon: ico,
title: title,
body: body,
}
const m = new Notification(opt);
m.show() } // 可点击事件的通知
function notiflyclick(title,body,callback){
notify(title, { body: body }, () => {
console.log('The notification got clicked on!')
callback()
})
} //自动获取图标
function getico(path){
let str = path.substring(path.lastIndexOf(".")+1);
switch (str) {
case 'doc':
return __dirname+'\\ioc/format/doc.png';
break;
case 'docx':
return __dirname+'\\ioc/format/doc.png';
break;
case 'xls':
return __dirname+'\\ioc/format/excel.png';
break;
case 'xlsx':
return __dirname+'\\ioc/format/excel.png';
break;
case 'csv':
return __dirname+'\\ioc/format/excel.png';
break;
case 'exe':
return __dirname+'\\ioc/format/exe.png';
break;
case 'html':
return __dirname+'\\ioc/format/file_html.png';
break;
case 'htm':
return __dirname+'\\ioc/format/file_html.png';
break;
case 'pptx':
return __dirname+'\\ioc/format/ppt.png';
break;
case 'ppx':
return __dirname+'\\ioc/format/ppt.png';
break;
case 'rar':
return __dirname+'\\ioc/format/rar.png';
break;
case 'zip':
return __dirname+'\\ioc/format/zip.png';
break;
case 'gz':
return __dirname+'\\ioc/format/zip.png';
break;
case 'tar':
return __dirname+'\\ioc/format/zip.png';
break;
case 'pdf':
return __dirname+'\\ioc/format/pdf.png';
break;
case 'png':
return __dirname+'\\ioc/format/png.png';
break;
case 'jpg':
return __dirname+'\\ioc/format/jpg.png';
break;
case 'gif':
return __dirname+'\\ioc/format/gif.png';
break;
default:
return __dirname+'\\ioc/format/file.png';
break;
}
}
//================ 升级 autoUpdater.setFeedURL('http://www.linksame.com/release/');
// 检测更新,在你想要检查更新的时候执行,renderer事件触发后的操作自行编写
function updateHandle(){ autoUpdater.on('error', function(error){
sendUpdateMessage(message.error)
});
autoUpdater.on('checking-for-update', function(info) {
console.log('checking for update:::',info)
sendUpdateMessage(message.checking)
});
autoUpdater.on('update-available', function(info) {
console.log('update-available:::',info)
upwin.webContents.send('checkinfo', info)
sendUpdateMessage(message.updateAva)
});
autoUpdater.on('update-not-available', function(info) {
sendUpdateMessage(message.updateNotAva)
}); // 更新下载进度事件
autoUpdater.on('download-progress', function(progressObj) {
console.log('downloading:',progressObj)
upwin.webContents.send('downloadProgress', progressObj)
})
autoUpdater.on('update-downloaded', function (event, releaseNotes, releaseName, releaseDate, updateUrl, quitAndUpdate) {
ipcMain.on('isUpdateNow', (e, arg) => {
//some code here to handle event
autoUpdater.quitAndInstall();
})
console.log(releaseNotes, releaseName, releaseDate, updateUrl, quitAndUpdate)
//upwin.webContents.send('isUpdateNow')
}); //执行自动更新检查
//autoUpdater.checkForUpdates();
ipcMain.on("checkForUpdate",()=>{
//执行自动更新检查 appUpdater.autoDownload = false
autoUpdater.checkForUpdates();
//console.log('checkinfo:',checkinfo) })
//执行下载
ipcMain.on("download",()=>{
autoUpdater.downloadUpdate()
})
console.log('now check updateing ~~~~')
// autoUpdater.checkForUpdates(); //open upgroud dialog
const modalPath = path.join('file://', __dirname, 'upgroud.html')
//let win = new BrowserWindow({ width: 705, height: 250,resizable:false,autoHideMenuBar:true,type: 'desktop', icon: './ioc/download2.png' })
let upwin = new BrowserWindow({
width: 705,
height: 250,
autoHideMenuBar:true,
type: 'desktop',
icon: __dirname+'\\ioc\\upgrate2.png',
resizable:false,
maximizable:false,
})
//win.setApplicationMenu(null);
upwin.on('close', function() { upwin.webContents.send('close') //ipcMain.removeAllListeners(["checkForUpdate", "download", "isUpdateNow"])
upwin = null
//ipcRenderer.removeAll(["checkForUpdate", "download", "isUpdateNow"]);
})
upwin.loadURL(modalPath)
upwin.show()
} // 通过main进程发送事件给renderer进程,提示更新信息
// mainWindow = new BrowserWindow()
function sendUpdateMessage(text){
console.log('text:',text)
//mainWindow.webContents.send('message', text)
} // 第一次运行软件 判断网络
function initview(){ }
// 自动随机检查升级包
function checkUp(){
let checkinfo=autoUpdater.checkForUpdates();
//console.log('checkinfo:',checkinfo)
checkinfo.then(function(data){
console.log('data:::',data.versionInfo.version)
if(data.versionInfo.version){
updateHandle();
}
}) }
//checkUp();
//随机时间执行检查升级
let randoms=Math.round(Math.random()*9+1)*60000;
console.log('randoms=',randoms)
setTimeout(function(){
checkUp();
},randoms)
// hi i'm a vision 1.0.2 hahah

electron 开发拆坑总结的更多相关文章

  1. Electron开发跨平台桌面程序入门教程

    最近一直在学习 Electron 开发桌面应用程序,在尝试了 java swing 和 FXjava 后,感叹还是 Electron 开发桌面应用上手最快.我会在这一篇文章中实现一个HelloWord ...

  2. 使用electron开发桌面级小程序自动部署系统

    那一天我二十一岁,在我一生的黄金时代,我有好多奢望.我想爱,想吃,还想在一瞬间变成天上半明半暗的云,后来我才知道,生活就是个缓慢受锤的过程,人一天天老下去,奢望也一天天消逝,最后变得像挨了锤的牛一样. ...

  3. Electron-使用Electron开发第一个应用

    使用Electron开发第一个应用 Electron 应用的目录结构如下: app/ ├── package.json ├── main.js └── index.html 新建一个app文件夹 将这 ...

  4. Electron开发环境部署

    Electron开发环境部署 安装node.js 可以从node.js官方网站上获取安装包,并进行安装,安装完可以通过 ndoe -v 指令进行版本查看. 本文的开发环境为node.js 4.4.5. ...

  5. 个推 Spark实践教你绕过开发那些“坑”

    Spark作为一个开源数据处理框架,它在数据计算过程中把中间数据直接缓存到内存里,能大大提高处理速度,特别是复杂的迭代计算.Spark主要包括SparkSQL,SparkStreaming,Spark ...

  6. 【Electron】Electron开发入门

    Electron简介: Electron提供了丰富的本地(操作系统)的API,使你能够使用纯JavaScript来创建桌面应用程序,并且跨平台(win,mac,linux等各种PC端平台).与其它各种 ...

  7. Android项目开发填坑记-Fragment的onBackPressed

    Github版 CSDN版 知识背景 Fragment在当前的Android开发中,有两种引用方式,一个是 Android 3.0 时加入的,一个是supportV4包中的.这里简称为Fragment ...

  8. Android项目开发填坑记-Fragment的onAttach

    背景 现在Android开发多使用一个Activity管理多个Fragment进行开发,不免需要两者相互传递数据,一般是给Fragment添加回调接口,让Activity继承并实现. 回调接口一般都写 ...

  9. Android项目开发填坑记-so文件引发的攻坚战

    故事的最初 我负责的项目A要求有播放在线视频的功能,当时从别人的聊天记录的一瞥中发现百度有相关的SDK,当时找到的是Baidu-T5Player-SDK-Android-1.4s,项目中Demo的so ...

随机推荐

  1. python 学习第二周总复习

    目录 数据类型内置方法 数字类型内置方法 整型 浮点型 字符串类型内置方法 列表类型内置方法 元祖类型内置方法 字典类型内置方法 集合类型内置方法 布尔类型 数据类型总结 拷贝 浅拷贝 深拷贝 053 ...

  2. Hive 启动报错,需先启动元数据

    Exception in thread "main" java.lang.RuntimeException: java.lang.RuntimeException: Unable ...

  3. Java-克隆一个对象

    如可方便的克隆一个对象 package com.tj; public class MyClass implements Cloneable { public Object clone() { Clon ...

  4. luogu2483 【模板】k短路([SDOI2010]魔法猪学院)

    模板题 #include <iostream> #include <cstring> #include <cstdio> #include <queue> ...

  5. tinyMCE获取鼠标选中的值

    今天遇到一个需求就是要在WordPress的文章编辑页面增加选中文字时要将选中值传递到弹出窗口中 解决方法: 去网上找到了下面这段代码,可以获取到选中文本 { type: 'textbox', nam ...

  6. 第四章 vim 可视模式

    第四章  vim 可视模式 vim的可视模式允许我们选中一块文本区域并进行操作 3种不同的可视模式  分为 操作字符文本      行文本 块文本 .命令用来重复执行可视模式中的命令   只有在操作面 ...

  7. Leetcode 327.区间和的个数

    区间和的个数 给定一个整数数组 nums,返回区间和在 [lower, upper] 之间的个数,包含 lower 和 upper.区间和 S(i, j) 表示在 nums 中,位置从 i 到 j 的 ...

  8. pytorch将cpu训练好的模型参数load到gpu上,或者gpu->cpu上

    假设我们只保存了模型的参数(model.state_dict())到文件名为modelparameters.pth, model = Net() 1. cpu -> cpu或者gpu -> ...

  9. hlgoj1881

    #include <stdio.h> +]; int main(){ int l,m; int i,j; int sign; num[]=; num[]=; while(~scanf(&q ...

  10. 【管理】个人主义—>集体主义

    导读:这个月作为学术部负责人,暴露了很多问题,个人的,集体的!我需要思考的,有很多.现在,我反思图书馆丢书这件事的处理方案:我虽然站在了管理层,却做着员工干的事儿.以一种个人主义.英雄主义去做事儿.却 ...