全局广播,键盘操作

This commit is contained in:
snltty
2023-09-28 01:00:05 +08:00
parent c264231c8d
commit faa57ec0c7
98 changed files with 5824 additions and 232 deletions

View File

@@ -17,6 +17,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "cmonitor.win", "cmonitor.wi
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cmonitor.volume", "cmonitor.volume\cmonitor.volume.vcxproj", "{EDA47DD6-82DC-415C-A3CC-35A564FF0D0F}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cmonitor.volume", "cmonitor.volume\cmonitor.volume.vcxproj", "{EDA47DD6-82DC-415C-A3CC-35A564FF0D0F}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "notify.win", "notify.win\notify.win.csproj", "{CED6A505-AD7E-4F61-AB40-8D3973F431AB}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU
@@ -156,6 +158,24 @@ Global
{EDA47DD6-82DC-415C-A3CC-35A564FF0D0F}.ReleaseLinux|x64.Build.0 = Release|x64 {EDA47DD6-82DC-415C-A3CC-35A564FF0D0F}.ReleaseLinux|x64.Build.0 = Release|x64
{EDA47DD6-82DC-415C-A3CC-35A564FF0D0F}.ReleaseLinux|x86.ActiveCfg = Release|Win32 {EDA47DD6-82DC-415C-A3CC-35A564FF0D0F}.ReleaseLinux|x86.ActiveCfg = Release|Win32
{EDA47DD6-82DC-415C-A3CC-35A564FF0D0F}.ReleaseLinux|x86.Build.0 = Release|Win32 {EDA47DD6-82DC-415C-A3CC-35A564FF0D0F}.ReleaseLinux|x86.Build.0 = Release|Win32
{CED6A505-AD7E-4F61-AB40-8D3973F431AB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{CED6A505-AD7E-4F61-AB40-8D3973F431AB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{CED6A505-AD7E-4F61-AB40-8D3973F431AB}.Debug|x64.ActiveCfg = Debug|Any CPU
{CED6A505-AD7E-4F61-AB40-8D3973F431AB}.Debug|x64.Build.0 = Debug|Any CPU
{CED6A505-AD7E-4F61-AB40-8D3973F431AB}.Debug|x86.ActiveCfg = Debug|Any CPU
{CED6A505-AD7E-4F61-AB40-8D3973F431AB}.Debug|x86.Build.0 = Debug|Any CPU
{CED6A505-AD7E-4F61-AB40-8D3973F431AB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{CED6A505-AD7E-4F61-AB40-8D3973F431AB}.Release|Any CPU.Build.0 = Release|Any CPU
{CED6A505-AD7E-4F61-AB40-8D3973F431AB}.Release|x64.ActiveCfg = Release|Any CPU
{CED6A505-AD7E-4F61-AB40-8D3973F431AB}.Release|x64.Build.0 = Release|Any CPU
{CED6A505-AD7E-4F61-AB40-8D3973F431AB}.Release|x86.ActiveCfg = Release|Any CPU
{CED6A505-AD7E-4F61-AB40-8D3973F431AB}.Release|x86.Build.0 = Release|Any CPU
{CED6A505-AD7E-4F61-AB40-8D3973F431AB}.ReleaseLinux|Any CPU.ActiveCfg = Release|Any CPU
{CED6A505-AD7E-4F61-AB40-8D3973F431AB}.ReleaseLinux|Any CPU.Build.0 = Release|Any CPU
{CED6A505-AD7E-4F61-AB40-8D3973F431AB}.ReleaseLinux|x64.ActiveCfg = Release|Any CPU
{CED6A505-AD7E-4F61-AB40-8D3973F431AB}.ReleaseLinux|x64.Build.0 = Release|Any CPU
{CED6A505-AD7E-4F61-AB40-8D3973F431AB}.ReleaseLinux|x86.ActiveCfg = Release|Any CPU
{CED6A505-AD7E-4F61-AB40-8D3973F431AB}.ReleaseLinux|x86.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE

View File

@@ -5,3 +5,8 @@ export const exec = (names, commands) => {
names, commands names, commands
}); });
} }
export const keyboard = (names, key, type) => {
return sendWebsocketMsg('command/Keyboard', {
names, input: { key, type }
});
}

View File

@@ -0,0 +1,8 @@
import { sendWebsocketMsg } from './request'
export const notifyUpdate = (speed, msg) => {
return sendWebsocketMsg('notify/update', {
speed, msg
});
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 77 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

View File

@@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1695713240314" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="14947" xmlns:xlink="http://www.w3.org/1999/xlink" width="400" height="400"><path d="M937.51 195.12h-852a80.09 80.09 0 0 0-80 80v473a80.09 80.09 0 0 0 80 80h852a80.09 80.09 0 0 0 80-80v-473a80.09 80.09 0 0 0-80-80z m20 553a20 20 0 0 1-20 20h-852a20 20 0 0 1-20-20v-473a20 20 0 0 1 20-20h852a20 20 0 0 1 20 20z" fill="#3e5a6e" p-id="14948"></path><path d="M197.51 374.12l100 0 0 80-100 0 0-80Z" fill="#3e5a6e" p-id="14949"></path><path d="M197.51 570.12l100 0 0 80-100 0 0-80Z" fill="#3e5a6e" p-id="14950"></path><path d="M373.51 374.12l100 0 0 80-100 0 0-80Z" fill="#3e5a6e" p-id="14951"></path><path d="M373.51 570.12l276 0 0 80-276 0 0-80Z" fill="#3e5a6e" p-id="14952"></path><path d="M550.51 374.12l100 0 0 80-100 0 0-80Z" fill="#3e5a6e" p-id="14953"></path><path d="M726.51 374.12l100 0 0 80-100 0 0-80Z" fill="#3e5a6e" p-id="14954"></path><path d="M726.51 570.12l100 0 0 80-100 0 0-80Z" fill="#3e5a6e" p-id="14955"></path></svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@@ -112,13 +112,24 @@ span.split-pad10 {
} }
.scrollbar, .scrollbar,
.scrollbar-1,
.scrollbar-4, .scrollbar-4,
.scrollbar-10 { .scrollbar-10 {
overflow: auto; overflow: auto;
} }
.scrollbar-1::-webkit-scrollbar {
width: 0px;
height: 1px;
}
.scrollbar-1::-webkit-scrollbar-thumb {
background: rgba(0, 0, 0, 0.1);
border-radius: 10px;
}
.scrollbar::-webkit-scrollbar { .scrollbar::-webkit-scrollbar {
width: 4px; width: 1px;
height: 1px; height: 1px;
} }
@@ -147,6 +158,17 @@ span.split-pad10 {
border-radius: 10px; border-radius: 10px;
} }
:root {
--el-color-primary: var(--el-color-success) !important;
--el-color-primary-light-3: var(--el-color-success-light-3) !important;
--el-color-primary-light-5: var(--el-color-success-light-5) !important;
--el-color-primary-light-7: var(--el-color-success-light-7) !important;
--el-color-primary-light-8: var(--el-color-success-light-8) !important;
--el-color-primary-light-9: var(--el-color-success-light-9) !important;
--el-color-primary-dark-2: var(--el-color-success-dark-2) !important;
}
.el-table--scrollable-y .el-table__body-wrapper::-webkit-scrollbar { .el-table--scrollable-y .el-table__body-wrapper::-webkit-scrollbar {
background: #f5f5f5 background: #f5f5f5
} }

View File

@@ -14,6 +14,7 @@ import 'element-plus/theme-chalk/dark/css-vars.css'
import { import {
ChromeFilled, Promotion, Grid, ArrowDown, Upload, Download, EditPen, Delete, Refresh, BellFilled, Microphone ChromeFilled, Promotion, Grid, ArrowDown, Upload, Download, EditPen, Delete, Refresh, BellFilled, Microphone
, Position, Message, Bell, Mute, SwitchButton, Lock, DataLine, CirclePlus, QuestionFilled, Monitor, Sunny, Warning, Umbrella , Position, Message, Bell, Mute, SwitchButton, Lock, DataLine, CirclePlus, QuestionFilled, Monitor, Sunny, Warning, Umbrella
, ScaleToOriginal, Close
} from '@element-plus/icons-vue' } from '@element-plus/icons-vue'
app.component(ChromeFilled.name, ChromeFilled); app.component(ChromeFilled.name, ChromeFilled);
app.component(Promotion.name, Promotion); app.component(Promotion.name, Promotion);
@@ -40,6 +41,8 @@ app.component(Monitor.name, Monitor);
app.component(Sunny.name, Sunny); app.component(Sunny.name, Sunny);
app.component(Warning.name, Warning); app.component(Warning.name, Warning);
app.component(Umbrella.name, Umbrella); app.component(Umbrella.name, Umbrella);
app.component(ScaleToOriginal.name, ScaleToOriginal);
app.component(Close.name, Close);
app.use(ElementPlus, { size: 'default' }).use(router).mount('#app'); app.use(ElementPlus, { size: 'default' }).use(router).mount('#app');

View File

@@ -7,7 +7,7 @@
</el-select> </el-select>
</div> </div>
<template #footer> <template #footer>
<el-button type="primary" @click="handleUsername"> </el-button> <el-button type="success" @click="handleUsername" plain> </el-button>
</template> </template>
</el-dialog> </el-dialog>
<el-dialog title="管理端口" destroy-on-close v-model="showPort" center :show-close="false" :close-on-click-modal="false" align-center width="70%"> <el-dialog title="管理端口" destroy-on-close v-model="showPort" center :show-close="false" :close-on-click-modal="false" align-center width="70%">
@@ -15,7 +15,7 @@
<el-input v-model="state.port" style="width:auto"></el-input> <el-input v-model="state.port" style="width:auto"></el-input>
</div> </div>
<template #footer> <template #footer>
<el-button type="primary" @click="handleConnect"> </el-button> <el-button type="success" @click="handleConnect" plain> </el-button>
</template> </template>
</el-dialog> </el-dialog>
</div> </div>

View File

@@ -50,10 +50,14 @@ export default {
transform: translateX(-50%) translateY(-50%); transform: translateX(-50%) translateY(-50%);
background-color: #fff; background-color: #fff;
height: 100%; height: 100%;
background-color: #333;
background-image: url('../assets/bg3.webp');
background-size: cover;
background-position: center top;
.body { .body {
position: relative; position: relative;
background-color: #fafafa; // background-color: #fafafa;
} }
} }
</style> </style>

View File

@@ -1,6 +1,6 @@
<template> <template>
<div class="device-list-wrap absolute flex flex-column" id="device-list-wrap"> <div class="device-list-wrap absolute flex flex-column" id="device-list-wrap">
<div class="items flex-1 relative scrollbar"> <div class="items flex-1 relative scrollbar-1">
<Items></Items> <Items></Items>
</div> </div>
<div class="foot"> <div class="foot">
@@ -49,7 +49,7 @@ export default {
<style lang="stylus" scoped> <style lang="stylus" scoped>
.device-list-wrap { .device-list-wrap {
.head { .head {
padding: 2rem 1rem 1rem 1rem; padding: 1rem 1rem 1rem 1rem;
border-bottom: 1px solid #ddd; border-bottom: 1px solid #ddd;
background-color: #f0f0f0; background-color: #f0f0f0;
z-index: 999; z-index: 999;
@@ -57,14 +57,22 @@ export default {
box-shadow: 1px 1px 4px rgba(0, 0, 0, 0.075); box-shadow: 1px 1px 4px rgba(0, 0, 0, 0.075);
} }
.items {
padding: 0.6rem;
transform-style: preserve-3d;
perspective: 600px;
padding-bottom: 11rem;
}
.foot { .foot {
position: absolute; position: absolute;
z-index: 999; z-index: 999;
left: 1rem; left: 0.6rem;
right: 1rem; right: 0.6rem;
bottom: 1rem; bottom: 0.6rem;
border-radius: 4px; border-radius: 4px;
// background-color: rgba(255, 255, 255, 0.8);
&:after { &:after {
content: ''; content: '';
position: absolute; position: absolute;
@@ -73,21 +81,13 @@ export default {
right: 0; right: 0;
bottom: 0; bottom: 0;
z-index: -1; z-index: -1;
border: 1px solid rgba(255, 255, 255, 0.4); border: 1px solid rgba(18, 63, 76, 0.8);
border-radius: 4px; border-radius: 4px;
background-color: rgba(186, 217, 255, 0.5); background-color: rgba(19, 67, 89, 0.5);
// background-color: rgba(219, 234, 255, 0.5);
// border: 1px solid rgba(18, 63, 76, 0.8);
backdrop-filter: blur(2px); backdrop-filter: blur(2px);
} }
} }
.items {
padding: 1rem 0.6rem;
transform-style: preserve-3d;
perspective: 600px;
background-color: #333;
background-image: url('../../assets/bg.webp');
background-size: cover;
padding-bottom: 13rem;
}
} }
</style> </style>

View File

@@ -19,7 +19,7 @@
</div> </div>
<template #footer> <template #footer>
<el-button @click="handleCancel"> </el-button> <el-button @click="handleCancel"> </el-button>
<el-button type="primary" @click="handleCancel"> </el-button> <el-button type="success" @click="handleCancel" plain> </el-button>
</template> </template>
</el-dialog> </el-dialog>
<el-dialog class="options" title="详细标题" destroy-on-close v-model="state.showTitles" center align-center width="94%"> <el-dialog class="options" title="详细标题" destroy-on-close v-model="state.showTitles" center align-center width="94%">
@@ -42,7 +42,7 @@
</div> </div>
<template #footer> <template #footer>
<el-button @click="handleCancel"> </el-button> <el-button @click="handleCancel"> </el-button>
<el-button type="primary" @click="handleCancel"> </el-button> <el-button type="success" @click="handleCancel" plain> </el-button>
</template> </template>
</el-dialog> </el-dialog>
</template> </template>

View File

@@ -19,7 +19,7 @@
</div> </div>
<template #footer> <template #footer>
<el-button @click="handleCancel"> </el-button> <el-button @click="handleCancel"> </el-button>
<el-button type="primary" :loading="state.loading" @click="handleSubmit"> </el-button> <el-button type="success" plain :loading="state.loading" @click="handleSubmit"> </el-button>
</template> </template>
</el-dialog> </el-dialog>
</template> </template>

View File

@@ -1,10 +1,9 @@
<template> <template>
<a href="javascript:;" @click="handleWindows"> <a href="javascript:;" @click="handleWindows">
<span>
<el-icon> <el-icon>
<Monitor /> <Monitor />
</el-icon>窗口 </el-icon>
</span> <span>窗口</span>
</a> </a>
</template> </template>
@@ -29,6 +28,11 @@ export default {
</script> </script>
<style lang="stylus" scoped> <style lang="stylus" scoped>
.el-icon {
vertical-align: middle;
margin-top: -3px;
}
span { span {
display: inline-flex; display: inline-flex;
line-height: 1; line-height: 1;

View File

@@ -21,7 +21,7 @@
</div> </div>
<template #footer> <template #footer>
<el-button @click="handleEditCancel"> </el-button> <el-button @click="handleEditCancel"> </el-button>
<el-button type="primary" :loading="state.loading" @click="handleEditSubmit"> </el-button> <el-button type="success" plain :loading="state.loading" @click="handleEditSubmit"> </el-button>
</template> </template>
</el-dialog> </el-dialog>
</a> </a>
@@ -58,12 +58,14 @@ export default {
}), }),
}) })
const handleCloseActive = () => { const handleCloseActive = () => {
ElMessageBox.confirm('是否确定关闭焦点窗口?', '提示', { const title = props.data.ActiveWindow.Title;
const pid = props.data.ActiveWindow.Pid;
ElMessageBox.confirm(`是否确定关闭焦点窗口?【${title}`, '提示', {
confirmButtonText: '确定', confirmButtonText: '确定',
cancelButtonText: '取消', cancelButtonText: '取消',
type: 'warning', type: 'warning',
}).then(() => { }).then(() => {
exec([props.data.MachineName], [`taskkill /f /pid ${props.data.ActiveWindow.Pid}`]).then((res) => { exec([props.data.MachineName], [`taskkill /f /pid ${pid}`]).then((res) => {
if (res) { if (res) {
ElMessage.success('操作成功'); ElMessage.success('操作成功');
} else { } else {

View File

@@ -36,7 +36,7 @@
</div> </div>
<template #footer> <template #footer>
<el-button @click="handleEditCancel"> </el-button> <el-button @click="handleEditCancel"> </el-button>
<el-button type="primary" :loading="state.loading" @click="handleEditSubmit"> </el-button> <el-button type="success" plain :loading="state.loading" @click="handleEditSubmit"> </el-button>
</template> </template>
</el-dialog> </el-dialog>
</div> </div>

View File

@@ -40,7 +40,7 @@
</div> </div>
<template #footer> <template #footer>
<el-button @click="handleEditCancel"> </el-button> <el-button @click="handleEditCancel"> </el-button>
<el-button type="primary" :loading="state.loading" @click="handleEditSubmit"> </el-button> <el-button type="success" plain :loading="state.loading" @click="handleEditSubmit"> </el-button>
</template> </template>
</el-dialog> </el-dialog>
</div> </div>
@@ -78,8 +78,9 @@ export default {
}); });
const handleAdd = (item) => { const handleAdd = (item) => {
item = item || { Name: '', ID: 0, Name: '' }; item = item || { Name: '', ID: 0, Desc: '' };
state.currentItem.Name = item.Name; state.currentItem.Name = item.Name;
state.currentItem.Desc = item.Desc;
state.currentItem.ID = item.ID; state.currentItem.ID = item.ID;
state.showEdit = true; state.showEdit = true;
} }

View File

@@ -1,18 +1,16 @@
<template> <template>
<div> <div>
<a href="javascript:;" @click="handleRebotSystem">
<el-icon>
<Refresh />
</el-icon>
</a>
<a href="javascript:;" @click="handleCloseSystem"> <a href="javascript:;" @click="handleCloseSystem">
<el-icon> <el-icon>
<SwitchButton /> <SwitchButton />
</el-icon> </el-icon>
</a> </a>
<a href="javascript:;" @click="handleKeyBoard">
<img src="../../../../assets/keyboard.svg" width="20">
</a>
<a href="javascript:;" @click="handleCommand"> <a href="javascript:;" @click="handleCommand">
<el-icon> <el-icon>
<Position /> <ScaleToOriginal />
</el-icon> </el-icon>
</a> </a>
</div> </div>
@@ -20,8 +18,6 @@
<script> <script>
import { injectPluginState } from '../../provide' import { injectPluginState } from '../../provide'
import { ElMessage, ElMessageBox } from 'element-plus';
import { exec } from '@/apis/command';
export default { export default {
props: ['data'], props: ['data'],
setup(props) { setup(props) {
@@ -32,34 +28,17 @@ export default {
pluginState.value.command.showCommand = true; pluginState.value.command.showCommand = true;
} }
const handleRebotSystem = () => {
handleSendCommand('确定重启系统吗?', `shutdown -r -f -t 00`);
}
const handleCloseSystem = () => { const handleCloseSystem = () => {
handleSendCommand('确定关闭系统吗?', `shutdown -s -f -t 00`); pluginState.value.command.items = [props.data];
pluginState.value.command.showCloseSystem = true;
} }
const handleKeyBoard = () => {
const handleSendCommand = (desc, command, value) => { pluginState.value.command.items = [props.data];
ElMessageBox.confirm(desc, '提示', { pluginState.value.command.showKeyBoard = true;
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
}).then(() => {
exec([props.data.MachineName], [command]).then((res) => {
if (res) {
ElMessage.success('操作成功');
} else {
ElMessage.error('操作失败');
}
}).catch(() => {
ElMessage.error('操作失败');
});
}).catch(() => { });
} }
return { return {
handleCommand, handleRebotSystem, handleCloseSystem handleCommand, handleCloseSystem, handleKeyBoard
} }
} }
} }

View File

@@ -1,6 +1,6 @@
<template> <template>
<el-dialog class="options" title="执行命令" destroy-on-close v-model="state.show" center align-center width="94%"> <el-dialog class="options" title="执行命令" destroy-on-close v-model="state.show" center align-center width="94%">
<div class="command-wrap flex"> <div class="command-wrap common-command-wrap flex">
<div class="items"> <div class="items">
<CheckBoxWrap ref="items" :data="globalData.devices" :items="state.items" label="MachineName" title="选择设备"></CheckBoxWrap> <CheckBoxWrap ref="items" :data="globalData.devices" :items="state.items" label="MachineName" title="选择设备"></CheckBoxWrap>
</div> </div>
@@ -19,7 +19,7 @@
</div> </div>
<template #footer> <template #footer>
<el-button @click="handleCancel"> </el-button> <el-button @click="handleCancel"> </el-button>
<el-button type="primary" @click="handleCancel"> </el-button> <el-button type="success" plain @click="handleCancel"> </el-button>
</template> </template>
</el-dialog> </el-dialog>
</template> </template>
@@ -57,6 +57,8 @@ export default {
{ label: '强制重启', value: 'shutdown -r -f -t 00' }, { label: '强制重启', value: 'shutdown -r -f -t 00' },
{ label: '打开锁屏', func: llockUpdate, value: true }, { label: '打开锁屏', func: llockUpdate, value: true },
{ label: '关闭锁屏', func: llockUpdate, value: false }, { label: '关闭锁屏', func: llockUpdate, value: false },
{ label: '开资源管理器', value: 'start explorer.exe' },
{ label: '关资源管理器', value: 'taskkill /f /t /im "explorer.exe"' },
{ label: '打开壁纸', func: wallpaperFunc, value: true }, { label: '打开壁纸', func: wallpaperFunc, value: true },
{ label: '关闭壁纸', func: wallpaperFunc, value: false }, { label: '关闭壁纸', func: wallpaperFunc, value: false },
{ label: '禁用U盘', func: usbUpdate, value: true }, { label: '禁用U盘', func: usbUpdate, value: true },
@@ -113,6 +115,15 @@ export default {
} }
} }
</script> </script>
<style lang="stylus">
.common-command-wrap {
.checkbox-wrap {
li:nth-child(2n) {
padding-bottom: 1rem;
}
}
}
</style>
<style lang="stylus" scoped> <style lang="stylus" scoped>
.command-wrap { .command-wrap {
height: 60vh; height: 60vh;
@@ -131,7 +142,7 @@ export default {
.btn { .btn {
text-align: center; text-align: center;
padding: 0.6rem 0; padding: 0.2rem 0;
width: 100%; width: 100%;
} }
} }

View File

@@ -1,6 +1,6 @@
<template> <template>
<el-button size="small" plain dark @click="handleCommand">命令<el-icon> <el-button size="small" plain dark @click="handleCommand">命令<el-icon>
<Position /> <ScaleToOriginal />
</el-icon></el-button> </el-icon></el-button>
</template> </template>

View File

@@ -1,17 +1,57 @@
<template> <template>
<div> <div>
<ChooseDig v-if="pluginState.command.showCommand" v-model="pluginState.command.showCommand"></ChooseDig> <ChooseDig v-if="pluginState.command.showCommand" v-model="pluginState.command.showCommand"></ChooseDig>
<KeyBoard v-if="pluginState.command.showKeyBoard" v-model="pluginState.command.showKeyBoard"></KeyBoard>
<el-dialog title="执行命令" destroy-on-close v-model="pluginState.command.showCloseSystem" center align-center width="94%">
<div class="t-c">
<el-button size="large" type="warning" plain @click="handleCloseSystem">强制关机</el-button>
<el-button size="large" type="danger" plain @click="handleRebotSystem">强制重启</el-button>
</div>
<template #footer></template>
</el-dialog>
</div> </div>
</template> </template>
<script> <script>
import { ElMessage, ElMessageBox } from 'element-plus';
import { injectPluginState } from '../../provide' import { injectPluginState } from '../../provide'
import ChooseDig from './ChooseDig.vue' import ChooseDig from './ChooseDig.vue'
import KeyBoard from './KeyBoard.vue'
import { exec } from '@/apis/command';
export default { export default {
components: { ChooseDig }, components: { ChooseDig, KeyBoard },
setup() { setup() {
const pluginState = injectPluginState(); const pluginState = injectPluginState();
return { pluginState }
const handleRebotSystem = () => {
handleSendCommand('确定重启系统吗?', `shutdown -r -f -t 00`);
}
const handleCloseSystem = () => {
handleSendCommand('确定关闭系统吗?', `shutdown -s -f -t 00`);
}
const handleSendCommand = (desc, command, value) => {
ElMessageBox.confirm(desc, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
}).then(() => {
pluginState.value.command.showCloseSystem = false;
const names = pluginState.value.command.items.map(c => c.MachineName);
exec(names, [command]).then((res) => {
if (res) {
ElMessage.success('操作成功');
} else {
ElMessage.error('操作失败');
}
}).catch(() => {
ElMessage.error('操作失败');
});
}).catch(() => { });
}
return { pluginState, handleRebotSystem, handleCloseSystem }
} }
} }
</script> </script>

View File

@@ -0,0 +1,139 @@
<template>
<div class="keyboard-wrap">
<a href="javascript:;" class="close"><el-icon>
<Close />
</el-icon></a>
<h3>{{state.name}}</h3>
<ul>
<template v-for="(item,index) in state.list" :key="index">
<li class="flex">
<template v-for="(item1,index1) in item" :key="index1">
<div class="flex-1 key" :style="item1.style">
<div class="inner" @mousedown="handleKeyDown(item1)" @mouseup="handleKeyUp(item1)">
{{item1.text}}
</div>
</div>
</template>
</li>
</template>
</ul>
</div>
</template>
<script>
import { computed, reactive } from 'vue'
import { injectPluginState } from '../../provide';
import { keyboard } from '@/apis/command';
export default {
setup() {
const pluginState = injectPluginState();
const state = reactive({
name: computed(() => pluginState.value.command.items.length > 0 ? pluginState.value.command.items[0].MachineName : 'unknow'),
names: computed(() => pluginState.value.command.items.map(c => c.MachineName)),
list: [
[
{ text: 'Esc', style: 'flex:0.8', key: 0x1B }, { text: 'F1', key: 0x70 }, { text: 'F4', key: 0x73 }, { text: 'F5', key: 0x74 }, { text: 'F12', key: 0x7B }, { text: '-', key: 0x6D }, { text: '+', key: 0x6B }
],
[
{ text: 'Tab', key: 0x9 }, { text: 'Q', key: 0x51 }, { text: 'W', key: 0x57 }, { text: 'E', key: 0x45 }, { text: 'Y', key: 0x59 }, { text: 'Ins', key: 0x2D }, { text: 'Back', key: 0x8 }
],
[
{ text: 'Cap', key: 0x14 }, { text: 'A', key: 0x41 }, { text: 'S', key: 0x53 }, { text: 'D', key: 0x44 }, { text: 'L', key: 0x4C }, { text: 'Enter', key: 0xD }
],
[
{ text: 'Shift', style: 'flex:1.5', key: 0xA0 }, { text: 'Z', key: 0x5A }, { text: 'X', key: 0x58 }, { text: 'C', key: 0x43 }, { text: 'V', key: 0x56 }, { text: 'Num', key: 0x90 }
],
[
{ text: 'Ctrl', key: 0xA2 }, { text: 'Win', key: 0x5B }, { text: 'Alt', key: 18 }, { text: 'Space', key: 0x20 }
]
]
});
const handleKeyDown = (item1) => {
keyboard(state.names, item1.key, 0);
}
const handleKeyUp = (item1) => {
keyboard(state.names, item1.key, 2);
}
return { state, handleKeyDown, handleKeyUp }
}
}
</script>
<style lang="stylus" scoped>
.keyboard-wrap {
position: absolute;
left: 0.6rem;
right: 0.6rem;
bottom: 0.6rem;
border-radius: 4px;
z-index: 99999;
&:after {
content: '';
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
z-index: -1;
border-radius: 4px;
background-color: rgba(219, 234, 255, 0.5);
border: 1px solid rgba(18, 63, 76, 0.8);
backdrop-filter: blur(2px);
}
a.close {
position: absolute;
right: -0.4rem;
top: -0.8rem;
color: #fff;
background-color: rgba(255, 255, 255, 0.2);
display: block;
border-radius: 50%;
border: 1px solid rgba(255, 255, 255, 0.2);
width: 1.6rem;
height: 1.6rem;
text-align: center;
line-height: 1.6rem;
}
h3 {
text-align: center;
padding-top: 0.6rem;
color: #164e51;
}
ul {
padding: 0.6rem;
.key {
padding: 0.2rem;
text-align: center;
.inner {
border: 1px solid rgba(46, 90, 95, 0.8);
background-color: rgba(255, 255, 255, 0.1);
padding: 0.6rem 0;
border-radius: 4px;
color: #164e51;
transition: 0.1s;
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
&:active {
background-color: rgba(46, 90, 95, 0.2);
color: #fff;
}
}
}
}
}
</style>

View File

@@ -1,5 +1,3 @@
import { commandPing } from '../../../../apis/command'
import { injectGlobalData } from '@/views/provide';
export default { export default {
field() { field() {
return {} return {}
@@ -7,6 +5,8 @@ export default {
state: { state: {
command: { command: {
showCommand: false, showCommand: false,
showCloseSystem: false,
showKeyBoard: false,
items: [] items: []
} }
}, },

View File

@@ -19,7 +19,7 @@
</div> </div>
<template #footer> <template #footer>
<el-button @click="handleCancel"> </el-button> <el-button @click="handleCancel"> </el-button>
<el-button type="primary" :loading="state.loading" @click="handleSubmit"> </el-button> <el-button type="success" plain :loading="state.loading" @click="handleSubmit"> </el-button>
</template> </template>
</el-dialog> </el-dialog>
</template> </template>

View File

@@ -1,8 +1,9 @@
<template> <template>
<a href="javascript:;" @click="handleDevices"> <a href="javascript:;" @click="handleDevices">
<span><el-icon> <el-icon>
<Grid /> <Grid />
</el-icon>设备</span> </el-icon>
<span>设备</span>
</a> </a>
</template> </template>
@@ -25,6 +26,11 @@ export default {
</script> </script>
<style lang="stylus" scoped> <style lang="stylus" scoped>
.el-icon {
vertical-align: middle;
margin-top: -3px;
}
span { span {
display: inline-flex; display: inline-flex;
line-height: 1; line-height: 1;

View File

@@ -17,7 +17,7 @@
</div> </div>
<template #footer> <template #footer>
<el-button @click="handleCancel"> </el-button> <el-button @click="handleCancel"> </el-button>
<el-button type="primary" :loading="state.loading" @click="handleSubmit"> </el-button> <el-button type="success" plain :loading="state.loading" @click="handleSubmit"> </el-button>
</template> </template>
</el-dialog> </el-dialog>
</template> </template>

View File

@@ -4,7 +4,8 @@
<span class="el-dropdown-link"> <span class="el-dropdown-link">
<el-icon> <el-icon>
<Umbrella /> <Umbrella />
</el-icon>网络 </el-icon>
<span>网络</span>
<el-icon class="el-icon--right"> <el-icon class="el-icon--right">
<arrow-down /> <arrow-down />
</el-icon> </el-icon>
@@ -42,15 +43,15 @@ export default {
<style lang="stylus" scoped> <style lang="stylus" scoped>
.el-icon { .el-icon {
font-size: 1.6rem; font-size: 1.6rem;
vertical-align: middle;
margin-top: -1px;
} }
.el-dropdown { .el-dropdown {
color: #ebffef; color: #f5f5f5;
font-size: 1.6rem; font-size: 1.6rem;
.el-dropdown-link { .el-dropdown-link {
display: inline-flex;
line-height: 1;
} }
} }
</style> </style>

View File

@@ -31,7 +31,7 @@ export default {
.speed { .speed {
font-size: 1.3rem; font-size: 1.3rem;
padding-top: 0.1rem; padding-top: 0.1rem;
color: #333; color: #666;
span:nth-child(1) { span:nth-child(1) {
margin-right: 1rem; margin-right: 1rem;

View File

@@ -36,7 +36,7 @@
</div> </div>
<template #footer> <template #footer>
<el-button @click="handleEditCancel"> </el-button> <el-button @click="handleEditCancel"> </el-button>
<el-button type="primary" :loading="state.loading" @click="handleEditSubmit"> </el-button> <el-button type="success" plain :loading="state.loading" @click="handleEditSubmit"> </el-button>
</template> </template>
</el-dialog> </el-dialog>
</div> </div>

View File

@@ -59,7 +59,7 @@
</div> </div>
<template #footer> <template #footer>
<el-button @click="handleEditCancel"> </el-button> <el-button @click="handleEditCancel"> </el-button>
<el-button type="primary" :loading="state.loading" @click="handleEditSubmit"> </el-button> <el-button type="success" plain :loading="state.loading" @click="handleEditSubmit"> </el-button>
</template> </template>
</el-dialog> </el-dialog>
</div> </div>

View File

@@ -36,7 +36,7 @@
</div> </div>
<template #footer> <template #footer>
<el-button @click="handleEditCancel"> </el-button> <el-button @click="handleEditCancel"> </el-button>
<el-button type="primary" :loading="state.loading" @click="handleEditSubmit"> </el-button> <el-button type="success" plain :loading="state.loading" @click="handleEditSubmit"> </el-button>
</template> </template>
</el-dialog> </el-dialog>
</div> </div>

View File

@@ -25,7 +25,7 @@
<div class="slider-wrap flex flex-column"> <div class="slider-wrap flex flex-column">
<div class="silder flex flex-1"> <div class="silder flex flex-1">
<div class="flex-1"> <div class="flex-1">
<el-slider @change="handleChangeLight" v-model="state.light" vertical height="100%" /> <el-slider type="success" @change="handleChangeLight" v-model="state.light" vertical height="100%" />
</div> </div>
</div> </div>
</div> </div>
@@ -35,7 +35,7 @@
</div> </div>
<template #footer> <template #footer>
<el-button @click="handleCancel"> </el-button> <el-button @click="handleCancel"> </el-button>
<el-button type="primary" @click="handleCancel"> </el-button> <el-button type="success" plain @click="handleCancel"> </el-button>
</template> </template>
</el-dialog> </el-dialog>
</template> </template>

View File

@@ -1,6 +1,6 @@
<template> <template>
<el-col :span="4"> <el-col :span="4">
<el-switch size="small" @click="handleLock" :model-value="data.LLock.Value" inline-prompt active-text="锁屏" inactive-text="锁屏" /> <el-switch class="llock" size="small" @click="handleLock" :model-value="data.LLock.Value" inline-prompt active-text="锁屏" inactive-text="锁屏" />
</el-col> </el-col>
</template> </template>
@@ -41,4 +41,9 @@ export default {
} }
</script> </script>
<style lang="stylus" scoped></style> <style lang="stylus" scoped>
.el-switch.llock {
// --el-switch-off-color: rgba(255, 255, 255, 0.1);
--el-switch-on-color: rgba(33, 153, 33, 0.8);
}
</style>

View File

@@ -24,7 +24,7 @@
</div> </div>
<template #footer> <template #footer>
<el-button @click="handleCancel"> </el-button> <el-button @click="handleCancel"> </el-button>
<el-button type="primary" :loading="state.loading" @click="handleSubmit"> </el-button> <el-button type="success" plain :loading="state.loading" @click="handleSubmit"> </el-button>
</template> </template>
</el-dialog> </el-dialog>
</template> </template>
@@ -59,7 +59,7 @@ export default {
loading: false loading: false
}); });
try { try {
if (pluginState.value.message.items.length == 1 && pluginState.value.message.items[0].Share.UserName) { if (pluginState.value.message.items.length == 1 && pluginState.value.message.items[0].Share.UserName.Value) {
state.prevs.push(`${pluginState.value.message.items[0].Share.UserName.Value}】请注意上课纪律!`); state.prevs.push(`${pluginState.value.message.items[0].Share.UserName.Value}】请注意上课纪律!`);
} }
} catch (e) { } catch (e) {

View File

@@ -1,12 +1,17 @@
<template> <template>
<div class="share-lock-wrap" v-if="data.Share.Lock.Value.val == 'ask'"> <div class="share-lock-wrap" v-if="data.Share.Lock.Value.val == 'ask'">
<div class="inner"> <div class="inner">
<h3>请求解锁</h3>
<h5> <h5>
<span>{{data.Share.Lock.TypeText}}</span> <span>{{data.Share.Lock.TypeText}}</span>
<span v-if="data.Share.Lock.Value.type == 'remark-block'">{{data.Share.Lock.Value.star}}</span> <template v-if="data.Share.Lock.Value.type == 'remark-block' || data.Share.Lock.Value.type == 'remark-cpp'">
<span v-if="data.Share.Lock.Value.type == 'remark-cpp'">{{data.Share.Lock.Value.star}}</span> <el-checkbox v-model="data.Share.Lock.Value.notify" size="small">广播</el-checkbox>
</template>
</h5> </h5>
<div>
<template v-if="data.Share.Lock.Value.type == 'remark-block' || data.Share.Lock.Value.type == 'remark-cpp'">
<el-rate @change="handleStarChange" v-model="data.Share.Lock.Value.star" size="large" />
</template>
</div>
<div> <div>
<el-popconfirm confirm-button-text="确认" cancel-button-text="取消" title="确认驳回请求吗?" @confirm="handleReject"> <el-popconfirm confirm-button-text="确认" cancel-button-text="取消" title="确认驳回请求吗?" @confirm="handleReject">
<template #reference> <template #reference>
@@ -26,6 +31,7 @@
<script> <script>
import { reactive } from 'vue' import { reactive } from 'vue'
import { shareUpdate } from '@/apis/share' import { shareUpdate } from '@/apis/share'
import { notifyUpdate } from '@/apis/notify'
import { ElMessage } from 'element-plus'; import { ElMessage } from 'element-plus';
export default { export default {
props: ['data'], props: ['data'],
@@ -57,6 +63,7 @@ export default {
state.loading = true; state.loading = true;
let value = JSON.parse(JSON.stringify(props.data.Share.Lock.Value)); let value = JSON.parse(JSON.stringify(props.data.Share.Lock.Value));
value.val = 'confirm'; value.val = 'confirm';
props.data.Share.Lock.Value.notify = false;
shareUpdate(props.data.MachineName, { shareUpdate(props.data.MachineName, {
index: props.data.Share.Lock.Index, index: props.data.Share.Lock.Index,
value: JSON.stringify(value) value: JSON.stringify(value)
@@ -64,6 +71,9 @@ export default {
state.loading = false; state.loading = false;
if (res) { if (res) {
ElMessage.success('操作成功!'); ElMessage.success('操作成功!');
if (value.notify) {
notifyUpdate(2, `恭喜[${props.data.Share.UserName.Value}]获得【${value.star}星】点评`);
}
} else { } else {
ElMessage.error('操作失败!'); ElMessage.error('操作失败!');
} }
@@ -73,8 +83,22 @@ export default {
}); });
} }
const handleStarChange = () => {
state.loading = true;
let value = JSON.parse(JSON.stringify(props.data.Share.Lock.Value));
shareUpdate(props.data.MachineName, {
index: props.data.Share.Lock.Index,
value: JSON.stringify(value)
}).then((res) => {
state.loading = false;
}).catch(() => {
state.loading = false;
ElMessage.error('操作失败!');
});
}
return { return {
data: props.data, state, handleReject, handleConfirm data: props.data, state, handleReject, handleConfirm, handleStarChange
} }
} }
} }
@@ -88,7 +112,6 @@ export default {
right: 0; right: 0;
bottom: 0; bottom: 0;
// background-color: rgba(0, 0, 0, 0.2);
.inner { .inner {
position: absolute; position: absolute;
left: 50%; left: 50%;
@@ -101,16 +124,21 @@ export default {
z-index: 2; z-index: 2;
border-radius: 0.4rem; border-radius: 0.4rem;
h3 {
font-size: 1.5rem;
font-weight: 600;
color: #fff;
}
h5 { h5 {
font-size: 1.3rem; font-size: 1.3rem;
padding-bottom: 1rem;
color: #fff; color: #fff;
line-height: 1.6rem;
.el-checkbox {
height: 1.6rem;
vertical-align: bottom;
color: #fff;
}
}
.el-rate.el-rate--large {
height: inherit;
padding: 0.6rem 0 1.6rem 0;
} }
} }
} }

View File

@@ -4,7 +4,7 @@ export default {
Share: { Share: {
KeyBoard: { Index: 0, Value: '' }, KeyBoard: { Index: 0, Value: '' },
UserName: { Index: 1, Value: '' }, UserName: { Index: 1, Value: '' },
Lock: { Index: 2, Value: { type: 'list', val: 'none', star: 0 }, TypeText: '' }, Lock: { Index: 2, Value: { type: 'list', val: 'none', star: 0, notify: false }, TypeText: '' },
draw(canvas, ctx) { draw(canvas, ctx) {
if (this.KeyBoard.Value) { if (this.KeyBoard.Value) {

View File

@@ -1,6 +1,6 @@
<template> <template>
<el-col :span="4"> <el-col :span="4">
<el-switch size="small" @click="handleUSB" :model-value="data.Usb.Value" inline-prompt active-color="#ff0000" active-text="U盘" inactive-text="U盘" /> <el-switch class="usb" size="small" @click="handleUSB" :model-value="data.Usb.Value" inline-prompt active-text="U盘" inactive-text="U盘" />
</el-col> </el-col>
</template> </template>
@@ -41,4 +41,10 @@ export default {
} }
</script> </script>
<style lang="stylus" scoped></style> <style lang="stylus" scoped>
// var (--el-switch-off-color)
.el-switch.usb {
// --el-switch-off-color: rgba(255, 255, 255, 0.1);
--el-switch-on-color: rgba(255, 0, 0, 0.8) !important;
}
</style>

View File

@@ -1,6 +1,6 @@
<template> <template>
<el-col :span="4"> <el-col :span="4">
<el-switch size="small" @click="handleVolumeMute" :model-value="data.Volume.Mute" inline-prompt active-text="静音" inactive-text="静音" /> <el-switch class="volume" size="small" @click="handleVolumeMute" :model-value="data.Volume.Mute" inline-prompt active-text="静音" inactive-text="静音" />
</el-col> </el-col>
</template> </template>
@@ -42,4 +42,9 @@ export default {
} }
</script> </script>
<style lang="stylus" scoped></style> <style lang="stylus" scoped>
.el-switch.volume {
// --el-switch-off-color: rgba(255, 255, 255, 0.1);
--el-switch-on-color: rgba(33, 153, 33, 0.8);
}
</style>

View File

@@ -41,7 +41,7 @@
</div> </div>
</div> </div>
<div class="btn"> <div class="btn">
<el-button @click="handleMute(true)">静音</el-button> <el-button @click="handleMute(true)">设置静音</el-button>
</div> </div>
<div class="btn"> <div class="btn">
<el-button @click="handleMute(false)">取消静音</el-button> <el-button @click="handleMute(false)">取消静音</el-button>
@@ -53,7 +53,7 @@
</div> </div>
<template #footer> <template #footer>
<el-button @click="handleCancel"> </el-button> <el-button @click="handleCancel"> </el-button>
<el-button type="primary" @click="handleCancel"> </el-button> <el-button type="success" plain @click="handleCancel"> </el-button>
</template> </template>
</el-dialog> </el-dialog>
</template> </template>

View File

@@ -1,6 +1,6 @@
<template> <template>
<el-col :span="4"> <el-col :span="4">
<el-switch size="small" @click="handleWallpaper" :model-value="data.Wallpaper.Value" inline-prompt active-text="壁纸" inactive-text="壁纸" /> <el-switch class="wallpaper" size="small" @click="handleWallpaper" :model-value="data.Wallpaper.Value" inline-prompt active-text="壁纸" inactive-text="壁纸" />
</el-col> </el-col>
</template> </template>

View File

@@ -23,13 +23,13 @@ export default {
<style lang="stylus"> <style lang="stylus">
.el-dialog.is-align-center.options { .el-dialog.is-align-center.options {
margin-top: 3vh; margin-top: 1vh;
} }
</style> </style>
<style lang="stylus" scoped> <style lang="stylus" scoped>
.foot-wrap { .foot-wrap {
border-top: 1px solid rgba(0, 0, 0, 0.2); border-top: 1px solid rgba(18, 63, 76, 0.8);
position: relative; position: relative;
z-index: 999; z-index: 999;
} }
@@ -39,10 +39,10 @@ ul li {
text-align: center; text-align: center;
a { a {
padding: 1.7rem 0; padding: 1.2rem 0;
font-size: 1.6rem; font-size: 1.6rem;
display: block; display: block;
color: #ebffef; color: #f5f5f5;
line-height: 1; line-height: 1;
&:hover { &:hover {

View File

@@ -65,8 +65,8 @@ export default {
padding: 0.6rem; padding: 0.6rem;
.el-button { .el-button {
background-color: rgba(58, 74, 102, 0.5); background-color: rgba(255, 255, 255, 0.05);
border-color: rgba(58, 74, 102, 0.2); border-color: rgba(18, 63, 76, 0.8);
color: #f5f5f5; color: #f5f5f5;
} }

View File

@@ -86,15 +86,16 @@ export default {
<style lang="stylus" scoped> <style lang="stylus" scoped>
.device-item { .device-item {
border: 1px solid #ddd; // border: 1px solid #ddd;
font-size: 1.6rem; font-size: 1.6rem;
background-color: #fff; // background-color: #fff;
box-shadow: 0 0 4px rgba(0, 0, 0, 0.05); box-shadow: 0 0 4px rgba(0, 0, 0, 0.05);
border-radius: 4px; width: 100%;
width: 98%;
margin: 0 auto 1rem auto; margin: 0 auto 1rem auto;
position: relative; position: relative;
transition: 0.3s; transition: 0.3s;
background-color: rgba(255, 255, 255, 0.5);
border-radius: 4px;
&:after { &:after {
content: ''; content: '';
@@ -104,6 +105,10 @@ export default {
right: 0; right: 0;
bottom: 0; bottom: 0;
z-index: -1; z-index: -1;
border: 1px solid rgba(251, 241, 242, 0.4);
// background-color: rgba(255, 255, 255, 0.5);
border-radius: 4px;
// backdrop-filter: blur(2px);
} }
dt { dt {
@@ -115,7 +120,7 @@ export default {
line-height: 2rem; line-height: 2rem;
&.connected { &.connected {
color: green; color: var(--el-color-primary);
font-weight: bold; font-weight: bold;
} }
} }
@@ -142,9 +147,9 @@ export default {
right: 0.6rem; right: 0.6rem;
bottom: 0.6rem; bottom: 0.6rem;
overflow: hidden; overflow: hidden;
background-color: #000; background-color: rgba(0, 0, 0, 0.1);
border-radius: 4px; border-radius: 4px;
border: 1px solid #ddd; border: 1px solid rgba(255, 255, 255, 0.2);
box-sizing: border-box; box-sizing: border-box;
canvas { canvas {

View File

@@ -95,7 +95,7 @@ export default {
//哪个是在最中间的 //哪个是在最中间的
const middleItem = doms.sort((a, b) => a.offset - b.offset)[0]; const middleItem = doms.sort((a, b) => a.offset - b.offset)[0];
for (let i = 0; i < items.length; i++) { for (let i = 0; i < items.length; i++) {
let style = 'z-index:9;background-color:#fff;'; let style = 'z-index:9;background-color:rgba(255,255,255,1);';
const dist = Math.abs((middleItem.index - i)); const dist = Math.abs((middleItem.index - i));
const opacity = 1 - Math.abs((middleItem.index - i)) / 10 * 2; const opacity = 1 - Math.abs((middleItem.index - i)) / 10 * 2;
const translateZ = 100 + (dist * 100); const translateZ = 100 + (dist * 100);

View File

@@ -30,6 +30,9 @@ using System.Reflection;
using cmonitor.server.client.reports.share; using cmonitor.server.client.reports.share;
using cmonitor.server.service.messengers.share; using cmonitor.server.service.messengers.share;
using cmonitor.server.client.reports.system; using cmonitor.server.client.reports.system;
using cmonitor.server.service.messengers.notify;
using cmonitor.server.client.reports.notify;
using cmonitor.server.client.reports.command;
namespace cmonitor namespace cmonitor
{ {
@@ -140,6 +143,9 @@ namespace cmonitor
serviceCollection.AddSingleton<LightReport>(); serviceCollection.AddSingleton<LightReport>();
serviceCollection.AddSingleton<ShareReport>(); serviceCollection.AddSingleton<ShareReport>();
serviceCollection.AddSingleton<SystemReport>(); serviceCollection.AddSingleton<SystemReport>();
serviceCollection.AddSingleton<NotifyReport>();
serviceCollection.AddSingleton<CommandReport>();
//服务 //服务
serviceCollection.AddSingleton<TcpServer>(); serviceCollection.AddSingleton<TcpServer>();
@@ -159,6 +165,7 @@ namespace cmonitor
serviceCollection.AddSingleton<WallpaperMessenger>(); serviceCollection.AddSingleton<WallpaperMessenger>();
serviceCollection.AddSingleton<LightMessenger>(); serviceCollection.AddSingleton<LightMessenger>();
serviceCollection.AddSingleton<ShareMessenger>(); serviceCollection.AddSingleton<ShareMessenger>();
serviceCollection.AddSingleton<NotifyMessenger>();
//api //api
serviceCollection.AddSingleton<RuleConfig>(); serviceCollection.AddSingleton<RuleConfig>();
@@ -175,6 +182,8 @@ namespace cmonitor
serviceCollection.AddSingleton<WallpaperClientService>(); serviceCollection.AddSingleton<WallpaperClientService>();
serviceCollection.AddSingleton<LightClientService>(); serviceCollection.AddSingleton<LightClientService>();
serviceCollection.AddSingleton<ShareClientService>(); serviceCollection.AddSingleton<ShareClientService>();
serviceCollection.AddSingleton<NotifyClientService>();
//web //web
serviceCollection.AddSingleton<IWebServer, WebServer>(); serviceCollection.AddSingleton<IWebServer, WebServer>();

View File

@@ -1,7 +1,7 @@
using cmonitor.server.service; using cmonitor.server.client.reports.command;
using cmonitor.server.service;
using cmonitor.server.service.messengers.command; using cmonitor.server.service.messengers.command;
using cmonitor.server.service.messengers.sign; using cmonitor.server.service.messengers.sign;
using common.libs;
using common.libs.extends; using common.libs.extends;
using MemoryPack; using MemoryPack;
@@ -11,16 +11,15 @@ namespace cmonitor.server.api.services
{ {
private readonly MessengerSender messengerSender; private readonly MessengerSender messengerSender;
private readonly SignCaching signCaching; private readonly SignCaching signCaching;
private readonly IClientServer clientServer; public CommandClientService(MessengerSender messengerSender, SignCaching signCaching)
public CommandClientService(MessengerSender messengerSender, SignCaching signCaching, IClientServer clientServer)
{ {
this.messengerSender = messengerSender; this.messengerSender = messengerSender;
this.signCaching = signCaching; this.signCaching = signCaching;
this.clientServer = clientServer;
} }
public async Task<bool> Exec(ClientServiceParamsInfo param) public async Task<bool> Exec(ClientServiceParamsInfo param)
{ {
ExecInfo info = param.Content.DeJson<ExecInfo>(); ExecInfo info = param.Content.DeJson<ExecInfo>();
byte[] bytes = MemoryPackSerializer.Serialize(info.Commands);
for (int i = 0; i < info.Names.Length; i++) for (int i = 0; i < info.Names.Length; i++)
{ {
if (signCaching.Get(info.Names[i], out SignCacheInfo cache) && cache.Connected) if (signCaching.Get(info.Names[i], out SignCacheInfo cache) && cache.Connected)
@@ -29,7 +28,27 @@ namespace cmonitor.server.api.services
{ {
Connection = cache.Connection, Connection = cache.Connection,
MessengerId = (ushort)CommandMessengerIds.Exec, MessengerId = (ushort)CommandMessengerIds.Exec,
Payload = MemoryPackSerializer.Serialize(info.Commands) Payload = bytes
});
}
}
return true;
}
public async Task<bool> KeyBoard(ClientServiceParamsInfo param)
{
KeyBoardInfo info = param.Content.DeJson<KeyBoardInfo>();
byte[] bytes = MemoryPackSerializer.Serialize(info.Input);
for (int i = 0; i < info.Names.Length; i++)
{
if (signCaching.Get(info.Names[i], out SignCacheInfo cache) && cache.Connected)
{
await messengerSender.SendOnly(new MessageRequestWrap
{
Connection = cache.Connection,
MessengerId = (ushort)CommandMessengerIds.KeyBoard,
Payload = bytes
}); });
} }
} }
@@ -44,4 +63,10 @@ namespace cmonitor.server.api.services
public string[] Names { get; set; } public string[] Names { get; set; }
public string[] Commands { get; set; } public string[] Commands { get; set; }
} }
public sealed class KeyBoardInfo
{
public string[] Names { get; set; }
public KeyBoardInputInfo Input { get; set; }
}
} }

View File

@@ -18,6 +18,7 @@ namespace cmonitor.server.api.services
public async Task<bool> Update(ClientServiceParamsInfo param) public async Task<bool> Update(ClientServiceParamsInfo param)
{ {
LLockUpdateInfo info = param.Content.DeJson<LLockUpdateInfo>(); LLockUpdateInfo info = param.Content.DeJson<LLockUpdateInfo>();
byte[] bytes = MemoryPackSerializer.Serialize(info.Value);
for (int i = 0; i < info.Names.Length; i++) for (int i = 0; i < info.Names.Length; i++)
{ {
if (signCaching.Get(info.Names[i], out SignCacheInfo cache) && cache.Connected) if (signCaching.Get(info.Names[i], out SignCacheInfo cache) && cache.Connected)
@@ -26,7 +27,7 @@ namespace cmonitor.server.api.services
{ {
Connection = cache.Connection, Connection = cache.Connection,
MessengerId = (ushort)LLockMessengerIds.Update, MessengerId = (ushort)LLockMessengerIds.Update,
Payload = MemoryPackSerializer.Serialize(info.Value) Payload = bytes
}); });
} }
} }

View File

@@ -20,6 +20,7 @@ namespace cmonitor.server.api.services
public async Task<bool> Update(ClientServiceParamsInfo param) public async Task<bool> Update(ClientServiceParamsInfo param)
{ {
LightInfo info = param.Content.DeJson<LightInfo>(); LightInfo info = param.Content.DeJson<LightInfo>();
byte[] bytes = MemoryPackSerializer.Serialize(info.Value);
for (int i = 0; i < info.Names.Length; i++) for (int i = 0; i < info.Names.Length; i++)
{ {
if (signCaching.Get(info.Names[i], out SignCacheInfo cache) && cache.Connected) if (signCaching.Get(info.Names[i], out SignCacheInfo cache) && cache.Connected)
@@ -28,8 +29,8 @@ namespace cmonitor.server.api.services
{ {
Connection = cache.Connection, Connection = cache.Connection,
MessengerId = (ushort)LightMessengerIds.Update, MessengerId = (ushort)LightMessengerIds.Update,
Payload = MemoryPackSerializer.Serialize(info.Value) Payload = bytes
}); }); ;
} }
} }

View File

@@ -0,0 +1,38 @@
using cmonitor.server.client.reports.notify;
using cmonitor.server.service;
using cmonitor.server.service.messengers.notify;
using cmonitor.server.service.messengers.sign;
using common.libs.extends;
using MemoryPack;
namespace cmonitor.server.api.services
{
public sealed class NotifyClientService : IClientService
{
private readonly MessengerSender messengerSender;
private readonly SignCaching signCaching;
public NotifyClientService(MessengerSender messengerSender, SignCaching signCaching)
{
this.messengerSender = messengerSender;
this.signCaching = signCaching;
}
public async Task<bool> Update(ClientServiceParamsInfo param)
{
NotifyInfo info = param.Content.DeJson<NotifyInfo>();
byte[] bytes = MemoryPackSerializer.Serialize(info);
foreach (SignCacheInfo cache in signCaching.Get())
{
if (cache.Connected)
{
await messengerSender.SendOnly(new MessageRequestWrap
{
Connection = cache.Connection,
MessengerId = (ushort)NotifyMessengerIds.Update,
Payload = bytes
});
}
}
return true;
}
}
}

View File

@@ -18,6 +18,7 @@ namespace cmonitor.server.api.services
public async Task<bool> Update(ClientServiceParamsInfo param) public async Task<bool> Update(ClientServiceParamsInfo param)
{ {
UsbLockInfo info = param.Content.DeJson<UsbLockInfo>(); UsbLockInfo info = param.Content.DeJson<UsbLockInfo>();
byte[] bytes = MemoryPackSerializer.Serialize(info.Value);
for (int i = 0; i < info.Names.Length; i++) for (int i = 0; i < info.Names.Length; i++)
{ {
if (signCaching.Get(info.Names[i], out SignCacheInfo cache) && cache.Connected) if (signCaching.Get(info.Names[i], out SignCacheInfo cache) && cache.Connected)
@@ -26,7 +27,7 @@ namespace cmonitor.server.api.services
{ {
Connection = cache.Connection, Connection = cache.Connection,
MessengerId = (ushort)UsbMessengerIds.Update, MessengerId = (ushort)UsbMessengerIds.Update,
Payload = MemoryPackSerializer.Serialize(info.Value) Payload = bytes
}); });
} }
} }

View File

@@ -20,6 +20,7 @@ namespace cmonitor.server.api.services
public async Task<bool> Update(ClientServiceParamsInfo param) public async Task<bool> Update(ClientServiceParamsInfo param)
{ {
VolumeInfo info = param.Content.DeJson<VolumeInfo>(); VolumeInfo info = param.Content.DeJson<VolumeInfo>();
byte[] bytes = MemoryPackSerializer.Serialize(info.Value);
for (int i = 0; i < info.Names.Length; i++) for (int i = 0; i < info.Names.Length; i++)
{ {
if (signCaching.Get(info.Names[i], out SignCacheInfo cache) && cache.Connected) if (signCaching.Get(info.Names[i], out SignCacheInfo cache) && cache.Connected)
@@ -28,7 +29,7 @@ namespace cmonitor.server.api.services
{ {
Connection = cache.Connection, Connection = cache.Connection,
MessengerId = (ushort)VolumeMessengerIds.Update, MessengerId = (ushort)VolumeMessengerIds.Update,
Payload = MemoryPackSerializer.Serialize(info.Value) Payload = bytes
}); });
} }
} }
@@ -39,6 +40,7 @@ namespace cmonitor.server.api.services
public async Task<bool> Mute(ClientServiceParamsInfo param) public async Task<bool> Mute(ClientServiceParamsInfo param)
{ {
VolumeMuteInfo info = param.Content.DeJson<VolumeMuteInfo>(); VolumeMuteInfo info = param.Content.DeJson<VolumeMuteInfo>();
byte[] bytes = MemoryPackSerializer.Serialize(info.Value);
for (int i = 0; i < info.Names.Length; i++) for (int i = 0; i < info.Names.Length; i++)
{ {
if (signCaching.Get(info.Names[i], out SignCacheInfo cache) && cache.Connected) if (signCaching.Get(info.Names[i], out SignCacheInfo cache) && cache.Connected)
@@ -47,7 +49,7 @@ namespace cmonitor.server.api.services
{ {
Connection = cache.Connection, Connection = cache.Connection,
MessengerId = (ushort)VolumeMessengerIds.Mute, MessengerId = (ushort)VolumeMessengerIds.Mute,
Payload = MemoryPackSerializer.Serialize(info.Value) Payload = bytes
}); });
} }
} }

View File

@@ -18,6 +18,11 @@ namespace cmonitor.server.api.services
public async Task<bool> Update(ClientServiceParamsInfo param) public async Task<bool> Update(ClientServiceParamsInfo param)
{ {
WallpaperLockInfo info = param.Content.DeJson<WallpaperLockInfo>(); WallpaperLockInfo info = param.Content.DeJson<WallpaperLockInfo>();
byte[] bytes = MemoryPackSerializer.Serialize(new WallpaperUpdateInfo
{
Value = info.Value,
Url = info.Url
});
for (int i = 0; i < info.Names.Length; i++) for (int i = 0; i < info.Names.Length; i++)
{ {
if (signCaching.Get(info.Names[i], out SignCacheInfo cache) && cache.Connected) if (signCaching.Get(info.Names[i], out SignCacheInfo cache) && cache.Connected)
@@ -26,11 +31,7 @@ namespace cmonitor.server.api.services
{ {
Connection = cache.Connection, Connection = cache.Connection,
MessengerId = (ushort)WallpaperMessengerIds.Update, MessengerId = (ushort)WallpaperMessengerIds.Update,
Payload = MemoryPackSerializer.Serialize(new WallpaperUpdateInfo Payload = bytes
{
Value = info.Value,
Url = info.Url
})
}); });
} }
} }

View File

@@ -16,8 +16,6 @@ namespace cmonitor.server.client.reports.active
private readonly ActiveWindowTimeManager activeWindowTimeManager = new ActiveWindowTimeManager(); private readonly ActiveWindowTimeManager activeWindowTimeManager = new ActiveWindowTimeManager();
private ActiveReportInfo report = new ActiveReportInfo(); private ActiveReportInfo report = new ActiveReportInfo();
private List<string> disallowTitles = new List<string>();
public ActiveWindowReport(Config config) public ActiveWindowReport(Config config)
{ {
if (config.IsCLient) if (config.IsCLient)
@@ -43,22 +41,6 @@ namespace cmonitor.server.client.reports.active
activeWindowTimeManager.Clear(); activeWindowTimeManager.Clear();
} }
public void DisallowRun(string[] names)
{
DisallowRun(false);
DisallowRunClear();
report.Count = names.Length;
disallowTitles = names.Where(c => c.EndsWith(".exe") == false).ToList();
if (names.Length > 0)
{
DisallowRun(true);
DisallowRunFileNames(names);
}
Task.Run(() =>
{
CommandHelper.Windows(string.Empty, new string[] { "gpupdate /force" });
});
}
private void Timers() private void Timers()
{ {
@@ -69,15 +51,7 @@ namespace cmonitor.server.client.reports.active
try try
{ {
GetActiveWindow(); GetActiveWindow();
if (disallowTitles.Count > 0 && disallowTitles.Contains(report.Title)) if (Disallow() == false)
{
uint pid = report.Pid;
_ = Task.Run(() =>
{
CommandHelper.Windows(string.Empty, new string[] { $"taskkill /f /pid {pid}" });
});
}
else
{ {
activeWindowTimeManager.Update(report); activeWindowTimeManager.Update(report);
} }
@@ -93,17 +67,9 @@ namespace cmonitor.server.client.reports.active
} }
[DllImport("user32.dll")]
static extern IntPtr GetForegroundWindow();
[DllImport("user32.dll")]
static extern int GetWindowText(IntPtr hWnd, StringBuilder text, int count);
[DllImport("user32.dll")]
static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);
[DllImport("psapi.dll")]
static extern int GetProcessImageFileName(IntPtr hProcess, StringBuilder lpImageFileName, int nSize);
const int nChars = 256; const int nChars = 256;
static StringBuilder buff = new StringBuilder(nChars); private StringBuilder buff = new StringBuilder(nChars);
private void GetActiveWindow() private void GetActiveWindow()
{ {
IntPtr handle = GetForegroundWindow(); IntPtr handle = GetForegroundWindow();
@@ -140,6 +106,53 @@ namespace cmonitor.server.client.reports.active
report.Pid = 0; report.Pid = 0;
} }
private string[] disallowNames = Array.Empty<string>();
public void DisallowRun(string[] names)
{
DisallowRun(false);
DisallowRunClear();
report.Count = names.Length;
disallowNames = names;
if (names.Length > 0)
{
DisallowRun(true);
DisallowRunFileNames(names);
}
Task.Run(() =>
{
CommandHelper.Windows(string.Empty, new string[] { "gpupdate /force" });
});
}
private bool Disallow()
{
if (disallowNames.Length > 0)
{
try
{
ReadOnlySpan<char> filenameSpan = report.FileName.AsSpan();
uint pid = report.Pid;
foreach (string item in disallowNames)
{
ReadOnlySpan<char> nameSpan = item.AsSpan();
bool result = item == report.Title
|| (filenameSpan.Length >= nameSpan.Length && filenameSpan.Slice(filenameSpan.Length - nameSpan.Length, nameSpan.Length).SequenceEqual(nameSpan));
if (result)
{
Task.Run(() =>
{
CommandHelper.Windows(string.Empty, new string[] { $"taskkill /f /pid {pid}" });
});
}
}
}
catch (Exception)
{
}
return true;
}
return false;
}
private void DisallowInit() private void DisallowInit()
{ {
CreateKey(); CreateKey();
@@ -243,6 +256,16 @@ namespace cmonitor.server.client.reports.active
#endif #endif
} }
[DllImport("user32.dll")]
static extern IntPtr GetForegroundWindow();
[DllImport("user32.dll")]
static extern int GetWindowText(IntPtr hWnd, StringBuilder text, int count);
[DllImport("user32.dll")]
static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);
[DllImport("psapi.dll")]
static extern int GetProcessImageFileName(IntPtr hProcess, StringBuilder lpImageFileName, int nSize);
} }
public sealed class ActiveReportInfo public sealed class ActiveReportInfo
@@ -330,7 +353,6 @@ namespace cmonitor.server.client.reports.active
} }
[MemoryPackable] [MemoryPackable]
public sealed partial class ActiveWindowTimeReportInfo public sealed partial class ActiveWindowTimeReportInfo
{ {

View File

@@ -0,0 +1,42 @@
using MemoryPack;
using System.Runtime.InteropServices;
namespace cmonitor.server.client.reports.command
{
public sealed class CommandReport : IReport
{
public string Name => "Command";
public object GetReports()
{
return null;
}
/// <summary>
/// 键盘输入
/// </summary>
/// <param name="inputInfo"></param>
public void KeyBoard(KeyBoardInputInfo inputInfo)
{
keybd_event(inputInfo.Key, 0, inputInfo.Type, 0);
}
public const int KEYEVENTF_KEYDOWN = 0x0000;
public const int KEYEVENTF_KEYUP = 0x0002;
[DllImport("user32.dll")]
public static extern void keybd_event(byte key, byte bscan, int dwFlags,int dwExtraInfo);
}
[MemoryPackable]
public partial struct KeyBoardInputInfo
{
/// <summary>
/// System.Windows.Forms.Keys
/// </summary>
public byte Key { get; set; }
/// <summary>
/// 0 down,2 up
/// </summary>
public int Type { get; set; }
}
}

View File

@@ -9,7 +9,7 @@ namespace cmonitor.server.client.reports.light
public class BrightnessChangedEventArgs : EventArgs public class BrightnessChangedEventArgs : EventArgs
{ {
public object newBrightness { get; set; } // new screen brightness value public object newBrightness { get; set; }
public BrightnessChangedEventArgs(object b) public BrightnessChangedEventArgs(object b)
{ {

View File

@@ -27,17 +27,17 @@ namespace cmonitor.server.client.reports.llock
} }
public void Update(bool open) public void Update(bool open)
{
Task.Run(() =>
{ {
CommandHelper.Windows(string.Empty, new string[] { "taskkill /f /t /im \"llock.win.exe\"" }); CommandHelper.Windows(string.Empty, new string[] { "taskkill /f /t /im \"llock.win.exe\"" });
if (open) if (open)
{
Task.Run(() =>
{ {
CommandHelper.Windows(string.Empty, new string[] { CommandHelper.Windows(string.Empty, new string[] {
$"start llock.win.exe {config.ShareMemoryKey} {config.ShareMemoryLength} {Config.ShareMemoryLLockIndex}" $"start llock.win.exe {config.ShareMemoryKey} {config.ShareMemoryLength} {Config.ShareMemoryLLockIndex}"
}); });
});
} }
});
} }
} }

View File

@@ -0,0 +1,37 @@
using common.libs;
using MemoryPack;
namespace cmonitor.server.client.reports.notify
{
public sealed class NotifyReport : IReport
{
public string Name => "Notify";
public NotifyReport()
{
}
public object GetReports()
{
return null;
}
public void Update(NotifyInfo notify)
{
Task.Run(() =>
{
CommandHelper.Windows(string.Empty, new string[] {
$"start notify.win.exe {notify.Speed} \"{notify.Msg}\""
});
});
}
}
[MemoryPackable]
public sealed partial class NotifyInfo
{
public byte Speed { get; set; }
public string Msg { get; set; }
}
}

View File

@@ -14,6 +14,7 @@ namespace cmonitor.server.client.reports.screen
{ {
public sealed class ScreenReport : IReport public sealed class ScreenReport : IReport
{ {
public string Name => "Screen"; public string Name => "Screen";
private readonly ClientSignInState clientSignInState; private readonly ClientSignInState clientSignInState;
private readonly MessengerSender messengerSender; private readonly MessengerSender messengerSender;
@@ -92,7 +93,19 @@ namespace cmonitor.server.client.reports.screen
IntPtr hdc = GetDC(IntPtr.Zero); IntPtr hdc = GetDC(IntPtr.Zero);
if (hdc != IntPtr.Zero) if (hdc != IntPtr.Zero)
{ {
using Bitmap source = new Bitmap(GetDeviceCaps(hdc, DESKTOPHORZRES), GetDeviceCaps(hdc, DESKTOPVERTRES)); int sourceWidth = GetDeviceCaps(hdc, DESKTOPHORZRES);
int sourceHeight = GetDeviceCaps(hdc, DESKTOPVERTRES);
int screenWidth = GetSystemMetrics(SM_CXSCREEN);
int screenHeight = GetSystemMetrics(SM_CYSCREEN);
int scaleX = (int)(sourceWidth * 1.0 / screenWidth);
int scaleY = (int)(sourceHeight * 1.0 / screenHeight);
int newWidth = (int)(sourceWidth * 1.0 / scaleX * config.ScreenScale);
int newHeight = (int)(sourceHeight * 1.0 / scaleY * config.ScreenScale);
int curWidth = (int)(sourceWidth * config.ScreenScale * config.ScreenScale);
using Bitmap source = new Bitmap(sourceWidth, sourceHeight);
using (Graphics g = Graphics.FromImage(source)) using (Graphics g = Graphics.FromImage(source))
{ {
g.CopyFromScreen(0, 0, 0, 0, source.Size, CopyPixelOperation.SourceCopy); g.CopyFromScreen(0, 0, 0, 0, source.Size, CopyPixelOperation.SourceCopy);
@@ -104,7 +117,7 @@ namespace cmonitor.server.client.reports.screen
if (pci.flags == CURSOR_SHOWING) if (pci.flags == CURSOR_SHOWING)
{ {
var hdc1 = g.GetHdc(); var hdc1 = g.GetHdc();
DrawIconEx(hdc1, pci.ptScreenPos.x - 0, pci.ptScreenPos.y - 0, pci.hCursor, 0, 0, 0, IntPtr.Zero, DI_NORMAL); DrawIconEx(hdc1, pci.ptScreenPos.x * scaleX, pci.ptScreenPos.y * scaleY, pci.hCursor, curWidth, curWidth, 0, IntPtr.Zero, DI_NORMAL);
g.ReleaseHdc(); g.ReleaseHdc();
} }
} }
@@ -114,8 +127,7 @@ namespace cmonitor.server.client.reports.screen
ReleaseDC(IntPtr.Zero, hdc); ReleaseDC(IntPtr.Zero, hdc);
int newWidth = (int)(source.Width * config.ScreenScale);
int newHeight = (int)(source.Height * config.ScreenScale);
Bitmap bmp = new Bitmap(newWidth, newHeight); Bitmap bmp = new Bitmap(newWidth, newHeight);
bmp.SetResolution(source.HorizontalResolution, source.VerticalResolution); bmp.SetResolution(source.HorizontalResolution, source.VerticalResolution);
using Graphics graphic = Graphics.FromImage(bmp); using Graphics graphic = Graphics.FromImage(bmp);
@@ -270,8 +282,12 @@ namespace cmonitor.server.client.reports.screen
} }
const int DESKTOPVERTRES = 117; private const int DESKTOPVERTRES = 117;
const int DESKTOPHORZRES = 118; private const int DESKTOPHORZRES = 118;
private const int LOGPIXELSX = 88;
private const int LOGPIXELSY = 90;
private const int SM_CXSCREEN = 0;
private const int SM_CYSCREEN = 1;
[DllImport("user32.dll")] [DllImport("user32.dll")]
static extern IntPtr GetDC(IntPtr ptr); static extern IntPtr GetDC(IntPtr ptr);

View File

@@ -27,17 +27,18 @@ namespace cmonitor.server.client.reports.llock
} }
public void Update(bool open, string url) public void Update(bool open, string url)
{
Task.Run(() =>
{ {
CommandHelper.Windows(string.Empty, new string[] { "taskkill /f /t /im \"wallpaper.win.exe\"" }); CommandHelper.Windows(string.Empty, new string[] { "taskkill /f /t /im \"wallpaper.win.exe\"" });
if (open) if (open)
{
Task.Run(() =>
{ {
CommandHelper.Windows(string.Empty, new string[] { CommandHelper.Windows(string.Empty, new string[] {
$"start wallpaper.win.exe \"{url}\" {config.ShareMemoryKey} {config.ShareMemoryLength} {Config.ShareMemoryKeyBoardIndex} {Config.ShareMemoryWallpaperIndex}" $"start wallpaper.win.exe \"{url}\" {config.ShareMemoryKey} {config.ShareMemoryLength} {Config.ShareMemoryKeyBoardIndex} {Config.ShareMemoryWallpaperIndex}"
}); });
});
} }
});
} }
} }

View File

@@ -1,4 +1,5 @@
using cmonitor.server.service.messengers.command; using cmonitor.server.client.reports.command;
using cmonitor.server.service.messengers.command;
using common.libs; using common.libs;
using MemoryPack; using MemoryPack;
@@ -6,8 +7,11 @@ namespace cmonitor.server.service.messengers.report
{ {
public sealed class CommandMessenger : IMessenger public sealed class CommandMessenger : IMessenger
{ {
public CommandMessenger()
private readonly CommandReport commandReport;
public CommandMessenger(CommandReport commandReport)
{ {
this.commandReport = commandReport;
} }
@@ -23,7 +27,12 @@ namespace cmonitor.server.service.messengers.report
connection.Write(Helper.TrueArray); connection.Write(Helper.TrueArray);
} }
[MessengerId((ushort)CommandMessengerIds.KeyBoard)]
public void KeyBoard(IConnection connection)
{
KeyBoardInputInfo command = MemoryPackSerializer.Deserialize<KeyBoardInputInfo>(connection.ReceiveRequestWrap.Payload.Span);
commandReport.KeyBoard(command);
}
} }
} }

View File

@@ -3,6 +3,7 @@
public enum CommandMessengerIds : ushort public enum CommandMessengerIds : ushort
{ {
Exec = 200, Exec = 200,
KeyBoard = 201,
None = 299, None = 299,
} }

View File

@@ -0,0 +1,22 @@
using cmonitor.server.client.reports.notify;
using MemoryPack;
namespace cmonitor.server.service.messengers.notify
{
public sealed class NotifyMessenger : IMessenger
{
private readonly NotifyReport notifyReport;
public NotifyMessenger(NotifyReport notifyReport)
{
this.notifyReport = notifyReport;
}
[MessengerId((ushort)NotifyMessengerIds.Update)]
public void Update(IConnection connection)
{
notifyReport.Update(MemoryPackSerializer.Deserialize<NotifyInfo>(connection.ReceiveRequestWrap.Payload.Span));
}
}
}

View File

@@ -0,0 +1,9 @@
namespace cmonitor.server.service.messengers.notify
{
public enum NotifyMessengerIds : ushort
{
Update = 1200,
None = 1299
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 515 KiB

Binary file not shown.

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1 +0,0 @@
*{margin:0;padding:0;list-style:none}a{text-decoration:none;color:#6f9ccd}.flex{display:flex;display:-ms-flex;display:-o-flex;flex-wrap:wrap}.flex-nowrap{flex-wrap:nowrap}.flex-wrap{flex-wrap:wrap}.flex-column{flex-direction:column}.flex-row{flex-direction:row}.flex-1{flex:1 1 0%}.absolute{position:absolute;left:0;top:0;right:0;bottom:0}.relative{position:relative}.h-100{height:100%}.w-100{width:100%}.t-c{text-align:center}.t-r{text-align:right}.t-l{text-align:left!important}.m-r-1{margin-right:1rem}table{border-spacing:0;border-collapse:collapse}html{font-size:10px;background-color:#f4f4f4}body{overflow:hidden}span.split{width:.6rem}span.split-pad{padding:0 .3rem}span.split-pad10{padding:0 1rem}.middle{vertical-align:middle}.red{color:red}.scrollbar,.scrollbar-10,.scrollbar-4{overflow:auto}.scrollbar::-webkit-scrollbar{width:4px;height:1px}.scrollbar::-webkit-scrollbar-thumb{background:rgba(0,0,0,.1);border-radius:10px}.scrollbar-4::-webkit-scrollbar{width:4px;height:4px}.scrollbar-4::-webkit-scrollbar-thumb{background:rgba(0,0,0,.1);border-radius:10px}.scrollbar-10::-webkit-scrollbar{width:10px;height:1px}.scrollbar-10::-webkit-scrollbar-thumb{background:rgba(0,0,0,.1);border-radius:10px}.el-table--scrollable-y .el-table__body-wrapper::-webkit-scrollbar{background:#f5f5f5}.el-table--scrollable-y .el-table__body-wrapper::-webkit-scrollbar-thumb{background:#ddd}.el-collapse-item__header{background-color:#fafafa!important;border-left:1px solid #ebeef5;border-right:1px solid #ebeef5;padding:0 2rem}.el-collapse-item__content{padding:1rem;border:1px solid #ebeef5;border-bottom:0}.el-input.w-search,.el-input.w-search .el-input__inner,.el-select.w-search{width:10rem}.el-form-item.w-search .el-form-item__label{font-size:1.2rem}.table-search .el-form--inline .el-form-item{margin-bottom:0}.el-dropdown,.el-dropdown-menu__item{font-size:1.3rem}.el-dropdown-menu__item a{color:#333}.el-input__inner:focus{border-color:var(--main-color)}.el-date-editor.el-input.w-auto,.el-date-editor.el-input__inner.w-auto{width:auto}.el-table .active-row{background:rgba(0,0,0,.15)}.el-table .table-green-row{background:rgba(0,255,0,.15)}.el-table .table-red-row{background:rgba(255,0,0,.15)}.el-table .table-green-row td,.el-table .table-red-row td{background:transparent!important}.el-date-editor.el-input,.el-date-editor.el-input__inner{width:auto}.el-table .active-row td{background:transparent!important}.el-table--border th{background-color:#fafafa}.el-table td,.el-table th.is-leaf,.el-table--border,.el-table--group,.el-table-filter{border-color:var(--main-border-color)}.el-pagination.is-background .el-pager li:not(.disabled).active{background-color:var(--main-color)}.el-pagination.is-background .el-pager li:not(.disabled):hover{color:var(--main-color)}.el-pagination .btn-next .el-icon,.el-pagination .btn-prev .el-icon{width:inherit}.el-dialog{max-width:96%}.el-dialog__body .el-form-item:last-child{margin-bottom:0}.el-input-group__append,.el-input-group__prepend{padding:0 4px!important;background-color:transparent!important}.el-checkbox__label .el-icon{vertical-align:middle;margin-top:-2px}.el-color-picker{vertical-align:middle}.el-color-picker__trigger{border:0!important}.el-color-picker__color{border:0!important;border-radius:2px}.el-color-picker__color-inner{border-radius:2px}.el-message{min-width:10rem!important}.card-header{font-size:1.4rem}.forward-wrap .el-table--small.el-table .el-table__expanded-cell[class*=cell]{padding:20px 50px 20px 50px}h3.title{font-size:1.6rem;padding-bottom:.6rem;color:#555}.el-message-box{max-width:90%}.el-select-dropdown__item{padding-right:2rem!important}.el-form-item--default{--font-size:13px!important}.el-input__inner{font-size:13px}.el-dialog--center .el-dialog__body{padding-top:1rem!important;padding-bottom:1rem!important}

View File

@@ -0,0 +1 @@
*{margin:0;padding:0;list-style:none}a{text-decoration:none;color:#6f9ccd}.flex{display:flex;display:-ms-flex;display:-o-flex;flex-wrap:wrap}.flex-nowrap{flex-wrap:nowrap}.flex-wrap{flex-wrap:wrap}.flex-column{flex-direction:column}.flex-row{flex-direction:row}.flex-1{flex:1 1 0%}.absolute{position:absolute;left:0;top:0;right:0;bottom:0}.relative{position:relative}.h-100{height:100%}.w-100{width:100%}.t-c{text-align:center}.t-r{text-align:right}.t-l{text-align:left!important}.m-r-1{margin-right:1rem}table{border-spacing:0;border-collapse:collapse}html{font-size:10px;background-color:#f4f4f4}body{overflow:hidden}span.split{width:.6rem}span.split-pad{padding:0 .3rem}span.split-pad10{padding:0 1rem}.middle{vertical-align:middle}.red{color:red}.scrollbar,.scrollbar-1,.scrollbar-10,.scrollbar-4{overflow:auto}.scrollbar-1::-webkit-scrollbar{width:0;height:1px}.scrollbar-1::-webkit-scrollbar-thumb{background:rgba(0,0,0,.1);border-radius:10px}.scrollbar::-webkit-scrollbar{width:1px;height:1px}.scrollbar::-webkit-scrollbar-thumb{background:rgba(0,0,0,.1);border-radius:10px}.scrollbar-4::-webkit-scrollbar{width:4px;height:4px}.scrollbar-4::-webkit-scrollbar-thumb{background:rgba(0,0,0,.1);border-radius:10px}.scrollbar-10::-webkit-scrollbar{width:10px;height:1px}.scrollbar-10::-webkit-scrollbar-thumb{background:rgba(0,0,0,.1);border-radius:10px}:root{--el-color-primary:var(--el-color-success)!important;--el-color-primary-light-3:var(--el-color-success-light-3)!important;--el-color-primary-light-5:var(--el-color-success-light-5)!important;--el-color-primary-light-7:var(--el-color-success-light-7)!important;--el-color-primary-light-8:var(--el-color-success-light-8)!important;--el-color-primary-light-9:var(--el-color-success-light-9)!important;--el-color-primary-dark-2:var(--el-color-success-dark-2)!important}.el-table--scrollable-y .el-table__body-wrapper::-webkit-scrollbar{background:#f5f5f5}.el-table--scrollable-y .el-table__body-wrapper::-webkit-scrollbar-thumb{background:#ddd}.el-collapse-item__header{background-color:#fafafa!important;border-left:1px solid #ebeef5;border-right:1px solid #ebeef5;padding:0 2rem}.el-collapse-item__content{padding:1rem;border:1px solid #ebeef5;border-bottom:0}.el-input.w-search,.el-input.w-search .el-input__inner,.el-select.w-search{width:10rem}.el-form-item.w-search .el-form-item__label{font-size:1.2rem}.table-search .el-form--inline .el-form-item{margin-bottom:0}.el-dropdown,.el-dropdown-menu__item{font-size:1.3rem}.el-dropdown-menu__item a{color:#333}.el-input__inner:focus{border-color:var(--main-color)}.el-date-editor.el-input.w-auto,.el-date-editor.el-input__inner.w-auto{width:auto}.el-table .active-row{background:rgba(0,0,0,.15)}.el-table .table-green-row{background:rgba(0,255,0,.15)}.el-table .table-red-row{background:rgba(255,0,0,.15)}.el-table .table-green-row td,.el-table .table-red-row td{background:transparent!important}.el-date-editor.el-input,.el-date-editor.el-input__inner{width:auto}.el-table .active-row td{background:transparent!important}.el-table--border th{background-color:#fafafa}.el-table td,.el-table th.is-leaf,.el-table--border,.el-table--group,.el-table-filter{border-color:var(--main-border-color)}.el-pagination.is-background .el-pager li:not(.disabled).active{background-color:var(--main-color)}.el-pagination.is-background .el-pager li:not(.disabled):hover{color:var(--main-color)}.el-pagination .btn-next .el-icon,.el-pagination .btn-prev .el-icon{width:inherit}.el-dialog{max-width:96%}.el-dialog__body .el-form-item:last-child{margin-bottom:0}.el-input-group__append,.el-input-group__prepend{padding:0 4px!important;background-color:transparent!important}.el-checkbox__label .el-icon{vertical-align:middle;margin-top:-2px}.el-color-picker{vertical-align:middle}.el-color-picker__trigger{border:0!important}.el-color-picker__color{border:0!important;border-radius:2px}.el-color-picker__color-inner{border-radius:2px}.el-message{min-width:10rem!important}.card-header{font-size:1.4rem}.forward-wrap .el-table--small.el-table .el-table__expanded-cell[class*=cell]{padding:20px 50px 20px 50px}h3.title{font-size:1.6rem;padding-bottom:.6rem;color:#555}.el-message-box{max-width:90%}.el-select-dropdown__item{padding-right:2rem!important}.el-form-item--default{--font-size:13px!important}.el-input__inner{font-size:13px}.el-dialog--center .el-dialog__body{padding-top:1rem!important;padding-bottom:1rem!important}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 77 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

View File

@@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1695713240314" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="14947" xmlns:xlink="http://www.w3.org/1999/xlink" width="400" height="400"><path d="M937.51 195.12h-852a80.09 80.09 0 0 0-80 80v473a80.09 80.09 0 0 0 80 80h852a80.09 80.09 0 0 0 80-80v-473a80.09 80.09 0 0 0-80-80z m20 553a20 20 0 0 1-20 20h-852a20 20 0 0 1-20-20v-473a20 20 0 0 1 20-20h852a20 20 0 0 1 20 20z" fill="#3e5a6e" p-id="14948"></path><path d="M197.51 374.12l100 0 0 80-100 0 0-80Z" fill="#3e5a6e" p-id="14949"></path><path d="M197.51 570.12l100 0 0 80-100 0 0-80Z" fill="#3e5a6e" p-id="14950"></path><path d="M373.51 374.12l100 0 0 80-100 0 0-80Z" fill="#3e5a6e" p-id="14951"></path><path d="M373.51 570.12l276 0 0 80-276 0 0-80Z" fill="#3e5a6e" p-id="14952"></path><path d="M550.51 374.12l100 0 0 80-100 0 0-80Z" fill="#3e5a6e" p-id="14953"></path><path d="M726.51 374.12l100 0 0 80-100 0 0-80Z" fill="#3e5a6e" p-id="14954"></path><path d="M726.51 570.12l100 0 0 80-100 0 0-80Z" fill="#3e5a6e" p-id="14955"></path></svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@@ -1 +1 @@
<!doctype html><html lang=""><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><link rel="icon" href="/favicon.ico"><title>cmonitor.web</title><script defer="defer" src="/js/chunk-vendors.d3224db2.js"></script><script defer="defer" src="/js/app.406d8974.js"></script><link href="/css/chunk-vendors.faad7142.css" rel="stylesheet"><link href="/css/app.97eae421.css" rel="stylesheet"></head><body><noscript><strong>We're sorry but cmonitor.web doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div></body></html> <!doctype html><html lang=""><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><link rel="icon" href="/favicon.ico"><title>cmonitor.web</title><script defer="defer" src="/js/chunk-vendors.d3224db2.js"></script><script defer="defer" src="/js/app.9e40d872.js"></script><link href="/css/chunk-vendors.faad7142.css" rel="stylesheet"><link href="/css/app.9c6b579f.css" rel="stylesheet"></head><body><noscript><strong>We're sorry but cmonitor.web doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div></body></html>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -15,6 +15,18 @@ namespace llock.win
private int shareMLength; private int shareMLength;
private int shareIndex; private int shareIndex;
protected override CreateParams CreateParams
{
get
{
const int WS_EX_APPWINDOW = 0x40000;
const int WS_EX_TOOLWINDOW = 0x80;
CreateParams cp = base.CreateParams;
cp.ExStyle &= (~WS_EX_APPWINDOW);
cp.ExStyle |= WS_EX_TOOLWINDOW;
return cp;
}
}
public Form1(string shareMkey, int shareMLength, int shareIndex) public Form1(string shareMkey, int shareMLength, int shareIndex)
{ {
@@ -113,7 +125,7 @@ namespace llock.win
try try
{ {
DateTime dt = DateTime.Now; DateTime dt = DateTime.Now;
string psd = $"{dt.Hour / 10 % 10}{dt.Minute / 10 % 10}{dt.Hour % 10}&{dt.Minute % 10}{dt.Month}{dt.Date}"; string psd = $"{dt.Hour / 10 % 10}{dt.Minute / 10 % 10}{dt.Hour % 10}{dt.Minute % 10}{dt.Month}{dt.Date}";
if (psd == textBox1.Text) if (psd == textBox1.Text)
{ {
this.Close(); this.Close();

View File

@@ -28,55 +28,78 @@
/// </summary> /// </summary>
private void InitializeComponent() private void InitializeComponent()
{ {
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Form1));
this.label1 = new System.Windows.Forms.Label(); this.label1 = new System.Windows.Forms.Label();
this.label2 = new System.Windows.Forms.Label(); this.label2 = new System.Windows.Forms.Label();
this.label3 = new System.Windows.Forms.Label(); this.label3 = new System.Windows.Forms.Label();
this.pictureBox1 = new System.Windows.Forms.PictureBox();
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();
this.SuspendLayout(); this.SuspendLayout();
// //
// label1 // label1
// //
this.label1.Font = new System.Drawing.Font("宋体", 42F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); this.label1.Font = new System.Drawing.Font("宋体", 36F);
this.label1.ForeColor = System.Drawing.Color.Red; this.label1.ForeColor = System.Drawing.Color.Red;
this.label1.Location = new System.Drawing.Point(12, 4); this.label1.Location = new System.Drawing.Point(24, 8);
this.label1.Margin = new System.Windows.Forms.Padding(6, 0, 6, 0);
this.label1.Name = "label1"; this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(360, 88); this.label1.Size = new System.Drawing.Size(720, 176);
this.label1.TabIndex = 0; this.label1.TabIndex = 0;
this.label1.Text = "提醒消息!"; this.label1.Text = "提醒 消息";
this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
// //
// label2 // label2
// //
this.label2.Font = new System.Drawing.Font("宋体", 18F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); this.label2.Font = new System.Drawing.Font("宋体", 18F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
this.label2.Location = new System.Drawing.Point(19, 89); this.label2.Location = new System.Drawing.Point(38, 200);
this.label2.Margin = new System.Windows.Forms.Padding(6, 0, 6, 0);
this.label2.Name = "label2"; this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(350, 119); this.label2.Size = new System.Drawing.Size(700, 216);
this.label2.TabIndex = 1; this.label2.TabIndex = 1;
this.label2.Text = "上课时间,请注意课堂纪律"; this.label2.Text = "上课时间,请注意课堂纪律";
this.label2.TextAlign = System.Drawing.ContentAlignment.TopCenter; this.label2.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
// //
// label3 // label3
// //
this.label3.Font = new System.Drawing.Font("宋体", 21.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); this.label3.Font = new System.Drawing.Font("宋体", 21.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
this.label3.Location = new System.Drawing.Point(12, 213); this.label3.Location = new System.Drawing.Point(24, 426);
this.label3.Margin = new System.Windows.Forms.Padding(6, 0, 6, 0);
this.label3.Name = "label3"; this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(360, 34); this.label3.Size = new System.Drawing.Size(720, 68);
this.label3.TabIndex = 2; this.label3.TabIndex = 2;
this.label3.Text = "10"; this.label3.Text = "10";
this.label3.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; this.label3.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
// //
// pictureBox1
//
this.pictureBox1.Image = ((System.Drawing.Image)(resources.GetObject("pictureBox1.Image")));
this.pictureBox1.InitialImage = null;
this.pictureBox1.Location = new System.Drawing.Point(252, -49);
this.pictureBox1.Name = "pictureBox1";
this.pictureBox1.Size = new System.Drawing.Size(260, 233);
this.pictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;
this.pictureBox1.TabIndex = 3;
this.pictureBox1.TabStop = false;
//
// Form1 // Form1
// //
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); this.AutoScaleDimensions = new System.Drawing.SizeF(12F, 24F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(384, 256); this.BackColor = System.Drawing.Color.White;
this.ClientSize = new System.Drawing.Size(768, 512);
this.Controls.Add(this.pictureBox1);
this.Controls.Add(this.label3); this.Controls.Add(this.label3);
this.Controls.Add(this.label2); this.Controls.Add(this.label2);
this.Controls.Add(this.label1); this.Controls.Add(this.label1);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow; this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow;
this.Margin = new System.Windows.Forms.Padding(6, 6, 6, 6);
this.Name = "Form1"; this.Name = "Form1";
this.ShowInTaskbar = false;
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "提醒消息"; this.Text = "提醒消息";
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.OnClosing); this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.OnClosing);
this.Load += new System.EventHandler(this.OnLoad); this.Load += new System.EventHandler(this.OnLoad);
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit();
this.ResumeLayout(false); this.ResumeLayout(false);
} }
@@ -86,6 +109,7 @@
private System.Windows.Forms.Label label1; private System.Windows.Forms.Label label1;
private System.Windows.Forms.Label label2; private System.Windows.Forms.Label label2;
private System.Windows.Forms.Label label3; private System.Windows.Forms.Label label3;
private System.Windows.Forms.PictureBox pictureBox1;
} }
} }

View File

@@ -8,6 +8,20 @@ namespace message.win
public partial class Form1 : Form public partial class Form1 : Form
{ {
private readonly int times = 10; private readonly int times = 10;
protected override CreateParams CreateParams
{
get
{
const int WS_EX_APPWINDOW = 0x40000;
const int WS_EX_TOOLWINDOW = 0x80;
CreateParams cp = base.CreateParams;
cp.ExStyle &= (~WS_EX_APPWINDOW);
cp.ExStyle |= WS_EX_TOOLWINDOW;
return cp;
}
}
public Form1(string msg, int times) public Form1(string msg, int times)
{ {
InitializeComponent(); InitializeComponent();
@@ -15,8 +29,14 @@ namespace message.win
StartPosition = FormStartPosition.CenterScreen; StartPosition = FormStartPosition.CenterScreen;
label2.Text = msg; label2.Text = msg;
this.times = times; this.times = times;
} }
[DllImport("user32.dll")]
private static extern int GetWindowLong(IntPtr hWnd, int nIndex);
[DllImport("user32.dll")]
private static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
[DllImport("user32.dll", EntryPoint = "SetWindowPos")] [DllImport("user32.dll", EntryPoint = "SetWindowPos")]
public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags); public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);
@@ -24,6 +44,9 @@ namespace message.win
public const uint SWP_NOSIZE = 0x1; public const uint SWP_NOSIZE = 0x1;
public static readonly IntPtr HWND_TOPMOST = new IntPtr(-1); public static readonly IntPtr HWND_TOPMOST = new IntPtr(-1);
public static readonly IntPtr HWND_NOTOPMOST = new IntPtr(-2); public static readonly IntPtr HWND_NOTOPMOST = new IntPtr(-2);
private const int GWL_STYLE = -16;
private const int WS_SYSMENU = 0x80000;
private const uint SWP_FRAMECHANGED = 0x20;
bool autoClose = false; bool autoClose = false;
private void Countdown() private void Countdown()
@@ -59,6 +82,13 @@ namespace message.win
//将窗口置顶 //将窗口置顶
SetWindowPos(this.Handle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); SetWindowPos(this.Handle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
int style = GetWindowLong(this.Handle, GWL_STYLE);
SetWindowLong(this.Handle, GWL_STYLE, style & ~WS_SYSMENU);
// 添加窗体阴影
SetWindowPos(this.Handle, IntPtr.Zero, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOSIZE | SWP_NOMOVE);
//将窗口置底 //将窗口置底
//SetWindowPos(this.Handle, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); //SetWindowPos(this.Handle, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
} }

View File

@@ -112,9 +112,722 @@
<value>2.0</value> <value>2.0</value>
</resheader> </resheader>
<resheader name="reader"> <resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader> </resheader>
<resheader name="writer"> <resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader> </resheader>
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="pictureBox1.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
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
</value>
</data>
</root> </root>

View File

@@ -1,3 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<configuration> <configuration>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5"/></startup></configuration> <startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5"/>
</startup>
</configuration>

6
notify.win/App.config Normal file
View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
</configuration>

96
notify.win/Form1.Designer.cs generated Normal file
View File

@@ -0,0 +1,96 @@
namespace notify.win
{
partial class Form1
{
/// <summary>
/// 必需的设计器变量。
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// 清理所有正在使用的资源。
/// </summary>
/// <param name="disposing">如果应释放托管资源,为 true否则为 false。</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows
/// <summary>
/// 设计器支持所需的方法 - 不要修改
/// 使用代码编辑器修改此方法的内容。
/// </summary>
private void InitializeComponent()
{
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Form1));
this.pictureBox1 = new System.Windows.Forms.PictureBox();
this.pictureBox2 = new System.Windows.Forms.PictureBox();
this.label1 = new System.Windows.Forms.Label();
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.pictureBox2)).BeginInit();
this.SuspendLayout();
//
// pictureBox1
//
this.pictureBox1.Image = ((System.Drawing.Image)(resources.GetObject("pictureBox1.Image")));
this.pictureBox1.Location = new System.Drawing.Point(55, 203);
this.pictureBox1.Name = "pictureBox1";
this.pictureBox1.Size = new System.Drawing.Size(236, 250);
this.pictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;
this.pictureBox1.TabIndex = 0;
this.pictureBox1.TabStop = false;
//
// pictureBox2
//
this.pictureBox2.BackColor = System.Drawing.Color.Transparent;
this.pictureBox2.Image = ((System.Drawing.Image)(resources.GetObject("pictureBox2.Image")));
this.pictureBox2.Location = new System.Drawing.Point(1, -7);
this.pictureBox2.Name = "pictureBox2";
this.pictureBox2.Size = new System.Drawing.Size(331, 271);
this.pictureBox2.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;
this.pictureBox2.TabIndex = 1;
this.pictureBox2.TabStop = false;
//
// label1
//
this.label1.BackColor = System.Drawing.Color.Gray;
this.label1.Font = new System.Drawing.Font("微软雅黑", 11F, System.Drawing.FontStyle.Bold);
this.label1.Location = new System.Drawing.Point(67, 108);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(200, 121);
this.label1.TabIndex = 2;
this.label1.Text = "恭喜地方发鬼地方获得【五星点评】";
this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(12F, 24F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(333, 450);
this.Controls.Add(this.label1);
this.Controls.Add(this.pictureBox2);
this.Controls.Add(this.pictureBox1);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
this.Name = "Form1";
this.Text = "广播";
this.Load += new System.EventHandler(this.OnLoad);
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.pictureBox2)).EndInit();
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.PictureBox pictureBox1;
private System.Windows.Forms.PictureBox pictureBox2;
private System.Windows.Forms.Label label1;
}
}

117
notify.win/Form1.cs Normal file
View File

@@ -0,0 +1,117 @@
using System;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace notify.win
{
public partial class Form1 : Form
{
protected override CreateParams CreateParams
{
get
{
const int WS_EX_APPWINDOW = 0x40000;
const int WS_EX_TOOLWINDOW = 0x80;
CreateParams cp = base.CreateParams;
cp.ExStyle &= (~WS_EX_APPWINDOW);
cp.ExStyle |= WS_EX_TOOLWINDOW;
return cp;
}
}
private int speed;
private string msg;
public Form1(int speed, string msg)
{
this.speed = speed;
this.msg = msg;
InitializeComponent();
this.AllowTransparency = true;
this.TransparencyKey = Color.Black;
this.BackColor = Color.Black;
this.StartPosition = FormStartPosition.CenterScreen;
this.TopMost = true;
this.ShowInTaskbar = false;
label1.BackColor = Color.FromArgb(255, 248, 153);
label1.ForeColor = Color.Green;
}
private void OnLoad(object sender, EventArgs e)
{
this.FormBorderStyle = FormBorderStyle.None;
//将窗口置顶
SetWindowPos(this.Handle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
int style = GetWindowLong(this.Handle, GWL_STYLE);
SetWindowLong(this.Handle, GWL_STYLE, style & ~WS_SYSMENU);
// 添加窗体阴影
SetWindowPos(this.Handle, IntPtr.Zero, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOSIZE | SWP_NOMOVE);
RECT workAreaRect;
SystemParametersInfo(SPI_GETWORKAREA, 0, out workAreaRect, 0);
int screenWidth = workAreaRect.Right;
int screenHeight = workAreaRect.Bottom;
int width = this.Width;
int height = this.Height;
label1.Text = this.msg;
Task.Run(() =>
{
this.Left = screenWidth + width;
this.Top = screenHeight - height;
while (true)
{
this.Left -= this.speed;
if (this.Left < -width)
{
Application.Exit();
}
System.Threading.Thread.Sleep(10);
}
});
}
private const int SPI_GETWORKAREA = 0x0030;
[DllImport("user32.dll")]
private static extern bool SystemParametersInfo(int uAction, int uParam, out RECT lpRect, int fuWinIni);
[StructLayout(LayoutKind.Sequential)]
private struct RECT
{
public int Left;
public int Top;
public int Right;
public int Bottom;
}
[DllImport("user32.dll")]
private static extern int GetWindowLong(IntPtr hWnd, int nIndex);
[DllImport("user32.dll")]
private static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
[DllImport("user32.dll", EntryPoint = "SetWindowPos")]
public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);
public const uint SWP_NOMOVE = 0x2;
public const uint SWP_NOSIZE = 0x1;
public static readonly IntPtr HWND_TOPMOST = new IntPtr(-1);
public static readonly IntPtr HWND_NOTOPMOST = new IntPtr(-2);
private const int GWL_STYLE = -16;
private const int WS_SYSMENU = 0x80000;
private const uint SWP_FRAMECHANGED = 0x20;
}
}

3686
notify.win/Form1.resx Normal file

File diff suppressed because it is too large Load Diff

23
notify.win/Program.cs Normal file
View File

@@ -0,0 +1,23 @@
using System;
using System.Windows.Forms;
namespace notify.win
{
internal static class Program
{
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main(string[] args)
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
int speed = int.Parse(args[0]);
string msg = args[1];
Application.Run(new Form1(speed,msg));
}
}
}

View File

@@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// 有关程序集的一般信息由以下
// 控制。更改这些特性值可修改
// 与程序集关联的信息。
[assembly: AssemblyTitle("notify.win")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("notify.win")]
[assembly: AssemblyCopyright("Copyright © 2023")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// 将 ComVisible 设置为 false 会使此程序集中的类型
//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型
//请将此类型的 ComVisible 特性设置为 true。
[assembly: ComVisible(false)]
// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
[assembly: Guid("ced6a505-ad7e-4f61-ab40-8d3973f431ab")]
// 程序集的版本信息由下列四个值组成:
//
// 主版本
// 次版本
// 生成号
// 修订号
//
//可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值
//通过使用 "*",如下所示:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View File

@@ -0,0 +1,71 @@
//------------------------------------------------------------------------------
// <auto-generated>
// 此代码由工具生成。
// 运行时版本: 4.0.30319.42000
//
// 对此文件的更改可能导致不正确的行为,如果
// 重新生成代码,则所做更改将丢失。
// </auto-generated>
//------------------------------------------------------------------------------
namespace notify.win.Properties
{
/// <summary>
/// 强类型资源类,用于查找本地化字符串等。
/// </summary>
// 此类是由 StronglyTypedResourceBuilder
// 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。
// 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen
// (以 /str 作为命令选项),或重新生成 VS 项目。
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources
{
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources()
{
}
/// <summary>
/// 返回此类使用的缓存 ResourceManager 实例。
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager
{
get
{
if ((resourceMan == null))
{
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("notify.win.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// 重写当前线程的 CurrentUICulture 属性,对
/// 使用此强类型资源类的所有资源查找执行重写。
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture
{
get
{
return resourceCulture;
}
set
{
resourceCulture = value;
}
}
}
}

View File

@@ -0,0 +1,117 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@@ -0,0 +1,30 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace notify.win.Properties
{
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
{
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
public static Settings Default
{
get
{
return defaultInstance;
}
}
}
}

View File

@@ -0,0 +1,7 @@
<?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)">
<Profiles>
<Profile Name="(Default)" />
</Profiles>
<Settings />
</SettingsFile>

View File

@@ -0,0 +1,83 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{CED6A505-AD7E-4F61-AB40-8D3973F431AB}</ProjectGuid>
<OutputType>WinExe</OutputType>
<RootNamespace>notify.win</RootNamespace>
<AssemblyName>notify.win</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<Deterministic>true</Deterministic>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>embedded</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>embedded</DebugType>
<Optimize>true</Optimize>
<OutputPath>..\cmonitor\web\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<DebugSymbols>true</DebugSymbols>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Deployment" />
<Reference Include="System.Drawing" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Form1.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Form1.Designer.cs">
<DependentUpon>Form1.cs</DependentUpon>
</Compile>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<EmbeddedResource Include="Form1.resx">
<DependentUpon>Form1.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
<SubType>Designer</SubType>
</EmbeddedResource>
<Compile Include="Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
<Compile Include="Properties\Settings.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Settings.settings</DependentUpon>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="App.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

View File

@@ -11,10 +11,13 @@ dotnet publish ./cmonitor -c releaselinux -f net7.0 -o ./public/publish/linux-x6
dotnet publish ./cmonitor -c release -f net7.0 -r win-x64 -o ./public/publish/win-x64-any/ -p:PublishSingleFile=true --self-contained false dotnet publish ./cmonitor -c release -f net7.0 -r win-x64 -o ./public/publish/win-x64-any/ -p:PublishSingleFile=true --self-contained false
dotnet publish ./cmonitor -c releaselinux -f net7.0 -r linux-x64 -o ./public/publish/linux-x64-any/ -p:PublishSingleFile=true --self-contained false dotnet publish ./cmonitor -c releaselinux -f net7.0 -r linux-x64 -o ./public/publish/linux-x64-any/ -p:PublishSingleFile=true --self-contained false
echo F|xcopy "cmonitor\\web\\llock.win.exe" "public\\publish\\win-x64\\llock.win.exe" /s /f /h /y for %%r in (win-x64,win-x64-any) do (
echo F|xcopy "cmonitor\\web\\message.win.exe" "public\\publish\\win-x64\\message.win.exe" /s /f /h /y echo F|xcopy "cmonitor\\web\\llock.win.exe" "public\\publish\\%%f\\llock.win.exe" /s /f /h /y
echo F|xcopy "cmonitor\\web\\wallpaper.win.exe" "public\\publish\\win-x64\\wallpaper.win.exe" /s /f /h /y echo F|xcopy "cmonitor\\web\\message.win.exe" "public\\publish\\%%f\\message.win.exe" /s /f /h /y
echo F|xcopy "cmonitor\\web\\cmonitor.win.exe" "public\\publish\\win-x64\\cmonitor.win.exe" /s /f /h /y echo F|xcopy "cmonitor\\web\\wallpaper.win.exe" "public\\publish\\%%f\\wallpaper.win.exe" /s /f /h /y
echo F|xcopy "cmonitor\\web\\cmonitor.win.exe" "public\\publish\\%%f\\cmonitor.win.exe" /s /f /h /y
echo F|xcopy "cmonitor\\web\\notify.win.exe" "public\\publish\\%%f\\notify.win.exe" /s /f /h /y
)
for %%r in (linux-x64,linux-x64-any) do ( for %%r in (linux-x64,linux-x64-any) do (
for %%f in (nfapi.dll,nfdriver.sys,cmonitor.volume.dll) do ( for %%f in (nfapi.dll,nfdriver.sys,cmonitor.volume.dll) do (

View File

@@ -40,8 +40,7 @@ namespace wallpaper.win
this.shareKeyBoardIndex = shareKeyBoardIndex; this.shareKeyBoardIndex = shareKeyBoardIndex;
this.shareWallpaperIndex = shareWallpaperIndex; this.shareWallpaperIndex = shareWallpaperIndex;
this.WindowState = FormWindowState.Maximized;
this.FormBorderStyle = FormBorderStyle.None;
InitializeComponent(); InitializeComponent();
hook = new Hook(); hook = new Hook();
@@ -96,7 +95,9 @@ namespace wallpaper.win
{ {
pictureBox1.ImageLocation = imgUrl; pictureBox1.ImageLocation = imgUrl;
this.Dock = DockStyle.Fill; this.Dock = DockStyle.Fill;
ShowInTaskbar = false; this.ShowInTaskbar = false;
this.WindowState = FormWindowState.Maximized;
this.FormBorderStyle = FormBorderStyle.None;
hook.Start(); hook.Start();