Initial commit
This commit is contained in:
commit
a47ba511c9
12 changed files with 2712 additions and 0 deletions
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
/target
|
||||
884
Cargo.lock
generated
Normal file
884
Cargo.lock
generated
Normal file
|
|
@ -0,0 +1,884 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 4
|
||||
|
||||
[[package]]
|
||||
name = "adler2"
|
||||
version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627"
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
|
||||
|
||||
[[package]]
|
||||
name = "base64"
|
||||
version = "0.22.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "2.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.2.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8e3a13707ac958681c13b39b458c073d0d9bc8a22cb1b2f4c8e55eb72c13f362"
|
||||
dependencies = [
|
||||
"shlex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "crc32fast"
|
||||
version = "1.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossterm"
|
||||
version = "0.27.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f476fe445d41c9e991fd07515a6f463074b782242ccf4a5b7b1d1012e70824df"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"crossterm_winapi",
|
||||
"libc",
|
||||
"mio",
|
||||
"parking_lot",
|
||||
"signal-hook",
|
||||
"signal-hook-mio",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossterm_winapi"
|
||||
version = "0.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "acdd7c62a3665c7f6830a51635d9ac9b23ed385797f70a83bb8bafe9c572ab2b"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "displaydoc"
|
||||
version = "0.2.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "flate2"
|
||||
version = "1.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7ced92e76e966ca2fd84c8f7aa01a4aea65b0eb6648d72f7c8f3e2764a67fece"
|
||||
dependencies = [
|
||||
"crc32fast",
|
||||
"miniz_oxide",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "form_urlencoded"
|
||||
version = "1.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456"
|
||||
dependencies = [
|
||||
"percent-encoding",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.2.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"wasi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "icu_collections"
|
||||
version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526"
|
||||
dependencies = [
|
||||
"displaydoc",
|
||||
"yoke",
|
||||
"zerofrom",
|
||||
"zerovec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "icu_locid"
|
||||
version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637"
|
||||
dependencies = [
|
||||
"displaydoc",
|
||||
"litemap",
|
||||
"tinystr",
|
||||
"writeable",
|
||||
"zerovec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "icu_locid_transform"
|
||||
version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e"
|
||||
dependencies = [
|
||||
"displaydoc",
|
||||
"icu_locid",
|
||||
"icu_locid_transform_data",
|
||||
"icu_provider",
|
||||
"tinystr",
|
||||
"zerovec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "icu_locid_transform_data"
|
||||
version = "1.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7515e6d781098bf9f7205ab3fc7e9709d34554ae0b21ddbcb5febfa4bc7df11d"
|
||||
|
||||
[[package]]
|
||||
name = "icu_normalizer"
|
||||
version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f"
|
||||
dependencies = [
|
||||
"displaydoc",
|
||||
"icu_collections",
|
||||
"icu_normalizer_data",
|
||||
"icu_properties",
|
||||
"icu_provider",
|
||||
"smallvec",
|
||||
"utf16_iter",
|
||||
"utf8_iter",
|
||||
"write16",
|
||||
"zerovec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "icu_normalizer_data"
|
||||
version = "1.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c5e8338228bdc8ab83303f16b797e177953730f601a96c25d10cb3ab0daa0cb7"
|
||||
|
||||
[[package]]
|
||||
name = "icu_properties"
|
||||
version = "1.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5"
|
||||
dependencies = [
|
||||
"displaydoc",
|
||||
"icu_collections",
|
||||
"icu_locid_transform",
|
||||
"icu_properties_data",
|
||||
"icu_provider",
|
||||
"tinystr",
|
||||
"zerovec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "icu_properties_data"
|
||||
version = "1.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "85fb8799753b75aee8d2a21d7c14d9f38921b54b3dbda10f5a3c7a7b82dba5e2"
|
||||
|
||||
[[package]]
|
||||
name = "icu_provider"
|
||||
version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9"
|
||||
dependencies = [
|
||||
"displaydoc",
|
||||
"icu_locid",
|
||||
"icu_provider_macros",
|
||||
"stable_deref_trait",
|
||||
"tinystr",
|
||||
"writeable",
|
||||
"yoke",
|
||||
"zerofrom",
|
||||
"zerovec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "icu_provider_macros"
|
||||
version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "idna"
|
||||
version = "1.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e"
|
||||
dependencies = [
|
||||
"idna_adapter",
|
||||
"smallvec",
|
||||
"utf8_iter",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "idna_adapter"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71"
|
||||
dependencies = [
|
||||
"icu_normalizer",
|
||||
"icu_properties",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.172"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa"
|
||||
|
||||
[[package]]
|
||||
name = "litemap"
|
||||
version = "0.7.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "23fb14cb19457329c82206317a5663005a4d404783dc74f4252769b0d5f42856"
|
||||
|
||||
[[package]]
|
||||
name = "lock_api"
|
||||
version = "0.4.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"scopeguard",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94"
|
||||
|
||||
[[package]]
|
||||
name = "miniz_oxide"
|
||||
version = "0.8.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3be647b768db090acb35d5ec5db2b0e1f1de11133ca123b9eacf5137868f892a"
|
||||
dependencies = [
|
||||
"adler2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mio"
|
||||
version = "0.8.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"log",
|
||||
"wasi",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "oh5_printer_installer"
|
||||
version = "1.0.3"
|
||||
dependencies = [
|
||||
"crossterm",
|
||||
"ureq",
|
||||
"windows",
|
||||
"winres",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.21.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot"
|
||||
version = "0.12.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27"
|
||||
dependencies = [
|
||||
"lock_api",
|
||||
"parking_lot_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot_core"
|
||||
version = "0.9.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"redox_syscall",
|
||||
"smallvec",
|
||||
"windows-targets 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "percent-encoding"
|
||||
version = "2.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.95"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.40"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.5.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d2f103c6d277498fbceb16e84d317e2a400f160f46904d5f5410848c829511a3"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ring"
|
||||
version = "0.17.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"cfg-if",
|
||||
"getrandom",
|
||||
"libc",
|
||||
"untrusted",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustls"
|
||||
version = "0.23.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "df51b5869f3a441595eac5e8ff14d486ff285f7b8c0df8770e49c3b56351f0f0"
|
||||
dependencies = [
|
||||
"log",
|
||||
"once_cell",
|
||||
"ring",
|
||||
"rustls-pki-types",
|
||||
"rustls-webpki",
|
||||
"subtle",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustls-pki-types"
|
||||
version = "1.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "917ce264624a4b4db1c364dcc35bfca9ded014d0a958cd47ad3e960e988ea51c"
|
||||
|
||||
[[package]]
|
||||
name = "rustls-webpki"
|
||||
version = "0.103.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fef8b8769aaccf73098557a87cd1816b4f9c7c16811c9c77142aa695c16f2c03"
|
||||
dependencies = [
|
||||
"ring",
|
||||
"rustls-pki-types",
|
||||
"untrusted",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "scopeguard"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.219"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.219"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "shlex"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
|
||||
|
||||
[[package]]
|
||||
name = "signal-hook"
|
||||
version = "0.3.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8621587d4798caf8eb44879d42e56b9a93ea5dcd315a6487c357130095b62801"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"signal-hook-registry",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "signal-hook-mio"
|
||||
version = "0.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "34db1a06d485c9142248b7a054f034b349b212551f3dfd19c94d45a754a217cd"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"mio",
|
||||
"signal-hook",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "signal-hook-registry"
|
||||
version = "1.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "smallvec"
|
||||
version = "1.15.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8917285742e9f3e1683f0a9c4e6b57960b7314d0b08d30d1ecd426713ee2eee9"
|
||||
|
||||
[[package]]
|
||||
name = "stable_deref_trait"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
|
||||
|
||||
[[package]]
|
||||
name = "subtle"
|
||||
version = "2.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.100"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "synstructure"
|
||||
version = "0.13.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tinystr"
|
||||
version = "0.7.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f"
|
||||
dependencies = [
|
||||
"displaydoc",
|
||||
"zerovec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml"
|
||||
version = "0.5.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
|
||||
|
||||
[[package]]
|
||||
name = "untrusted"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1"
|
||||
|
||||
[[package]]
|
||||
name = "ureq"
|
||||
version = "2.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "02d1a66277ed75f640d608235660df48c8e3c19f3b4edb6a263315626cc3c01d"
|
||||
dependencies = [
|
||||
"base64",
|
||||
"flate2",
|
||||
"log",
|
||||
"once_cell",
|
||||
"rustls",
|
||||
"rustls-pki-types",
|
||||
"url",
|
||||
"webpki-roots",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "url"
|
||||
version = "2.5.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60"
|
||||
dependencies = [
|
||||
"form_urlencoded",
|
||||
"idna",
|
||||
"percent-encoding",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "utf16_iter"
|
||||
version = "1.0.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246"
|
||||
|
||||
[[package]]
|
||||
name = "utf8_iter"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be"
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.11.0+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
||||
|
||||
[[package]]
|
||||
name = "webpki-roots"
|
||||
version = "0.26.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2210b291f7ea53617fbafcc4939f10914214ec15aace5ba62293a668f322c5c9"
|
||||
dependencies = [
|
||||
"rustls-pki-types",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
||||
dependencies = [
|
||||
"winapi-i686-pc-windows-gnu",
|
||||
"winapi-x86_64-pc-windows-gnu",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-i686-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
|
||||
[[package]]
|
||||
name = "windows"
|
||||
version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e48a53791691ab099e5e2ad123536d0fff50652600abaf43bbf952894110d0be"
|
||||
dependencies = [
|
||||
"windows-core",
|
||||
"windows-targets 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-core"
|
||||
version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9"
|
||||
dependencies = [
|
||||
"windows-targets 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.48.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
|
||||
dependencies = [
|
||||
"windows-targets 0.48.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
|
||||
dependencies = [
|
||||
"windows-targets 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm 0.48.5",
|
||||
"windows_aarch64_msvc 0.48.5",
|
||||
"windows_i686_gnu 0.48.5",
|
||||
"windows_i686_msvc 0.48.5",
|
||||
"windows_x86_64_gnu 0.48.5",
|
||||
"windows_x86_64_gnullvm 0.48.5",
|
||||
"windows_x86_64_msvc 0.48.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm 0.52.6",
|
||||
"windows_aarch64_msvc 0.52.6",
|
||||
"windows_i686_gnu 0.52.6",
|
||||
"windows_i686_gnullvm",
|
||||
"windows_i686_msvc 0.52.6",
|
||||
"windows_x86_64_gnu 0.52.6",
|
||||
"windows_x86_64_gnullvm 0.52.6",
|
||||
"windows_x86_64_msvc 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnullvm"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
|
||||
|
||||
[[package]]
|
||||
name = "winres"
|
||||
version = "0.1.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b68db261ef59e9e52806f688020631e987592bd83619edccda9c47d42cde4f6c"
|
||||
dependencies = [
|
||||
"toml",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "write16"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936"
|
||||
|
||||
[[package]]
|
||||
name = "writeable"
|
||||
version = "0.5.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51"
|
||||
|
||||
[[package]]
|
||||
name = "yoke"
|
||||
version = "0.7.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"stable_deref_trait",
|
||||
"yoke-derive",
|
||||
"zerofrom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "yoke-derive"
|
||||
version = "0.7.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"synstructure",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zerofrom"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5"
|
||||
dependencies = [
|
||||
"zerofrom-derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zerofrom-derive"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"synstructure",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zeroize"
|
||||
version = "1.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde"
|
||||
|
||||
[[package]]
|
||||
name = "zerovec"
|
||||
version = "0.10.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079"
|
||||
dependencies = [
|
||||
"yoke",
|
||||
"zerofrom",
|
||||
"zerovec-derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zerovec-derive"
|
||||
version = "0.10.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
20
Cargo.toml
Normal file
20
Cargo.toml
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
[package]
|
||||
name = "oh5_printer_installer"
|
||||
version = "1.0.3"
|
||||
edition = "2024"
|
||||
build = "build.rs"
|
||||
|
||||
[build-dependencies]
|
||||
winres = "0.1"
|
||||
|
||||
[dependencies]
|
||||
crossterm = "0.27"
|
||||
ureq = "2"
|
||||
|
||||
windows = { version = "0.52.0", features = [
|
||||
"Win32_Foundation",
|
||||
"Win32_Security",
|
||||
"Win32_System_Threading",
|
||||
"Win32_UI_Shell", # ← DAS hier ist wichtig!
|
||||
"Win32_UI_WindowsAndMessaging" # ← für SW_SHOWNORMAL
|
||||
]}
|
||||
18
build.rs
Normal file
18
build.rs
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
fn main() {
|
||||
let mut res = winres::WindowsResource::new();
|
||||
|
||||
let version = env!("CARGO_PKG_VERSION");
|
||||
|
||||
res.set_icon("favicon.ico");
|
||||
|
||||
res.set("FileDescription", "OH5 Drucker Installer");
|
||||
res.set("ProductName", "OH5 Drucker-Tool");
|
||||
res.set("CompanyName", "Office Hoch 5 GmbH");
|
||||
res.set("LegalCopyright", "Copyright © 2025 Office Hoch 5 GmbH");
|
||||
res.set("OriginalFilename", "OH5 Drucker Installer.exe");
|
||||
// Version aus Cargo.toml ziehen 👇
|
||||
res.set("FileVersion", version);
|
||||
res.set("ProductVersion", version);
|
||||
|
||||
res.compile().unwrap();
|
||||
}
|
||||
BIN
favicon.ico
Normal file
BIN
favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 149 KiB |
313
src/brother.rs
Normal file
313
src/brother.rs
Normal file
|
|
@ -0,0 +1,313 @@
|
|||
// brother.rs – Brother Color Installer als Rust-Funktion (hybrid mit Command)
|
||||
|
||||
use std::fs;
|
||||
use std::io::Stdout;
|
||||
use std::process::{Command, exit};
|
||||
use crate::clear_screen;
|
||||
use crate::utils::{read_input,pause,set_default_printer_config,set_default_printer_config_mono};
|
||||
|
||||
//Color
|
||||
pub fn brother_color(stdout: &mut Stdout) {
|
||||
clear_screen(stdout);
|
||||
println!("Brother Color Installer gestartet\n");
|
||||
|
||||
// Admin-Check überspringen (erst später mit UAC)
|
||||
|
||||
// 1. Eingabe IP & Name
|
||||
let printer_ip = read_input("Gib die IP-Adresse des Druckers ein: ");
|
||||
let printer_ip = printer_ip.trim();
|
||||
|
||||
let printer_name = read_input("Gib den Namen des Druckers ein (ohne SW/Farbe): ");
|
||||
let printer_name = printer_name.trim();
|
||||
|
||||
let printer_list = [format!("{} (SW)", printer_name), format!("{} (Farbe)", printer_name)];
|
||||
|
||||
// 2. Treiberpfad
|
||||
let base_path = std::env::current_exe()
|
||||
.unwrap()
|
||||
.parent()
|
||||
.unwrap()
|
||||
.to_path_buf();
|
||||
let driver_path = base_path.join("brother-treiber");
|
||||
let zip_path = base_path.join("brother-treiber.zip");
|
||||
|
||||
println!("Verwende automatisch den Treiberordner: {:?}", driver_path);
|
||||
|
||||
if !driver_path.exists() {
|
||||
|
||||
//Download
|
||||
println!("Treiber nicht gefunden! Lade ihn herunter...");
|
||||
|
||||
let url = "https://oh5.kryptographen.eu/Brother-Treiber.zip";
|
||||
let zip_path_str = zip_path.to_str().unwrap();
|
||||
|
||||
let ps_command = format!(
|
||||
"(New-Object System.Net.WebClient).DownloadFile('{}', '{}')",
|
||||
url, zip_path_str
|
||||
);
|
||||
|
||||
let status = Command::new("powershell")
|
||||
.args(["-NoProfile", "-Command", &ps_command])
|
||||
.status()
|
||||
.expect("PowerShell konnte nicht ausgeführt werden");
|
||||
|
||||
if !status.success() {
|
||||
println!("❌ Fehler: Der Treiber konnte nicht heruntergeladen werden!");
|
||||
pause(); // z. B. deine eigene Funktion
|
||||
return;
|
||||
}
|
||||
|
||||
//Unzip
|
||||
let driver_path_str = driver_path.to_str().unwrap();
|
||||
|
||||
println!("Entpacke den Treiber...");
|
||||
let ps_expand = format!(
|
||||
"Expand-Archive -Path '{}' -DestinationPath '{}' -Force",
|
||||
zip_path_str, driver_path_str
|
||||
);
|
||||
|
||||
let status = Command::new("powershell")
|
||||
.args(["-NoProfile", "-Command", &ps_expand])
|
||||
.status()
|
||||
.expect("PowerShell konnte nicht ausgeführt werden");
|
||||
|
||||
if !status.success() {
|
||||
println!("❌ Fehler: Das Entpacken ist fehlgeschlagen!");
|
||||
pause(); // deine eigene Pause-Funktion
|
||||
return;
|
||||
}
|
||||
|
||||
fs::remove_file(&zip_path).unwrap_or(());
|
||||
println!("Treiber erfolgreich entpackt.\n");
|
||||
}
|
||||
|
||||
if !driver_path.exists() {
|
||||
println!("Fehler: Der Treiberordner {:?} existiert nicht!", driver_path);
|
||||
pause();
|
||||
return;
|
||||
}
|
||||
|
||||
// 3. Port erstellen
|
||||
println!("Erstelle TCP/IP-Port...");
|
||||
|
||||
let windir = std::env::var("WINDIR").expect("WINDIR nicht gefunden");
|
||||
let prnport_path = format!(r"{}\System32\Printing_Admin_Scripts\de-DE\prnport.vbs", windir);
|
||||
|
||||
|
||||
let _ = Command::new("cscript")
|
||||
.args([
|
||||
&prnport_path,
|
||||
"-a",
|
||||
"-r",
|
||||
printer_ip,
|
||||
"-h",
|
||||
printer_ip,
|
||||
"-o",
|
||||
"raw",
|
||||
])
|
||||
.status();
|
||||
|
||||
// 4. Treiber installieren
|
||||
println!("Installiere Druckertreiber...");
|
||||
let inf_path = driver_path.join("GER").join("BHPCL5E.inf");
|
||||
let _ = Command::new("pnputil")
|
||||
.args(["/add-driver", inf_path.to_str().unwrap(), "/install"])
|
||||
.status();
|
||||
|
||||
// 5. Drucker installieren
|
||||
for printer in &printer_list {
|
||||
println!("Installiere Drucker: {}", printer);
|
||||
let _ = Command::new("rundll32")
|
||||
.args([
|
||||
"printui.dll,PrintUIEntry",
|
||||
"/if",
|
||||
"/b",
|
||||
printer,
|
||||
"/r",
|
||||
printer_ip,
|
||||
"/m",
|
||||
"Brother PCLXL Generic Driver",
|
||||
])
|
||||
.status();
|
||||
}
|
||||
|
||||
// 6. PowerShell: Standarddruckeinstellungen setzen
|
||||
set_default_printer_config(printer_name);
|
||||
|
||||
let confirm = crate::utils::read_input(&format!(
|
||||
"Soll '{}' als Standard gesetzt werden? (J/N): ",
|
||||
printer_list[0]
|
||||
));
|
||||
|
||||
if confirm.trim().eq_ignore_ascii_case("j") {
|
||||
let _ = Command::new("rundll32")
|
||||
.args(["printui.dll,PrintUIEntry", "/y", "/n", &printer_list[0]])
|
||||
.status();
|
||||
}
|
||||
|
||||
// 8. Treiberordner löschen
|
||||
if driver_path.exists() {
|
||||
println!("Lösche Treiberordner...");
|
||||
let _ = fs::remove_dir_all(&driver_path);
|
||||
}
|
||||
|
||||
println!("Installation abgeschlossen.");
|
||||
pause();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
||||
//Color End
|
||||
|
||||
|
||||
//Mono
|
||||
pub fn brother_mono(stdout: &mut Stdout) {
|
||||
clear_screen(stdout);
|
||||
println!("Brother Color Installer gestartet\n");
|
||||
|
||||
// Admin-Check überspringen (erst später mit UAC)
|
||||
|
||||
// 1. Eingabe IP & Name
|
||||
let printer_ip = read_input("Gib die IP-Adresse des Druckers ein: ");
|
||||
let printer_ip = printer_ip.trim();
|
||||
|
||||
let printer_name = read_input("Gib den Namen des Druckers ein: ");
|
||||
let printer_name = printer_name.trim();
|
||||
|
||||
let printer_list = [format!("{}", printer_name)];
|
||||
|
||||
// 2. Treiberpfad
|
||||
let base_path = std::env::current_exe()
|
||||
.unwrap()
|
||||
.parent()
|
||||
.unwrap()
|
||||
.to_path_buf();
|
||||
let driver_path = base_path.join("brother-treiber");
|
||||
let zip_path = base_path.join("brother-treiber.zip");
|
||||
|
||||
println!("Verwende automatisch den Treiberordner: {:?}", driver_path);
|
||||
|
||||
if !driver_path.exists() {
|
||||
|
||||
//Download
|
||||
println!("Treiber nicht gefunden! Lade ihn herunter...");
|
||||
|
||||
let url = "https://oh5.kryptographen.eu/Brother-Treiber.zip";
|
||||
let zip_path_str = zip_path.to_str().unwrap();
|
||||
|
||||
let ps_command = format!(
|
||||
"(New-Object System.Net.WebClient).DownloadFile('{}', '{}')",
|
||||
url, zip_path_str
|
||||
);
|
||||
|
||||
let status = Command::new("powershell")
|
||||
.args(["-NoProfile", "-Command", &ps_command])
|
||||
.status()
|
||||
.expect("PowerShell konnte nicht ausgeführt werden");
|
||||
|
||||
if !status.success() {
|
||||
println!("❌ Fehler: Der Treiber konnte nicht heruntergeladen werden!");
|
||||
pause(); // z. B. deine eigene Funktion
|
||||
return;
|
||||
}
|
||||
|
||||
//Unzip
|
||||
let driver_path_str = driver_path.to_str().unwrap();
|
||||
|
||||
println!("Entpacke den Treiber...");
|
||||
let ps_expand = format!(
|
||||
"Expand-Archive -Path '{}' -DestinationPath '{}' -Force",
|
||||
zip_path_str, driver_path_str
|
||||
);
|
||||
|
||||
let status = Command::new("powershell")
|
||||
.args(["-NoProfile", "-Command", &ps_expand])
|
||||
.status()
|
||||
.expect("PowerShell konnte nicht ausgeführt werden");
|
||||
|
||||
if !status.success() {
|
||||
println!("❌ Fehler: Das Entpacken ist fehlgeschlagen!");
|
||||
pause(); // deine eigene Pause-Funktion
|
||||
return;
|
||||
}
|
||||
|
||||
fs::remove_file(&zip_path).unwrap_or(());
|
||||
println!("Treiber erfolgreich entpackt.\n");
|
||||
}
|
||||
|
||||
if !driver_path.exists() {
|
||||
println!("Fehler: Der Treiberordner {:?} existiert nicht!", driver_path);
|
||||
pause();
|
||||
return;
|
||||
}
|
||||
|
||||
// 3. Port erstellen
|
||||
println!("Erstelle TCP/IP-Port...");
|
||||
|
||||
let windir = std::env::var("WINDIR").expect("WINDIR nicht gefunden");
|
||||
let prnport_path = format!(r"{}\System32\Printing_Admin_Scripts\de-DE\prnport.vbs", windir);
|
||||
|
||||
|
||||
let _ = Command::new("cscript")
|
||||
.args([
|
||||
&prnport_path,
|
||||
"-a",
|
||||
"-r",
|
||||
printer_ip,
|
||||
"-h",
|
||||
printer_ip,
|
||||
"-o",
|
||||
"raw",
|
||||
])
|
||||
.status();
|
||||
|
||||
// 4. Treiber installieren
|
||||
println!("Installiere Druckertreiber...");
|
||||
let inf_path = driver_path.join("GER").join("BHPCL5E.inf");
|
||||
let _ = Command::new("pnputil")
|
||||
.args(["/add-driver", inf_path.to_str().unwrap(), "/install"])
|
||||
.status();
|
||||
|
||||
// 5. Drucker installieren
|
||||
for printer in &printer_list {
|
||||
println!("Installiere Drucker: {}", printer);
|
||||
let _ = Command::new("rundll32")
|
||||
.args([
|
||||
"printui.dll,PrintUIEntry",
|
||||
"/if",
|
||||
"/b",
|
||||
printer,
|
||||
"/r",
|
||||
printer_ip,
|
||||
"/m",
|
||||
"Brother PCLXL Generic Driver",
|
||||
])
|
||||
.status();
|
||||
}
|
||||
|
||||
// 6. PowerShell: Standarddruckeinstellungen setzen
|
||||
set_default_printer_config_mono(printer_name);
|
||||
|
||||
let confirm = crate::utils::read_input(&format!(
|
||||
"Soll '{}' als Standard gesetzt werden? (J/N): ",
|
||||
printer_list[0]
|
||||
));
|
||||
|
||||
if confirm.trim().eq_ignore_ascii_case("j") {
|
||||
let _ = Command::new("rundll32")
|
||||
.args(["printui.dll,PrintUIEntry", "/y", "/n", &printer_list[0]])
|
||||
.status();
|
||||
}
|
||||
|
||||
// 8. Treiberordner löschen
|
||||
if driver_path.exists() {
|
||||
println!("Lösche Treiberordner...");
|
||||
let _ = fs::remove_dir_all(&driver_path);
|
||||
}
|
||||
|
||||
println!("Installation abgeschlossen.");
|
||||
pause();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
||||
313
src/epson.rs
Normal file
313
src/epson.rs
Normal file
|
|
@ -0,0 +1,313 @@
|
|||
// epson.rs – epson Color Installer als Rust-Funktion (hybrid mit Command)
|
||||
|
||||
use std::fs;
|
||||
use std::io::Stdout;
|
||||
use std::process::{Command, exit};
|
||||
use crate::clear_screen;
|
||||
use crate::utils::{read_input,pause,set_default_printer_config,set_default_printer_config_mono};
|
||||
|
||||
//Color
|
||||
pub fn epson_color(stdout: &mut Stdout) {
|
||||
clear_screen(stdout);
|
||||
println!("Epson Color Installer gestartet\n");
|
||||
|
||||
// Admin-Check überspringen (erst später mit UAC)
|
||||
|
||||
// 1. Eingabe IP & Name
|
||||
let printer_ip = read_input("Gib die IP-Adresse des Druckers ein: ");
|
||||
let printer_ip = printer_ip.trim();
|
||||
|
||||
let printer_name = read_input("Gib den Namen des Druckers ein (ohne SW/Farbe): ");
|
||||
let printer_name = printer_name.trim();
|
||||
|
||||
let printer_list = [format!("{} (SW)", printer_name), format!("{} (Farbe)", printer_name)];
|
||||
|
||||
// 2. Treiberpfad
|
||||
let base_path = std::env::current_exe()
|
||||
.unwrap()
|
||||
.parent()
|
||||
.unwrap()
|
||||
.to_path_buf();
|
||||
let driver_path = base_path.join("epson-treiber");
|
||||
let zip_path = base_path.join("epson-treiber.zip");
|
||||
|
||||
println!("Verwende automatisch den Treiberordner: {:?}", driver_path);
|
||||
|
||||
if !driver_path.exists() {
|
||||
|
||||
//Download
|
||||
println!("Treiber nicht gefunden! Lade ihn herunter...");
|
||||
|
||||
let url = "https://oh5.kryptographen.eu/Epson-Treiber.zip";
|
||||
let zip_path_str = zip_path.to_str().unwrap();
|
||||
|
||||
let ps_command = format!(
|
||||
"(New-Object System.Net.WebClient).DownloadFile('{}', '{}')",
|
||||
url, zip_path_str
|
||||
);
|
||||
|
||||
let status = Command::new("powershell")
|
||||
.args(["-NoProfile", "-Command", &ps_command])
|
||||
.status()
|
||||
.expect("PowerShell konnte nicht ausgeführt werden");
|
||||
|
||||
if !status.success() {
|
||||
println!("❌ Fehler: Der Treiber konnte nicht heruntergeladen werden!");
|
||||
pause(); // z. B. deine eigene Funktion
|
||||
return;
|
||||
}
|
||||
|
||||
//Unzip
|
||||
let driver_path_str = driver_path.to_str().unwrap();
|
||||
|
||||
println!("Entpacke den Treiber...");
|
||||
let ps_expand = format!(
|
||||
"Expand-Archive -Path '{}' -DestinationPath '{}' -Force",
|
||||
zip_path_str, driver_path_str
|
||||
);
|
||||
|
||||
let status = Command::new("powershell")
|
||||
.args(["-NoProfile", "-Command", &ps_expand])
|
||||
.status()
|
||||
.expect("PowerShell konnte nicht ausgeführt werden");
|
||||
|
||||
if !status.success() {
|
||||
println!("❌ Fehler: Das Entpacken ist fehlgeschlagen!");
|
||||
pause(); // deine eigene Pause-Funktion
|
||||
return;
|
||||
}
|
||||
|
||||
fs::remove_file(&zip_path).unwrap_or(());
|
||||
println!("Treiber erfolgreich entpackt.\n");
|
||||
}
|
||||
|
||||
if !driver_path.exists() {
|
||||
println!("Fehler: Der Treiberordner {:?} existiert nicht!", driver_path);
|
||||
pause();
|
||||
return;
|
||||
}
|
||||
|
||||
// 3. Port erstellen
|
||||
println!("Erstelle TCP/IP-Port...");
|
||||
|
||||
let windir = std::env::var("WINDIR").expect("WINDIR nicht gefunden");
|
||||
let prnport_path = format!(r"{}\System32\Printing_Admin_Scripts\de-DE\prnport.vbs", windir);
|
||||
|
||||
|
||||
let _ = Command::new("cscript")
|
||||
.args([
|
||||
&prnport_path,
|
||||
"-a",
|
||||
"-r",
|
||||
printer_ip,
|
||||
"-h",
|
||||
printer_ip,
|
||||
"-o",
|
||||
"raw",
|
||||
])
|
||||
.status();
|
||||
|
||||
// 4. Treiber installieren
|
||||
println!("Installiere Druckertreiber...");
|
||||
let inf_path = driver_path.join("Universal_Print_Driver_x64_29000").join("E_JFB0DE.inf");
|
||||
let _ = Command::new("pnputil")
|
||||
.args(["/add-driver", inf_path.to_str().unwrap(), "/install"])
|
||||
.status();
|
||||
|
||||
// 5. Drucker installieren
|
||||
for printer in &printer_list {
|
||||
println!("Installiere Drucker: {}", printer);
|
||||
let _ = Command::new("rundll32")
|
||||
.args([
|
||||
"printui.dll,PrintUIEntry",
|
||||
"/if",
|
||||
"/b",
|
||||
printer,
|
||||
"/r",
|
||||
printer_ip,
|
||||
"/m",
|
||||
"EPSON Universal Print Driver",
|
||||
])
|
||||
.status();
|
||||
}
|
||||
|
||||
// 6. PowerShell: Standarddruckeinstellungen setzen
|
||||
set_default_printer_config(printer_name);
|
||||
|
||||
let confirm = crate::utils::read_input(&format!(
|
||||
"Soll '{}' als Standard gesetzt werden? (J/N): ",
|
||||
printer_list[0]
|
||||
));
|
||||
|
||||
if confirm.trim().eq_ignore_ascii_case("j") {
|
||||
let _ = Command::new("rundll32")
|
||||
.args(["printui.dll,PrintUIEntry", "/y", "/n", &printer_list[0]])
|
||||
.status();
|
||||
}
|
||||
|
||||
// 8. Treiberordner löschen
|
||||
if driver_path.exists() {
|
||||
println!("Lösche Treiberordner...");
|
||||
let _ = fs::remove_dir_all(&driver_path);
|
||||
}
|
||||
|
||||
println!("Installation abgeschlossen.");
|
||||
pause();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
||||
//Color End
|
||||
|
||||
|
||||
//Mono
|
||||
pub fn epson_mono(stdout: &mut Stdout) {
|
||||
clear_screen(stdout);
|
||||
println!("Epson Color Installer gestartet\n");
|
||||
|
||||
// Admin-Check überspringen (erst später mit UAC)
|
||||
|
||||
// 1. Eingabe IP & Name
|
||||
let printer_ip = read_input("Gib die IP-Adresse des Druckers ein: ");
|
||||
let printer_ip = printer_ip.trim();
|
||||
|
||||
let printer_name = read_input("Gib den Namen des Druckers ein: ");
|
||||
let printer_name = printer_name.trim();
|
||||
|
||||
let printer_list = [format!("{}", printer_name)];
|
||||
|
||||
// 2. Treiberpfad
|
||||
let base_path = std::env::current_exe()
|
||||
.unwrap()
|
||||
.parent()
|
||||
.unwrap()
|
||||
.to_path_buf();
|
||||
let driver_path = base_path.join("epson-treiber");
|
||||
let zip_path = base_path.join("epson-treiber.zip");
|
||||
|
||||
println!("Verwende automatisch den Treiberordner: {:?}", driver_path);
|
||||
|
||||
if !driver_path.exists() {
|
||||
|
||||
//Download
|
||||
println!("Treiber nicht gefunden! Lade ihn herunter...");
|
||||
|
||||
let url = "https://oh5.kryptographen.eu/Epson-Treiber.zip";
|
||||
let zip_path_str = zip_path.to_str().unwrap();
|
||||
|
||||
let ps_command = format!(
|
||||
"(New-Object System.Net.WebClient).DownloadFile('{}', '{}')",
|
||||
url, zip_path_str
|
||||
);
|
||||
|
||||
let status = Command::new("powershell")
|
||||
.args(["-NoProfile", "-Command", &ps_command])
|
||||
.status()
|
||||
.expect("PowerShell konnte nicht ausgeführt werden");
|
||||
|
||||
if !status.success() {
|
||||
println!("❌ Fehler: Der Treiber konnte nicht heruntergeladen werden!");
|
||||
pause(); // z. B. deine eigene Funktion
|
||||
return;
|
||||
}
|
||||
|
||||
//Unzip
|
||||
let driver_path_str = driver_path.to_str().unwrap();
|
||||
|
||||
println!("Entpacke den Treiber...");
|
||||
let ps_expand = format!(
|
||||
"Expand-Archive -Path '{}' -DestinationPath '{}' -Force",
|
||||
zip_path_str, driver_path_str
|
||||
);
|
||||
|
||||
let status = Command::new("powershell")
|
||||
.args(["-NoProfile", "-Command", &ps_expand])
|
||||
.status()
|
||||
.expect("PowerShell konnte nicht ausgeführt werden");
|
||||
|
||||
if !status.success() {
|
||||
println!("❌ Fehler: Das Entpacken ist fehlgeschlagen!");
|
||||
pause(); // deine eigene Pause-Funktion
|
||||
return;
|
||||
}
|
||||
|
||||
fs::remove_file(&zip_path).unwrap_or(());
|
||||
println!("Treiber erfolgreich entpackt.\n");
|
||||
}
|
||||
|
||||
if !driver_path.exists() {
|
||||
println!("Fehler: Der Treiberordner {:?} existiert nicht!", driver_path);
|
||||
pause();
|
||||
return;
|
||||
}
|
||||
|
||||
// 3. Port erstellen
|
||||
println!("Erstelle TCP/IP-Port...");
|
||||
|
||||
let windir = std::env::var("WINDIR").expect("WINDIR nicht gefunden");
|
||||
let prnport_path = format!(r"{}\System32\Printing_Admin_Scripts\de-DE\prnport.vbs", windir);
|
||||
|
||||
|
||||
let _ = Command::new("cscript")
|
||||
.args([
|
||||
&prnport_path,
|
||||
"-a",
|
||||
"-r",
|
||||
printer_ip,
|
||||
"-h",
|
||||
printer_ip,
|
||||
"-o",
|
||||
"raw",
|
||||
])
|
||||
.status();
|
||||
|
||||
// 4. Treiber installieren
|
||||
println!("Installiere Druckertreiber...");
|
||||
let inf_path = driver_path.join("Universal_Print_Driver_x64_29000").join("E_JFB0DE.inf");
|
||||
let _ = Command::new("pnputil")
|
||||
.args(["/add-driver", inf_path.to_str().unwrap(), "/install"])
|
||||
.status();
|
||||
|
||||
// 5. Drucker installieren
|
||||
for printer in &printer_list {
|
||||
println!("Installiere Drucker: {}", printer);
|
||||
let _ = Command::new("rundll32")
|
||||
.args([
|
||||
"printui.dll,PrintUIEntry",
|
||||
"/if",
|
||||
"/b",
|
||||
printer,
|
||||
"/r",
|
||||
printer_ip,
|
||||
"/m",
|
||||
"EPSON Universal Print Driver",
|
||||
])
|
||||
.status();
|
||||
}
|
||||
|
||||
// 6. PowerShell: Standarddruckeinstellungen setzen
|
||||
set_default_printer_config_mono(printer_name);
|
||||
|
||||
let confirm = crate::utils::read_input(&format!(
|
||||
"Soll '{}' als Standard gesetzt werden? (J/N): ",
|
||||
printer_list[0]
|
||||
));
|
||||
|
||||
if confirm.trim().eq_ignore_ascii_case("j") {
|
||||
let _ = Command::new("rundll32")
|
||||
.args(["printui.dll,PrintUIEntry", "/y", "/n", &printer_list[0]])
|
||||
.status();
|
||||
}
|
||||
|
||||
// 8. Treiberordner löschen
|
||||
if driver_path.exists() {
|
||||
println!("Lösche Treiberordner...");
|
||||
let _ = fs::remove_dir_all(&driver_path);
|
||||
}
|
||||
|
||||
println!("Installation abgeschlossen.");
|
||||
pause();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
||||
313
src/hp.rs
Normal file
313
src/hp.rs
Normal file
|
|
@ -0,0 +1,313 @@
|
|||
// hp.rs – HP Color Installer als Rust-Funktion (hybrid mit Command)
|
||||
|
||||
use std::fs;
|
||||
use std::io::Stdout;
|
||||
use std::process::{Command, exit};
|
||||
use crate::clear_screen;
|
||||
use crate::utils::{read_input,pause,set_default_printer_config,set_default_printer_config_mono};
|
||||
|
||||
//Color
|
||||
pub fn hp_color(stdout: &mut Stdout) {
|
||||
clear_screen(stdout);
|
||||
println!("HP Color Installer gestartet\n");
|
||||
|
||||
// Admin-Check überspringen (erst später mit UAC)
|
||||
|
||||
// 1. Eingabe IP & Name
|
||||
let printer_ip = read_input("Gib die IP-Adresse des Druckers ein: ");
|
||||
let printer_ip = printer_ip.trim();
|
||||
|
||||
let printer_name = read_input("Gib den Namen des Druckers ein (ohne SW/Farbe): ");
|
||||
let printer_name = printer_name.trim();
|
||||
|
||||
let printer_list = [format!("{} (SW)", printer_name), format!("{} (Farbe)", printer_name)];
|
||||
|
||||
// 2. Treiberpfad
|
||||
let base_path = std::env::current_exe()
|
||||
.unwrap()
|
||||
.parent()
|
||||
.unwrap()
|
||||
.to_path_buf();
|
||||
let driver_path = base_path.join("hp-treiber");
|
||||
let zip_path = base_path.join("hp-treiber.zip");
|
||||
|
||||
println!("Verwende automatisch den Treiberordner: {:?}", driver_path);
|
||||
|
||||
if !driver_path.exists() {
|
||||
|
||||
//Download
|
||||
println!("Treiber nicht gefunden! Lade ihn herunter...");
|
||||
|
||||
let url = "https://oh5.kryptographen.eu/HP-Treiber.zip";
|
||||
let zip_path_str = zip_path.to_str().unwrap();
|
||||
|
||||
let ps_command = format!(
|
||||
"(New-Object System.Net.WebClient).DownloadFile('{}', '{}')",
|
||||
url, zip_path_str
|
||||
);
|
||||
|
||||
let status = Command::new("powershell")
|
||||
.args(["-NoProfile", "-Command", &ps_command])
|
||||
.status()
|
||||
.expect("PowerShell konnte nicht ausgeführt werden");
|
||||
|
||||
if !status.success() {
|
||||
println!("❌ Fehler: Der Treiber konnte nicht heruntergeladen werden!");
|
||||
pause(); // z. B. deine eigene Funktion
|
||||
return;
|
||||
}
|
||||
|
||||
//Unzip
|
||||
let driver_path_str = driver_path.to_str().unwrap();
|
||||
|
||||
println!("Entpacke den Treiber...");
|
||||
let ps_expand = format!(
|
||||
"Expand-Archive -Path '{}' -DestinationPath '{}' -Force",
|
||||
zip_path_str, driver_path_str
|
||||
);
|
||||
|
||||
let status = Command::new("powershell")
|
||||
.args(["-NoProfile", "-Command", &ps_expand])
|
||||
.status()
|
||||
.expect("PowerShell konnte nicht ausgeführt werden");
|
||||
|
||||
if !status.success() {
|
||||
println!("❌ Fehler: Das Entpacken ist fehlgeschlagen!");
|
||||
pause(); // deine eigene Pause-Funktion
|
||||
return;
|
||||
}
|
||||
|
||||
fs::remove_file(&zip_path).unwrap_or(());
|
||||
println!("Treiber erfolgreich entpackt.\n");
|
||||
}
|
||||
|
||||
if !driver_path.exists() {
|
||||
println!("Fehler: Der Treiberordner {:?} existiert nicht!", driver_path);
|
||||
pause();
|
||||
return;
|
||||
}
|
||||
|
||||
// 3. Port erstellen
|
||||
println!("Erstelle TCP/IP-Port...");
|
||||
|
||||
let windir = std::env::var("WINDIR").expect("WINDIR nicht gefunden");
|
||||
let prnport_path = format!(r"{}\System32\Printing_Admin_Scripts\de-DE\prnport.vbs", windir);
|
||||
|
||||
|
||||
let _ = Command::new("cscript")
|
||||
.args([
|
||||
&prnport_path,
|
||||
"-a",
|
||||
"-r",
|
||||
printer_ip,
|
||||
"-h",
|
||||
printer_ip,
|
||||
"-o",
|
||||
"raw",
|
||||
])
|
||||
.status();
|
||||
|
||||
// 4. Treiber installieren
|
||||
println!("Installiere Druckertreiber...");
|
||||
let inf_path = driver_path.join("hpcu315u.inf");
|
||||
let _ = Command::new("pnputil")
|
||||
.args(["/add-driver", inf_path.to_str().unwrap(), "/install"])
|
||||
.status();
|
||||
|
||||
// 5. Drucker installieren
|
||||
for printer in &printer_list {
|
||||
println!("Installiere Drucker: {}", printer);
|
||||
let _ = Command::new("rundll32")
|
||||
.args([
|
||||
"printui.dll,PrintUIEntry",
|
||||
"/if",
|
||||
"/b",
|
||||
printer,
|
||||
"/r",
|
||||
printer_ip,
|
||||
"/m",
|
||||
"HP Universal Printing PCL 6",
|
||||
])
|
||||
.status();
|
||||
}
|
||||
|
||||
// 6. PowerShell: Standarddruckeinstellungen setzen
|
||||
set_default_printer_config(printer_name);
|
||||
|
||||
let confirm = crate::utils::read_input(&format!(
|
||||
"Soll '{}' als Standard gesetzt werden? (J/N): ",
|
||||
printer_list[0]
|
||||
));
|
||||
|
||||
if confirm.trim().eq_ignore_ascii_case("j") {
|
||||
let _ = Command::new("rundll32")
|
||||
.args(["printui.dll,PrintUIEntry", "/y", "/n", &printer_list[0]])
|
||||
.status();
|
||||
}
|
||||
|
||||
// 8. Treiberordner löschen
|
||||
if driver_path.exists() {
|
||||
println!("Lösche Treiberordner...");
|
||||
let _ = fs::remove_dir_all(&driver_path);
|
||||
}
|
||||
|
||||
println!("Installation abgeschlossen.");
|
||||
pause();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
||||
//Color End
|
||||
|
||||
|
||||
//Mono
|
||||
pub fn hp_mono(stdout: &mut Stdout) {
|
||||
clear_screen(stdout);
|
||||
println!("HP Color Installer gestartet\n");
|
||||
|
||||
// Admin-Check überspringen (erst später mit UAC)
|
||||
|
||||
// 1. Eingabe IP & Name
|
||||
let printer_ip = read_input("Gib die IP-Adresse des Druckers ein: ");
|
||||
let printer_ip = printer_ip.trim();
|
||||
|
||||
let printer_name = read_input("Gib den Namen des Druckers ein: ");
|
||||
let printer_name = printer_name.trim();
|
||||
|
||||
let printer_list = [format!("{}", printer_name)];
|
||||
|
||||
// 2. Treiberpfad
|
||||
let base_path = std::env::current_exe()
|
||||
.unwrap()
|
||||
.parent()
|
||||
.unwrap()
|
||||
.to_path_buf();
|
||||
let driver_path = base_path.join("hp-treiber");
|
||||
let zip_path = base_path.join("hp-treiber.zip");
|
||||
|
||||
println!("Verwende automatisch den Treiberordner: {:?}", driver_path);
|
||||
|
||||
if !driver_path.exists() {
|
||||
|
||||
//Download
|
||||
println!("Treiber nicht gefunden! Lade ihn herunter...");
|
||||
|
||||
let url = "https://oh5.kryptographen.eu/HP-Treiber.zip";
|
||||
let zip_path_str = zip_path.to_str().unwrap();
|
||||
|
||||
let ps_command = format!(
|
||||
"(New-Object System.Net.WebClient).DownloadFile('{}', '{}')",
|
||||
url, zip_path_str
|
||||
);
|
||||
|
||||
let status = Command::new("powershell")
|
||||
.args(["-NoProfile", "-Command", &ps_command])
|
||||
.status()
|
||||
.expect("PowerShell konnte nicht ausgeführt werden");
|
||||
|
||||
if !status.success() {
|
||||
println!("❌ Fehler: Der Treiber konnte nicht heruntergeladen werden!");
|
||||
pause(); // z. B. deine eigene Funktion
|
||||
return;
|
||||
}
|
||||
|
||||
//Unzip
|
||||
let driver_path_str = driver_path.to_str().unwrap();
|
||||
|
||||
println!("Entpacke den Treiber...");
|
||||
let ps_expand = format!(
|
||||
"Expand-Archive -Path '{}' -DestinationPath '{}' -Force",
|
||||
zip_path_str, driver_path_str
|
||||
);
|
||||
|
||||
let status = Command::new("powershell")
|
||||
.args(["-NoProfile", "-Command", &ps_expand])
|
||||
.status()
|
||||
.expect("PowerShell konnte nicht ausgeführt werden");
|
||||
|
||||
if !status.success() {
|
||||
println!("❌ Fehler: Das Entpacken ist fehlgeschlagen!");
|
||||
pause(); // deine eigene Pause-Funktion
|
||||
return;
|
||||
}
|
||||
|
||||
fs::remove_file(&zip_path).unwrap_or(());
|
||||
println!("Treiber erfolgreich entpackt.\n");
|
||||
}
|
||||
|
||||
if !driver_path.exists() {
|
||||
println!("Fehler: Der Treiberordner {:?} existiert nicht!", driver_path);
|
||||
pause();
|
||||
return;
|
||||
}
|
||||
|
||||
// 3. Port erstellen
|
||||
println!("Erstelle TCP/IP-Port...");
|
||||
|
||||
let windir = std::env::var("WINDIR").expect("WINDIR nicht gefunden");
|
||||
let prnport_path = format!(r"{}\System32\Printing_Admin_Scripts\de-DE\prnport.vbs", windir);
|
||||
|
||||
|
||||
let _ = Command::new("cscript")
|
||||
.args([
|
||||
&prnport_path,
|
||||
"-a",
|
||||
"-r",
|
||||
printer_ip,
|
||||
"-h",
|
||||
printer_ip,
|
||||
"-o",
|
||||
"raw",
|
||||
])
|
||||
.status();
|
||||
|
||||
// 4. Treiber installieren
|
||||
println!("Installiere Druckertreiber...");
|
||||
let inf_path = driver_path.join("hpcu315u.inf");
|
||||
let _ = Command::new("pnputil")
|
||||
.args(["/add-driver", inf_path.to_str().unwrap(), "/install"])
|
||||
.status();
|
||||
|
||||
// 5. Drucker installieren
|
||||
for printer in &printer_list {
|
||||
println!("Installiere Drucker: {}", printer);
|
||||
let _ = Command::new("rundll32")
|
||||
.args([
|
||||
"printui.dll,PrintUIEntry",
|
||||
"/if",
|
||||
"/b",
|
||||
printer,
|
||||
"/r",
|
||||
printer_ip,
|
||||
"/m",
|
||||
"HP Universal Printing PCL 6",
|
||||
])
|
||||
.status();
|
||||
}
|
||||
|
||||
// 6. PowerShell: Standarddruckeinstellungen setzen
|
||||
set_default_printer_config_mono(printer_name);
|
||||
|
||||
let confirm = crate::utils::read_input(&format!(
|
||||
"Soll '{}' als Standard gesetzt werden? (J/N): ",
|
||||
printer_list[0]
|
||||
));
|
||||
|
||||
if confirm.trim().eq_ignore_ascii_case("j") {
|
||||
let _ = Command::new("rundll32")
|
||||
.args(["printui.dll,PrintUIEntry", "/y", "/n", &printer_list[0]])
|
||||
.status();
|
||||
}
|
||||
|
||||
// 8. Treiberordner löschen
|
||||
if driver_path.exists() {
|
||||
println!("Lösche Treiberordner...");
|
||||
let _ = fs::remove_dir_all(&driver_path);
|
||||
}
|
||||
|
||||
println!("Installation abgeschlossen.");
|
||||
pause();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
||||
231
src/main.rs
Normal file
231
src/main.rs
Normal file
|
|
@ -0,0 +1,231 @@
|
|||
// OH5 Drucker Installer – Crossterm Edition mit Debounce und Modifier-Ignore
|
||||
mod hp;
|
||||
mod epson;
|
||||
mod brother;
|
||||
mod sharp;
|
||||
mod utils;
|
||||
mod update;
|
||||
|
||||
use crossterm::{ExecutableCommand, event::{self, Event, KeyCode, KeyEventKind}, style::{Color, ResetColor, SetForegroundColor}, terminal};
|
||||
use std::io::{stdout, Write};
|
||||
use std::time::Duration;
|
||||
use utils::{is_running_as_admin, relaunch_as_admin, clear_screen, VERSION};
|
||||
|
||||
|
||||
fn main() {
|
||||
if !is_running_as_admin() {
|
||||
println!("Starte mit Admin-Rechten neu...");
|
||||
relaunch_as_admin();
|
||||
}
|
||||
|
||||
let mut stdout = stdout();
|
||||
terminal::enable_raw_mode().unwrap();
|
||||
main_menu(&mut stdout);
|
||||
terminal::disable_raw_mode().unwrap();
|
||||
}
|
||||
|
||||
fn main_menu(stdout: &mut std::io::Stdout) {
|
||||
let update_info = update::check_for_update();
|
||||
loop {
|
||||
clear_screen(stdout);
|
||||
|
||||
println!("╔════════════════════════════════════════════════════════════╗");
|
||||
|
||||
print!("║ ");
|
||||
let _ = stdout.execute(SetForegroundColor(Color::Blue));
|
||||
let _ = write!(stdout, "OH");
|
||||
let _ = stdout.execute(SetForegroundColor(Color::Red));
|
||||
let _ = write!(stdout, "5");
|
||||
let _ = stdout.execute(ResetColor);
|
||||
|
||||
// Text + Version zusammensetzen
|
||||
let line = format!(" Drucker Installer v{VERSION}");
|
||||
|
||||
// Fülle auf 57 Zeichen (weil links 19 schon kamen, insgesamt 76)
|
||||
let padded = format!("{:<42}", line);
|
||||
let _ = writeln!(stdout, "{}║", padded);
|
||||
|
||||
|
||||
println!("╠════════════════════════════════════════════════════════════╣");
|
||||
println!("║ Bitte wähle deine Druckermarke: ║");
|
||||
println!("║ ║");
|
||||
println!("║ 1. HP ║");
|
||||
println!("║ 2. Sharp ║");
|
||||
println!("║ 3. Utax (Work in Progress) ║");
|
||||
println!("║ 4. Epson ║");
|
||||
println!("║ 5. Brother ║");
|
||||
println!("║ ║");
|
||||
println!("║ 6. Beenden ║");
|
||||
|
||||
//update Edit
|
||||
if update_info.is_some() {
|
||||
println!("╠════════════════════════════════════════════════════════════╣");
|
||||
println!("║ [U] = Update ║");
|
||||
}
|
||||
|
||||
//Closing Box
|
||||
println!("╚════════════════════════════════════════════════════════════╝");
|
||||
|
||||
|
||||
//Update
|
||||
if let Some(new_version) = update_info.as_ref() {
|
||||
|
||||
let _ = stdout.execute(SetForegroundColor(Color::Red));
|
||||
let _ = write!(stdout, "Eine neue Version ist verfügbar: ");
|
||||
|
||||
let _ = stdout.execute(SetForegroundColor(Color::Green));
|
||||
let _ = writeln!(stdout, "v{}", new_version);
|
||||
|
||||
let _ = stdout.execute(ResetColor);
|
||||
}
|
||||
|
||||
|
||||
|
||||
match read_clean_key() {
|
||||
'1' => hp_menu(stdout),
|
||||
'2' => sharp_menu(stdout),
|
||||
'3' => utax_menu(stdout),
|
||||
'4' => epson_menu(stdout),
|
||||
'5' => brother_menu(stdout),
|
||||
'6' => break,
|
||||
'u' | 'U' => {
|
||||
if let Some(new_version) = update_info.as_ref() {
|
||||
update::update_software(stdout, new_version);
|
||||
pause();
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn hp_menu(stdout: &mut std::io::Stdout) {
|
||||
loop {
|
||||
clear_screen(stdout);
|
||||
println!("╔════════════════════════════════════════════════════════════╗");
|
||||
println!("║ HP Drucker Installation ║");
|
||||
println!("╠════════════════════════════════════════════════════════════╣");
|
||||
println!("║ 1. Einfache Installation (Color) ║");
|
||||
println!("║ 2. Einfache Installation (Mono) ║");
|
||||
println!("║ 3. Zurück ║");
|
||||
println!("╚════════════════════════════════════════════════════════════╝");
|
||||
match read_clean_key() {
|
||||
'1' => hp::hp_color(stdout),
|
||||
'2' => hp::hp_mono(stdout),
|
||||
'3' => return,
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn sharp_menu(stdout: &mut std::io::Stdout) {
|
||||
loop {
|
||||
clear_screen(stdout);
|
||||
println!("╔════════════════════════════════════════════════════════════╗");
|
||||
println!("║ Sharp Drucker Installation ║");
|
||||
println!("╠════════════════════════════════════════════════════════════╣");
|
||||
println!("║ 1. Einfache Installation (Color) ║");
|
||||
println!("║ 2. Einfache Installation (Mono) ║");
|
||||
println!("║ 3. Zurück ║");
|
||||
println!("╚════════════════════════════════════════════════════════════╝");
|
||||
match read_clean_key() {
|
||||
'1' => sharp::sharp_color(stdout),
|
||||
'2' => sharp::sharp_mono(stdout),
|
||||
'3' => return,
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn utax_menu(stdout: &mut std::io::Stdout) {
|
||||
show_wip(stdout, "Utax Menü (WIP)");
|
||||
}
|
||||
|
||||
fn epson_menu(stdout: &mut std::io::Stdout) {
|
||||
loop {
|
||||
clear_screen(stdout);
|
||||
println!("╔════════════════════════════════════════════════════════════╗");
|
||||
println!("║ Epson Drucker Installation ║");
|
||||
println!("╠════════════════════════════════════════════════════════════╣");
|
||||
println!("║ 1. Einfache Installation (Color) ║");
|
||||
println!("║ 2. Einfache Installation (Mono) ║");
|
||||
println!("║ 3. Zurück ║");
|
||||
println!("╚════════════════════════════════════════════════════════════╝");
|
||||
match read_clean_key() {
|
||||
'1' => epson::epson_color(stdout),
|
||||
'2' => epson::epson_mono(stdout),
|
||||
'3' => return,
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn brother_menu(stdout: &mut std::io::Stdout) {
|
||||
loop {
|
||||
clear_screen(stdout);
|
||||
println!("╔════════════════════════════════════════════════════════════╗");
|
||||
println!("║ Brother Drucker Installation ║");
|
||||
println!("╠════════════════════════════════════════════════════════════╣");
|
||||
println!("║ 1. Einfache Installation (Color) ║");
|
||||
println!("║ 2. Einfache Installation (Mono) ║");
|
||||
println!("║ 3. Zurück ║");
|
||||
println!("╚════════════════════════════════════════════════════════════╝");
|
||||
match read_clean_key() {
|
||||
'1' => brother::brother_color(stdout),
|
||||
'2' => brother::brother_mono(stdout),
|
||||
'3' => return,
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn show_wip(stdout: &mut std::io::Stdout, msg: &str) {
|
||||
clear_screen(stdout);
|
||||
println!("╔════════════════════════════════════════════════════════════╗");
|
||||
println!("║ {:<58} ║", msg);
|
||||
println!("╠════════════════════════════════════════════════════════════╣");
|
||||
println!("║ Diese Option ist noch in Arbeit. ║");
|
||||
println!("║ Bitte versuche es später erneut. ║");
|
||||
println!("╚════════════════════════════════════════════════════════════╝");
|
||||
pause();
|
||||
}
|
||||
|
||||
|
||||
fn pause() {
|
||||
println!("\nDrücke eine beliebige Taste, um fortzufahren...");
|
||||
let _ = read_clean_key();
|
||||
}
|
||||
|
||||
fn read_clean_key() -> char {
|
||||
loop {
|
||||
if event::poll(Duration::from_millis(10)).unwrap() {
|
||||
if let Event::Key(event) = event::read().unwrap() {
|
||||
if event.kind == KeyEventKind::Press && event.modifiers.is_empty() {
|
||||
if let KeyCode::Char(c) = event.code {
|
||||
wait_for_key_release(c); // ← erst loslassen!
|
||||
return c;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn wait_for_key_release(target: char) {
|
||||
use crossterm::event::{poll, read, Event, KeyCode, KeyEventKind};
|
||||
use std::time::Duration;
|
||||
|
||||
loop {
|
||||
if poll(Duration::from_millis(10)).unwrap() {
|
||||
if let Event::Key(event) = read().unwrap() {
|
||||
if event.kind == KeyEventKind::Release {
|
||||
if let KeyCode::Char(c) = event.code {
|
||||
if c == target {
|
||||
break; // erst jetzt darf man neu drücken
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
364
src/sharp.rs
Normal file
364
src/sharp.rs
Normal file
|
|
@ -0,0 +1,364 @@
|
|||
// sharp.rs – Sharp Color Installer als Rust-Funktion (hybrid mit Command)
|
||||
|
||||
use std::fs;
|
||||
use std::io::Stdout;
|
||||
use std::process::{Command, exit};
|
||||
use crate::clear_screen;
|
||||
use crate::utils::{read_input,pause,set_default_printer_config,set_default_printer_config_mono};
|
||||
|
||||
//Color
|
||||
pub fn sharp_color(stdout: &mut Stdout) {
|
||||
clear_screen(stdout);
|
||||
println!("Sharp Color Installer gestartet\n");
|
||||
|
||||
// Admin-Check überspringen (erst später mit UAC)
|
||||
|
||||
// Maschinenart auswählen
|
||||
println!("Waehle die Maschinenart:");
|
||||
println!("[1] BP Maschine");
|
||||
println!("[2] MX Maschine");
|
||||
|
||||
let machine_type = read_input("Waehle die Maschinenart (1 oder 2): ");
|
||||
let machine_type = machine_type.trim();
|
||||
|
||||
let (url, machine_name) = match machine_type {
|
||||
"1" => (
|
||||
"https://oh5.kryptographen.eu/SharpBP-Treiber.zip",
|
||||
"BP Maschine"
|
||||
),
|
||||
"2" => (
|
||||
"https://oh5.kryptographen.eu/SharpMX-Treiber.zip",
|
||||
"MX Maschine"
|
||||
),
|
||||
_ => {
|
||||
println!("Ungueltige Eingabe! Bitte wähle 1 oder 2.");
|
||||
pause(); // deine eigene pause()-Funktion
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
println!("Gewählt: {}", machine_name);
|
||||
|
||||
// 1. Eingabe IP & Name
|
||||
let printer_ip = read_input("Gib die IP-Adresse des Druckers ein: ");
|
||||
let printer_ip = printer_ip.trim();
|
||||
|
||||
let printer_name = read_input("Gib den Namen des Druckers ein (ohne SW/Farbe): ");
|
||||
let printer_name = printer_name.trim();
|
||||
|
||||
let printer_list = [format!("{} (SW)", printer_name), format!("{} (Farbe)", printer_name)];
|
||||
|
||||
// 2. Treiberpfad
|
||||
let base_path = std::env::current_exe()
|
||||
.unwrap()
|
||||
.parent()
|
||||
.unwrap()
|
||||
.to_path_buf();
|
||||
let driver_path = base_path.join("sharp-treiber");
|
||||
let zip_path = base_path.join("sharp-treiber.zip");
|
||||
|
||||
println!("Verwende automatisch den Treiberordner: {:?}", driver_path);
|
||||
|
||||
if !driver_path.exists() {
|
||||
|
||||
//Download
|
||||
println!("Treiber nicht gefunden! Lade ihn herunter...");
|
||||
|
||||
let zip_path_str = zip_path.to_str().unwrap();
|
||||
|
||||
let ps_command = format!(
|
||||
"(New-Object System.Net.WebClient).DownloadFile('{}', '{}')",
|
||||
url, zip_path_str
|
||||
);
|
||||
|
||||
let status = Command::new("powershell")
|
||||
.args(["-NoProfile", "-Command", &ps_command])
|
||||
.status()
|
||||
.expect("PowerShell konnte nicht ausgeführt werden");
|
||||
|
||||
if !status.success() {
|
||||
println!("❌ Fehler: Der Treiber konnte nicht heruntergeladen werden!");
|
||||
pause(); // z. B. deine eigene Funktion
|
||||
return;
|
||||
}
|
||||
|
||||
//Unzip
|
||||
let driver_path_str = driver_path.to_str().unwrap();
|
||||
|
||||
println!("Entpacke den Treiber...");
|
||||
let ps_expand = format!(
|
||||
"Expand-Archive -Path '{}' -DestinationPath '{}' -Force",
|
||||
zip_path_str, driver_path_str
|
||||
);
|
||||
|
||||
let status = Command::new("powershell")
|
||||
.args(["-NoProfile", "-Command", &ps_expand])
|
||||
.status()
|
||||
.expect("PowerShell konnte nicht ausgeführt werden");
|
||||
|
||||
if !status.success() {
|
||||
println!("❌ Fehler: Das Entpacken ist fehlgeschlagen!");
|
||||
pause(); // deine eigene Pause-Funktion
|
||||
return;
|
||||
}
|
||||
|
||||
fs::remove_file(&zip_path).unwrap_or(());
|
||||
println!("Treiber erfolgreich entpackt.\n");
|
||||
}
|
||||
|
||||
if !driver_path.exists() {
|
||||
println!("Fehler: Der Treiberordner {:?} existiert nicht!", driver_path);
|
||||
pause();
|
||||
return;
|
||||
}
|
||||
|
||||
// 3. Port erstellen
|
||||
println!("Erstelle TCP/IP-Port...");
|
||||
|
||||
let windir = std::env::var("WINDIR").expect("WINDIR nicht gefunden");
|
||||
let prnport_path = format!(r"{}\System32\Printing_Admin_Scripts\de-DE\prnport.vbs", windir);
|
||||
|
||||
|
||||
let _ = Command::new("cscript")
|
||||
.args([
|
||||
&prnport_path,
|
||||
"-a",
|
||||
"-r",
|
||||
printer_ip,
|
||||
"-h",
|
||||
printer_ip,
|
||||
"-o",
|
||||
"raw",
|
||||
])
|
||||
.status();
|
||||
|
||||
// 4. Treiber installieren
|
||||
println!("Installiere Druckertreiber...");
|
||||
let inf_path = driver_path.join("PCL6").join("64bit").join("sv0emenu.inf");
|
||||
let _ = Command::new("pnputil")
|
||||
.args(["/add-driver", inf_path.to_str().unwrap(), "/install"])
|
||||
.status();
|
||||
|
||||
// 5. Drucker installieren
|
||||
for printer in &printer_list {
|
||||
println!("Installiere Drucker: {}", printer);
|
||||
let _ = Command::new("rundll32")
|
||||
.args([
|
||||
"printui.dll,PrintUIEntry",
|
||||
"/if",
|
||||
"/b",
|
||||
printer,
|
||||
"/r",
|
||||
printer_ip,
|
||||
"/m",
|
||||
"SHARP UD3 PCL6",
|
||||
])
|
||||
.status();
|
||||
}
|
||||
|
||||
// 6. PowerShell: Standarddruckeinstellungen setzen
|
||||
set_default_printer_config(printer_name);
|
||||
|
||||
let confirm = crate::utils::read_input(&format!(
|
||||
"Soll '{}' als Standard gesetzt werden? (J/N): ",
|
||||
printer_list[0]
|
||||
));
|
||||
|
||||
if confirm.trim().eq_ignore_ascii_case("j") {
|
||||
let _ = Command::new("rundll32")
|
||||
.args(["printui.dll,PrintUIEntry", "/y", "/n", &printer_list[0]])
|
||||
.status();
|
||||
}
|
||||
|
||||
// 8. Treiberordner löschen
|
||||
if driver_path.exists() {
|
||||
println!("Lösche Treiberordner...");
|
||||
let _ = fs::remove_dir_all(&driver_path);
|
||||
}
|
||||
|
||||
println!("Installation abgeschlossen.");
|
||||
pause();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
||||
//Color End
|
||||
|
||||
|
||||
//Mono
|
||||
pub fn sharp_mono(stdout: &mut Stdout) {
|
||||
clear_screen(stdout);
|
||||
println!("Sharp Color Installer gestartet\n");
|
||||
|
||||
// Admin-Check überspringen (erst später mit UAC)
|
||||
|
||||
|
||||
// Maschinenart auswählen
|
||||
println!("Waehle die Maschinenart:");
|
||||
println!("[1] BP Maschine");
|
||||
println!("[2] MX Maschine");
|
||||
|
||||
let machine_type = read_input("Waehle die Maschinenart (1 oder 2): ");
|
||||
let machine_type = machine_type.trim();
|
||||
|
||||
let (url, machine_name) = match machine_type {
|
||||
"1" => (
|
||||
"https://oh5.kryptographen.eu/SharpBP-Treiber.zip",
|
||||
"BP Maschine"
|
||||
),
|
||||
"2" => (
|
||||
"https://oh5.kryptographen.eu/SharpMX-Treiber.zip",
|
||||
"MX Maschine"
|
||||
),
|
||||
_ => {
|
||||
println!("Ungueltige Eingabe! Bitte wähle 1 oder 2.");
|
||||
pause(); // deine eigene pause()-Funktion
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
println!("Gewählt: {}", machine_name);
|
||||
|
||||
// 1. Eingabe IP & Name
|
||||
let printer_ip = read_input("Gib die IP-Adresse des Druckers ein: ");
|
||||
let printer_ip = printer_ip.trim();
|
||||
|
||||
let printer_name = read_input("Gib den Namen des Druckers ein: ");
|
||||
let printer_name = printer_name.trim();
|
||||
|
||||
let printer_list = [format!("{}", printer_name)];
|
||||
|
||||
// 2. Treiberpfad
|
||||
let base_path = std::env::current_exe()
|
||||
.unwrap()
|
||||
.parent()
|
||||
.unwrap()
|
||||
.to_path_buf();
|
||||
let driver_path = base_path.join("sharp-treiber");
|
||||
let zip_path = base_path.join("sharp-treiber.zip");
|
||||
|
||||
println!("Verwende automatisch den Treiberordner: {:?}", driver_path);
|
||||
|
||||
if !driver_path.exists() {
|
||||
|
||||
//Download
|
||||
println!("Treiber nicht gefunden! Lade ihn herunter...");
|
||||
|
||||
let zip_path_str = zip_path.to_str().unwrap();
|
||||
|
||||
let ps_command = format!(
|
||||
"(New-Object System.Net.WebClient).DownloadFile('{}', '{}')",
|
||||
url, zip_path_str
|
||||
);
|
||||
|
||||
let status = Command::new("powershell")
|
||||
.args(["-NoProfile", "-Command", &ps_command])
|
||||
.status()
|
||||
.expect("PowerShell konnte nicht ausgeführt werden");
|
||||
|
||||
if !status.success() {
|
||||
println!("❌ Fehler: Der Treiber konnte nicht heruntergeladen werden!");
|
||||
pause(); // z. B. deine eigene Funktion
|
||||
return;
|
||||
}
|
||||
|
||||
//Unzip
|
||||
let driver_path_str = driver_path.to_str().unwrap();
|
||||
|
||||
println!("Entpacke den Treiber...");
|
||||
let ps_expand = format!(
|
||||
"Expand-Archive -Path '{}' -DestinationPath '{}' -Force",
|
||||
zip_path_str, driver_path_str
|
||||
);
|
||||
|
||||
let status = Command::new("powershell")
|
||||
.args(["-NoProfile", "-Command", &ps_expand])
|
||||
.status()
|
||||
.expect("PowerShell konnte nicht ausgeführt werden");
|
||||
|
||||
if !status.success() {
|
||||
println!("❌ Fehler: Das Entpacken ist fehlgeschlagen!");
|
||||
pause(); // deine eigene Pause-Funktion
|
||||
return;
|
||||
}
|
||||
|
||||
fs::remove_file(&zip_path).unwrap_or(());
|
||||
println!("Treiber erfolgreich entpackt.\n");
|
||||
}
|
||||
|
||||
if !driver_path.exists() {
|
||||
println!("Fehler: Der Treiberordner {:?} existiert nicht!", driver_path);
|
||||
pause();
|
||||
return;
|
||||
}
|
||||
|
||||
// 3. Port erstellen
|
||||
println!("Erstelle TCP/IP-Port...");
|
||||
|
||||
let windir = std::env::var("WINDIR").expect("WINDIR nicht gefunden");
|
||||
let prnport_path = format!(r"{}\System32\Printing_Admin_Scripts\de-DE\prnport.vbs", windir);
|
||||
|
||||
|
||||
let _ = Command::new("cscript")
|
||||
.args([
|
||||
&prnport_path,
|
||||
"-a",
|
||||
"-r",
|
||||
printer_ip,
|
||||
"-h",
|
||||
printer_ip,
|
||||
"-o",
|
||||
"raw",
|
||||
])
|
||||
.status();
|
||||
|
||||
// 4. Treiber installieren
|
||||
println!("Installiere Druckertreiber...");
|
||||
let inf_path = driver_path.join("PCL6").join("64bit").join("sv0emenu.inf");
|
||||
let _ = Command::new("pnputil")
|
||||
.args(["/add-driver", inf_path.to_str().unwrap(), "/install"])
|
||||
.status();
|
||||
|
||||
// 5. Drucker installieren
|
||||
for printer in &printer_list {
|
||||
println!("Installiere Drucker: {}", printer);
|
||||
let _ = Command::new("rundll32")
|
||||
.args([
|
||||
"printui.dll,PrintUIEntry",
|
||||
"/if",
|
||||
"/b",
|
||||
printer,
|
||||
"/r",
|
||||
printer_ip,
|
||||
"/m",
|
||||
"SHARP UD3 PCL6",
|
||||
])
|
||||
.status();
|
||||
}
|
||||
|
||||
// 6. PowerShell: Standarddruckeinstellungen setzen
|
||||
set_default_printer_config_mono(printer_name);
|
||||
|
||||
let confirm = crate::utils::read_input(&format!(
|
||||
"Soll '{}' als Standard gesetzt werden? (J/N): ",
|
||||
printer_list[0]
|
||||
));
|
||||
|
||||
if confirm.trim().eq_ignore_ascii_case("j") {
|
||||
let _ = Command::new("rundll32")
|
||||
.args(["printui.dll,PrintUIEntry", "/y", "/n", &printer_list[0]])
|
||||
.status();
|
||||
}
|
||||
|
||||
// 8. Treiberordner löschen
|
||||
if driver_path.exists() {
|
||||
println!("Lösche Treiberordner...");
|
||||
let _ = fs::remove_dir_all(&driver_path);
|
||||
}
|
||||
|
||||
println!("Installation abgeschlossen.");
|
||||
pause();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
||||
103
src/update.rs
Normal file
103
src/update.rs
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
use std::cmp::Ordering;
|
||||
use std::fs;
|
||||
use std::io::Write;
|
||||
use std::env;
|
||||
use std::io::Read;
|
||||
use crossterm::{ExecutableCommand, style::{Color, SetForegroundColor, ResetColor}};
|
||||
use ureq;
|
||||
use std::thread;
|
||||
use std::time::Duration;
|
||||
use std::process::exit;
|
||||
|
||||
pub fn check_for_update() -> Option<String> {
|
||||
let local_version = env!("CARGO_PKG_VERSION");
|
||||
|
||||
match fetch_latest_version() {
|
||||
Ok(remote_version) => {
|
||||
if compare_versions(local_version, &remote_version) == Ordering::Less {
|
||||
return Some(remote_version); // Neue Version!
|
||||
}
|
||||
}
|
||||
Err(_) => {} // kein Fehler anzeigen
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
|
||||
fn fetch_latest_version() -> Result<String, Box<dyn std::error::Error>> {
|
||||
let response = ureq::get("https://oh5.kryptographen.eu/Utils/PrintInstaller/latest_version.txt")
|
||||
.call()?;
|
||||
|
||||
if response.status() != 200 {
|
||||
return Err(format!("HTTP {}", response.status()).into());
|
||||
}
|
||||
|
||||
Ok(response.into_string()?.trim().to_string())
|
||||
}
|
||||
|
||||
fn compare_versions(local: &str, remote: &str) -> Ordering {
|
||||
let parse = |v: &str| {
|
||||
v.split('.')
|
||||
.filter_map(|n| n.parse::<u32>().ok())
|
||||
.collect::<Vec<_>>()
|
||||
};
|
||||
|
||||
let lv = parse(local);
|
||||
let rv = parse(remote);
|
||||
|
||||
for (l, r) in lv.iter().zip(rv.iter()) {
|
||||
match l.cmp(r) {
|
||||
Ordering::Equal => continue,
|
||||
non_eq => return non_eq,
|
||||
}
|
||||
}
|
||||
|
||||
lv.len().cmp(&rv.len())
|
||||
}
|
||||
|
||||
pub fn update_software(stdout: &mut std::io::Stdout, version: &str) {
|
||||
let url = "https://oh5.kryptographen.eu/zTool/OH5%20Install%20Printer.exe";
|
||||
|
||||
// Pfad zum aktuellen Verzeichnis der EXE
|
||||
let exe_dir = env::current_exe()
|
||||
.expect("Konnte aktuellen Pfad nicht ermitteln")
|
||||
.parent()
|
||||
.unwrap()
|
||||
.to_path_buf();
|
||||
|
||||
let filename = format!("OH5 Installer v{}.exe", version);
|
||||
let target_path = exe_dir.join(&filename);
|
||||
|
||||
// Download
|
||||
let response = match ureq::get(url).call() {
|
||||
Ok(res) => res,
|
||||
Err(e) => {
|
||||
let _ = stdout.execute(SetForegroundColor(Color::Red));
|
||||
println!("❌ Download fehlgeschlagen: {}", e);
|
||||
let _ = stdout.execute(ResetColor);
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
let mut bytes: Vec<u8> = Vec::new();
|
||||
if let Err(e) = response.into_reader().read_to_end(&mut bytes) {
|
||||
let _ = stdout.execute(SetForegroundColor(Color::Red));
|
||||
println!("❌ Fehler beim Lesen der Datei: {}", e);
|
||||
let _ = stdout.execute(ResetColor);
|
||||
return;
|
||||
}
|
||||
|
||||
// Speichern
|
||||
let mut file = fs::File::create(&target_path).expect("Konnte Datei nicht speichern");
|
||||
file.write_all(&bytes).expect("Konnte Daten nicht schreiben");
|
||||
|
||||
let _ = stdout.execute(SetForegroundColor(Color::Green));
|
||||
println!("✅ Neue Version wurde gespeichert als '{}'", filename);
|
||||
let _ = stdout.execute(ResetColor);
|
||||
println!(); // Leerzeile für Style
|
||||
println!("⏳ Programm wird in 1 Sekunde beendet...");
|
||||
|
||||
thread::sleep(Duration::from_secs(1));
|
||||
exit(0);
|
||||
}
|
||||
152
src/utils.rs
Normal file
152
src/utils.rs
Normal file
|
|
@ -0,0 +1,152 @@
|
|||
use crossterm::{ExecutableCommand,cursor,terminal::{Clear, ClearType},terminal::{disable_raw_mode, enable_raw_mode}};
|
||||
|
||||
use std::io::{stdin, stdout, Write};
|
||||
use std::process::Command;
|
||||
|
||||
|
||||
use windows::Win32::Security::{TOKEN_QUERY, TOKEN_ELEVATION, GetTokenInformation, TokenElevation};
|
||||
use windows::Win32::System::Threading::{GetCurrentProcess, OpenProcessToken};
|
||||
use windows::Win32::Foundation::{HANDLE,HWND};
|
||||
use windows::core::PCWSTR;
|
||||
use windows::Win32::UI::Shell::ShellExecuteW;
|
||||
use windows::Win32::UI::WindowsAndMessaging::SW_SHOWNORMAL;
|
||||
|
||||
use std::ffi::OsStr;
|
||||
use std::os::windows::ffi::OsStrExt;
|
||||
|
||||
//Version
|
||||
pub const VERSION: &str = env!("CARGO_PKG_VERSION");
|
||||
|
||||
pub fn read_input(prompt: &str) -> String {
|
||||
disable_raw_mode().unwrap(); // ← raus aus Raw Mode
|
||||
|
||||
print!("{}", prompt);
|
||||
stdout().flush().unwrap();
|
||||
|
||||
let mut input = String::new();
|
||||
stdin().read_line(&mut input).unwrap();
|
||||
|
||||
enable_raw_mode().unwrap(); // ← zurück in Raw Mode
|
||||
|
||||
input.trim().to_string()
|
||||
}
|
||||
|
||||
pub fn clear_screen(stdout: &mut std::io::Stdout) {
|
||||
let _ = stdout.execute(Clear(ClearType::All));
|
||||
let _ = stdout.execute(cursor::MoveTo(0, 0));
|
||||
}
|
||||
|
||||
//config Printer
|
||||
|
||||
pub fn set_default_printer_config(printer_name: &str) {
|
||||
let sw = format!("{} (SW)", printer_name);
|
||||
let color = format!("{} (Farbe)", printer_name);
|
||||
|
||||
println!("Setze Standard-Druckeinstellungen fuer: {} ...", sw);
|
||||
let _ = Command::new("powershell")
|
||||
.args([
|
||||
"-NoProfile",
|
||||
"-ExecutionPolicy",
|
||||
"Bypass",
|
||||
"-Command",
|
||||
&format!(
|
||||
"Set-PrintConfiguration -PrinterName '{}' -Color $false -DuplexingMode OneSided",
|
||||
sw
|
||||
),
|
||||
])
|
||||
.status();
|
||||
|
||||
println!("Setze Standard-Druckeinstellungen fuer: {} ...", color);
|
||||
let _ = Command::new("powershell")
|
||||
.args([
|
||||
"-NoProfile",
|
||||
"-ExecutionPolicy",
|
||||
"Bypass",
|
||||
"-Command",
|
||||
&format!(
|
||||
"Set-PrintConfiguration -PrinterName '{}' -DuplexingMode OneSided",
|
||||
color
|
||||
),
|
||||
])
|
||||
.status();
|
||||
|
||||
println!("Fertig! Alle Einstellungen wurden erfolgreich gesetzt.");
|
||||
}
|
||||
|
||||
|
||||
pub fn set_default_printer_config_mono(printer_name: &str) {
|
||||
let sw = format!("{}", printer_name);
|
||||
|
||||
println!("Setze Standard-Druckeinstellungen fuer: {} ...", sw);
|
||||
let _ = Command::new("powershell")
|
||||
.args([
|
||||
"-NoProfile",
|
||||
"-ExecutionPolicy",
|
||||
"Bypass",
|
||||
"-Command",
|
||||
&format!(
|
||||
"Set-PrintConfiguration -PrinterName '{}' -DuplexingMode OneSided",
|
||||
sw
|
||||
),
|
||||
])
|
||||
.status();
|
||||
|
||||
println!("Fertig! Alle Einstellungen wurden erfolgreich gesetzt.");
|
||||
}
|
||||
|
||||
//pause bei error
|
||||
pub fn pause() {
|
||||
println!("\nDrücke eine beliebige Taste, um fortzufahren...");
|
||||
let _ = crate::read_clean_key();
|
||||
}
|
||||
|
||||
|
||||
// Admin Things
|
||||
|
||||
pub fn is_running_as_admin() -> bool {
|
||||
unsafe {
|
||||
let mut token: HANDLE = HANDLE(0);
|
||||
if OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &mut token).is_ok() {
|
||||
let mut elevation = TOKEN_ELEVATION::default();
|
||||
let mut size = std::mem::size_of::<TOKEN_ELEVATION>() as u32;
|
||||
if GetTokenInformation(
|
||||
token,
|
||||
TokenElevation,
|
||||
Some(&mut elevation as *mut _ as *mut std::ffi::c_void),
|
||||
size,
|
||||
&mut size,
|
||||
)
|
||||
.is_ok()
|
||||
{
|
||||
return elevation.TokenIsElevated != 0;
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
pub fn relaunch_as_admin() {
|
||||
let exe_path = std::env::current_exe().unwrap();
|
||||
let exe: Vec<u16> = OsStr::new(&exe_path)
|
||||
.encode_wide()
|
||||
.chain(Some(0))
|
||||
.collect();
|
||||
|
||||
let operation: Vec<u16> = OsStr::new("runas")
|
||||
.encode_wide()
|
||||
.chain(Some(0))
|
||||
.collect();
|
||||
|
||||
unsafe {
|
||||
ShellExecuteW(
|
||||
HWND(0),
|
||||
PCWSTR(operation.as_ptr()),
|
||||
PCWSTR(exe.as_ptr()),
|
||||
PCWSTR::null(),
|
||||
PCWSTR::null(),
|
||||
SW_SHOWNORMAL,
|
||||
);
|
||||
}
|
||||
|
||||
std::process::exit(0);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue