├── .gitignore ├── Makefile ├── README.md ├── icon.ico ├── install.reg ├── launch.rc ├── launch ├── .gitignore ├── Cargo.lock ├── Cargo.toml ├── build.rs └── src │ ├── errors.rs │ └── main.rs └── remoteserver.py /.gitignore: -------------------------------------------------------------------------------- 1 | *.a 2 | *.res 3 | *.exe 4 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: all clean 2 | 3 | all: launch.exe 4 | 5 | launch.exe: launch/src/main.rs launch/Cargo.toml libres.a 6 | (cd launch && cargo build --release --target=x86_64-pc-windows-gnu) 7 | mv launch/target/x86_64-pc-windows-gnu/release/launch.exe . 8 | x86_64-w64-mingw32-strip launch.exe 9 | 10 | icon.res: launch.rc icon.ico 11 | x86_64-w64-mingw32-windres launch.rc -O coff -o icon.res 12 | 13 | libres.a: icon.res 14 | x86_64-w64-mingw32-ar q libres.a icon.res 15 | 16 | clean: 17 | -rm *.a *.res 18 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # remotebrowser 2 | open URLs from Windows virtual machines in the host system 3 | 4 | [中文介绍文章](https://blog.lilydjwg.me/2018/1/18/hi-win10-this-is-my-browser.211960.html)。 5 | -------------------------------------------------------------------------------- /icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lilydjwg/remotebrowser/f0610fd4367fec97f97f5156193e2ee14d8d6cc6/icon.ico -------------------------------------------------------------------------------- /install.reg: -------------------------------------------------------------------------------- 1 | Windows Registry Editor Version 5.00 2 | 3 | [HKEY_LOCAL_MACHINE\SOFTWARE\Clients\StartMenuInternet\RemoteBrowser] 4 | @="RemoteBrowser" 5 | 6 | [HKEY_LOCAL_MACHINE\SOFTWARE\Clients\StartMenuInternet\RemoteBrowser\Capabilities] 7 | "ApplicationName"="RemoteBrowser" 8 | "ApplicationIcon"="C:\\RemoteBrowser\\launch.exe,0" 9 | "ApplicationDescription"="RemoteBrowser" 10 | 11 | [HKEY_LOCAL_MACHINE\SOFTWARE\Clients\StartMenuInternet\RemoteBrowser\Capabilities\StartMenu] 12 | "StartMenuInternet"="RemoteBrowser" 13 | 14 | [HKEY_LOCAL_MACHINE\SOFTWARE\Clients\StartMenuInternet\RemoteBrowser\Capabilities\URLAssociations] 15 | "https"="RemoteBrowserHTML" 16 | "http"="RemoteBrowserHTML" 17 | "ftp"="RemoteBrowserHTML" 18 | 19 | [HKEY_LOCAL_MACHINE\SOFTWARE\Clients\StartMenuInternet\RemoteBrowser\DefaultIcon] 20 | @="C:\\RemoteBrowser\\launch.exe,0" 21 | 22 | [HKEY_LOCAL_MACHINE\SOFTWARE\Clients\StartMenuInternet\RemoteBrowser\InstallInfo] 23 | "IconsVisible"=dword:00000001 24 | "ShowIconsCommand"="\"C:\\RemoteBrowser\\launch.exe\" --show-icons" 25 | "HideIconsCommand"="\"C:\\RemoteBrowser\\launch.exe\" --hide-icons" 26 | "ReinstallCommand"="\"C:\\RemoteBrowser\\launch.exe\" --make-default-browser" 27 | 28 | [HKEY_LOCAL_MACHINE\SOFTWARE\Clients\StartMenuInternet\RemoteBrowser\shell] 29 | 30 | [HKEY_LOCAL_MACHINE\SOFTWARE\Clients\StartMenuInternet\RemoteBrowser\shell\open] 31 | 32 | [HKEY_LOCAL_MACHINE\SOFTWARE\Clients\StartMenuInternet\RemoteBrowser\shell\open\command] 33 | @="\"C:\\RemoteBrowser\\launch.exe\" \"%1\"" 34 | 35 | [HKEY_LOCAL_MACHINE\SOFTWARE\RegisteredApplications] 36 | "RemoteBrowser"="SOFTWARE\\Clients\\StartMenuInternet\\RemoteBrowser\\Capabilities" 37 | 38 | [HKEY_CURRENT_USER\Software\Microsoft\Windows\Shell\Associations\UrlAssociations] 39 | 40 | [HKEY_CURRENT_USER\Software\Microsoft\Windows\Shell\Associations\UrlAssociations\http] 41 | 42 | [HKEY_CURRENT_USER\Software\Microsoft\Windows\Shell\Associations\UrlAssociations\http\UserChoice] 43 | "Progid"="RemoteBrowserHTML" 44 | 45 | [HKEY_CURRENT_USER\Software\Microsoft\Windows\Shell\Associations\UrlAssociations\https] 46 | 47 | [HKEY_CURRENT_USER\Software\Microsoft\Windows\Shell\Associations\UrlAssociations\https\UserChoice] 48 | "Progid"="RemoteBrowserHTML" 49 | 50 | [HKEY_CLASSES_ROOT\RemoteBrowserHTML] 51 | @="RemoteBrowser" 52 | "FriendlyTypeName"="RemoteBrowser" 53 | "URL Protocol"="" 54 | "EditFlags"=dword:00000002 55 | 56 | [HKEY_CLASSES_ROOT\RemoteBrowserHTML\DefaultIcon] 57 | @="C:\\RemoteBrowser\\launch.exe,0" 58 | 59 | [HKEY_CLASSES_ROOT\RemoteBrowserHTML\shell] 60 | @="open" 61 | 62 | [HKEY_CLASSES_ROOT\RemoteBrowserHTML\shell\open] 63 | 64 | [HKEY_CLASSES_ROOT\RemoteBrowserHTML\shell\open\command] 65 | @="\"C:\\RemoteBrowser\\launch.exe\" \"%1\"" 66 | -------------------------------------------------------------------------------- /launch.rc: -------------------------------------------------------------------------------- 1 | 1 ICON DISCARDABLE "icon.ico" 2 | -------------------------------------------------------------------------------- /launch/.gitignore: -------------------------------------------------------------------------------- 1 | 2 | /target/ 3 | **/*.rs.bk 4 | -------------------------------------------------------------------------------- /launch/Cargo.lock: -------------------------------------------------------------------------------- 1 | [[package]] 2 | name = "backtrace" 3 | version = "0.3.5" 4 | source = "registry+https://github.com/rust-lang/crates.io-index" 5 | dependencies = [ 6 | "backtrace-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", 7 | "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", 8 | "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)", 9 | "rustc-demangle 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", 10 | "winapi 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", 11 | ] 12 | 13 | [[package]] 14 | name = "backtrace-sys" 15 | version = "0.1.16" 16 | source = "registry+https://github.com/rust-lang/crates.io-index" 17 | dependencies = [ 18 | "cc 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", 19 | "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)", 20 | ] 21 | 22 | [[package]] 23 | name = "cc" 24 | version = "1.0.4" 25 | source = "registry+https://github.com/rust-lang/crates.io-index" 26 | 27 | [[package]] 28 | name = "cfg-if" 29 | version = "0.1.2" 30 | source = "registry+https://github.com/rust-lang/crates.io-index" 31 | 32 | [[package]] 33 | name = "error-chain" 34 | version = "0.11.0" 35 | source = "registry+https://github.com/rust-lang/crates.io-index" 36 | dependencies = [ 37 | "backtrace 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", 38 | ] 39 | 40 | [[package]] 41 | name = "launch" 42 | version = "0.1.0" 43 | dependencies = [ 44 | "error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", 45 | ] 46 | 47 | [[package]] 48 | name = "libc" 49 | version = "0.2.35" 50 | source = "registry+https://github.com/rust-lang/crates.io-index" 51 | 52 | [[package]] 53 | name = "rustc-demangle" 54 | version = "0.1.5" 55 | source = "registry+https://github.com/rust-lang/crates.io-index" 56 | 57 | [[package]] 58 | name = "winapi" 59 | version = "0.3.3" 60 | source = "registry+https://github.com/rust-lang/crates.io-index" 61 | dependencies = [ 62 | "winapi-i686-pc-windows-gnu 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", 63 | "winapi-x86_64-pc-windows-gnu 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", 64 | ] 65 | 66 | [[package]] 67 | name = "winapi-i686-pc-windows-gnu" 68 | version = "0.3.2" 69 | source = "registry+https://github.com/rust-lang/crates.io-index" 70 | 71 | [[package]] 72 | name = "winapi-x86_64-pc-windows-gnu" 73 | version = "0.3.2" 74 | source = "registry+https://github.com/rust-lang/crates.io-index" 75 | 76 | [metadata] 77 | "checksum backtrace 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ebbbf59b1c43eefa8c3ede390fcc36820b4999f7914104015be25025e0d62af2" 78 | "checksum backtrace-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "44585761d6161b0f57afc49482ab6bd067e4edef48c12a152c237eb0203f7661" 79 | "checksum cc 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "deaf9ec656256bb25b404c51ef50097207b9cbb29c933d31f92cae5a8a0ffee0" 80 | "checksum cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de" 81 | "checksum error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff511d5dc435d703f4971bc399647c9bc38e20cb41452e3b9feb4765419ed3f3" 82 | "checksum libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)" = "96264e9b293e95d25bfcbbf8a88ffd1aedc85b754eba8b7d78012f638ba220eb" 83 | "checksum rustc-demangle 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "aee45432acc62f7b9a108cc054142dac51f979e69e71ddce7d6fc7adf29e817e" 84 | "checksum winapi 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b09fb3b6f248ea4cd42c9a65113a847d612e17505d6ebd1f7357ad68a8bf8693" 85 | "checksum winapi-i686-pc-windows-gnu 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ec6667f60c23eca65c561e63a13d81b44234c2e38a6b6c959025ee907ec614cc" 86 | "checksum winapi-x86_64-pc-windows-gnu 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "98f12c52b2630cd05d2c3ffd8e008f7f48252c042b4871c72aed9dc733b96668" 87 | -------------------------------------------------------------------------------- /launch/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "launch" 3 | version = "0.1.0" 4 | authors = ["lilydjwg "] 5 | build = "build.rs" 6 | 7 | [dependencies] 8 | error-chain = "*" 9 | 10 | [profile.release] 11 | lto = true 12 | -------------------------------------------------------------------------------- /launch/build.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | println!("cargo:rustc-link-search=native=.."); 3 | println!("cargo:rustc-link-lib=static=res"); 4 | } 5 | -------------------------------------------------------------------------------- /launch/src/errors.rs: -------------------------------------------------------------------------------- 1 | use std; 2 | 3 | error_chain! { 4 | foreign_links { 5 | IoError(std::io::Error); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /launch/src/main.rs: -------------------------------------------------------------------------------- 1 | #[macro_use] extern crate error_chain; 2 | 3 | use std::process::Command; 4 | use std::net::TcpStream; 5 | use std::io::prelude::*; 6 | use std::env::args; 7 | use std::io::stdin; 8 | 9 | const SERVER_ADDR: &str = "10.0.2.2:4543"; 10 | const LOCAL_BROWSER: &str = r"C:\Program Files\Mozilla Firefox\firefox.exe"; 11 | 12 | mod errors; 13 | 14 | use errors::*; 15 | 16 | fn open_local(url: &str) -> Result<()> { 17 | Command::new(LOCAL_BROWSER) 18 | .arg(url) 19 | .status()?; 20 | Ok(()) 21 | } 22 | 23 | fn open_remote(url: &str) -> Result<()> { 24 | let mut stream = TcpStream::connect(SERVER_ADDR)?; 25 | stream.write_all(url.as_bytes())?; 26 | Ok(()) 27 | } 28 | 29 | fn main2() -> Result<()> { 30 | let url = args().nth(1).ok_or("no url given")?; 31 | if let Err(e) = open_remote(&url) { 32 | eprintln!("open remotely failed: {:?}", e); 33 | println!("Press Enter to open locally."); 34 | stdin().read_line(&mut String::new())?; 35 | open_local(&url) 36 | } else { 37 | Ok(()) 38 | } 39 | } 40 | 41 | fn main() { 42 | if let Err(e) = main2() { 43 | eprintln!("Error: {:?}", e); 44 | println!("Press Enter to exit."); 45 | stdin().read_line(&mut String::new()).unwrap(); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /remoteserver.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import asyncio 4 | import webbrowser 5 | 6 | async def server(reader, writer): 7 | url = await reader.read() 8 | url = url.decode('gb18030') 9 | print(f'open url {url}', flush=True) 10 | webbrowser.open(url) 11 | writer.write_eof() 12 | 13 | async def main(addr): 14 | s = await asyncio.start_server(server, host=addr[0], port=addr[1]) 15 | await s.wait_closed() 16 | 17 | if __name__ == '__main__': 18 | addr = '127.0.0.1', 4543 19 | loop = asyncio.get_event_loop() 20 | loop.run_until_complete(main(addr)) 21 | --------------------------------------------------------------------------------