windows: Publish nightly (#24800)
The installer, uninstaller, and the Zed binary files are all signed using Microsoft’s newly launched Trusted Signing service. For demonstration purposes, I have used my own account for the signing process. For more information about Trusted Signing, you can refer to the following links: - [Microsoft Security Blog: Trusted Signing is in Public Preview](https://techcommunity.microsoft.com/blog/microsoft-security-blog/trusted-signing-is-in-public-preview/4103457) - [Overview of Azure Trusted Signing](https://learn.microsoft.com/en-us/azure/trusted-signing/overview) **TODO:** - [x] `InnoSetup` script to setup an installer - [x] Signing process - [x] `Open with Zed` in right click context menu (by using sparse package) - [x] Integrate with `cli` - [x] Implement `cli` (#25412) - [x] Pack `cli.exe` into installer - [x] Implement auto updating (#25734) - [x] Pack autoupdater helper into installer - [x] Implement dock menus - [x] Add `Recent Documents` entries (#26369) - [x] Make `zed.exe` aware of sigle instance (#25412) - [x] Properly handle dock menu events (#26010) - [x] Handle `zed://***` uri **Materials needed:** - [ ] Icons - [ ] App icon for all channels (#9571) - [ ] Associated file icons, at minimum a default icon ([example](https://github.com/microsoft/vscode/tree/main/resources/win32)) - [ ] Logos for installer wizard - [ ] Icons for appx - [x] Code signing - [x] Secrets: AZURE_TENANT_ID, AZURE_CLIENT_ID, AZURE_CLIENT_SECRET, ACCOUNT_NAME, CERT_PROFILE_NAME - [x] Other constants: ENDPOINT, Identity Signature (i.e. `CN=Junkui Zhang, O=Junkui Zhang, L=Wuhan, S=Hubei, C=CN`)  https://github.com/user-attachments/assets/4f1092b4-90fc-4a47-a868-8f2f1a5d8ad8 Release Notes: - N/A --------- Co-authored-by: Kate <kate@zed.dev> Co-authored-by: localcc <work@localcc.cc> Co-authored-by: Peter Tripp <peter@zed.dev> Co-authored-by: Max Brunsfeld <maxbrunsfeld@gmail.com>
This commit is contained in:
parent
3a247ee947
commit
df57754baf
33 changed files with 3040 additions and 19 deletions
78
crates/explorer_command_injector/AppxManifest-Nightly.xml
Normal file
78
crates/explorer_command_injector/AppxManifest-Nightly.xml
Normal file
|
@ -0,0 +1,78 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Package
|
||||
xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
|
||||
xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
|
||||
xmlns:uap2="http://schemas.microsoft.com/appx/manifest/uap/windows10/2"
|
||||
xmlns:uap3="http://schemas.microsoft.com/appx/manifest/uap/windows10/3"
|
||||
xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"
|
||||
xmlns:desktop="http://schemas.microsoft.com/appx/manifest/desktop/windows10"
|
||||
xmlns:desktop4="http://schemas.microsoft.com/appx/manifest/desktop/windows10/4"
|
||||
xmlns:desktop5="http://schemas.microsoft.com/appx/manifest/desktop/windows10/5"
|
||||
xmlns:desktop6="http://schemas.microsoft.com/appx/manifest/desktop/windows10/6"
|
||||
xmlns:uap10="http://schemas.microsoft.com/appx/manifest/uap/windows10/10"
|
||||
xmlns:com="http://schemas.microsoft.com/appx/manifest/com/windows10"
|
||||
IgnorableNamespaces="uap uap2 uap3 rescap desktop desktop4 desktop5 desktop6 uap10 com">
|
||||
<!-- TODO: Use Zed's signature here. -->
|
||||
<Identity
|
||||
Name="ZedIndustries.Zed.Nightly"
|
||||
Publisher="CN=Zed Industries Inc, O=Zed Industries Inc, L=Denver, S=Colorado, C=US"
|
||||
Version="1.0.0.0" />
|
||||
<Properties>
|
||||
<DisplayName>Zed Editor Nightly</DisplayName>
|
||||
<PublisherDisplayName>Zed Industries</PublisherDisplayName>
|
||||
<!-- TODO: Use actual icon here. -->
|
||||
<Logo>resources\logo_150x150.png</Logo>
|
||||
<uap10:AllowExternalContent>true</uap10:AllowExternalContent>
|
||||
<desktop6:RegistryWriteVirtualization>disabled</desktop6:RegistryWriteVirtualization>
|
||||
<desktop6:FileSystemWriteVirtualization>disabled</desktop6:FileSystemWriteVirtualization>
|
||||
</Properties>
|
||||
<Resources>
|
||||
<Resource Language="en-us" />
|
||||
<Resource Language="zh-cn" />
|
||||
</Resources>
|
||||
<Dependencies>
|
||||
<TargetDeviceFamily Name="Windows.Desktop" MinVersion="10.0.19000.0" MaxVersionTested="10.0.22000.0" />
|
||||
</Dependencies>
|
||||
<Capabilities>
|
||||
<rescap:Capability Name="runFullTrust" />
|
||||
<rescap:Capability Name="unvirtualizedResources"/>
|
||||
</Capabilities>
|
||||
<Applications>
|
||||
<Application Id="ZedNightly"
|
||||
Executable="Zed.exe"
|
||||
uap10:TrustLevel="mediumIL"
|
||||
uap10:RuntimeBehavior="win32App">
|
||||
<!-- TODO: Use actual icon here. -->
|
||||
<uap:VisualElements
|
||||
AppListEntry="none"
|
||||
DisplayName="Zed Editor Nightly"
|
||||
Description="Zed Editor Nightly explorer command injector"
|
||||
BackgroundColor="transparent"
|
||||
Square150x150Logo="resources\logo_150x150.png"
|
||||
Square44x44Logo="resources\logo_70x70.png">
|
||||
</uap:VisualElements>
|
||||
<Extensions>
|
||||
<desktop4:Extension Category="windows.fileExplorerContextMenus">
|
||||
<desktop4:FileExplorerContextMenus>
|
||||
<desktop5:ItemType Type="Directory">
|
||||
<desktop5:Verb Id="OpenWithZedNightly" Clsid="266f2cfe-1653-42af-b55c-fe3590c83871" />
|
||||
</desktop5:ItemType>
|
||||
<desktop5:ItemType Type="Directory\Background">
|
||||
<desktop5:Verb Id="OpenWithZedNightly" Clsid="266f2cfe-1653-42af-b55c-fe3590c83871" />
|
||||
</desktop5:ItemType>
|
||||
<desktop5:ItemType Type="*">
|
||||
<desktop5:Verb Id="OpenWithZedNightly" Clsid="266f2cfe-1653-42af-b55c-fe3590c83871" />
|
||||
</desktop5:ItemType>
|
||||
</desktop4:FileExplorerContextMenus>
|
||||
</desktop4:Extension>
|
||||
<com:Extension Category="windows.comServer">
|
||||
<com:ComServer>
|
||||
<com:SurrogateServer DisplayName="Zed Editor Nightly">
|
||||
<com:Class Id="266f2cfe-1653-42af-b55c-fe3590c83871" Path="zed_explorer_command_injector.dll" ThreadingModel="STA"/>
|
||||
</com:SurrogateServer>
|
||||
</com:ComServer>
|
||||
</com:Extension>
|
||||
</Extensions>
|
||||
</Application>
|
||||
</Applications>
|
||||
</Package>
|
78
crates/explorer_command_injector/AppxManifest-Preview.xml
Normal file
78
crates/explorer_command_injector/AppxManifest-Preview.xml
Normal file
|
@ -0,0 +1,78 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Package
|
||||
xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
|
||||
xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
|
||||
xmlns:uap2="http://schemas.microsoft.com/appx/manifest/uap/windows10/2"
|
||||
xmlns:uap3="http://schemas.microsoft.com/appx/manifest/uap/windows10/3"
|
||||
xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"
|
||||
xmlns:desktop="http://schemas.microsoft.com/appx/manifest/desktop/windows10"
|
||||
xmlns:desktop4="http://schemas.microsoft.com/appx/manifest/desktop/windows10/4"
|
||||
xmlns:desktop5="http://schemas.microsoft.com/appx/manifest/desktop/windows10/5"
|
||||
xmlns:desktop6="http://schemas.microsoft.com/appx/manifest/desktop/windows10/6"
|
||||
xmlns:uap10="http://schemas.microsoft.com/appx/manifest/uap/windows10/10"
|
||||
xmlns:com="http://schemas.microsoft.com/appx/manifest/com/windows10"
|
||||
IgnorableNamespaces="uap uap2 uap3 rescap desktop desktop4 desktop5 desktop6 uap10 com">
|
||||
<!-- TODO: Use Zed's signature here. -->
|
||||
<Identity
|
||||
Name="ZedIndustries.Zed.Preview"
|
||||
Publisher="CN=Zed Industries Inc, O=Zed Industries Inc, L=Denver, S=Colorado, C=US"
|
||||
Version="1.0.0.0" />
|
||||
<Properties>
|
||||
<DisplayName>Zed Editor Preview</DisplayName>
|
||||
<PublisherDisplayName>Zed Industries</PublisherDisplayName>
|
||||
<!-- TODO: Use actual icon here. -->
|
||||
<Logo>resources\logo_150x150.png</Logo>
|
||||
<uap10:AllowExternalContent>true</uap10:AllowExternalContent>
|
||||
<desktop6:RegistryWriteVirtualization>disabled</desktop6:RegistryWriteVirtualization>
|
||||
<desktop6:FileSystemWriteVirtualization>disabled</desktop6:FileSystemWriteVirtualization>
|
||||
</Properties>
|
||||
<Resources>
|
||||
<Resource Language="en-us" />
|
||||
<Resource Language="zh-cn" />
|
||||
</Resources>
|
||||
<Dependencies>
|
||||
<TargetDeviceFamily Name="Windows.Desktop" MinVersion="10.0.19000.0" MaxVersionTested="10.0.22000.0" />
|
||||
</Dependencies>
|
||||
<Capabilities>
|
||||
<rescap:Capability Name="runFullTrust" />
|
||||
<rescap:Capability Name="unvirtualizedResources"/>
|
||||
</Capabilities>
|
||||
<Applications>
|
||||
<Application Id="ZedPreview"
|
||||
Executable="Zed.exe"
|
||||
uap10:TrustLevel="mediumIL"
|
||||
uap10:RuntimeBehavior="win32App">
|
||||
<!-- TODO: Use actual icon here. -->
|
||||
<uap:VisualElements
|
||||
AppListEntry="none"
|
||||
DisplayName="Zed Editor Preview"
|
||||
Description="Zed Editor Preview explorer command injector"
|
||||
BackgroundColor="transparent"
|
||||
Square150x150Logo="resources\logo_150x150.png"
|
||||
Square44x44Logo="resources\logo_70x70.png">
|
||||
</uap:VisualElements>
|
||||
<Extensions>
|
||||
<desktop4:Extension Category="windows.fileExplorerContextMenus">
|
||||
<desktop4:FileExplorerContextMenus>
|
||||
<desktop5:ItemType Type="Directory">
|
||||
<desktop5:Verb Id="OpenWithZedPreview" Clsid="af8e85ea-fb20-4db2-93cf-56513c1ec697" />
|
||||
</desktop5:ItemType>
|
||||
<desktop5:ItemType Type="Directory\Background">
|
||||
<desktop5:Verb Id="OpenWithZedPreview" Clsid="af8e85ea-fb20-4db2-93cf-56513c1ec697" />
|
||||
</desktop5:ItemType>
|
||||
<desktop5:ItemType Type="*">
|
||||
<desktop5:Verb Id="OpenWithZedPreview" Clsid="af8e85ea-fb20-4db2-93cf-56513c1ec697" />
|
||||
</desktop5:ItemType>
|
||||
</desktop4:FileExplorerContextMenus>
|
||||
</desktop4:Extension>
|
||||
<com:Extension Category="windows.comServer">
|
||||
<com:ComServer>
|
||||
<com:SurrogateServer DisplayName="Zed Editor Preview">
|
||||
<com:Class Id="af8e85ea-fb20-4db2-93cf-56513c1ec697" Path="zed_explorer_command_injector.dll" ThreadingModel="STA"/>
|
||||
</com:SurrogateServer>
|
||||
</com:ComServer>
|
||||
</com:Extension>
|
||||
</Extensions>
|
||||
</Application>
|
||||
</Applications>
|
||||
</Package>
|
79
crates/explorer_command_injector/AppxManifest.xml
Normal file
79
crates/explorer_command_injector/AppxManifest.xml
Normal file
|
@ -0,0 +1,79 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Package
|
||||
xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
|
||||
xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
|
||||
xmlns:uap2="http://schemas.microsoft.com/appx/manifest/uap/windows10/2"
|
||||
xmlns:uap3="http://schemas.microsoft.com/appx/manifest/uap/windows10/3"
|
||||
xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"
|
||||
xmlns:desktop="http://schemas.microsoft.com/appx/manifest/desktop/windows10"
|
||||
xmlns:desktop4="http://schemas.microsoft.com/appx/manifest/desktop/windows10/4"
|
||||
xmlns:desktop5="http://schemas.microsoft.com/appx/manifest/desktop/windows10/5"
|
||||
xmlns:desktop6="http://schemas.microsoft.com/appx/manifest/desktop/windows10/6"
|
||||
xmlns:uap10="http://schemas.microsoft.com/appx/manifest/uap/windows10/10"
|
||||
xmlns:com="http://schemas.microsoft.com/appx/manifest/com/windows10"
|
||||
IgnorableNamespaces="uap uap2 uap3 rescap desktop desktop4 desktop5 desktop6 uap10 com">
|
||||
<!-- TODO: Use Zed's signature here. -->
|
||||
<Identity
|
||||
Name="ZedIndustries.Zed"
|
||||
Publisher="CN=Zed Industries Inc, O=Zed Industries Inc, L=Denver, S=Colorado, C=US"
|
||||
Version="1.0.0.0" />
|
||||
<Properties>
|
||||
<DisplayName>Zed Editor</DisplayName>
|
||||
|
||||
<PublisherDisplayName>Zed Industries</PublisherDisplayName>
|
||||
<!-- TODO: Use actual icon here. -->
|
||||
<Logo>resources\logo_150x150.png</Logo>
|
||||
<uap10:AllowExternalContent>true</uap10:AllowExternalContent>
|
||||
<desktop6:RegistryWriteVirtualization>disabled</desktop6:RegistryWriteVirtualization>
|
||||
<desktop6:FileSystemWriteVirtualization>disabled</desktop6:FileSystemWriteVirtualization>
|
||||
</Properties>
|
||||
<Resources>
|
||||
<Resource Language="en-us" />
|
||||
<Resource Language="zh-cn" />
|
||||
</Resources>
|
||||
<Dependencies>
|
||||
<TargetDeviceFamily Name="Windows.Desktop" MinVersion="10.0.19000.0" MaxVersionTested="10.0.22000.0" />
|
||||
</Dependencies>
|
||||
<Capabilities>
|
||||
<rescap:Capability Name="runFullTrust" />
|
||||
<rescap:Capability Name="unvirtualizedResources"/>
|
||||
</Capabilities>
|
||||
<Applications>
|
||||
<Application Id="Zed"
|
||||
Executable="Zed.exe"
|
||||
uap10:TrustLevel="mediumIL"
|
||||
uap10:RuntimeBehavior="win32App">
|
||||
<!-- TODO: Use actual icon here. -->
|
||||
<uap:VisualElements
|
||||
AppListEntry="none"
|
||||
DisplayName="Zed Editor"
|
||||
Description="Zed Editor explorer command injector"
|
||||
BackgroundColor="transparent"
|
||||
Square150x150Logo="resources\logo_150x150.png"
|
||||
Square44x44Logo="resources\logo_70x70.png">
|
||||
</uap:VisualElements>
|
||||
<Extensions>
|
||||
<desktop4:Extension Category="windows.fileExplorerContextMenus">
|
||||
<desktop4:FileExplorerContextMenus>
|
||||
<desktop5:ItemType Type="Directory">
|
||||
<desktop5:Verb Id="OpenWithZed" Clsid="6a1f6b13-3b82-48a1-9e06-7bb0a6d0bffd" />
|
||||
</desktop5:ItemType>
|
||||
<desktop5:ItemType Type="Directory\Background">
|
||||
<desktop5:Verb Id="OpenWithZed" Clsid="6a1f6b13-3b82-48a1-9e06-7bb0a6d0bffd" />
|
||||
</desktop5:ItemType>
|
||||
<desktop5:ItemType Type="*">
|
||||
<desktop5:Verb Id="OpenWithZed" Clsid="6a1f6b13-3b82-48a1-9e06-7bb0a6d0bffd" />
|
||||
</desktop5:ItemType>
|
||||
</desktop4:FileExplorerContextMenus>
|
||||
</desktop4:Extension>
|
||||
<com:Extension Category="windows.comServer">
|
||||
<com:ComServer>
|
||||
<com:SurrogateServer DisplayName="Zed Editor">
|
||||
<com:Class Id="6a1f6b13-3b82-48a1-9e06-7bb0a6d0bffd" Path="zed_explorer_command_injector.dll" ThreadingModel="STA"/>
|
||||
</com:SurrogateServer>
|
||||
</com:ComServer>
|
||||
</com:Extension>
|
||||
</Extensions>
|
||||
</Application>
|
||||
</Applications>
|
||||
</Package>
|
28
crates/explorer_command_injector/Cargo.toml
Normal file
28
crates/explorer_command_injector/Cargo.toml
Normal file
|
@ -0,0 +1,28 @@
|
|||
[package]
|
||||
name = "explorer_command_injector"
|
||||
version = "0.1.0"
|
||||
edition.workspace = true
|
||||
publish.workspace = true
|
||||
license = "GPL-3.0-or-later"
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
||||
[lib]
|
||||
crate-type = ["cdylib"]
|
||||
path = "src/explorer_command_injector.rs"
|
||||
doctest = false
|
||||
|
||||
[features]
|
||||
default = ["nightly"]
|
||||
stable = []
|
||||
preview = []
|
||||
nightly = []
|
||||
|
||||
[target.'cfg(target_os = "windows")'.dependencies]
|
||||
windows.workspace = true
|
||||
windows-core.workspace = true
|
||||
windows-registry = "0.5"
|
||||
|
||||
[dependencies]
|
||||
workspace-hack.workspace = true
|
1
crates/explorer_command_injector/LICENSE-GPL
Symbolic link
1
crates/explorer_command_injector/LICENSE-GPL
Symbolic link
|
@ -0,0 +1 @@
|
|||
../../LICENSE-GPL
|
|
@ -0,0 +1,201 @@
|
|||
#![cfg(target_os = "windows")]
|
||||
|
||||
use std::{os::windows::ffi::OsStringExt, path::PathBuf};
|
||||
|
||||
use windows::{
|
||||
Win32::{
|
||||
Foundation::{
|
||||
CLASS_E_CLASSNOTAVAILABLE, E_FAIL, E_INVALIDARG, E_NOTIMPL, ERROR_INSUFFICIENT_BUFFER,
|
||||
GetLastError, HINSTANCE, MAX_PATH,
|
||||
},
|
||||
Globalization::u_strlen,
|
||||
System::{
|
||||
Com::{IBindCtx, IClassFactory, IClassFactory_Impl},
|
||||
LibraryLoader::GetModuleFileNameW,
|
||||
SystemServices::DLL_PROCESS_ATTACH,
|
||||
},
|
||||
UI::Shell::{
|
||||
ECF_DEFAULT, ECS_ENABLED, IEnumExplorerCommand, IExplorerCommand,
|
||||
IExplorerCommand_Impl, IShellItemArray, SHStrDupW, SIGDN_FILESYSPATH,
|
||||
},
|
||||
},
|
||||
core::{BOOL, GUID, HRESULT, HSTRING, Interface, Ref, Result, implement},
|
||||
};
|
||||
|
||||
static mut DLL_INSTANCE: HINSTANCE = HINSTANCE(std::ptr::null_mut());
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
extern "system" fn DllMain(
|
||||
hinstdll: HINSTANCE,
|
||||
fdwreason: u32,
|
||||
_lpvreserved: *mut core::ffi::c_void,
|
||||
) -> bool {
|
||||
if fdwreason == DLL_PROCESS_ATTACH {
|
||||
unsafe { DLL_INSTANCE = hinstdll };
|
||||
}
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
#[implement(IExplorerCommand)]
|
||||
struct ExplorerCommandInjector;
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
impl IExplorerCommand_Impl for ExplorerCommandInjector_Impl {
|
||||
fn GetTitle(&self, _: Ref<IShellItemArray>) -> Result<windows_core::PWSTR> {
|
||||
let command_description =
|
||||
retrieve_command_description().unwrap_or(HSTRING::from("Open with Zed"));
|
||||
unsafe { SHStrDupW(&command_description) }
|
||||
}
|
||||
|
||||
fn GetIcon(&self, _: Ref<IShellItemArray>) -> Result<windows_core::PWSTR> {
|
||||
let Some(zed_exe) = get_zed_exe_path() else {
|
||||
return Err(E_FAIL.into());
|
||||
};
|
||||
unsafe { SHStrDupW(&HSTRING::from(zed_exe)) }
|
||||
}
|
||||
|
||||
fn GetToolTip(&self, _: Ref<IShellItemArray>) -> Result<windows_core::PWSTR> {
|
||||
Err(E_NOTIMPL.into())
|
||||
}
|
||||
|
||||
fn GetCanonicalName(&self) -> Result<windows_core::GUID> {
|
||||
Ok(GUID::zeroed())
|
||||
}
|
||||
|
||||
fn GetState(&self, _: Ref<IShellItemArray>, _: BOOL) -> Result<u32> {
|
||||
Ok(ECS_ENABLED.0 as _)
|
||||
}
|
||||
|
||||
fn Invoke(&self, psiitemarray: Ref<IShellItemArray>, _: Ref<IBindCtx>) -> Result<()> {
|
||||
let items = psiitemarray.ok()?;
|
||||
let Some(zed_exe) = get_zed_exe_path() else {
|
||||
return Ok(());
|
||||
};
|
||||
|
||||
let count = unsafe { items.GetCount()? };
|
||||
for idx in 0..count {
|
||||
let item = unsafe { items.GetItemAt(idx)? };
|
||||
let item_path = unsafe { item.GetDisplayName(SIGDN_FILESYSPATH)?.to_string()? };
|
||||
std::process::Command::new(&zed_exe)
|
||||
.arg(&item_path)
|
||||
.spawn()
|
||||
.map_err(|_| E_INVALIDARG)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn GetFlags(&self) -> Result<u32> {
|
||||
Ok(ECF_DEFAULT.0 as _)
|
||||
}
|
||||
|
||||
fn EnumSubCommands(&self) -> Result<IEnumExplorerCommand> {
|
||||
Err(E_NOTIMPL.into())
|
||||
}
|
||||
}
|
||||
|
||||
#[implement(IClassFactory)]
|
||||
struct ExplorerCommandInjectorFactory;
|
||||
|
||||
impl IClassFactory_Impl for ExplorerCommandInjectorFactory_Impl {
|
||||
fn CreateInstance(
|
||||
&self,
|
||||
punkouter: Ref<windows_core::IUnknown>,
|
||||
riid: *const windows_core::GUID,
|
||||
ppvobject: *mut *mut core::ffi::c_void,
|
||||
) -> Result<()> {
|
||||
unsafe {
|
||||
*ppvobject = std::ptr::null_mut();
|
||||
}
|
||||
if punkouter.is_none() {
|
||||
let factory: IExplorerCommand = ExplorerCommandInjector {}.into();
|
||||
let ret = unsafe { factory.query(riid, ppvobject).ok() };
|
||||
if ret.is_ok() {
|
||||
unsafe {
|
||||
*ppvobject = factory.into_raw();
|
||||
}
|
||||
}
|
||||
ret
|
||||
} else {
|
||||
Err(E_INVALIDARG.into())
|
||||
}
|
||||
}
|
||||
|
||||
fn LockServer(&self, _: BOOL) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(all(feature = "stable", not(feature = "preview"), not(feature = "nightly")))]
|
||||
const MODULE_ID: GUID = GUID::from_u128(0x6a1f6b13_3b82_48a1_9e06_7bb0a6d0bffd);
|
||||
#[cfg(all(feature = "preview", not(feature = "stable"), not(feature = "nightly")))]
|
||||
const MODULE_ID: GUID = GUID::from_u128(0xaf8e85ea_fb20_4db2_93cf_56513c1ec697);
|
||||
#[cfg(all(feature = "nightly", not(feature = "stable"), not(feature = "preview")))]
|
||||
const MODULE_ID: GUID = GUID::from_u128(0x266f2cfe_1653_42af_b55c_fe3590c83871);
|
||||
|
||||
// Make cargo clippy happy
|
||||
#[cfg(all(feature = "nightly", feature = "stable", feature = "preview"))]
|
||||
const MODULE_ID: GUID = GUID::from_u128(0x685f4d49_6718_4c55_b271_ebb5c6a48d6f);
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
extern "system" fn DllGetClassObject(
|
||||
class_id: *const GUID,
|
||||
iid: *const GUID,
|
||||
out: *mut *mut std::ffi::c_void,
|
||||
) -> HRESULT {
|
||||
unsafe {
|
||||
*out = std::ptr::null_mut();
|
||||
}
|
||||
let class_id = unsafe { *class_id };
|
||||
if class_id == MODULE_ID {
|
||||
let instance: IClassFactory = ExplorerCommandInjectorFactory {}.into();
|
||||
let ret = unsafe { instance.query(iid, out) };
|
||||
if ret.is_ok() {
|
||||
unsafe {
|
||||
*out = instance.into_raw();
|
||||
}
|
||||
}
|
||||
ret
|
||||
} else {
|
||||
CLASS_E_CLASSNOTAVAILABLE
|
||||
}
|
||||
}
|
||||
|
||||
fn get_zed_install_folder() -> Option<PathBuf> {
|
||||
let mut buf = vec![0u16; MAX_PATH as usize];
|
||||
unsafe { GetModuleFileNameW(Some(DLL_INSTANCE.into()), &mut buf) };
|
||||
|
||||
while unsafe { GetLastError() } == ERROR_INSUFFICIENT_BUFFER {
|
||||
buf = vec![0u16; buf.len() * 2];
|
||||
unsafe { GetModuleFileNameW(Some(DLL_INSTANCE.into()), &mut buf) };
|
||||
}
|
||||
let len = unsafe { u_strlen(buf.as_ptr()) };
|
||||
let path: PathBuf = std::ffi::OsString::from_wide(&buf[..len as usize])
|
||||
.into_string()
|
||||
.ok()?
|
||||
.into();
|
||||
Some(path.parent()?.parent()?.to_path_buf())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn get_zed_exe_path() -> Option<String> {
|
||||
get_zed_install_folder().map(|path| path.join("Zed.exe").to_string_lossy().to_string())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn retrieve_command_description() -> Result<HSTRING> {
|
||||
#[cfg(all(feature = "stable", not(feature = "preview"), not(feature = "nightly")))]
|
||||
const REG_PATH: &str = "Software\\Classes\\ZedEditorContextMenu";
|
||||
#[cfg(all(feature = "preview", not(feature = "stable"), not(feature = "nightly")))]
|
||||
const REG_PATH: &str = "Software\\Classes\\ZedEditorPreviewContextMenu";
|
||||
#[cfg(all(feature = "nightly", not(feature = "stable"), not(feature = "preview")))]
|
||||
const REG_PATH: &str = "Software\\Classes\\ZedEditorNightlyContextMenu";
|
||||
|
||||
// Make cargo clippy happy
|
||||
#[cfg(all(feature = "nightly", feature = "stable", feature = "preview"))]
|
||||
const REG_PATH: &str = "Software\\Classes\\ZedEditorClippyContextMenu";
|
||||
|
||||
let key = windows_registry::CURRENT_USER.open(REG_PATH)?;
|
||||
key.get_hstring("Title")
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue