├── .gitignore ├── LICENSE ├── README.txt └── src ├── Build ├── Build-All.bat ├── Build-All.ps1 ├── Build-HonorShare.bat ├── Build-HuaweiShare.bat ├── Build-XiaomiShare.bat ├── BuildCore.ps1 └── version.txt ├── MiDrop.Core ├── FilesHelper.cs ├── HonorPCManagerHelper.cs ├── HuaweiPCManagerHelper.cs ├── MiDrop.Core.csproj ├── NativeMethods.json ├── NativeMethods.txt └── XiaomiPcManagerHelper.cs ├── MiDrop.Helper ├── MiDrop.Helper.csproj └── Program.cs ├── MiDropShellExt.Package ├── HonorImages │ ├── LockScreenLogo.scale-400.png │ ├── Share.ico │ ├── SplashScreen.scale-200.png │ ├── Square150x150Logo.png │ ├── Square150x150Logo.scale-400.png │ ├── Square44x44Logo.altform-unplated_targetsize-256.png │ ├── Square44x44Logo.scale-400.png │ ├── Square44x44Logo.targetsize-24_altform-unplated.png │ ├── StoreLogo.png │ ├── Wide310x150Logo.png │ └── Wide310x150Logo.scale-400.png ├── HonorShare.Package.appxmanifest ├── HuaweiImages │ ├── LockScreenLogo.scale-400.png │ ├── Share.ico │ ├── SplashScreen.scale-200.png │ ├── Square150x150Logo.png │ ├── Square150x150Logo.scale-400.png │ ├── Square44x44Logo.altform-unplated_targetsize-256.png │ ├── Square44x44Logo.scale-400.png │ ├── Square44x44Logo.targetsize-24_altform-unplated.png │ ├── StoreLogo.png │ ├── Wide310x150Logo.png │ └── Wide310x150Logo.scale-400.png ├── HuaweiShare.Package.appxmanifest ├── MiDropShellExt.Package.wapproj ├── XiaomiImages │ ├── LockScreenLogo.scale-400.png │ ├── SplashScreen.scale-200.png │ ├── Square150x150Logo.png │ ├── Square150x150Logo.scale-400.png │ ├── Square44x44Logo.altform-unplated_targetsize-256.png │ ├── Square44x44Logo.scale-400.png │ ├── Square44x44Logo.targetsize-24_altform-unplated.png │ ├── StoreLogo.png │ ├── Wide310x150Logo.png │ └── Wide310x150Logo.scale-400.png └── XiaomiShare.Package.appxmanifest ├── MiDropShellExt.sln └── ShellExt ├── ContextMenu.cs ├── DllMain.cs └── ShellExt.csproj /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.suo 8 | *.user 9 | *.userosscache 10 | *.sln.docstates 11 | 12 | # User-specific files (MonoDevelop/Xamarin Studio) 13 | *.userprefs 14 | 15 | # Build results 16 | [Dd]ebug/ 17 | [Dd]ebugPublic/ 18 | [Rr]elease/ 19 | [Rr]eleases/ 20 | x64/ 21 | x86/ 22 | arm64/ 23 | bld/ 24 | [Bb]in/ 25 | [Oo]bj/ 26 | [Ll]og/ 27 | 28 | # Visual Studio 2015/2017 cache/options directory 29 | .vs/ 30 | # Uncomment if you have tasks that create the project's static files in wwwroot 31 | #wwwroot/ 32 | 33 | # Visual Studio 2017 auto generated files 34 | Generated\ Files/ 35 | 36 | # MSTest test Results 37 | [Tt]est[Rr]esult*/ 38 | [Bb]uild[Ll]og.* 39 | 40 | # NUNIT 41 | *.VisualState.xml 42 | TestResult.xml 43 | 44 | # Build Results of an ATL Project 45 | [Dd]ebugPS/ 46 | [Rr]eleasePS/ 47 | dlldata.c 48 | 49 | # Benchmark Results 50 | BenchmarkDotNet.Artifacts/ 51 | 52 | # .NET Core 53 | project.lock.json 54 | project.fragment.lock.json 55 | artifacts/ 56 | **/Properties/launchSettings.json 57 | 58 | # StyleCop 59 | StyleCopReport.xml 60 | 61 | # Files built by Visual Studio 62 | *_i.c 63 | *_p.c 64 | *_i.h 65 | *.ilk 66 | *.meta 67 | *.obj 68 | *.iobj 69 | *.pch 70 | *.pdb 71 | *.ipdb 72 | *.pgc 73 | *.pgd 74 | *.rsp 75 | *.sbr 76 | *.tlb 77 | *.tli 78 | *.tlh 79 | *.tmp 80 | *.tmp_proj 81 | *.log 82 | *.vspscc 83 | *.vssscc 84 | .builds 85 | *.pidb 86 | *.svclog 87 | *.scc 88 | 89 | # Chutzpah Test files 90 | _Chutzpah* 91 | 92 | # Visual C++ cache files 93 | ipch/ 94 | *.aps 95 | *.ncb 96 | *.opendb 97 | *.opensdf 98 | *.sdf 99 | *.cachefile 100 | *.VC.db 101 | *.VC.VC.opendb 102 | 103 | # Visual Studio profiler 104 | *.psess 105 | *.vsp 106 | *.vspx 107 | *.sap 108 | 109 | # Visual Studio Trace Files 110 | *.e2e 111 | 112 | # TFS 2012 Local Workspace 113 | $tf/ 114 | 115 | # Guidance Automation Toolkit 116 | *.gpState 117 | 118 | # ReSharper is a .NET coding add-in 119 | _ReSharper*/ 120 | *.[Rr]e[Ss]harper 121 | *.DotSettings.user 122 | 123 | # JustCode is a .NET coding add-in 124 | .JustCode 125 | 126 | # TeamCity is a build add-in 127 | _TeamCity* 128 | 129 | # DotCover is a Code Coverage Tool 130 | *.dotCover 131 | 132 | # AxoCover is a Code Coverage Tool 133 | .axoCover/* 134 | !.axoCover/settings.json 135 | 136 | # Visual Studio code coverage results 137 | *.coverage 138 | *.coveragexml 139 | 140 | # NCrunch 141 | _NCrunch_* 142 | .*crunch*.local.xml 143 | nCrunchTemp_* 144 | 145 | # MightyMoose 146 | *.mm.* 147 | AutoTest.Net/ 148 | 149 | # Web workbench (sass) 150 | .sass-cache/ 151 | 152 | # Installshield output folder 153 | [Ee]xpress/ 154 | 155 | # DocProject is a documentation generator add-in 156 | DocProject/buildhelp/ 157 | DocProject/Help/*.HxT 158 | DocProject/Help/*.HxC 159 | DocProject/Help/*.hhc 160 | DocProject/Help/*.hhk 161 | DocProject/Help/*.hhp 162 | DocProject/Help/Html2 163 | DocProject/Help/html 164 | 165 | # Click-Once directory 166 | publish/ 167 | 168 | # Publish Web Output 169 | *.[Pp]ublish.xml 170 | *.azurePubxml 171 | # Note: Comment the next line if you want to checkin your web deploy settings, 172 | # but database connection strings (with potential passwords) will be unencrypted 173 | *.pubxml 174 | *.publishproj 175 | 176 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 177 | # checkin your Azure Web App publish settings, but sensitive information contained 178 | # in these scripts will be unencrypted 179 | PublishScripts/ 180 | 181 | # NuGet Packages 182 | *.nupkg 183 | # The packages folder can be ignored because of Package Restore 184 | **/[Pp]ackages/* 185 | # except build/, which is used as an MSBuild target. 186 | !**/[Pp]ackages/build/ 187 | # Uncomment if necessary however generally it will be regenerated when needed 188 | #!**/[Pp]ackages/repositories.config 189 | # NuGet v3's project.json files produces more ignorable files 190 | *.nuget.props 191 | *.nuget.targets 192 | 193 | # Microsoft Azure Build Output 194 | csx/ 195 | *.build.csdef 196 | 197 | # Microsoft Azure Emulator 198 | ecf/ 199 | rcf/ 200 | 201 | # Windows Store app package directories and files 202 | AppPackages/ 203 | BundleArtifacts/ 204 | Package.StoreAssociation.xml 205 | _pkginfo.txt 206 | *.appx 207 | 208 | # Visual Studio cache files 209 | # files ending in .cache can be ignored 210 | *.[Cc]ache 211 | # but keep track of directories ending in .cache 212 | !*.[Cc]ache/ 213 | 214 | # Others 215 | ClientBin/ 216 | ~$* 217 | *~ 218 | *.dbmdl 219 | *.dbproj.schemaview 220 | *.jfm 221 | *.pfx 222 | *.publishsettings 223 | orleans.codegen.cs 224 | 225 | # Including strong name files can present a security risk 226 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 227 | #*.snk 228 | 229 | # Since there are multiple workflows, uncomment next line to ignore bower_components 230 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 231 | #bower_components/ 232 | 233 | # RIA/Silverlight projects 234 | Generated_Code/ 235 | 236 | # Backup & report files from converting an old project file 237 | # to a newer Visual Studio version. Backup files are not needed, 238 | # because we have git ;-) 239 | _UpgradeReport_Files/ 240 | Backup*/ 241 | UpgradeLog*.XML 242 | UpgradeLog*.htm 243 | ServiceFabricBackup/ 244 | *.rptproj.bak 245 | 246 | # SQL Server files 247 | *.mdf 248 | *.ldf 249 | *.ndf 250 | 251 | # Business Intelligence projects 252 | *.rdl.data 253 | *.bim.layout 254 | *.bim_*.settings 255 | *.rptproj.rsuser 256 | 257 | # Microsoft Fakes 258 | FakesAssemblies/ 259 | 260 | # GhostDoc plugin setting file 261 | *.GhostDoc.xml 262 | 263 | # Node.js Tools for Visual Studio 264 | .ntvs_analysis.dat 265 | node_modules/ 266 | 267 | # Visual Studio 6 build log 268 | *.plg 269 | 270 | # Visual Studio 6 workspace options file 271 | *.opt 272 | 273 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 274 | *.vbw 275 | 276 | # Visual Studio LightSwitch build output 277 | **/*.HTMLClient/GeneratedArtifacts 278 | **/*.DesktopClient/GeneratedArtifacts 279 | **/*.DesktopClient/ModelManifest.xml 280 | **/*.Server/GeneratedArtifacts 281 | **/*.Server/ModelManifest.xml 282 | _Pvt_Extensions 283 | 284 | # Paket dependency manager 285 | .paket/paket.exe 286 | paket-files/ 287 | 288 | # FAKE - F# Make 289 | .fake/ 290 | 291 | # JetBrains Rider 292 | .idea/ 293 | *.sln.iml 294 | 295 | # CodeRush 296 | .cr/ 297 | 298 | # Python Tools for Visual Studio (PTVS) 299 | __pycache__/ 300 | *.pyc 301 | 302 | # Cake - Uncomment if you are using it 303 | # tools/** 304 | # !tools/packages.config 305 | 306 | # Tabs Studio 307 | *.tss 308 | 309 | # Telerik's JustMock configuration file 310 | *.jmconfig 311 | 312 | # BizTalk build output 313 | *.btp.cs 314 | *.btm.cs 315 | *.odx.cs 316 | *.xsd.cs 317 | 318 | # OpenCover UI analysis results 319 | OpenCover/ 320 | 321 | # Azure Stream Analytics local run output 322 | ASALocalRun/ 323 | 324 | # MSBuild Binary and Structured Log 325 | *.binlog 326 | 327 | # NVidia Nsight GPU debugger configuration file 328 | *.nvuser 329 | 330 | # MFractors (Xamarin productivity tool) working folder 331 | .mfractor/ 332 | 333 | /src/MiDropShellExt.Package/ShellExt 334 | /src/MiDrop.Core/NonPackagedApp 335 | /src/MiDrop.Helper/NonPackagedApp 336 | /src/MiDrop.Helper/NonPackagedAppnative 337 | /src/MiDropShellExt.Package/NonPackagedApp 338 | /src/Build/XiaomiShare/ 339 | /src/Build/HonorShare/ 340 | /src/Build/HuaweiShare/ 341 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 cnbluefire 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.txt: -------------------------------------------------------------------------------- 1 | 为 Windows 11 的新式右键菜单添加小米互传选项。 2 | 3 | 安装:解压 Releases 中的压缩包,右键 Install.ps1,跟随系统引导安装,可能需要手动打开系统的开发者模式。 4 | 5 | 卸载:打开设置,应用,安装的应用,搜索 MiDropShellExt.Package,点击右侧三个点卸载。 6 | 7 | 1.0.2 版本开始,新增桌面触发角,将文件拖拽到 *主屏幕* 左上角即可触发。 8 | 9 | 由于 Windows 11 新增了 *拖拽文件到屏幕顶部共享*,1.0.6 版本移除了桌面触发角。 10 | 11 | 1.0.10 版本开始,新增了华为分享和荣耀分享的支持。 -------------------------------------------------------------------------------- /src/Build/Build-All.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | powershell -ExecutionPolicy Bypass -File Build-All.ps1 -------------------------------------------------------------------------------- /src/Build/Build-All.ps1: -------------------------------------------------------------------------------- 1 | function GetVersion(){ 2 | $versionText = Get-Content "version.txt" 3 | if ($versionText -eq "") { $versionText = '1.0.0' } 4 | 5 | $version1 = [System.Version]::Parse($versionText) 6 | $version2 = New-Object -TypeName System.Version -ArgumentList ($version1.Major, $version1.Minor, $version1.Build, 0) 7 | return $version2.ToString(4); 8 | } 9 | 10 | .\BuildCore.ps1 XiaomiShare 11 | if(!$?){ 12 | Write-Host "Build xiaomi share failed" 13 | return false 14 | } 15 | 16 | .\BuildCore.ps1 HonorShare 17 | if(!$?){ 18 | Write-Host "Build honor share failed" 19 | return false 20 | } 21 | 22 | .\BuildCore.ps1 HuaweiShare 23 | if(!$?){ 24 | Write-Host "Build huawei share failed" 25 | return false 26 | } 27 | 28 | $version = GetVersion 29 | if (!(Test-Path -Path ".\Publish\$($version)")) { 30 | mkdir ".\Publish\$($version)" 31 | } 32 | 33 | Compress-Archive -Path ".\XiaomiShare\MiDropShellExt.Package_$($version)_Test\*" -DestinationPath ".\Publish\$($version)\XiaomiShare.Package_$($version).zip" -Force 34 | Compress-Archive -Path ".\HonorShare\MiDropShellExt.Package_$($version)_Test\*" -DestinationPath ".\Publish\$($version)\HonorShare.Package_$($version).zip" -Force 35 | Compress-Archive -Path ".\HuaweiShare\MiDropShellExt.Package_$($version)_Test\*" -DestinationPath ".\Publish\$($version)\HuaweiShare.Package_$($version).zip" -Force -------------------------------------------------------------------------------- /src/Build/Build-HonorShare.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | powershell -ExecutionPolicy Bypass -File BuildCore.ps1 HonorShare -------------------------------------------------------------------------------- /src/Build/Build-HuaweiShare.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | powershell -ExecutionPolicy Bypass -File BuildCore.ps1 HuaweiShare -------------------------------------------------------------------------------- /src/Build/Build-XiaomiShare.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | powershell -ExecutionPolicy Bypass -File BuildCore.ps1 XiaomiShare -------------------------------------------------------------------------------- /src/Build/BuildCore.ps1: -------------------------------------------------------------------------------- 1 | function UpdateVersion($path){ 2 | $versionText = Get-Content "version.txt" 3 | if ($versionText -eq "") { $versionText = '1.0.0' } 4 | 5 | $version1 = [System.Version]::Parse($versionText) 6 | $version2 = New-Object -TypeName System.Version -ArgumentList ($version1.Major, $version1.Minor, $version1.Build, 0) 7 | $fullVersionText = $version2.ToString(4); 8 | 9 | [xml]$manifest= get-content $path 10 | $manifest.Package.Identity.Version = $fullVersionText 11 | $manifest.save($path) 12 | } 13 | 14 | $SHARE_TARGET = $args[0] 15 | if($SHARE_TARGET -eq "") { 16 | Write-Host 'Share target is empty' 17 | return false 18 | } 19 | if(($SHARE_TARGET -ne 'XiaomiShare') -and ($SHARE_TARGET -ne 'HonorShare') -and ($SHARE_TARGET -ne 'HuaweiShare')){ 20 | Write-Host 'Unknown share target' 21 | return false 22 | } 23 | 24 | $scriptDir = (Split-Path -Parent $MyInvocation.MyCommand.Definition) 25 | $OUTOUT_PATH="$scriptDir\$SHARE_TARGET" 26 | 27 | $MSBUILD_PATH = & "$([Environment]::GetEnvironmentVariable("ProgramFiles(x86)"))\Microsoft Visual Studio\Installer\vswhere.exe" -latest -prerelease -products * -requires Microsoft.Component.MSBuild -find MSBuild\**\Bin\MSBuild.exe 28 | if($MSBUILD_PATH -eq ""){ 29 | Write-Host 'Cannot find msbuild' 30 | return false 31 | } 32 | 33 | if ((Test-Path -Path '..\MiDropShellExt.Package\obj')) { 34 | Remove-Item '..\MiDropShellExt.Package\obj' -Recurse 35 | } 36 | if ((Test-Path -Path '..\MiDropShellExt.Package\bin')) { 37 | Remove-Item '..\MiDropShellExt.Package\bin' -Recurse 38 | } 39 | 40 | UpdateVersion("..\MiDropShellExt.Package\$($SHARE_TARGET).Package.appxmanifest"); 41 | 42 | & $MSBUILD_PATH ../MiDropShellExt.Package/MiDropShellExt.Package.wapproj ` 43 | /p:ShareProjectTargetName=$SHARE_TARGET ` 44 | /p:Configuration=Release ` 45 | /p:Platform=x64 ` 46 | /p:AppxBundlePlatforms=x64 ` 47 | /p:OutputPath=NonPackagedApp ` 48 | /p:UapAppxPackageBuildMode=SideLoadOnly ` 49 | /p:AppxBundle=Always ` 50 | /p:AppxPackageDir=$OUTOUT_PATH\ ` 51 | /p:AppxPackageSigningEnabled=true ` 52 | /p:PackageCertificateThumbprint=cfcc41845e3d8f50ffc5f35adf3f06788c717f7d ` 53 | /p:PackageCertificatePassword=123456 54 | 55 | return $? -------------------------------------------------------------------------------- /src/Build/version.txt: -------------------------------------------------------------------------------- 1 | 1.0.10 -------------------------------------------------------------------------------- /src/MiDrop.Core/FilesHelper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace MiDrop.Core 8 | { 9 | public static class FilesHelper 10 | { 11 | private static readonly string FilesCacheFolder = 12 | System.IO.Path.Combine( 13 | Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), 14 | "MiDropHelper", 15 | "ShareFiles"); 16 | 17 | public static async Task SaveFilesAsync(string[] files, CancellationToken cancellationToken) 18 | { 19 | DeleteExpiredFiles(); 20 | 21 | if (!System.IO.Directory.Exists(FilesCacheFolder)) 22 | { 23 | System.IO.Directory.CreateDirectory(FilesCacheFolder); 24 | } 25 | 26 | var xiaomiFile = XiaomiPcManagerHelper.CreateXiaomiFile(files); 27 | if (!string.IsNullOrEmpty(xiaomiFile)) 28 | { 29 | var key = Guid.NewGuid().ToString("N"); 30 | 31 | try 32 | { 33 | var filePath = System.IO.Path.Combine(FilesCacheFolder, key); 34 | await System.IO.File.WriteAllTextAsync(filePath, xiaomiFile); 35 | return key; 36 | } 37 | catch { } 38 | } 39 | return string.Empty; 40 | } 41 | 42 | public static async Task GetXiaomiFileAsync(string cacheKey, CancellationToken cancellationToken) 43 | { 44 | DeleteExpiredFiles(); 45 | 46 | try 47 | { 48 | var filePath = System.IO.Path.Combine(FilesCacheFolder, cacheKey); 49 | using (var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read | FileShare.Delete, 4096, FileOptions.DeleteOnClose)) 50 | using (var reader = new StreamReader(fileStream, Encoding.UTF8, leaveOpen: true)) 51 | { 52 | return await reader.ReadToEndAsync(cancellationToken); 53 | } 54 | } 55 | catch { } 56 | return string.Empty; 57 | } 58 | 59 | public static string[] GetFilesFromXiaomiFileContent(string fileContent) 60 | { 61 | return fileContent.Split('|', StringSplitOptions.RemoveEmptyEntries) 62 | .Where(c => File.Exists(c) || Directory.Exists(c)) 63 | .ToArray(); 64 | } 65 | 66 | private static void DeleteExpiredFiles() 67 | { 68 | try 69 | { 70 | var files = System.IO.Directory.GetFiles(FilesCacheFolder); 71 | if (files != null && files.Length > 0) 72 | { 73 | var now = DateTime.Now; 74 | for (int i = 0; i < files.Length; i++) 75 | { 76 | try 77 | { 78 | var createTime = System.IO.File.GetCreationTime(files[i]); 79 | if ((now - createTime).TotalDays > 0.5) 80 | { 81 | System.IO.File.Delete(files[i]); 82 | } 83 | } 84 | catch { } 85 | } 86 | } 87 | } 88 | catch { } 89 | } 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /src/MiDrop.Core/HonorPCManagerHelper.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Win32; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Diagnostics; 5 | using System.Linq; 6 | using System.Runtime.CompilerServices; 7 | using System.Runtime.InteropServices; 8 | using System.Text; 9 | using System.Threading.Tasks; 10 | 11 | namespace MiDrop.Core 12 | { 13 | public static class HonorPCManagerHelper 14 | { 15 | private static readonly IReadOnlyList PcManagerRegKeys = [ 16 | // 5.x 17 | "{9557F42F-BD61-4E26-9752-33A8A20FC9FA}", 18 | ]; 19 | 20 | public static string GetInstallPath() 21 | { 22 | try 23 | { 24 | for (int i = 0; i < PcManagerRegKeys.Count; i++) 25 | { 26 | using (var subKey = Registry.ClassesRoot.OpenSubKey($"CLSID\\{PcManagerRegKeys[i]}\\InprocServer32")) 27 | { 28 | if (subKey != null && subKey.GetValue(null) is string path && !string.IsNullOrEmpty(path)) 29 | { 30 | var folder = Path.GetDirectoryName(path); 31 | if (Directory.Exists(folder)) 32 | { 33 | return folder; 34 | } 35 | } 36 | } 37 | } 38 | } 39 | catch { } 40 | 41 | return string.Empty; 42 | } 43 | 44 | public static async Task LaunchApp() 45 | { 46 | var path = GetInstallPath(); 47 | var appPath = Path.Combine(path, "PCManager.exe"); 48 | await Task.Run(() => 49 | { 50 | Process.Start(appPath); 51 | }); 52 | } 53 | public static async Task SendFilesAsync(IReadOnlyList items) 54 | { 55 | var path = GetInstallPath(); 56 | var dllPath = Path.Combine(path, "HonorFileShareMenuControl.dll"); 57 | 58 | Console.WriteLine($"dllPath: {dllPath}"); 59 | 60 | if (!File.Exists(dllPath)) return false; 61 | 62 | return await Task.Run(() => HuaweiPCManagerHelper.SendToHuaweiShareDllCore(dllPath, items)); 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/MiDrop.Core/HuaweiPCManagerHelper.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Win32; 2 | using System.Diagnostics; 3 | using Windows.Win32; 4 | using Windows.Win32.Foundation; 5 | using Windows.Win32.System.Com; 6 | using Windows.Win32.UI.Shell; 7 | using Windows.Win32.UI.Shell.Common; 8 | 9 | namespace MiDrop.Core 10 | { 11 | public static class HuaweiPCManagerHelper 12 | { 13 | private static Dictionary modules = new Dictionary(); 14 | 15 | private static readonly IReadOnlyList PcManagerRegKeys = [ 16 | // 5.x 17 | "{9557F42F-BD61-4E26-9752-33A8A20FC9F9}", 18 | ]; 19 | 20 | public static string GetInstallPath() 21 | { 22 | try 23 | { 24 | for (int i = 0; i < PcManagerRegKeys.Count; i++) 25 | { 26 | using (var subKey = Registry.ClassesRoot.OpenSubKey($"CLSID\\{PcManagerRegKeys[i]}\\InprocServer32")) 27 | { 28 | if (subKey != null && subKey.GetValue(null) is string path && !string.IsNullOrEmpty(path)) 29 | { 30 | var folder = Path.GetDirectoryName(path); 31 | if (Directory.Exists(folder)) 32 | { 33 | return folder; 34 | } 35 | } 36 | } 37 | } 38 | } 39 | catch { } 40 | 41 | return string.Empty; 42 | } 43 | 44 | public static async Task LaunchApp() 45 | { 46 | var path = GetInstallPath(); 47 | var appPath = Path.Combine(path, "PCManager.exe"); 48 | await Task.Run(() => 49 | { 50 | Process.Start(appPath); 51 | }); 52 | } 53 | 54 | public static async Task SendFilesAsync(IReadOnlyList items) 55 | { 56 | var path = GetInstallPath(); 57 | var dllPath = Path.Combine(path, "ShareMenuControl.dll"); 58 | 59 | if (!File.Exists(dllPath)) return false; 60 | 61 | return await Task.Run(() => SendToHuaweiShareDllCore(dllPath, items)); 62 | } 63 | 64 | internal static unsafe bool SendToHuaweiShareDllCore(string dllPath, IReadOnlyList items) 65 | { 66 | HuaweiShareModule? module; 67 | lock (modules) 68 | { 69 | if (!modules.TryGetValue(dllPath, out module)) 70 | { 71 | module = new HuaweiShareModule(dllPath); 72 | modules[dllPath] = module; 73 | } 74 | } 75 | 76 | Console.WriteLine($"module is null: {module.IsNull}"); 77 | 78 | if (!module.IsNull) 79 | { 80 | lock (module) 81 | { 82 | var dataObject = CreateDataObject(items); 83 | Console.WriteLine($"dataObject: {(nint)dataObject}"); 84 | 85 | if (dataObject != null) 86 | { 87 | var hr = module.Initialize(null, dataObject, default); 88 | Console.WriteLine($"Initialize: {hr}"); 89 | if (hr.Failed) return false; 90 | 91 | var hMenu = PInvoke.CreatePopupMenu(); 92 | try 93 | { 94 | const int SCRATCH_QCM_FIRST = 1; 95 | const int SCRATCH_QCM_LAST = 0x7FFF; 96 | const int CMF_NORMAL = 0; 97 | 98 | hr = module.QueryContextMenu(hMenu, 0, SCRATCH_QCM_FIRST, SCRATCH_QCM_LAST, CMF_NORMAL); 99 | Console.WriteLine($"QueryContextMenu: {hr}"); 100 | if (hr.Failed) return false; 101 | 102 | CMINVOKECOMMANDINFO info = default; 103 | info.cbSize = (uint)sizeof(CMINVOKECOMMANDINFO); 104 | info.hwnd = default; 105 | info.lpVerb = default; 106 | hr = module.InvokeCommand(&info); 107 | Console.WriteLine($"InvokeCommand: {hr}"); 108 | return hr.Succeeded; 109 | } 110 | finally 111 | { 112 | PInvoke.DestroyMenu(hMenu); 113 | } 114 | } 115 | } 116 | } 117 | 118 | return false; 119 | } 120 | 121 | private static unsafe IDataObject* CreateDataObject(IReadOnlyList items) 122 | { 123 | if (items == null || items.Count == 0) return null; 124 | 125 | var maxCount = Math.Min(items.Count, 100); 126 | int count = 0; 127 | ITEMIDLIST** pidls = stackalloc ITEMIDLIST*[maxCount]; 128 | IShellItemArray* array = null; 129 | try 130 | { 131 | for (int i = 0; i < maxCount; i++) 132 | { 133 | var pidl = PInvoke.ILCreateFromPath(items[i]); 134 | if (pidl != null) pidls[count++] = pidl; 135 | } 136 | 137 | if (count > 0) 138 | { 139 | var hr = PInvoke.SHCreateShellItemArrayFromIDLists((uint)count, pidls, &array); 140 | if (hr.Succeeded) 141 | { 142 | hr = array->BindToHandler(null, PInvoke.BHID_DataObject, IDataObject.IID_Guid, out var ppv); 143 | if (hr.Succeeded) 144 | { 145 | return (IDataObject*)ppv; 146 | } 147 | } 148 | } 149 | 150 | return null; 151 | } 152 | finally 153 | { 154 | for (int i = 0; i < count; i++) 155 | { 156 | PInvoke.ILFree(pidls[i]); 157 | } 158 | if (array != null) array->Release(); 159 | } 160 | } 161 | 162 | private class HuaweiShareModule 163 | { 164 | private HMODULE module; 165 | private nint pInitialize; 166 | private nint pQueryContextMenu; 167 | private nint pInvokeCommand; 168 | 169 | public HuaweiShareModule(string dllPath) 170 | { 171 | module = PInvoke.LoadLibraryEx(dllPath, Windows.Win32.System.LibraryLoader.LOAD_LIBRARY_FLAGS.LOAD_WITH_ALTERED_SEARCH_PATH); 172 | if (!module.IsNull) 173 | { 174 | pInitialize = PInvoke.GetProcAddress(module, "Initialize"); 175 | pQueryContextMenu = PInvoke.GetProcAddress(module, "QueryContextMenu"); 176 | pInvokeCommand = PInvoke.GetProcAddress(module, "InvokeCommand"); 177 | } 178 | } 179 | 180 | public bool IsNull => pInitialize == 0 || pQueryContextMenu == 0 || pInvokeCommand == 0; 181 | 182 | public unsafe HRESULT Initialize(ITEMIDLIST* pidlFolder, IDataObject* pdtobj, Windows.Win32.System.Registry.HKEY hkeyProgID) 183 | { 184 | if (pInitialize == 0) return (HRESULT)(unchecked((int)0x80004001)); 185 | return ((delegate* unmanaged[Stdcall])pInitialize)(pidlFolder, pdtobj, hkeyProgID); 186 | } 187 | 188 | public unsafe HRESULT QueryContextMenu(Windows.Win32.UI.WindowsAndMessaging.HMENU hmenu, uint indexMenu, uint idCmdFirst, uint idCmdLast, uint uFlags) 189 | { 190 | if (pQueryContextMenu == 0) return (HRESULT)(unchecked((int)0x80004001)); 191 | return ((delegate* unmanaged[Stdcall])pQueryContextMenu)(hmenu, indexMenu, idCmdFirst, idCmdLast, uFlags); 192 | } 193 | 194 | public unsafe HRESULT InvokeCommand(CMINVOKECOMMANDINFO* pici) 195 | { 196 | if (pInvokeCommand == 0) return (HRESULT)(unchecked((int)0x80004001)); 197 | return ((delegate* unmanaged[Stdcall])pInvokeCommand)(pici); 198 | } 199 | } 200 | } 201 | } 202 | -------------------------------------------------------------------------------- /src/MiDrop.Core/MiDrop.Core.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net9.0-windows 5 | enable 6 | enable 7 | x64 8 | x64 9 | win-x64 10 | true 11 | true 12 | 13 | 14 | 15 | 16 | all 17 | runtime; build; native; contentfiles; analyzers 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /src/MiDrop.Core/NativeMethods.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://aka.ms/CsWin32.schema.json", 3 | "comInterop": { 4 | "preserveSigMethods": [ 5 | "*" 6 | ], 7 | "useIntPtrForComOutPointers": true 8 | }, 9 | "allowMarshaling": false, 10 | "useSafeHandles": false 11 | } -------------------------------------------------------------------------------- /src/MiDrop.Core/NativeMethods.txt: -------------------------------------------------------------------------------- 1 | ILCreateFromPathW 2 | ILFree 3 | SHCreateShellItemArrayFromIDLists 4 | LoadLibraryExW 5 | GetProcAddress 6 | CreatePopupMenu 7 | DestroyMenu 8 | 9 | IDataObject 10 | IContextMenu 11 | IShellExtInit 12 | 13 | BHID_* 14 | CMF_NORMAL -------------------------------------------------------------------------------- /src/MiDrop.Core/XiaomiPcManagerHelper.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Win32; 2 | using System.Diagnostics; 3 | using System.IO; 4 | using System.Runtime.InteropServices; 5 | using System.Text; 6 | 7 | namespace MiDrop.Core; 8 | 9 | public class XiaomiPcManagerHelper 10 | { 11 | private static readonly IReadOnlyList PcManagerRegKeys = [ 12 | // 5.x 13 | "{504d69c0-cb52-48df-b5b5-7161829fabc8}", 14 | 15 | // 4.x 16 | "{1bca9901-05c3-4d01-8ad4-78da2eac9b3f}", 17 | ]; 18 | 19 | public static string GetInstallPath() 20 | { 21 | try 22 | { 23 | for (int i = 0; i < PcManagerRegKeys.Count; i++) 24 | { 25 | using (var subKey = Registry.ClassesRoot.OpenSubKey($"CLSID\\{PcManagerRegKeys[i]}\\InprocServer32")) 26 | { 27 | if (subKey != null && subKey.GetValue(null) is string path && !string.IsNullOrEmpty(path)) 28 | { 29 | var folder = Path.GetDirectoryName(path); 30 | if (Directory.Exists(folder)) 31 | { 32 | return folder; 33 | } 34 | } 35 | } 36 | } 37 | } 38 | catch { } 39 | 40 | return string.Empty; 41 | } 42 | 43 | public static string GetExecuteFile() 44 | { 45 | var installPath = GetInstallPath(); 46 | if (!string.IsNullOrEmpty(installPath)) 47 | { 48 | var filePath = Path.Combine(installPath, "XiaomiPcManager.exe"); 49 | if (File.Exists(filePath)) 50 | { 51 | return filePath; 52 | } 53 | } 54 | return string.Empty; 55 | } 56 | 57 | public static Task LaunchAsync(CancellationToken cancellationToken) 58 | { 59 | return LaunchAsync(null, cancellationToken); 60 | } 61 | 62 | public static Task LaunchAsync(string? arguments, CancellationToken cancellationToken) 63 | { 64 | var messageWindow = FindMessageWindow(); 65 | if (messageWindow != 0) 66 | { 67 | if (string.IsNullOrEmpty(arguments)) return Task.FromResult(true); 68 | } 69 | 70 | var executeFile = GetExecuteFile(); 71 | if (!string.IsNullOrEmpty(executeFile)) 72 | { 73 | return LaunchAsyncCore(executeFile, arguments, cancellationToken); 74 | } 75 | return Task.FromResult(false); 76 | } 77 | 78 | public static async Task SendCachedFilesAsync(string cacheKey, TimeSpan timeout) 79 | { 80 | var xiaomiFile = await FilesHelper.GetXiaomiFileAsync(cacheKey, default).ConfigureAwait(false); 81 | if (!string.IsNullOrEmpty(xiaomiFile)) 82 | { 83 | return await SendFilesAsyncCore(xiaomiFile, timeout); 84 | } 85 | return false; 86 | } 87 | 88 | public static Task SendFilesAsync(string[] files, TimeSpan timeout) 89 | { 90 | var xiaomiFile = CreateXiaomiFile(files); 91 | if (!string.IsNullOrEmpty(xiaomiFile)) 92 | { 93 | return SendFilesAsyncCore(xiaomiFile, timeout); 94 | } 95 | 96 | return Task.FromResult(false); 97 | } 98 | 99 | private static Task LaunchAsyncCore(string executeFile, string? arguments, CancellationToken cancellationToken) 100 | { 101 | var psi = new ProcessStartInfo(executeFile, arguments ?? "") 102 | { 103 | UseShellExecute = true 104 | }; 105 | 106 | var tcs = new TaskCompletionSource(); 107 | 108 | var registration = cancellationToken.Register(() => 109 | { 110 | tcs.TrySetCanceled(cancellationToken); 111 | }); 112 | 113 | var thread = new Thread(() => 114 | { 115 | try 116 | { 117 | var process = Process.Start(executeFile); 118 | while (!cancellationToken.IsCancellationRequested && !process.HasExited) 119 | { 120 | var messageWindow = FindMessageWindow(); 121 | if (messageWindow != 0) 122 | { 123 | tcs.TrySetResult(true); 124 | break; 125 | } 126 | 127 | Thread.Sleep(500); 128 | } 129 | } 130 | catch { } 131 | registration.Dispose(); 132 | tcs.TrySetResult(false); 133 | }); 134 | thread.IsBackground = true; 135 | thread.Start(); 136 | 137 | return tcs.Task; 138 | } 139 | 140 | 141 | internal static Task SendFilesAsyncCore(string xiaomiFile, TimeSpan timeout) 142 | { 143 | if (string.IsNullOrEmpty(xiaomiFile)) return Task.FromResult(false); 144 | //if (files == null || files.Length == 0) return Task.FromResult(false); 145 | 146 | var messageWindow = FindMessageWindow(); 147 | if (messageWindow == 0) return Task.FromResult(false); 148 | 149 | var tcs = new TaskCompletionSource(); 150 | 151 | var thread = new Thread(() => 152 | { 153 | try 154 | { 155 | tcs.TrySetResult(SendFilesCore(messageWindow, xiaomiFile, timeout)); 156 | } 157 | catch { } 158 | tcs.TrySetResult(false); 159 | 160 | unsafe static bool SendFilesCore(nint messageWindow, string xiaomiFiles, TimeSpan timeout) 161 | { 162 | fixed (char* ptr = xiaomiFiles) 163 | { 164 | var s = default(COPYDATASTRUCT); 165 | s.dwData = 0; 166 | s.cbData = (xiaomiFiles.Length) * 2; 167 | s.lpData = (nint)ptr; 168 | 169 | var timeout2 = unchecked((uint)timeout.TotalMilliseconds); 170 | if (timeout2 > 15 * 1000) timeout2 = 15 * 1000; 171 | if (timeout2 < 0) timeout2 = 0; 172 | 173 | var res = SendMessageTimeoutW(messageWindow, 74, (IntPtr)1, (nint)(&s), 0, timeout2, out var lpdwResult); 174 | return res != 0; 175 | } 176 | } 177 | }); 178 | thread.IsBackground = true; 179 | thread.Start(); 180 | 181 | return tcs.Task; 182 | } 183 | 184 | internal static string CreateXiaomiFile(string[] files) 185 | { 186 | var sb = new StringBuilder(); 187 | for (int i = 0; i < files.Length; i++) 188 | { 189 | var path = files[i]; 190 | 191 | if (!string.IsNullOrEmpty(path) 192 | && Path.IsPathRooted(path)) 193 | { 194 | if (sb.Length > 0) sb.Append('|'); 195 | sb.Append(path); 196 | } 197 | } 198 | 199 | return sb.ToString(); 200 | } 201 | 202 | 203 | private unsafe static nint FindMessageWindow() 204 | { 205 | const string WindowClassName = "XiaomiPCManager"; 206 | 207 | fixed (char* pClassName = WindowClassName) 208 | { 209 | return FindWindowW(pClassName, null); 210 | } 211 | } 212 | 213 | [DllImport("user32.dll")] 214 | private static unsafe extern nint SendMessageW(nint hWnd, int Msg, IntPtr wParam, IntPtr lParam); 215 | 216 | [DllImport("user32.dll")] 217 | private static unsafe extern int SendMessageTimeoutW(nint hWnd, int Msg, IntPtr wParam, IntPtr lParam, uint fuFlags, uint uTimeout, out nint lpdwResult); 218 | 219 | [DllImport("user32.dll")] 220 | private static unsafe extern nint FindWindowW(char* lpClassName, char* lpWindowName); 221 | 222 | private struct COPYDATASTRUCT 223 | { 224 | public nint dwData; 225 | 226 | public int cbData; 227 | 228 | public nint lpData; 229 | } 230 | 231 | } 232 | -------------------------------------------------------------------------------- /src/MiDrop.Helper/MiDrop.Helper.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | WinExe 5 | net9.0-windows10.0.22000.0 6 | enable 7 | enable 8 | x64 9 | x64 10 | win-x64 11 | true 12 | 13 | 14 | 15 | false 16 | true 17 | Size 18 | true 19 | false 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /src/MiDrop.Helper/Program.cs: -------------------------------------------------------------------------------- 1 | // See https://aka.ms/new-console-template for more information 2 | using Microsoft.Win32; 3 | using MiDrop.Core; 4 | using System; 5 | using System.CommandLine; 6 | using System.IO.MemoryMappedFiles; 7 | using System.Runtime.InteropServices; 8 | using System.Text; 9 | using Windows.ApplicationModel; 10 | using Windows.ApplicationModel.Activation; 11 | using Windows.ApplicationModel.DataTransfer; 12 | using WinRT; 13 | 14 | namespace MiDrop.Helper; 15 | 16 | public static class Program 17 | { 18 | public static async Task Main(string[] args) 19 | { 20 | bool hasCommandLineArgs = false; 21 | 22 | var fileOption = new Option("--share-files"); 23 | var targetOption = new Option("--target"); 24 | var rootCommand = new Command("MiDropShellExtHelper") 25 | { 26 | fileOption, 27 | targetOption, 28 | }; 29 | rootCommand.SetHandler(async (string file, string? target) => 30 | { 31 | if (!string.IsNullOrEmpty(file)) 32 | { 33 | hasCommandLineArgs = true; 34 | 35 | if (target == "XiaomiShare") 36 | { 37 | await MiDrop.Core.XiaomiPcManagerHelper.LaunchAsync(default); 38 | await MiDrop.Core.XiaomiPcManagerHelper.SendCachedFilesAsync(file, TimeSpan.FromSeconds(5)); 39 | } 40 | else if (target == "HuaweiShare" || target == "HonorShare") 41 | { 42 | var xiaomiFileContent = await FilesHelper.GetXiaomiFileAsync(file, default); 43 | var files = FilesHelper.GetFilesFromXiaomiFileContent(xiaomiFileContent); 44 | 45 | Console.WriteLine("files:"); 46 | Console.WriteLine(string.Join(Environment.NewLine, files)); 47 | 48 | if (target == "HuaweiShare") await HuaweiPCManagerHelper.SendFilesAsync(files); 49 | if (target == "HonorShare") await HonorPCManagerHelper.SendFilesAsync(files); 50 | } 51 | } 52 | }, fileOption, targetOption); 53 | await rootCommand.InvokeAsync(args); 54 | 55 | if (!hasCommandLineArgs) 56 | { 57 | var aumid = GetCurrentApplicationUserModelId(); 58 | var appIdIndex = aumid?.LastIndexOf('!') ?? -1; 59 | var appId = appIdIndex != -1 ? aumid![(appIdIndex + 1)..] : null; 60 | 61 | var activatedEventArgs = AppInstance.GetActivatedEventArgs(); 62 | if (activatedEventArgs.Kind == Windows.ApplicationModel.Activation.ActivationKind.ShareTarget) 63 | { 64 | if (appId == "XiaomiShare" || appId == "HuaweiShare" || appId == "HonorShare") 65 | { 66 | var sharedTargetActivatedEventArgs = activatedEventArgs.As(); 67 | var shareOperation = sharedTargetActivatedEventArgs.ShareOperation; 68 | 69 | shareOperation.ReportStarted(); 70 | try 71 | { 72 | var dataPackageView = shareOperation.Data; 73 | 74 | if (dataPackageView.Contains(StandardDataFormats.StorageItems)) 75 | { 76 | var items = await dataPackageView.GetStorageItemsAsync(); 77 | var itemsPathList = items 78 | .Select(c => c.Path) 79 | .Where(c => File.Exists(c) || Directory.Exists(c)) 80 | .ToArray(); 81 | 82 | if (itemsPathList != null && itemsPathList.Length > 0) 83 | { 84 | if (appId == "XiaomiShare") 85 | { 86 | var key = MiDrop.Core.FilesHelper.SaveFilesAsync(itemsPathList, default).Result; 87 | await MiDrop.Core.XiaomiPcManagerHelper.LaunchAsync(default); 88 | await MiDrop.Core.XiaomiPcManagerHelper.SendCachedFilesAsync(key, TimeSpan.FromSeconds(5)); 89 | } 90 | else if (appId == "HuaweiShare") 91 | { 92 | await HuaweiPCManagerHelper.SendFilesAsync(itemsPathList); 93 | } 94 | else if (appId == "HonorShare") 95 | { 96 | await HonorPCManagerHelper.SendFilesAsync(itemsPathList); 97 | } 98 | } 99 | } 100 | } 101 | finally 102 | { 103 | shareOperation.ReportCompleted(); 104 | } 105 | 106 | return; 107 | } 108 | } 109 | 110 | if (appId == "XiaomiApp") 111 | { 112 | await MiDrop.Core.XiaomiPcManagerHelper.LaunchAsync("open_controlcenter", default); 113 | } 114 | else if (appId == "HonorApp") 115 | { 116 | 117 | } 118 | else if (appId == "HuaweiApp") 119 | { 120 | 121 | } 122 | } 123 | 124 | } 125 | 126 | 127 | [DllImport("Kernel32.dll")] 128 | private unsafe static extern int GetCurrentApplicationUserModelId(uint* applicationUserModelIdLength, char* applicationUserModelId); 129 | 130 | private unsafe static string? GetCurrentApplicationUserModelId() 131 | { 132 | const int ERROR_INSUFFICIENT_BUFFER = 122; 133 | 134 | uint length = 0; 135 | 136 | var error = GetCurrentApplicationUserModelId(&length, null); 137 | if (error == ERROR_INSUFFICIENT_BUFFER && length > 0) 138 | { 139 | char* buffer = stackalloc char[(int)length]; 140 | error = GetCurrentApplicationUserModelId(&length, buffer); 141 | 142 | if (error == 0 && length > 1) 143 | { 144 | return new string(buffer, 0, (int)length - 1); 145 | } 146 | } 147 | return null; 148 | } 149 | } -------------------------------------------------------------------------------- /src/MiDropShellExt.Package/HonorImages/LockScreenLogo.scale-400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnbluefire/MiDropShellExtForWindows11/a7c39ab8b449862a562e5294569639b38902d9dc/src/MiDropShellExt.Package/HonorImages/LockScreenLogo.scale-400.png -------------------------------------------------------------------------------- /src/MiDropShellExt.Package/HonorImages/Share.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnbluefire/MiDropShellExtForWindows11/a7c39ab8b449862a562e5294569639b38902d9dc/src/MiDropShellExt.Package/HonorImages/Share.ico -------------------------------------------------------------------------------- /src/MiDropShellExt.Package/HonorImages/SplashScreen.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnbluefire/MiDropShellExtForWindows11/a7c39ab8b449862a562e5294569639b38902d9dc/src/MiDropShellExt.Package/HonorImages/SplashScreen.scale-200.png -------------------------------------------------------------------------------- /src/MiDropShellExt.Package/HonorImages/Square150x150Logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnbluefire/MiDropShellExtForWindows11/a7c39ab8b449862a562e5294569639b38902d9dc/src/MiDropShellExt.Package/HonorImages/Square150x150Logo.png -------------------------------------------------------------------------------- /src/MiDropShellExt.Package/HonorImages/Square150x150Logo.scale-400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnbluefire/MiDropShellExtForWindows11/a7c39ab8b449862a562e5294569639b38902d9dc/src/MiDropShellExt.Package/HonorImages/Square150x150Logo.scale-400.png -------------------------------------------------------------------------------- /src/MiDropShellExt.Package/HonorImages/Square44x44Logo.altform-unplated_targetsize-256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnbluefire/MiDropShellExtForWindows11/a7c39ab8b449862a562e5294569639b38902d9dc/src/MiDropShellExt.Package/HonorImages/Square44x44Logo.altform-unplated_targetsize-256.png -------------------------------------------------------------------------------- /src/MiDropShellExt.Package/HonorImages/Square44x44Logo.scale-400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnbluefire/MiDropShellExtForWindows11/a7c39ab8b449862a562e5294569639b38902d9dc/src/MiDropShellExt.Package/HonorImages/Square44x44Logo.scale-400.png -------------------------------------------------------------------------------- /src/MiDropShellExt.Package/HonorImages/Square44x44Logo.targetsize-24_altform-unplated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnbluefire/MiDropShellExtForWindows11/a7c39ab8b449862a562e5294569639b38902d9dc/src/MiDropShellExt.Package/HonorImages/Square44x44Logo.targetsize-24_altform-unplated.png -------------------------------------------------------------------------------- /src/MiDropShellExt.Package/HonorImages/StoreLogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnbluefire/MiDropShellExtForWindows11/a7c39ab8b449862a562e5294569639b38902d9dc/src/MiDropShellExt.Package/HonorImages/StoreLogo.png -------------------------------------------------------------------------------- /src/MiDropShellExt.Package/HonorImages/Wide310x150Logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnbluefire/MiDropShellExtForWindows11/a7c39ab8b449862a562e5294569639b38902d9dc/src/MiDropShellExt.Package/HonorImages/Wide310x150Logo.png -------------------------------------------------------------------------------- /src/MiDropShellExt.Package/HonorImages/Wide310x150Logo.scale-400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnbluefire/MiDropShellExtForWindows11/a7c39ab8b449862a562e5294569639b38902d9dc/src/MiDropShellExt.Package/HonorImages/Wide310x150Logo.scale-400.png -------------------------------------------------------------------------------- /src/MiDropShellExt.Package/HonorShare.Package.appxmanifest: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | HonorShare Helper 6 | blue-fire 7 | HonorImages\StoreLogo.png 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | Bitmap 52 | StorageItems 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /src/MiDropShellExt.Package/HuaweiImages/LockScreenLogo.scale-400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnbluefire/MiDropShellExtForWindows11/a7c39ab8b449862a562e5294569639b38902d9dc/src/MiDropShellExt.Package/HuaweiImages/LockScreenLogo.scale-400.png -------------------------------------------------------------------------------- /src/MiDropShellExt.Package/HuaweiImages/Share.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnbluefire/MiDropShellExtForWindows11/a7c39ab8b449862a562e5294569639b38902d9dc/src/MiDropShellExt.Package/HuaweiImages/Share.ico -------------------------------------------------------------------------------- /src/MiDropShellExt.Package/HuaweiImages/SplashScreen.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnbluefire/MiDropShellExtForWindows11/a7c39ab8b449862a562e5294569639b38902d9dc/src/MiDropShellExt.Package/HuaweiImages/SplashScreen.scale-200.png -------------------------------------------------------------------------------- /src/MiDropShellExt.Package/HuaweiImages/Square150x150Logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnbluefire/MiDropShellExtForWindows11/a7c39ab8b449862a562e5294569639b38902d9dc/src/MiDropShellExt.Package/HuaweiImages/Square150x150Logo.png -------------------------------------------------------------------------------- /src/MiDropShellExt.Package/HuaweiImages/Square150x150Logo.scale-400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnbluefire/MiDropShellExtForWindows11/a7c39ab8b449862a562e5294569639b38902d9dc/src/MiDropShellExt.Package/HuaweiImages/Square150x150Logo.scale-400.png -------------------------------------------------------------------------------- /src/MiDropShellExt.Package/HuaweiImages/Square44x44Logo.altform-unplated_targetsize-256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnbluefire/MiDropShellExtForWindows11/a7c39ab8b449862a562e5294569639b38902d9dc/src/MiDropShellExt.Package/HuaweiImages/Square44x44Logo.altform-unplated_targetsize-256.png -------------------------------------------------------------------------------- /src/MiDropShellExt.Package/HuaweiImages/Square44x44Logo.scale-400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnbluefire/MiDropShellExtForWindows11/a7c39ab8b449862a562e5294569639b38902d9dc/src/MiDropShellExt.Package/HuaweiImages/Square44x44Logo.scale-400.png -------------------------------------------------------------------------------- /src/MiDropShellExt.Package/HuaweiImages/Square44x44Logo.targetsize-24_altform-unplated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnbluefire/MiDropShellExtForWindows11/a7c39ab8b449862a562e5294569639b38902d9dc/src/MiDropShellExt.Package/HuaweiImages/Square44x44Logo.targetsize-24_altform-unplated.png -------------------------------------------------------------------------------- /src/MiDropShellExt.Package/HuaweiImages/StoreLogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnbluefire/MiDropShellExtForWindows11/a7c39ab8b449862a562e5294569639b38902d9dc/src/MiDropShellExt.Package/HuaweiImages/StoreLogo.png -------------------------------------------------------------------------------- /src/MiDropShellExt.Package/HuaweiImages/Wide310x150Logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnbluefire/MiDropShellExtForWindows11/a7c39ab8b449862a562e5294569639b38902d9dc/src/MiDropShellExt.Package/HuaweiImages/Wide310x150Logo.png -------------------------------------------------------------------------------- /src/MiDropShellExt.Package/HuaweiImages/Wide310x150Logo.scale-400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnbluefire/MiDropShellExtForWindows11/a7c39ab8b449862a562e5294569639b38902d9dc/src/MiDropShellExt.Package/HuaweiImages/Wide310x150Logo.scale-400.png -------------------------------------------------------------------------------- /src/MiDropShellExt.Package/HuaweiShare.Package.appxmanifest: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | HuaweiShare Helper 6 | blue-fire 7 | HuaweiImages\StoreLogo.png 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | Bitmap 52 | StorageItems 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /src/MiDropShellExt.Package/MiDropShellExt.Package.wapproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 15.0 5 | 6 | 7 | 8 | Debug 9 | x64 10 | 11 | 12 | Release 13 | x64 14 | 15 | 16 | 17 | $(MSBuildExtensionsPath)\Microsoft\DesktopBridge\ 18 | 19 | 20 | 21 | 338a92ea-3827-4b63-870b-a6fda0b902e5 22 | 10.0.22000.0 23 | 10.0.18362.0 24 | zh-CN 25 | True 26 | $(NoWarn);NU1702 27 | ..\MiDrop.Helper\MiDrop.Helper.csproj 28 | False 29 | SHA256 30 | False 31 | True 32 | x64 33 | 0 34 | CFCC41845E3D8F50FFC5F35ADF3F06788C717F7D 35 | DXFeatureLevel 36 | XiaomiShare 37 | 38 | 39 | Always 40 | 41 | 42 | Always 43 | 44 | 45 | 46 | Designer 47 | 48 | 49 | Designer 50 | 51 | 52 | Designer 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | -------------------------------------------------------------------------------- /src/MiDropShellExt.Package/XiaomiImages/LockScreenLogo.scale-400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnbluefire/MiDropShellExtForWindows11/a7c39ab8b449862a562e5294569639b38902d9dc/src/MiDropShellExt.Package/XiaomiImages/LockScreenLogo.scale-400.png -------------------------------------------------------------------------------- /src/MiDropShellExt.Package/XiaomiImages/SplashScreen.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnbluefire/MiDropShellExtForWindows11/a7c39ab8b449862a562e5294569639b38902d9dc/src/MiDropShellExt.Package/XiaomiImages/SplashScreen.scale-200.png -------------------------------------------------------------------------------- /src/MiDropShellExt.Package/XiaomiImages/Square150x150Logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnbluefire/MiDropShellExtForWindows11/a7c39ab8b449862a562e5294569639b38902d9dc/src/MiDropShellExt.Package/XiaomiImages/Square150x150Logo.png -------------------------------------------------------------------------------- /src/MiDropShellExt.Package/XiaomiImages/Square150x150Logo.scale-400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnbluefire/MiDropShellExtForWindows11/a7c39ab8b449862a562e5294569639b38902d9dc/src/MiDropShellExt.Package/XiaomiImages/Square150x150Logo.scale-400.png -------------------------------------------------------------------------------- /src/MiDropShellExt.Package/XiaomiImages/Square44x44Logo.altform-unplated_targetsize-256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnbluefire/MiDropShellExtForWindows11/a7c39ab8b449862a562e5294569639b38902d9dc/src/MiDropShellExt.Package/XiaomiImages/Square44x44Logo.altform-unplated_targetsize-256.png -------------------------------------------------------------------------------- /src/MiDropShellExt.Package/XiaomiImages/Square44x44Logo.scale-400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnbluefire/MiDropShellExtForWindows11/a7c39ab8b449862a562e5294569639b38902d9dc/src/MiDropShellExt.Package/XiaomiImages/Square44x44Logo.scale-400.png -------------------------------------------------------------------------------- /src/MiDropShellExt.Package/XiaomiImages/Square44x44Logo.targetsize-24_altform-unplated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnbluefire/MiDropShellExtForWindows11/a7c39ab8b449862a562e5294569639b38902d9dc/src/MiDropShellExt.Package/XiaomiImages/Square44x44Logo.targetsize-24_altform-unplated.png -------------------------------------------------------------------------------- /src/MiDropShellExt.Package/XiaomiImages/StoreLogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnbluefire/MiDropShellExtForWindows11/a7c39ab8b449862a562e5294569639b38902d9dc/src/MiDropShellExt.Package/XiaomiImages/StoreLogo.png -------------------------------------------------------------------------------- /src/MiDropShellExt.Package/XiaomiImages/Wide310x150Logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnbluefire/MiDropShellExtForWindows11/a7c39ab8b449862a562e5294569639b38902d9dc/src/MiDropShellExt.Package/XiaomiImages/Wide310x150Logo.png -------------------------------------------------------------------------------- /src/MiDropShellExt.Package/XiaomiImages/Wide310x150Logo.scale-400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnbluefire/MiDropShellExtForWindows11/a7c39ab8b449862a562e5294569639b38902d9dc/src/MiDropShellExt.Package/XiaomiImages/Wide310x150Logo.scale-400.png -------------------------------------------------------------------------------- /src/MiDropShellExt.Package/XiaomiShare.Package.appxmanifest: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | MiDrop Helper 6 | blue-fire 7 | XiaomiImages\StoreLogo.png 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | Bitmap 52 | StorageItems 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /src/MiDropShellExt.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.13.35507.96 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{C7167F0D-BC9F-4E6E-AFE1-012C56B48DB5}") = "MiDropShellExt.Package", "MiDropShellExt.Package\MiDropShellExt.Package.wapproj", "{338A92EA-3827-4B63-870B-A6FDA0B902E5}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MiDrop.Helper", "MiDrop.Helper\MiDrop.Helper.csproj", "{20AB2056-2FFB-48B3-9E1F-C61EDEA677CD}" 9 | EndProject 10 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ShellExt", "ShellExt\ShellExt.csproj", "{F2683AA5-554F-4E5E-A2A7-181443A36A58}" 11 | EndProject 12 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MiDrop.Core", "MiDrop.Core\MiDrop.Core.csproj", "{E659F239-7FF9-4394-9015-8137FBBBB576}" 13 | EndProject 14 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "PackageProjects", "PackageProjects", "{02EA681E-C7D8-13C7-8484-4AC65E1B71E8}" 15 | EndProject 16 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Application", "Application", "{192CB46B-EFC7-4495-9EF5-E4D0BC52771D}" 17 | EndProject 18 | Global 19 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 20 | Debug|x64 = Debug|x64 21 | Release|x64 = Release|x64 22 | EndGlobalSection 23 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 24 | {338A92EA-3827-4B63-870B-A6FDA0B902E5}.Debug|x64.ActiveCfg = Debug|x64 25 | {338A92EA-3827-4B63-870B-A6FDA0B902E5}.Debug|x64.Build.0 = Debug|x64 26 | {338A92EA-3827-4B63-870B-A6FDA0B902E5}.Debug|x64.Deploy.0 = Debug|x64 27 | {338A92EA-3827-4B63-870B-A6FDA0B902E5}.Release|x64.ActiveCfg = Release|x64 28 | {338A92EA-3827-4B63-870B-A6FDA0B902E5}.Release|x64.Build.0 = Release|x64 29 | {338A92EA-3827-4B63-870B-A6FDA0B902E5}.Release|x64.Deploy.0 = Release|x64 30 | {20AB2056-2FFB-48B3-9E1F-C61EDEA677CD}.Debug|x64.ActiveCfg = Debug|x64 31 | {20AB2056-2FFB-48B3-9E1F-C61EDEA677CD}.Debug|x64.Build.0 = Debug|x64 32 | {20AB2056-2FFB-48B3-9E1F-C61EDEA677CD}.Release|x64.ActiveCfg = Release|x64 33 | {20AB2056-2FFB-48B3-9E1F-C61EDEA677CD}.Release|x64.Build.0 = Release|x64 34 | {F2683AA5-554F-4E5E-A2A7-181443A36A58}.Debug|x64.ActiveCfg = Debug|x64 35 | {F2683AA5-554F-4E5E-A2A7-181443A36A58}.Debug|x64.Build.0 = Debug|x64 36 | {F2683AA5-554F-4E5E-A2A7-181443A36A58}.Release|x64.ActiveCfg = Release|x64 37 | {F2683AA5-554F-4E5E-A2A7-181443A36A58}.Release|x64.Build.0 = Release|x64 38 | {E659F239-7FF9-4394-9015-8137FBBBB576}.Debug|x64.ActiveCfg = Debug|x64 39 | {E659F239-7FF9-4394-9015-8137FBBBB576}.Debug|x64.Build.0 = Debug|x64 40 | {E659F239-7FF9-4394-9015-8137FBBBB576}.Release|x64.ActiveCfg = Release|x64 41 | {E659F239-7FF9-4394-9015-8137FBBBB576}.Release|x64.Build.0 = Release|x64 42 | EndGlobalSection 43 | GlobalSection(SolutionProperties) = preSolution 44 | HideSolutionNode = FALSE 45 | EndGlobalSection 46 | GlobalSection(NestedProjects) = preSolution 47 | {338A92EA-3827-4B63-870B-A6FDA0B902E5} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8} 48 | {20AB2056-2FFB-48B3-9E1F-C61EDEA677CD} = {192CB46B-EFC7-4495-9EF5-E4D0BC52771D} 49 | {F2683AA5-554F-4E5E-A2A7-181443A36A58} = {192CB46B-EFC7-4495-9EF5-E4D0BC52771D} 50 | {E659F239-7FF9-4394-9015-8137FBBBB576} = {192CB46B-EFC7-4495-9EF5-E4D0BC52771D} 51 | EndGlobalSection 52 | GlobalSection(ExtensibilityGlobals) = postSolution 53 | SolutionGuid = {91E393C5-B663-4753-B603-8D52ED3A13DF} 54 | EndGlobalSection 55 | EndGlobal 56 | -------------------------------------------------------------------------------- /src/ShellExt/ContextMenu.cs: -------------------------------------------------------------------------------- 1 | using ShellExtensions; 2 | using ShellExtensions.Helpers; 3 | using System.Runtime.CompilerServices; 4 | using System.Runtime.InteropServices; 5 | using System.Text; 6 | 7 | namespace ShellExt 8 | { 9 | public class ContextMenu : ExplorerCommand 10 | { 11 | private readonly string target; 12 | private readonly string icon; 13 | private readonly string title; 14 | 15 | public ContextMenu(string target, string icon, string title) 16 | { 17 | this.target = target; 18 | this.icon = icon; 19 | this.title = title; 20 | } 21 | 22 | public override string? GetIcon(ShellItemArray shellItems) 23 | { 24 | return icon; 25 | } 26 | 27 | public override string? GetTitle(ShellItemArray shellItems) 28 | { 29 | return title; 30 | } 31 | 32 | public override ExplorerCommandState GetState(ShellItemArray shellItems, bool fOkToBeSlow, out bool pending) 33 | { 34 | pending = false; 35 | if (this.ServiceProvider.GetService() is { } accessor) 36 | { 37 | if (accessor.ContextMenuType == ContextMenuType.ModernContextMenu 38 | || accessor.ContextMenuType == ContextMenuType.Unknown) 39 | { 40 | return ExplorerCommandState.ECS_ENABLED; 41 | } 42 | } 43 | 44 | return ExplorerCommandState.ECS_HIDDEN; 45 | } 46 | 47 | public override unsafe void Invoke(ExplorerCommandInvokeEventArgs args) 48 | { 49 | var files = args.ShellItems.Select(c => c.FullPath).ToArray(); 50 | if (files != null && files.Length > 0) 51 | { 52 | DllMain.StartShare(target, files); 53 | } 54 | } 55 | 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/ShellExt/DllMain.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Win32; 2 | using MiDrop.Core; 3 | using ShellExtensions; 4 | using System.Diagnostics; 5 | using System.Runtime.CompilerServices; 6 | using System.Runtime.InteropServices; 7 | using System.Text; 8 | 9 | namespace ShellExt 10 | { 11 | public static class DllMain 12 | { 13 | private static readonly Guid PackagedClsid1 = new Guid("976D43D8-907F-46AF-B47F-07084C71A2F0"); 14 | private static readonly Guid PackagedClsid2 = new Guid("3EE2A0FD-EA1B-4630-9972-02F51EC786FF"); 15 | private static readonly Guid PackagedClsid3 = new Guid("3FA37C0D-64B9-4E51-A9DF-411647E9DE79"); 16 | 17 | #pragma warning disable CA2255 18 | [ModuleInitializer] 19 | #pragma warning restore CA2255 20 | public static void _DllMain() 21 | { 22 | try 23 | { 24 | var folder1 = XiaomiPcManagerHelper.GetInstallPath(); 25 | if (Directory.Exists(folder1)) 26 | { 27 | ShellExtensions.ShellExtensionsClassFactory.RegisterInProcess( 28 | PackagedClsid1, 29 | () => new ContextMenu( 30 | "XiaomiShare", 31 | Path.Combine(folder1, "XiaomiPcManager.exe,-32512"), 32 | "使用小米互传发送")); 33 | } 34 | } 35 | catch { } 36 | 37 | try 38 | { 39 | var folder = HonorPCManagerHelper.GetInstallPath(); 40 | if (Directory.Exists(folder)) 41 | { 42 | ShellExtensions.ShellExtensionsClassFactory.RegisterInProcess( 43 | PackagedClsid2, 44 | () => new ContextMenu( 45 | "HonorShare", 46 | Path.GetFullPath(Path.Combine(DllModule.BaseDirectory, "..", "HonorImages", "Share.ico")), 47 | "使用荣耀分享发送")); 48 | } 49 | } 50 | catch { } 51 | 52 | try 53 | { 54 | var folder = HuaweiPCManagerHelper.GetInstallPath(); 55 | if (Directory.Exists(folder)) 56 | { 57 | ShellExtensions.ShellExtensionsClassFactory.RegisterInProcess( 58 | PackagedClsid1, 59 | () => new ContextMenu( 60 | "HuaweiShare", 61 | Path.GetFullPath(Path.Combine(DllModule.BaseDirectory, "..", "HuaweiImages", "Share.ico")), 62 | "使用华为分享发送")); 63 | } 64 | } 65 | catch { } 66 | } 67 | 68 | [UnmanagedCallersOnly(EntryPoint = "DllCanUnloadNow")] 69 | private static int DllCanUnloadNow() => ShellExtensions.ShellExtensionsClassFactory.DllCanUnloadNow(); 70 | 71 | [UnmanagedCallersOnly(EntryPoint = "DllGetClassObject")] 72 | private unsafe static int DllGetClassObject(Guid* clsid, Guid* riid, void** ppv) => ShellExtensions.ShellExtensionsClassFactory.DllGetClassObject(clsid, riid, ppv); 73 | 74 | public static unsafe void StartShare(string target, string[] files) 75 | { 76 | var installLocation = PackageProperties.Current?.PackageInstallLocation; 77 | if (!string.IsNullOrEmpty(installLocation)) 78 | { 79 | var helperExecute = System.IO.Path.Combine(installLocation, "MiDrop.Helper", "MiDrop.Helper.exe"); 80 | if (System.IO.File.Exists(helperExecute)) 81 | { 82 | var key = MiDrop.Core.FilesHelper.SaveFilesAsync(files, default).Result; 83 | if (!string.IsNullOrEmpty(key)) 84 | { 85 | try 86 | { 87 | Process.Start(helperExecute, $"--target {target} --share-files {key}"); 88 | } 89 | catch { } 90 | } 91 | } 92 | } 93 | } 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /src/ShellExt/ShellExt.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net9.0-windows 5 | enable 6 | enable 7 | x64 8 | x64 9 | win-x64 10 | true 11 | 12 | 13 | 14 | true 15 | true 16 | true 17 | Size 18 | true 19 | true 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | --------------------------------------------------------------------------------