mirror of
https://bitbucket.org/cjdskunkworks/lynxastrodewcontroller.git
synced 2026-05-03 09:18:51 +00:00
Version 1 of the LynxAstro.DewController.Switch driver
This commit is contained in:
+222
@@ -0,0 +1,222 @@
|
||||
## Ignore Visual Studio temporary files, build results, and
|
||||
## files generated by popular Visual Studio add-ons.
|
||||
|
||||
# User-specific files
|
||||
*.suo
|
||||
*.user
|
||||
*.userosscache
|
||||
*.sln.docstates
|
||||
|
||||
# User-specific files (MonoDevelop/Xamarin Studio)
|
||||
*.userprefs
|
||||
|
||||
# Build results
|
||||
[Dd]ebug/
|
||||
[Dd]ebugPublic/
|
||||
[Rr]elease/
|
||||
[Rr]eleases/
|
||||
x64/
|
||||
x86/
|
||||
build/
|
||||
bld/
|
||||
[Bb]in/
|
||||
[Oo]bj/
|
||||
|
||||
# Visual Studio 2015 cache/options directory
|
||||
.vs/
|
||||
# Uncomment if you have tasks that create the project's static files in wwwroot
|
||||
#wwwroot/
|
||||
|
||||
# MSTest test Results
|
||||
[Tt]est[Rr]esult*/
|
||||
[Bb]uild[Ll]og.*
|
||||
|
||||
# NUNIT
|
||||
*.VisualState.xml
|
||||
TestResult.xml
|
||||
|
||||
# Build Results of an ATL Project
|
||||
[Dd]ebugPS/
|
||||
[Rr]eleasePS/
|
||||
dlldata.c
|
||||
|
||||
# DNX
|
||||
project.lock.json
|
||||
artifacts/
|
||||
|
||||
*_i.c
|
||||
*_p.c
|
||||
*_i.h
|
||||
*.ilk
|
||||
*.meta
|
||||
*.obj
|
||||
*.pch
|
||||
*.pdb
|
||||
*.pgc
|
||||
*.pgd
|
||||
*.rsp
|
||||
*.sbr
|
||||
*.tlb
|
||||
*.tli
|
||||
*.tlh
|
||||
*.tmp
|
||||
*.tmp_proj
|
||||
*.log
|
||||
*.vspscc
|
||||
*.vssscc
|
||||
.builds
|
||||
*.pidb
|
||||
*.svclog
|
||||
*.scc
|
||||
|
||||
# Chutzpah Test files
|
||||
_Chutzpah*
|
||||
|
||||
# Visual C++ cache files
|
||||
ipch/
|
||||
*.aps
|
||||
*.ncb
|
||||
*.opensdf
|
||||
*.sdf
|
||||
*.cachefile
|
||||
|
||||
# Visual Studio profiler
|
||||
*.psess
|
||||
*.vsp
|
||||
*.vspx
|
||||
|
||||
# TFS 2012 Local Workspace
|
||||
$tf/
|
||||
|
||||
# Guidance Automation Toolkit
|
||||
*.gpState
|
||||
|
||||
# ReSharper is a .NET coding add-in
|
||||
_ReSharper*/
|
||||
*.[Rr]e[Ss]harper
|
||||
*.DotSettings.user
|
||||
|
||||
# JustCode is a .NET coding add-in
|
||||
.JustCode
|
||||
|
||||
# TeamCity is a build add-in
|
||||
_TeamCity*
|
||||
|
||||
# DotCover is a Code Coverage Tool
|
||||
*.dotCover
|
||||
|
||||
# NCrunch
|
||||
_NCrunch_*
|
||||
.*crunch*.local.xml
|
||||
nCrunchTemp_*
|
||||
*ncrunchsolution.user
|
||||
|
||||
# MightyMoose
|
||||
*.mm.*
|
||||
AutoTest.Net/
|
||||
|
||||
# Web workbench (sass)
|
||||
.sass-cache/
|
||||
|
||||
# Installshield output folder
|
||||
[Ee]xpress/
|
||||
|
||||
# DocProject is a documentation generator add-in
|
||||
DocProject/buildhelp/
|
||||
DocProject/Help/*.HxT
|
||||
DocProject/Help/*.HxC
|
||||
DocProject/Help/*.hhc
|
||||
DocProject/Help/*.hhk
|
||||
DocProject/Help/*.hhp
|
||||
DocProject/Help/Html2
|
||||
DocProject/Help/html
|
||||
|
||||
# Click-Once directory
|
||||
publish/
|
||||
|
||||
# Publish Web Output
|
||||
*.[Pp]ublish.xml
|
||||
*.azurePubxml
|
||||
# TODO: Comment the next line if you want to checkin your web deploy settings
|
||||
# but database connection strings (with potential passwords) will be unencrypted
|
||||
*.pubxml
|
||||
*.publishproj
|
||||
|
||||
# NuGet Packages
|
||||
*.nupkg
|
||||
# The packages folder can be ignored because of Package Restore
|
||||
**/packages/*
|
||||
# except build/, which is used as an MSBuild target.
|
||||
!**/packages/build/
|
||||
# Uncomment if necessary however generally it will be regenerated when needed
|
||||
#!**/packages/repositories.config
|
||||
|
||||
# Windows Azure Build Output
|
||||
csx/
|
||||
*.build.csdef
|
||||
|
||||
# Windows Store app package directory
|
||||
AppPackages/
|
||||
|
||||
# Visual Studio cache files
|
||||
# files ending in .cache can be ignored
|
||||
*.[Cc]ache
|
||||
# but keep track of directories ending in .cache
|
||||
!*.[Cc]ache/
|
||||
|
||||
# Others
|
||||
ClientBin/
|
||||
[Ss]tyle[Cc]op.*
|
||||
~$*
|
||||
*~
|
||||
*.dbmdl
|
||||
*.dbproj.schemaview
|
||||
*.pfx
|
||||
*.publishsettings
|
||||
node_modules/
|
||||
orleans.codegen.cs
|
||||
|
||||
# RIA/Silverlight projects
|
||||
Generated_Code/
|
||||
|
||||
# Backup & report files from converting an old project file
|
||||
# to a newer Visual Studio version. Backup files are not needed,
|
||||
# because we have git ;-)
|
||||
_UpgradeReport_Files/
|
||||
Backup*/
|
||||
UpgradeLog*.XML
|
||||
UpgradeLog*.htm
|
||||
|
||||
# SQL Server files
|
||||
*.mdf
|
||||
*.ldf
|
||||
|
||||
# Business Intelligence projects
|
||||
*.rdl.data
|
||||
*.bim.layout
|
||||
*.bim_*.settings
|
||||
|
||||
# Microsoft Fakes
|
||||
FakesAssemblies/
|
||||
|
||||
# Node.js Tools for Visual Studio
|
||||
.ntvs_analysis.dat
|
||||
|
||||
# Visual Studio 6 build log
|
||||
*.plg
|
||||
|
||||
# Visual Studio 6 workspace options file
|
||||
*.opt
|
||||
|
||||
# Visual Studio LightSwitch build output
|
||||
**/*.HTMLClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/ModelManifest.xml
|
||||
**/*.Server/GeneratedArtifacts
|
||||
**/*.Server/ModelManifest.xml
|
||||
_Pvt_Extensions
|
||||
|
||||
# nCrunch items
|
||||
*.ncrunchsolution
|
||||
*.DotSettings
|
||||
*.ncrunchproject
|
||||
@@ -0,0 +1,349 @@
|
||||
Conform Report Hash (V1): 5A431672269EA8E8AC10FDAB37C418D8AC06BDA9D013E7B57D8D46B4494A80B03209D002BC052DA6FDDC36320956A15ECA4AA1ED59B40D7BE27F35854C5B8CAF
|
||||
|
||||
|
||||
ConformanceCheck ASCOM Device Conformance Checker Version 6.5.7500.22514, Build time: 14/07/2020 13:30:28
|
||||
ConformanceCheck Running on: ASCOM Platform 6.5 SP1 6.5.1.3234
|
||||
|
||||
ConformanceCheck Driver ProgID: ASCOM.LynxAstro.DewController.Switch
|
||||
|
||||
Error handling
|
||||
Error number for "Not Implemented" is: 80040400
|
||||
Error number for "Invalid Value 1" is: 80040405
|
||||
Error number for "Value Not Set 1" is: 80040402
|
||||
Error number for "Value Not Set 2" is: 80040403
|
||||
Error messages will not be interpreted to infer state.
|
||||
|
||||
19:28:43.452 Driver Access Checks OK
|
||||
19:28:44.135 AccessChecks OK Successfully created driver using late binding
|
||||
19:28:44.176 AccessChecks OK Successfully connected using late binding
|
||||
19:28:44.179 AccessChecks INFO The driver is a .NET object
|
||||
19:28:44.183 AccessChecks INFO The AssemblyQualifiedName is: ASCOM.LynxAstro.DewController.Switch, ASCOM.LynxAstro.DewController.Switch,
|
||||
19:28:44.186 AccessChecks INFO The driver implements interface: ASCOM.DeviceInterface.ISwitchV2
|
||||
19:28:44.850 AccessChecks INFO Device does not expose interface ISwitch
|
||||
19:28:44.876 AccessChecks INFO Device exposes interface ISwitchV2
|
||||
19:28:45.546 AccessChecks OK Successfully created driver using driver access toolkit
|
||||
19:28:45.574 AccessChecks OK Successfully connected using driver access toolkit
|
||||
|
||||
Conform is using ASCOM.DriverAccess.Switch to get a Switch object
|
||||
19:28:45.612 ConformanceCheck OK Driver instance created successfully
|
||||
19:28:45.700 ConformanceCheck OK Connected OK
|
||||
|
||||
Common Driver Methods
|
||||
19:28:45.750 InterfaceVersion OK 2
|
||||
19:28:45.790 Connected OK True
|
||||
19:28:45.836 Description OK ASCOM Switch Driver for LynxAstro.DewController
|
||||
19:28:45.883 DriverInfo OK ASCOM Switch Driver for LynxAstro.DewController .net driver. Version: 6.5.1.0
|
||||
19:28:45.928 DriverVersion OK 6.5.1.0
|
||||
19:28:45.975 Name OK LynxAstro.DewController
|
||||
19:28:46.022 CommandString INFO Conform cannot test the CommandString method
|
||||
19:28:46.026 CommandBlind INFO Conform cannot test the CommandBlind method
|
||||
19:28:46.031 CommandBool INFO Conform cannot test the CommandBool method
|
||||
19:28:46.036 Action INFO Conform cannot test the Action method
|
||||
19:28:46.041 SupportedActions OK Driver returned an empty action list
|
||||
|
||||
Properties
|
||||
19:28:46.198 MaxSwitch OK 4
|
||||
|
||||
Methods
|
||||
19:28:46.314 SwitchNumber OK Switch device threw an InvalidOperationException when a switch ID below 0 was used in method: CanWrite
|
||||
19:28:46.320 SwitchNumber OK Switch device threw an InvalidOperationException when a switch ID above MaxSwitch was used in method: CanWrite
|
||||
19:28:46.326 SwitchNumber OK Switch device threw an InvalidOperationException when a switch ID below 0 was used in method: GetSwitch
|
||||
19:28:46.331 SwitchNumber OK Switch device threw an InvalidOperationException when a switch ID above MaxSwitch was used in method: GetSwitch
|
||||
19:28:46.337 SwitchNumber OK Switch device threw an InvalidOperationException when a switch ID below 0 was used in method: GetSwitchDescription
|
||||
19:28:46.343 SwitchNumber OK Switch device threw an InvalidOperationException when a switch ID above MaxSwitch was used in method: GetSwitchDescription
|
||||
19:28:46.350 SwitchNumber OK Switch device threw an InvalidOperationException when a switch ID below 0 was used in method: GetSwitchName
|
||||
19:28:46.356 SwitchNumber OK Switch device threw an InvalidOperationException when a switch ID above MaxSwitch was used in method: GetSwitchName
|
||||
19:28:46.362 SwitchNumber OK Switch device threw an InvalidOperationException when a switch ID below 0 was used in method: GetSwitchValue
|
||||
19:28:46.368 SwitchNumber OK Switch device threw an InvalidOperationException when a switch ID above MaxSwitch was used in method: GetSwitchValue
|
||||
19:28:46.374 SwitchNumber OK Switch device threw an InvalidOperationException when a switch ID below 0 was used in method: MaxSwitchValue
|
||||
19:28:46.380 SwitchNumber OK Switch device threw an InvalidOperationException when a switch ID above MaxSwitch was used in method: MaxSwitchValue
|
||||
19:28:46.387 SwitchNumber OK Switch device threw an InvalidOperationException when a switch ID below 0 was used in method: MinSwitchValue
|
||||
19:28:46.393 SwitchNumber OK Switch device threw an InvalidOperationException when a switch ID above MaxSwitch was used in method: MinSwitchValue
|
||||
19:28:46.400 SwitchNumber OK Switch device threw an InvalidOperationException when a switch ID below 0 was used in method: SetSwitch
|
||||
19:28:46.406 SwitchNumber OK Switch device threw an InvalidOperationException when a switch ID above MaxSwitch was used in method: SetSwitch
|
||||
19:28:46.414 SwitchNumber OK Switch device threw an InvalidOperationException when a switch ID below 0 was used in method: SetSwitchValue
|
||||
19:28:46.420 SwitchNumber OK Switch device threw an InvalidOperationException when a switch ID above MaxSwitch was used in method: SetSwitchValue
|
||||
19:28:46.427 SwitchNumber OK Switch device threw an InvalidOperationException when a switch ID below 0 was used in method: SwitchStep
|
||||
19:28:46.434 SwitchNumber OK Switch device threw an InvalidOperationException when a switch ID above MaxSwitch was used in method: SwitchStep
|
||||
19:28:49.553 GetSwitchName OK Found switch 0
|
||||
19:28:49.559 GetSwitchName OK Name:
|
||||
19:28:49.566 GetSwitchDescription OK Description: Control Knob
|
||||
19:28:49.572 MinSwitchValue OK Minimum: 0
|
||||
19:28:49.579 MaxSwitchValue OK Maximum: 1023
|
||||
19:28:49.586 SwitchStep OK Step size: 1
|
||||
19:28:49.593 SwitchStep OK Step size is greater than zero
|
||||
19:28:49.600 SwitchStep OK Step size is less than the range of possible values
|
||||
19:28:49.607 SwitchStep OK The switch range is an integer multiple of the step size.
|
||||
19:28:49.615 CanWrite OK CanWrite: True
|
||||
19:28:49.623 GetSwitch OK False
|
||||
19:28:49.633 GetSwitchValue OK 0
|
||||
19:28:49.690 SetSwitch OK GetSwitch returned False after SetSwitch(False)
|
||||
19:28:49.699 SetSwitch OK GetSwitchValue returned MINIMUM_VALUE after SetSwitch(False)
|
||||
19:28:49.799 SetSwitch OK GetSwitch read True after SetSwitch(True)
|
||||
19:28:49.809 SetSwitch OK GetSwitchValue returned MAXIMUM_VALUE after SetSwitch(True)
|
||||
19:28:49.953 SetSwitchValue OK GetSwitch returned False after SetSwitchValue(MINIMUM_VALUE)
|
||||
19:28:49.961 SetSwitchValue OK GetSwitchValue returned MINIMUM_VALUE after SetSwitchValue(MINIMUM_VALUE)
|
||||
19:28:50.014 SetSwitchValue OK Switch threw an InvalidOperationException when a value below SwitchMinimum was set: -1
|
||||
19:28:50.155 SetSwitchValue OK GetSwitch returned True after SetSwitchValue(MAXIMUM_VALUE)
|
||||
19:28:50.165 SetSwitchValue OK GetSwitchValue returned MAXIMUM_VALUE after SetSwitchValue(MAXIMUM_VALUE)
|
||||
19:28:50.215 SetSwitchValue OK Switch threw an InvalidOperationException when a value above SwitchMaximum was set: 1024
|
||||
19:28:50.309 SetSwitchValue INFO Testing with steps that are 0% offset from integer SwitchStep values
|
||||
19:28:50.402 SetSwitchValue Offset: 0% OK Set and read match: 0
|
||||
19:28:50.572 SetSwitchValue Offset: 0% OK Set and read match: 102
|
||||
19:28:50.743 SetSwitchValue Offset: 0% OK Set and read match: 205
|
||||
19:28:50.913 SetSwitchValue Offset: 0% OK Set and read match: 307
|
||||
19:28:51.083 SetSwitchValue Offset: 0% OK Set and read match: 409
|
||||
19:28:51.253 SetSwitchValue Offset: 0% OK Set and read match: 512
|
||||
19:28:51.423 SetSwitchValue Offset: 0% OK Set and read match: 614
|
||||
19:28:51.594 SetSwitchValue Offset: 0% OK Set and read match: 716
|
||||
19:28:51.764 SetSwitchValue Offset: 0% OK Set and read match: 818
|
||||
19:28:51.934 SetSwitchValue Offset: 0% OK Set and read match: 921
|
||||
19:28:52.105 SetSwitchValue Offset: 0% OK Set and read match: 1023
|
||||
19:28:52.226 SetSwitchValue INFO Testing with steps that are 25% offset from integer SwitchStep values
|
||||
19:28:52.320 SetSwitchValue Offset: 25% INFO Set/Read differ by 20-30% of SwitchStep. Set: 0.25, Read: 0
|
||||
19:28:52.491 SetSwitchValue Offset: 25% INFO Set/Read differ by 20-30% of SwitchStep. Set: 102.25, Read: 102
|
||||
19:28:52.661 SetSwitchValue Offset: 25% INFO Set/Read differ by 20-30% of SwitchStep. Set: 205.25, Read: 205
|
||||
19:28:52.831 SetSwitchValue Offset: 25% INFO Set/Read differ by 20-30% of SwitchStep. Set: 307.25, Read: 307
|
||||
19:28:53.002 SetSwitchValue Offset: 25% INFO Set/Read differ by 20-30% of SwitchStep. Set: 409.25, Read: 409
|
||||
19:28:53.172 SetSwitchValue Offset: 25% INFO Set/Read differ by 20-30% of SwitchStep. Set: 512.25, Read: 512
|
||||
19:28:53.342 SetSwitchValue Offset: 25% INFO Set/Read differ by 20-30% of SwitchStep. Set: 614.25, Read: 614
|
||||
19:28:53.512 SetSwitchValue Offset: 25% INFO Set/Read differ by 20-30% of SwitchStep. Set: 716.25, Read: 716
|
||||
19:28:53.682 SetSwitchValue Offset: 25% INFO Set/Read differ by 20-30% of SwitchStep. Set: 818.25, Read: 818
|
||||
19:28:53.853 SetSwitchValue Offset: 25% INFO Set/Read differ by 20-30% of SwitchStep. Set: 921.25, Read: 921
|
||||
19:28:54.005 SetSwitchValue INFO Testing with steps that are 50% offset from integer SwitchStep values
|
||||
19:28:54.100 SetSwitchValue Offset: 50% INFO Set/Read differ by 40-50% of SwitchStep. Set: 0.5, Read: 1
|
||||
19:28:54.270 SetSwitchValue Offset: 50% INFO Set/Read differ by 40-50% of SwitchStep. Set: 102.5, Read: 103
|
||||
19:28:54.440 SetSwitchValue Offset: 50% INFO Set/Read differ by 40-50% of SwitchStep. Set: 205.5, Read: 206
|
||||
19:28:54.611 SetSwitchValue Offset: 50% INFO Set/Read differ by 40-50% of SwitchStep. Set: 307.5, Read: 308
|
||||
19:28:54.781 SetSwitchValue Offset: 50% INFO Set/Read differ by 40-50% of SwitchStep. Set: 409.5, Read: 410
|
||||
19:28:54.951 SetSwitchValue Offset: 50% INFO Set/Read differ by 40-50% of SwitchStep. Set: 512.5, Read: 513
|
||||
19:28:55.121 SetSwitchValue Offset: 50% INFO Set/Read differ by 40-50% of SwitchStep. Set: 614.5, Read: 615
|
||||
19:28:55.291 SetSwitchValue Offset: 50% INFO Set/Read differ by 40-50% of SwitchStep. Set: 716.5, Read: 717
|
||||
19:28:55.462 SetSwitchValue Offset: 50% INFO Set/Read differ by 40-50% of SwitchStep. Set: 818.5, Read: 819
|
||||
19:28:55.632 SetSwitchValue Offset: 50% INFO Set/Read differ by 40-50% of SwitchStep. Set: 921.5, Read: 922
|
||||
19:28:55.785 SetSwitchValue INFO Testing with steps that are 75% offset from integer SwitchStep values
|
||||
19:28:55.879 SetSwitchValue Offset: 75% INFO Set/Read differ by 20-30% of SwitchStep. Set: 0.75, Read: 1
|
||||
19:28:56.050 SetSwitchValue Offset: 75% INFO Set/Read differ by 20-30% of SwitchStep. Set: 102.75, Read: 103
|
||||
19:28:56.220 SetSwitchValue Offset: 75% INFO Set/Read differ by 20-30% of SwitchStep. Set: 205.75, Read: 206
|
||||
19:28:56.390 SetSwitchValue Offset: 75% INFO Set/Read differ by 20-30% of SwitchStep. Set: 307.75, Read: 308
|
||||
19:28:56.561 SetSwitchValue Offset: 75% INFO Set/Read differ by 20-30% of SwitchStep. Set: 409.75, Read: 410
|
||||
19:28:56.731 SetSwitchValue Offset: 75% INFO Set/Read differ by 20-30% of SwitchStep. Set: 512.75, Read: 513
|
||||
19:28:56.901 SetSwitchValue Offset: 75% INFO Set/Read differ by 20-30% of SwitchStep. Set: 614.75, Read: 615
|
||||
19:28:57.071 SetSwitchValue Offset: 75% INFO Set/Read differ by 20-30% of SwitchStep. Set: 716.75, Read: 717
|
||||
19:28:57.241 SetSwitchValue Offset: 75% INFO Set/Read differ by 20-30% of SwitchStep. Set: 818.75, Read: 819
|
||||
19:28:57.396 SetSwitchValue Offset: 75% INFO Set/Read differ by 20-30% of SwitchStep. Set: 921.75, Read: 922
|
||||
19:28:57.551 SetSwitchValue OK Switch has been reset to its original state
|
||||
|
||||
19:28:57.692 GetSwitchName OK Found switch 1
|
||||
19:28:57.700 GetSwitchName OK Name:
|
||||
19:28:57.710 GetSwitchDescription OK Description: Control Knob
|
||||
19:28:57.719 MinSwitchValue OK Minimum: 0
|
||||
19:28:57.729 MaxSwitchValue OK Maximum: 1023
|
||||
19:28:57.738 SwitchStep OK Step size: 1
|
||||
19:28:57.747 SwitchStep OK Step size is greater than zero
|
||||
19:28:57.756 SwitchStep OK Step size is less than the range of possible values
|
||||
19:28:57.766 SwitchStep OK The switch range is an integer multiple of the step size.
|
||||
19:28:57.775 CanWrite OK CanWrite: True
|
||||
19:28:57.786 GetSwitch OK True
|
||||
19:28:57.798 GetSwitchValue OK 470
|
||||
19:28:57.860 SetSwitch OK GetSwitch returned False after SetSwitch(False)
|
||||
19:28:57.871 SetSwitch OK GetSwitchValue returned MINIMUM_VALUE after SetSwitch(False)
|
||||
19:28:58.015 SetSwitch OK GetSwitch read True after SetSwitch(True)
|
||||
19:28:58.030 SetSwitch OK GetSwitchValue returned MAXIMUM_VALUE after SetSwitch(True)
|
||||
19:28:58.216 SetSwitchValue OK GetSwitch returned False after SetSwitchValue(MINIMUM_VALUE)
|
||||
19:28:58.227 SetSwitchValue OK GetSwitchValue returned MINIMUM_VALUE after SetSwitchValue(MINIMUM_VALUE)
|
||||
19:28:58.276 SetSwitchValue OK Switch threw an InvalidOperationException when a value below SwitchMinimum was set: -1
|
||||
19:28:58.417 SetSwitchValue OK GetSwitch returned True after SetSwitchValue(MAXIMUM_VALUE)
|
||||
19:28:58.429 SetSwitchValue OK GetSwitchValue returned MAXIMUM_VALUE after SetSwitchValue(MAXIMUM_VALUE)
|
||||
19:28:58.524 SetSwitchValue OK Switch threw an InvalidOperationException when a value above SwitchMaximum was set: 1024
|
||||
19:28:58.616 SetSwitchValue INFO Testing with steps that are 0% offset from integer SwitchStep values
|
||||
19:28:58.711 SetSwitchValue Offset: 0% OK Set and read match: 0
|
||||
19:28:58.882 SetSwitchValue Offset: 0% OK Set and read match: 102
|
||||
19:28:59.052 SetSwitchValue Offset: 0% OK Set and read match: 205
|
||||
19:28:59.222 SetSwitchValue Offset: 0% OK Set and read match: 307
|
||||
19:28:59.392 SetSwitchValue Offset: 0% OK Set and read match: 409
|
||||
19:28:59.562 SetSwitchValue Offset: 0% OK Set and read match: 512
|
||||
19:28:59.732 SetSwitchValue Offset: 0% OK Set and read match: 614
|
||||
19:28:59.903 SetSwitchValue Offset: 0% OK Set and read match: 716
|
||||
19:29:00.057 SetSwitchValue Offset: 0% OK Set and read match: 818
|
||||
19:29:00.228 SetSwitchValue Offset: 0% OK Set and read match: 921
|
||||
19:29:00.398 SetSwitchValue Offset: 0% OK Set and read match: 1023
|
||||
19:29:00.520 SetSwitchValue INFO Testing with steps that are 25% offset from integer SwitchStep values
|
||||
19:29:00.583 SetSwitchValue Offset: 25% INFO Set/Read differ by 20-30% of SwitchStep. Set: 0.25, Read: 0
|
||||
19:29:00.754 SetSwitchValue Offset: 25% INFO Set/Read differ by 20-30% of SwitchStep. Set: 102.25, Read: 102
|
||||
19:29:00.924 SetSwitchValue Offset: 25% INFO Set/Read differ by 20-30% of SwitchStep. Set: 205.25, Read: 205
|
||||
19:29:01.094 SetSwitchValue Offset: 25% INFO Set/Read differ by 20-30% of SwitchStep. Set: 307.25, Read: 307
|
||||
19:29:01.264 SetSwitchValue Offset: 25% INFO Set/Read differ by 20-30% of SwitchStep. Set: 409.25, Read: 409
|
||||
19:29:01.435 SetSwitchValue Offset: 25% INFO Set/Read differ by 20-30% of SwitchStep. Set: 512.25, Read: 512
|
||||
19:29:01.605 SetSwitchValue Offset: 25% INFO Set/Read differ by 20-30% of SwitchStep. Set: 614.25, Read: 614
|
||||
19:29:01.775 SetSwitchValue Offset: 25% INFO Set/Read differ by 20-30% of SwitchStep. Set: 716.25, Read: 716
|
||||
19:29:01.945 SetSwitchValue Offset: 25% INFO Set/Read differ by 20-30% of SwitchStep. Set: 818.25, Read: 818
|
||||
19:29:02.116 SetSwitchValue Offset: 25% INFO Set/Read differ by 20-30% of SwitchStep. Set: 921.25, Read: 921
|
||||
19:29:02.268 SetSwitchValue INFO Testing with steps that are 50% offset from integer SwitchStep values
|
||||
19:29:02.363 SetSwitchValue Offset: 50% INFO Set/Read differ by >100% of SwitchStep. Set: 0.5, Read: 468
|
||||
19:29:02.533 SetSwitchValue Offset: 50% INFO Set/Read differ by 40-50% of SwitchStep. Set: 102.5, Read: 103
|
||||
19:29:02.703 SetSwitchValue Offset: 50% INFO Set/Read differ by >100% of SwitchStep. Set: 205.5, Read: 475
|
||||
19:29:02.874 SetSwitchValue Offset: 50% INFO Set/Read differ by >100% of SwitchStep. Set: 307.5, Read: 469
|
||||
19:29:03.044 SetSwitchValue Offset: 50% INFO Set/Read differ by 40-50% of SwitchStep. Set: 409.5, Read: 410
|
||||
19:29:03.214 SetSwitchValue Offset: 50% INFO Set/Read differ by 40-50% of SwitchStep. Set: 512.5, Read: 513
|
||||
19:29:03.384 SetSwitchValue Offset: 50% INFO Set/Read differ by 40-50% of SwitchStep. Set: 614.5, Read: 615
|
||||
19:29:03.554 SetSwitchValue Offset: 50% INFO Set/Read differ by 40-50% of SwitchStep. Set: 716.5, Read: 717
|
||||
19:29:03.724 SetSwitchValue Offset: 50% INFO Set/Read differ by 40-50% of SwitchStep. Set: 818.5, Read: 819
|
||||
19:29:03.895 SetSwitchValue Offset: 50% INFO Set/Read differ by 40-50% of SwitchStep. Set: 921.5, Read: 922
|
||||
19:29:04.047 SetSwitchValue INFO Testing with steps that are 75% offset from integer SwitchStep values
|
||||
19:29:04.142 SetSwitchValue Offset: 75% INFO Set/Read differ by 20-30% of SwitchStep. Set: 0.75, Read: 1
|
||||
19:29:04.312 SetSwitchValue Offset: 75% INFO Set/Read differ by 20-30% of SwitchStep. Set: 102.75, Read: 103
|
||||
19:29:04.467 SetSwitchValue Offset: 75% INFO Set/Read differ by 20-30% of SwitchStep. Set: 205.75, Read: 206
|
||||
19:29:04.637 SetSwitchValue Offset: 75% INFO Set/Read differ by 20-30% of SwitchStep. Set: 307.75, Read: 308
|
||||
19:29:04.808 SetSwitchValue Offset: 75% INFO Set/Read differ by 20-30% of SwitchStep. Set: 409.75, Read: 410
|
||||
19:29:04.978 SetSwitchValue Offset: 75% INFO Set/Read differ by 20-30% of SwitchStep. Set: 512.75, Read: 513
|
||||
19:29:05.148 SetSwitchValue Offset: 75% INFO Set/Read differ by 20-30% of SwitchStep. Set: 614.75, Read: 615
|
||||
19:29:05.318 SetSwitchValue Offset: 75% INFO Set/Read differ by 20-30% of SwitchStep. Set: 716.75, Read: 717
|
||||
19:29:05.488 SetSwitchValue Offset: 75% INFO Set/Read differ by 20-30% of SwitchStep. Set: 818.75, Read: 819
|
||||
19:29:05.658 SetSwitchValue Offset: 75% INFO Set/Read differ by 20-30% of SwitchStep. Set: 921.75, Read: 922
|
||||
19:29:05.814 SetSwitchValue OK Switch has been reset to its original state
|
||||
|
||||
19:29:05.954 GetSwitchName OK Found switch 2
|
||||
19:29:05.963 GetSwitchName OK Name:
|
||||
19:29:05.972 GetSwitchDescription OK Description: Control Knob
|
||||
19:29:05.981 MinSwitchValue OK Minimum: 0
|
||||
19:29:05.991 MaxSwitchValue OK Maximum: 1023
|
||||
19:29:06.001 SwitchStep OK Step size: 1
|
||||
19:29:06.010 SwitchStep OK Step size is greater than zero
|
||||
19:29:06.020 SwitchStep OK Step size is less than the range of possible values
|
||||
19:29:06.029 SwitchStep OK The switch range is an integer multiple of the step size.
|
||||
19:29:06.039 CanWrite OK CanWrite: True
|
||||
19:29:06.051 GetSwitch OK False
|
||||
19:29:06.061 GetSwitchValue OK 0
|
||||
19:29:06.122 SetSwitch OK GetSwitch returned False after SetSwitch(False)
|
||||
19:29:06.133 SetSwitch OK GetSwitchValue returned MINIMUM_VALUE after SetSwitch(False)
|
||||
19:29:06.231 SetSwitch OK GetSwitch read True after SetSwitch(True)
|
||||
19:29:06.244 SetSwitch OK GetSwitchValue returned MAXIMUM_VALUE after SetSwitch(True)
|
||||
19:29:06.431 SetSwitchValue OK GetSwitch returned False after SetSwitchValue(MINIMUM_VALUE)
|
||||
19:29:06.442 SetSwitchValue OK GetSwitchValue returned MINIMUM_VALUE after SetSwitchValue(MINIMUM_VALUE)
|
||||
19:29:06.492 SetSwitchValue OK Switch threw an InvalidOperationException when a value below SwitchMinimum was set: -1
|
||||
19:29:06.634 SetSwitchValue OK GetSwitch returned True after SetSwitchValue(MAXIMUM_VALUE)
|
||||
19:29:06.646 SetSwitchValue OK GetSwitchValue returned MAXIMUM_VALUE after SetSwitchValue(MAXIMUM_VALUE)
|
||||
19:29:06.740 SetSwitchValue OK Switch threw an InvalidOperationException when a value above SwitchMaximum was set: 1024
|
||||
19:29:06.832 SetSwitchValue INFO Testing with steps that are 0% offset from integer SwitchStep values
|
||||
19:29:06.896 SetSwitchValue Offset: 0% OK Set and read match: 0
|
||||
19:29:07.066 SetSwitchValue Offset: 0% OK Set and read match: 102
|
||||
19:29:07.237 SetSwitchValue Offset: 0% OK Set and read match: 205
|
||||
19:29:07.407 SetSwitchValue Offset: 0% OK Set and read match: 307
|
||||
19:29:07.577 SetSwitchValue Offset: 0% OK Set and read match: 409
|
||||
19:29:07.747 SetSwitchValue Offset: 0% OK Set and read match: 512
|
||||
19:29:07.917 SetSwitchValue Offset: 0% OK Set and read match: 614
|
||||
19:29:08.088 SetSwitchValue Offset: 0% OK Set and read match: 716
|
||||
19:29:08.258 SetSwitchValue Offset: 0% OK Set and read match: 818
|
||||
19:29:08.428 SetSwitchValue Offset: 0% OK Set and read match: 921
|
||||
19:29:08.599 SetSwitchValue Offset: 0% OK Set and read match: 1023
|
||||
19:29:08.720 SetSwitchValue INFO Testing with steps that are 25% offset from integer SwitchStep values
|
||||
19:29:08.814 SetSwitchValue Offset: 25% INFO Set/Read differ by 20-30% of SwitchStep. Set: 0.25, Read: 0
|
||||
19:29:08.985 SetSwitchValue Offset: 25% INFO Set/Read differ by 20-30% of SwitchStep. Set: 102.25, Read: 102
|
||||
19:29:09.155 SetSwitchValue Offset: 25% INFO Set/Read differ by 20-30% of SwitchStep. Set: 205.25, Read: 205
|
||||
19:29:09.325 SetSwitchValue Offset: 25% INFO Set/Read differ by 20-30% of SwitchStep. Set: 307.25, Read: 307
|
||||
19:29:09.481 SetSwitchValue Offset: 25% INFO Set/Read differ by 20-30% of SwitchStep. Set: 409.25, Read: 409
|
||||
19:29:09.650 SetSwitchValue Offset: 25% INFO Set/Read differ by 20-30% of SwitchStep. Set: 512.25, Read: 512
|
||||
19:29:09.821 SetSwitchValue Offset: 25% INFO Set/Read differ by 20-30% of SwitchStep. Set: 614.25, Read: 614
|
||||
19:29:09.991 SetSwitchValue Offset: 25% INFO Set/Read differ by 20-30% of SwitchStep. Set: 716.25, Read: 716
|
||||
19:29:10.161 SetSwitchValue Offset: 25% INFO Set/Read differ by 20-30% of SwitchStep. Set: 818.25, Read: 818
|
||||
19:29:10.331 SetSwitchValue Offset: 25% INFO Set/Read differ by 20-30% of SwitchStep. Set: 921.25, Read: 921
|
||||
19:29:10.484 SetSwitchValue INFO Testing with steps that are 50% offset from integer SwitchStep values
|
||||
19:29:10.578 SetSwitchValue Offset: 50% INFO Set/Read differ by 40-50% of SwitchStep. Set: 0.5, Read: 1
|
||||
19:29:10.749 SetSwitchValue Offset: 50% INFO Set/Read differ by 40-50% of SwitchStep. Set: 102.5, Read: 103
|
||||
19:29:10.921 SetSwitchValue Offset: 50% INFO Set/Read differ by 40-50% of SwitchStep. Set: 205.5, Read: 206
|
||||
19:29:11.059 SetSwitchValue Offset: 50% INFO Set/Read differ by 40-50% of SwitchStep. Set: 307.5, Read: 308
|
||||
19:29:11.229 SetSwitchValue Offset: 50% INFO Set/Read differ by 40-50% of SwitchStep. Set: 409.5, Read: 410
|
||||
19:29:11.400 SetSwitchValue Offset: 50% INFO Set/Read differ by 40-50% of SwitchStep. Set: 512.5, Read: 513
|
||||
19:29:11.569 SetSwitchValue Offset: 50% INFO Set/Read differ by 40-50% of SwitchStep. Set: 614.5, Read: 615
|
||||
19:29:11.739 SetSwitchValue Offset: 50% INFO Set/Read differ by 40-50% of SwitchStep. Set: 716.5, Read: 717
|
||||
19:29:11.910 SetSwitchValue Offset: 50% INFO Set/Read differ by 40-50% of SwitchStep. Set: 818.5, Read: 819
|
||||
19:29:12.080 SetSwitchValue Offset: 50% INFO Set/Read differ by 40-50% of SwitchStep. Set: 921.5, Read: 922
|
||||
19:29:12.233 SetSwitchValue INFO Testing with steps that are 75% offset from integer SwitchStep values
|
||||
19:29:12.327 SetSwitchValue Offset: 75% INFO Set/Read differ by 20-30% of SwitchStep. Set: 0.75, Read: 1
|
||||
19:29:12.497 SetSwitchValue Offset: 75% INFO Set/Read differ by 20-30% of SwitchStep. Set: 102.75, Read: 103
|
||||
19:29:12.668 SetSwitchValue Offset: 75% INFO Set/Read differ by 20-30% of SwitchStep. Set: 205.75, Read: 206
|
||||
19:29:12.838 SetSwitchValue Offset: 75% INFO Set/Read differ by 20-30% of SwitchStep. Set: 307.75, Read: 308
|
||||
19:29:13.008 SetSwitchValue Offset: 75% INFO Set/Read differ by 20-30% of SwitchStep. Set: 409.75, Read: 410
|
||||
19:29:13.178 SetSwitchValue Offset: 75% INFO Set/Read differ by 20-30% of SwitchStep. Set: 512.75, Read: 513
|
||||
19:29:13.349 SetSwitchValue Offset: 75% INFO Set/Read differ by 20-30% of SwitchStep. Set: 614.75, Read: 615
|
||||
19:29:13.519 SetSwitchValue Offset: 75% INFO Set/Read differ by 20-30% of SwitchStep. Set: 716.75, Read: 717
|
||||
19:29:13.689 SetSwitchValue Offset: 75% INFO Set/Read differ by 20-30% of SwitchStep. Set: 818.75, Read: 819
|
||||
19:29:13.859 SetSwitchValue Offset: 75% INFO Set/Read differ by 20-30% of SwitchStep. Set: 921.75, Read: 922
|
||||
19:29:14.014 SetSwitchValue OK Switch has been reset to its original state
|
||||
|
||||
19:29:14.155 GetSwitchName OK Found switch 3
|
||||
19:29:14.165 GetSwitchName OK Name:
|
||||
19:29:14.174 GetSwitchDescription OK Description: Control Knob
|
||||
19:29:14.184 MinSwitchValue OK Minimum: 0
|
||||
19:29:14.194 MaxSwitchValue OK Maximum: 1023
|
||||
19:29:14.205 SwitchStep OK Step size: 1
|
||||
19:29:14.214 SwitchStep OK Step size is greater than zero
|
||||
19:29:14.224 SwitchStep OK Step size is less than the range of possible values
|
||||
19:29:14.233 SwitchStep OK The switch range is an integer multiple of the step size.
|
||||
19:29:14.243 CanWrite OK CanWrite: True
|
||||
19:29:14.254 GetSwitch OK False
|
||||
19:29:14.265 GetSwitchValue OK 0
|
||||
19:29:14.385 SetSwitch OK GetSwitch returned False after SetSwitch(False)
|
||||
19:29:14.396 SetSwitch OK GetSwitchValue returned MINIMUM_VALUE after SetSwitch(False)
|
||||
19:29:14.494 SetSwitch OK GetSwitch read True after SetSwitch(True)
|
||||
19:29:14.506 SetSwitch OK GetSwitchValue returned MAXIMUM_VALUE after SetSwitch(True)
|
||||
19:29:14.694 SetSwitchValue OK GetSwitch returned False after SetSwitchValue(MINIMUM_VALUE)
|
||||
19:29:14.707 SetSwitchValue OK GetSwitchValue returned MINIMUM_VALUE after SetSwitchValue(MINIMUM_VALUE)
|
||||
19:29:14.802 SetSwitchValue OK Switch threw an InvalidOperationException when a value below SwitchMinimum was set: -1
|
||||
19:29:14.943 SetSwitchValue OK GetSwitch returned True after SetSwitchValue(MAXIMUM_VALUE)
|
||||
19:29:14.954 SetSwitchValue OK GetSwitchValue returned MAXIMUM_VALUE after SetSwitchValue(MAXIMUM_VALUE)
|
||||
19:29:15.049 SetSwitchValue OK Switch threw an InvalidOperationException when a value above SwitchMaximum was set: 1024
|
||||
19:29:15.142 SetSwitchValue INFO Testing with steps that are 0% offset from integer SwitchStep values
|
||||
19:29:15.236 SetSwitchValue Offset: 0% OK Set and read match: 0
|
||||
19:29:15.407 SetSwitchValue Offset: 0% OK Set and read match: 102
|
||||
19:29:15.577 SetSwitchValue Offset: 0% OK Set and read match: 205
|
||||
19:29:15.747 SetSwitchValue Offset: 0% OK Set and read match: 307
|
||||
19:29:15.917 SetSwitchValue Offset: 0% OK Set and read match: 409
|
||||
19:29:16.087 SetSwitchValue Offset: 0% OK Set and read match: 512
|
||||
19:29:16.258 SetSwitchValue Offset: 0% OK Set and read match: 614
|
||||
19:29:16.428 SetSwitchValue Offset: 0% OK Set and read match: 716
|
||||
19:29:16.583 SetSwitchValue Offset: 0% OK Set and read match: 818
|
||||
19:29:16.753 SetSwitchValue Offset: 0% OK Set and read match: 921
|
||||
19:29:16.924 SetSwitchValue Offset: 0% OK Set and read match: 1023
|
||||
19:29:17.045 SetSwitchValue INFO Testing with steps that are 25% offset from integer SwitchStep values
|
||||
19:29:17.139 SetSwitchValue Offset: 25% INFO Set/Read differ by 20-30% of SwitchStep. Set: 0.25, Read: 0
|
||||
19:29:17.310 SetSwitchValue Offset: 25% INFO Set/Read differ by 20-30% of SwitchStep. Set: 102.25, Read: 102
|
||||
19:29:17.480 SetSwitchValue Offset: 25% INFO Set/Read differ by 20-30% of SwitchStep. Set: 205.25, Read: 205
|
||||
19:29:17.650 SetSwitchValue Offset: 25% INFO Set/Read differ by 20-30% of SwitchStep. Set: 307.25, Read: 307
|
||||
19:29:17.821 SetSwitchValue Offset: 25% INFO Set/Read differ by 20-30% of SwitchStep. Set: 409.25, Read: 409
|
||||
19:29:17.991 SetSwitchValue Offset: 25% INFO Set/Read differ by 20-30% of SwitchStep. Set: 512.25, Read: 512
|
||||
19:29:18.161 SetSwitchValue Offset: 25% INFO Set/Read differ by 20-30% of SwitchStep. Set: 614.25, Read: 614
|
||||
19:29:18.331 SetSwitchValue Offset: 25% INFO Set/Read differ by 20-30% of SwitchStep. Set: 716.25, Read: 716
|
||||
19:29:18.501 SetSwitchValue Offset: 25% INFO Set/Read differ by 20-30% of SwitchStep. Set: 818.25, Read: 818
|
||||
19:29:18.671 SetSwitchValue Offset: 25% INFO Set/Read differ by 20-30% of SwitchStep. Set: 921.25, Read: 921
|
||||
19:29:18.824 SetSwitchValue INFO Testing with steps that are 50% offset from integer SwitchStep values
|
||||
19:29:18.918 SetSwitchValue Offset: 50% INFO Set/Read differ by 40-50% of SwitchStep. Set: 0.5, Read: 1
|
||||
19:29:19.089 SetSwitchValue Offset: 50% INFO Set/Read differ by 40-50% of SwitchStep. Set: 102.5, Read: 103
|
||||
19:29:19.260 SetSwitchValue Offset: 50% INFO Set/Read differ by 40-50% of SwitchStep. Set: 205.5, Read: 206
|
||||
19:29:19.415 SetSwitchValue Offset: 50% INFO Set/Read differ by 40-50% of SwitchStep. Set: 307.5, Read: 308
|
||||
19:29:19.584 SetSwitchValue Offset: 50% INFO Set/Read differ by 40-50% of SwitchStep. Set: 409.5, Read: 410
|
||||
19:29:19.754 SetSwitchValue Offset: 50% INFO Set/Read differ by 40-50% of SwitchStep. Set: 512.5, Read: 513
|
||||
19:29:19.925 SetSwitchValue Offset: 50% INFO Set/Read differ by 40-50% of SwitchStep. Set: 614.5, Read: 615
|
||||
19:29:20.095 SetSwitchValue Offset: 50% INFO Set/Read differ by 40-50% of SwitchStep. Set: 716.5, Read: 717
|
||||
19:29:20.265 SetSwitchValue Offset: 50% INFO Set/Read differ by 40-50% of SwitchStep. Set: 818.5, Read: 819
|
||||
19:29:20.435 SetSwitchValue Offset: 50% INFO Set/Read differ by 40-50% of SwitchStep. Set: 921.5, Read: 922
|
||||
19:29:20.588 SetSwitchValue INFO Testing with steps that are 75% offset from integer SwitchStep values
|
||||
19:29:20.682 SetSwitchValue Offset: 75% INFO Set/Read differ by 20-30% of SwitchStep. Set: 0.75, Read: 1
|
||||
19:29:20.853 SetSwitchValue Offset: 75% INFO Set/Read differ by 20-30% of SwitchStep. Set: 102.75, Read: 103
|
||||
19:29:21.023 SetSwitchValue Offset: 75% INFO Set/Read differ by 20-30% of SwitchStep. Set: 205.75, Read: 206
|
||||
19:29:21.194 SetSwitchValue Offset: 75% INFO Set/Read differ by 20-30% of SwitchStep. Set: 307.75, Read: 308
|
||||
19:29:21.364 SetSwitchValue Offset: 75% INFO Set/Read differ by 20-30% of SwitchStep. Set: 409.75, Read: 410
|
||||
19:29:21.534 SetSwitchValue Offset: 75% INFO Set/Read differ by 20-30% of SwitchStep. Set: 512.75, Read: 513
|
||||
19:29:21.704 SetSwitchValue Offset: 75% INFO Set/Read differ by 20-30% of SwitchStep. Set: 614.75, Read: 615
|
||||
19:29:21.874 SetSwitchValue Offset: 75% INFO Set/Read differ by 20-30% of SwitchStep. Set: 716.75, Read: 717
|
||||
19:29:22.045 SetSwitchValue Offset: 75% INFO Set/Read differ by 20-30% of SwitchStep. Set: 818.75, Read: 819
|
||||
19:29:22.199 SetSwitchValue Offset: 75% INFO Set/Read differ by 20-30% of SwitchStep. Set: 921.75, Read: 922
|
||||
19:29:22.354 SetSwitchValue OK Switch has been reset to its original state
|
||||
|
||||
|
||||
Conformance test complete
|
||||
|
||||
No errors, warnings or issues found: your driver passes ASCOM validation!!
|
||||
|
||||
Driver Hash Value: 2324CFC7AD89514CA3132538F5949BD837ABDF01A2CB27A7E8B4F11F6E34A60F1D0A054FDD9B71AAAEBDE250B552785A4FD3EE2521E13C2AFFDD32F423269B1E
|
||||
@@ -0,0 +1,42 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
|
||||
<?include $(sys.CURRENTDIR)\Config.wxi?>
|
||||
<Fragment>
|
||||
<DirectoryRef Id="INSTALLFOLDER"/>
|
||||
<ComponentGroup Id="cgAscomLocalServer" Directory="INSTALLFOLDER">
|
||||
<Component Id="cmpAscomLocalServer" Guid="*" Win64="no">
|
||||
<File Id="filLocalServerAssembly"
|
||||
Source="$(var.LynxAstro.DewController.TargetPath)"
|
||||
KeyPath="yes"
|
||||
Vital="yes"
|
||||
Assembly=".net"
|
||||
AssemblyApplication="filLocalServerAssembly" />
|
||||
</Component>
|
||||
</ComponentGroup>
|
||||
|
||||
<CustomAction Id="RegisterEXE"
|
||||
Directory="INSTALLFOLDER"
|
||||
ExeCommand=""[#filLocalServerAssembly]" /register"
|
||||
Execute="deferred"
|
||||
Return="ignore"
|
||||
Impersonate="no"
|
||||
/>
|
||||
|
||||
<CustomAction Id="UnRegisterEXE"
|
||||
Directory="INSTALLFOLDER"
|
||||
ExeCommand=""[#filLocalServerAssembly]" /unregister"
|
||||
Execute="deferred"
|
||||
Return="ignore"
|
||||
Impersonate="no"
|
||||
/>
|
||||
|
||||
<InstallExecuteSequence>
|
||||
<Custom Action='RegisterEXE' Before="InstallFinalize">
|
||||
<![CDATA[(NOT Installed)]]>
|
||||
</Custom>
|
||||
<Custom Action="UnRegisterEXE" After="InstallInitialize">
|
||||
<![CDATA[(REMOVE ~= "ALL" AND NOT UPGRADINGPRODUCTCODE)]]>
|
||||
</Custom>
|
||||
</InstallExecuteSequence>
|
||||
</Fragment>
|
||||
</Wix>
|
||||
@@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
|
||||
<?include $(sys.CURRENTDIR)\Config.wxi?>
|
||||
<!--
|
||||
ASCOM Switch Driver with COM registry entries suitable for a LocalServer Served Class
|
||||
-->
|
||||
<Fragment>
|
||||
<DirectoryRef Id="INSTALLFOLDER" />
|
||||
<ComponentGroup Id="cgAscomSwitchDriver">
|
||||
<Component Id="cmpAscomSwitchDriver"
|
||||
Directory="INSTALLFOLDER"
|
||||
Guid="*"
|
||||
Win64="no">
|
||||
<File Id="filSwitchDriverAssembly"
|
||||
Source="$(var.LynxAstro.DewController.Switch.TargetPath)"
|
||||
KeyPath="yes"
|
||||
Vital="yes"
|
||||
Assembly=".net"
|
||||
AssemblyApplication="filSwitchDriverAssembly" />
|
||||
</Component>
|
||||
</ComponentGroup>
|
||||
</Fragment>
|
||||
</Wix>
|
||||
@@ -0,0 +1,44 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
|
||||
<Include>
|
||||
<!--
|
||||
User Configuration - you must ensure all these variables have correct values for your project.
|
||||
GUIDs specified here must match those used in the project files, and must be unique to this product.
|
||||
The LocalServerAppId is defined in the Server project, in LocalServer.cs
|
||||
Driver Class IDs are defined in each driver class, in the [Guid()] attribute.
|
||||
Driver ProgIDs must match those used in the source code, typically this will be defined in the LocalServer
|
||||
project as a constant in the SharedResources static class.
|
||||
UpgradeCode must be unique to this product and should not be changed for the product lifetime.
|
||||
-->
|
||||
|
||||
<?define InstallName = "ASCOM LynxAstro.DewController" ?>
|
||||
<?define Manufacturer = "cjdawson.com" ?>
|
||||
<?define UpgradeCode = "{57597bb6-f207-4998-97f4-8a041950d062}" ?>
|
||||
<?define INSTALLFOLDER = "$(var.InstallName)" ?>
|
||||
|
||||
<?define LocalServerAppId = "{5EBBCD3B-3FC9-4D9F-868D-E0C2D085A58B}" ?>
|
||||
<?define CopyrightNotice="Copyright © 2021 cjdawson.com, all rights reserved" ?>
|
||||
|
||||
<?define SwitchDriverClassId="{A3C01556-C4CD-4259-AB1F-5C08061BACA0}" ?>
|
||||
<?define SwitchDriverProgId="LynxAstro.DewController.Switch" ?>
|
||||
<?define SwitchDriverDescription="LynxAstro.DewController"?>
|
||||
|
||||
<!-- End of User Configuration - do not edit anything beyond this point -->
|
||||
|
||||
<!-- Define platform-specific names and locations -->
|
||||
<!-- <?if $(var.Platform) = x64 ?>
|
||||
<?define ProductName = "$(var.InstallName) (x64)" ?>
|
||||
<?define Win64 = "yes" ?>
|
||||
<?define PlatformProgramFilesFolder = "ProgramFiles64Folder" ?>
|
||||
<?define PlatformCommonFilesFolder = "CommonFiles64Folder" ?>
|
||||
<?else ?>-->
|
||||
<?define ProductName = "$(var.InstallName) (x86)" ?>
|
||||
<?define Win64 = "no" ?>
|
||||
<?define PlatformProgramFilesFolder = "ProgramFilesFolder" ?>
|
||||
<?define PlatformCommonFilesFolder = "CommonFilesFolder" ?>
|
||||
<!-- <?endif ?> -->
|
||||
|
||||
<!-- Set installer version based on the file version of the main assembly. -->
|
||||
<?define ProductVersion="!(bind.FileVersion.filLocalServerAssembly)"?>
|
||||
<!--<?define ProductVersion="0.7.0.0"?>-->
|
||||
</Include>
|
||||
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
|
||||
<?include $(sys.CURRENTDIR)\Config.wxi?>
|
||||
<Fragment>
|
||||
<Directory Id="TARGETDIR" Name="SourceDir">
|
||||
<Directory Id="ProgramFilesFolder">
|
||||
<Directory Id="dirManufacturer" Name="$(var.Manufacturer)">
|
||||
<Directory Id="INSTALLFOLDER" Name="$(var.InstallName)"/>
|
||||
</Directory>
|
||||
</Directory>
|
||||
</Directory>
|
||||
</Fragment>
|
||||
</Wix>
|
||||
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
|
||||
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi" >
|
||||
<?include $(sys.CURRENTDIR)\Config.wxi?>
|
||||
<Fragment>
|
||||
<FeatureGroup Id="fgRoot" >
|
||||
<Feature Id="featAscomDrivers" Title="ASCOM drivers" Level="1" Absent="disallow"
|
||||
Display="expand" >
|
||||
<ComponentGroupRef Id="cgAscomLocalServer" />
|
||||
<ComponentGroupRef Id="cgAscomSwitchDriver"/>
|
||||
</Feature>
|
||||
</FeatureGroup>
|
||||
</Fragment>
|
||||
</Wix>
|
||||
@@ -0,0 +1,81 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. -->
|
||||
|
||||
|
||||
|
||||
<!--
|
||||
First-time install dialog sequence:
|
||||
- WixUI_WelcomeDlg
|
||||
- WixUI_LicenseAgreementDlg
|
||||
- WixUI_InstallDirDlg
|
||||
- WixUI_VerifyReadyDlg
|
||||
- WixUI_DiskCostDlg
|
||||
|
||||
Maintenance dialog sequence:
|
||||
- WixUI_MaintenanceWelcomeDlg
|
||||
- WixUI_MaintenanceTypeDlg
|
||||
- WixUI_InstallDirDlg
|
||||
- WixUI_VerifyReadyDlg
|
||||
|
||||
Patch dialog sequence:
|
||||
- WixUI_WelcomeDlg
|
||||
- WixUI_VerifyReadyDlg
|
||||
|
||||
-->
|
||||
|
||||
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
|
||||
<Fragment>
|
||||
<UI Id="InstallationUI">
|
||||
<TextStyle Id="WixUI_Font_Normal" FaceName="Tahoma" Size="8" />
|
||||
<TextStyle Id="WixUI_Font_Bigger" FaceName="Tahoma" Size="12" />
|
||||
<TextStyle Id="WixUI_Font_Title" FaceName="Tahoma" Size="9" Bold="yes" />
|
||||
|
||||
<Property Id="DefaultUIFont" Value="WixUI_Font_Normal" />
|
||||
<Property Id="WixUI_Mode" Value="InstallDir" />
|
||||
|
||||
<DialogRef Id="BrowseDlg" />
|
||||
<DialogRef Id="DiskCostDlg" />
|
||||
<DialogRef Id="ErrorDlg" />
|
||||
<DialogRef Id="FatalError" />
|
||||
<DialogRef Id="FilesInUse" />
|
||||
<DialogRef Id="MsiRMFilesInUse" />
|
||||
<DialogRef Id="PrepareDlg" />
|
||||
<DialogRef Id="ProgressDlg" />
|
||||
<DialogRef Id="ResumeDlg" />
|
||||
<DialogRef Id="UserExit" />
|
||||
|
||||
<Publish Dialog="BrowseDlg" Control="OK" Event="DoAction" Value="WixUIValidatePath" Order="3">1</Publish>
|
||||
<Publish Dialog="BrowseDlg" Control="OK" Event="SpawnDialog" Value="InvalidDirDlg" Order="4"><![CDATA[NOT WIXUI_DONTVALIDATEPATH AND WIXUI_INSTALLDIR_VALID<>"1"]]></Publish>
|
||||
|
||||
<Publish Dialog="ExitDialog" Control="Finish" Event="EndDialog" Value="Return" Order="999">1</Publish>
|
||||
|
||||
<Publish Dialog="WelcomeDlg" Control="Next" Event="NewDialog" Value="LicenseAgreementDlg">NOT Installed</Publish>
|
||||
<Publish Dialog="WelcomeDlg" Control="Next" Event="NewDialog" Value="VerifyReadyDlg">Installed AND PATCH</Publish>
|
||||
|
||||
<Publish Dialog="LicenseAgreementDlg" Control="Back" Event="NewDialog" Value="WelcomeDlg">1</Publish>
|
||||
<Publish Dialog="LicenseAgreementDlg" Control="Next" Event="NewDialog" Value="InstallDirDlg">LicenseAccepted = "1"</Publish>
|
||||
|
||||
<Publish Dialog="InstallDirDlg" Control="Back" Event="NewDialog" Value="LicenseAgreementDlg">1</Publish>
|
||||
<Publish Dialog="InstallDirDlg" Control="Next" Event="SetTargetPath" Value="[WIXUI_INSTALLDIR]" Order="1">1</Publish>
|
||||
<Publish Dialog="InstallDirDlg" Control="Next" Event="DoAction" Value="WixUIValidatePath" Order="2">NOT WIXUI_DONTVALIDATEPATH</Publish>
|
||||
<Publish Dialog="InstallDirDlg" Control="Next" Event="SpawnDialog" Value="InvalidDirDlg" Order="3"><![CDATA[NOT WIXUI_DONTVALIDATEPATH AND WIXUI_INSTALLDIR_VALID<>"1"]]></Publish>
|
||||
<Publish Dialog="InstallDirDlg" Control="Next" Event="NewDialog" Value="VerifyReadyDlg" Order="4">WIXUI_DONTVALIDATEPATH OR WIXUI_INSTALLDIR_VALID="1"</Publish>
|
||||
<Publish Dialog="InstallDirDlg" Control="ChangeFolder" Property="_BrowseProperty" Value="[WIXUI_INSTALLDIR]" Order="1">1</Publish>
|
||||
<Publish Dialog="InstallDirDlg" Control="ChangeFolder" Event="SpawnDialog" Value="BrowseDlg" Order="2">1</Publish>
|
||||
|
||||
<Publish Dialog="VerifyReadyDlg" Control="Back" Event="NewDialog" Value="InstallDirDlg" Order="1">NOT Installed</Publish>
|
||||
<Publish Dialog="VerifyReadyDlg" Control="Back" Event="NewDialog" Value="MaintenanceTypeDlg" Order="2">Installed AND NOT PATCH</Publish>
|
||||
<Publish Dialog="VerifyReadyDlg" Control="Back" Event="NewDialog" Value="WelcomeDlg" Order="2">Installed AND PATCH</Publish>
|
||||
|
||||
<Publish Dialog="MaintenanceWelcomeDlg" Control="Next" Event="NewDialog" Value="MaintenanceTypeDlg">1</Publish>
|
||||
|
||||
<Publish Dialog="MaintenanceTypeDlg" Control="RepairButton" Event="NewDialog" Value="VerifyReadyDlg">1</Publish>
|
||||
<Publish Dialog="MaintenanceTypeDlg" Control="RemoveButton" Event="NewDialog" Value="VerifyReadyDlg">1</Publish>
|
||||
<Publish Dialog="MaintenanceTypeDlg" Control="Back" Event="NewDialog" Value="MaintenanceWelcomeDlg">1</Publish>
|
||||
|
||||
<Property Id="ARPNOMODIFY" Value="1" />
|
||||
</UI>
|
||||
|
||||
<UIRef Id="WixUI_Common" />
|
||||
</Fragment>
|
||||
</Wix>
|
||||
Binary file not shown.
@@ -0,0 +1,74 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" DefaultTargets="Build" InitialTargets="EnsureWixToolsetInstalled" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
|
||||
<ProductVersion>3.10</ProductVersion>
|
||||
<ProjectGuid>{1073a462-d9a4-4c72-9c3f-a345b307153a}</ProjectGuid>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<OutputName>LynxAstro.DewController.Setup</OutputName>
|
||||
<OutputType>Package</OutputType>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
|
||||
<OutputPath>bin\$(Configuration)\</OutputPath>
|
||||
<IntermediateOutputPath>obj\$(Configuration)\</IntermediateOutputPath>
|
||||
<DefineConstants>Debug</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
|
||||
<OutputPath>bin\$(Configuration)\</OutputPath>
|
||||
<IntermediateOutputPath>obj\$(Configuration)\</IntermediateOutputPath>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="AscomLocalServer.wxs" />
|
||||
<Compile Include="AscomSwitchDriver.wxs" />
|
||||
<Compile Include="Directories.wxs" />
|
||||
<Compile Include="FeatureTree.wxs" />
|
||||
<Compile Include="InstallationUI.wxs" />
|
||||
<Compile Include="Product.wxs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\LynxAstro.DewController.Switch\LynxAstro.DewController.Switch.csproj">
|
||||
<Name>LynxAstro.DewController.Switch</Name>
|
||||
<Project>{64308775-bd4a-469c-bcab-3ed830b811af}</Project>
|
||||
<Private>True</Private>
|
||||
<DoNotHarvest>True</DoNotHarvest>
|
||||
<RefProjectOutputGroups>Binaries;Content;Satellites</RefProjectOutputGroups>
|
||||
<RefTargetDir>INSTALLFOLDER</RefTargetDir>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\LynxAstro.DewController\LynxAstro.DewController.csproj">
|
||||
<Name>LynxAstro.DewController</Name>
|
||||
<Project>{c708e487-e3a9-4073-a545-294b88674225}</Project>
|
||||
<Private>True</Private>
|
||||
<DoNotHarvest>True</DoNotHarvest>
|
||||
<RefProjectOutputGroups>Binaries;Content;Satellites</RefProjectOutputGroups>
|
||||
<RefTargetDir>INSTALLFOLDER</RefTargetDir>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<WixExtension Include="WixUIExtension">
|
||||
<HintPath>$(WixExtDir)\WixUIExtension.dll</HintPath>
|
||||
<Name>WixUIExtension</Name>
|
||||
</WixExtension>
|
||||
<WixExtension Include="WixNetFxExtension">
|
||||
<HintPath>$(WixExtDir)\WixNetFxExtension.dll</HintPath>
|
||||
<Name>WixNetFxExtension</Name>
|
||||
</WixExtension>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Config.wxi" />
|
||||
<Content Include="License.rtf" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(WixTargetsPath)" Condition=" '$(WixTargetsPath)' != '' " />
|
||||
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\WiX\v3.x\Wix.targets" Condition=" '$(WixTargetsPath)' == '' AND Exists('$(MSBuildExtensionsPath32)\Microsoft\WiX\v3.x\Wix.targets') " />
|
||||
<Target Name="EnsureWixToolsetInstalled" Condition=" '$(WixTargetsImported)' != 'true' ">
|
||||
<Error Text="The WiX Toolset v3.11 (or newer) build tools must be installed to build this project. To download the WiX Toolset, see http://wixtoolset.org/releases/" />
|
||||
</Target>
|
||||
<!--
|
||||
To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Wix.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
||||
@@ -0,0 +1,48 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
|
||||
<?include $(sys.CURRENTDIR)\Config.wxi?>
|
||||
<Product Id="*"
|
||||
Name="$(var.InstallName)"
|
||||
Language="1033"
|
||||
Version="$(var.ProductVersion)"
|
||||
Manufacturer="$(var.Manufacturer)"
|
||||
UpgradeCode="$(var.UpgradeCode)">
|
||||
<Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />
|
||||
|
||||
<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
|
||||
|
||||
<MediaTemplate EmbedCab="yes" />
|
||||
|
||||
<Property Id="ASCOMPLATFORMVERSION">
|
||||
<RegistrySearch Id="AscomPlatformVersion"
|
||||
Root="HKLM"
|
||||
Key="SOFTWARE\ASCOM\Platform"
|
||||
Name="Platform Version"
|
||||
Type="raw" />
|
||||
</Property>
|
||||
|
||||
<Condition Message="This application requires Ascom Platform 6.4 SP1 or higher. Please install this before installing the driver.">
|
||||
<![CDATA[Installed OR ASCOMPLATFORMVERSION >= "6.4.1"]]>
|
||||
</Condition>
|
||||
|
||||
<PropertyRef Id="NETFRAMEWORK45"/>
|
||||
<Condition Message="This application requires .NET Framework 4.5 or higher. Please install the .NET Framework then run this installer again.">
|
||||
<![CDATA[Installed OR NETFRAMEWORK45]]>
|
||||
</Condition>
|
||||
|
||||
<!-- <Condition Message="Please use the correct installer for your operating system - x86 for 32-bit, x64 for 64-bit.">
|
||||
<?if $(var.Win64) = "yes" ?>
|
||||
VersionNT64
|
||||
<?else?>
|
||||
NOT VersionNT64
|
||||
<?endif?>
|
||||
</Condition> -->
|
||||
|
||||
|
||||
<UIRef Id="InstallationUI"/>
|
||||
<Property Id="WIXUI_INSTALLDIR" Value="INSTALLFOLDER" />
|
||||
<WixVariable Id="WixUILicenseRtf" Value="License.rtf" />
|
||||
|
||||
<FeatureGroupRef Id="fgRoot"/>
|
||||
</Product>
|
||||
</Wix>
|
||||
+120
@@ -0,0 +1,120 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="..\packages\NUnit.3.13.1\build\NUnit.props" Condition="Exists('..\packages\NUnit.3.13.1\build\NUnit.props')" />
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{AFA5A4A4-188C-4180-B910-7C5BA7D5C11F}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>LynxAstro.DewController.Switch.UnitTests</RootNamespace>
|
||||
<AssemblyName>LynxAstro.DewController.Switch.UnitTests</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<Deterministic>true</Deterministic>
|
||||
<NuGetPackageImportStamp>
|
||||
</NuGetPackageImportStamp>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="ASCOM.Astrometry, Version=6.0.0.0, Culture=neutral, PublicKeyToken=565de7938946fba7, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\ASCOM.Platform.6.5.2\lib\net40\ASCOM.Astrometry.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="ASCOM.Attributes, Version=6.0.0.0, Culture=neutral, PublicKeyToken=565de7938946fba7, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\ASCOM.Platform.6.5.2\lib\net40\ASCOM.Attributes.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="ASCOM.Cache, Version=6.0.0.0, Culture=neutral, PublicKeyToken=565de7938946fba7, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\ASCOM.Platform.6.5.2\lib\net40\ASCOM.Cache.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="ASCOM.Controls, Version=6.0.0.0, Culture=neutral, PublicKeyToken=565de7938946fba7, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\ASCOM.Platform.6.5.2\lib\net40\ASCOM.Controls.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="ASCOM.DeviceInterfaces, Version=6.0.0.0, Culture=neutral, PublicKeyToken=565de7938946fba7, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\ASCOM.Platform.6.5.2\lib\net40\ASCOM.DeviceInterfaces.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="ASCOM.DriverAccess, Version=6.0.0.0, Culture=neutral, PublicKeyToken=565de7938946fba7, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\ASCOM.Platform.6.5.2\lib\net40\ASCOM.DriverAccess.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="ASCOM.Exceptions, Version=6.0.0.0, Culture=neutral, PublicKeyToken=565de7938946fba7, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\ASCOM.Platform.6.5.2\lib\net40\ASCOM.Exceptions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="ASCOM.Internal.Extensions, Version=6.0.0.0, Culture=neutral, PublicKeyToken=565de7938946fba7, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\ASCOM.Platform.6.5.2\lib\net40\ASCOM.Internal.Extensions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="ASCOM.SettingsProvider, Version=6.0.0.0, Culture=neutral, PublicKeyToken=565de7938946fba7, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\ASCOM.Platform.6.5.2\lib\net40\ASCOM.SettingsProvider.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="ASCOM.Utilities, Version=6.0.0.0, Culture=neutral, PublicKeyToken=565de7938946fba7, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\ASCOM.Platform.6.5.2\lib\net40\ASCOM.Utilities.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="ASCOM.Utilities.Video, Version=6.1.0.0, Culture=neutral, PublicKeyToken=565de7938946fba7, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\ASCOM.Platform.6.5.2\lib\net40\ASCOM.Utilities.Video.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Castle.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Castle.Core.4.4.0\lib\net45\Castle.Core.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Moq, Version=4.16.0.0, Culture=neutral, PublicKeyToken=69f491c39445e920, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Moq.4.16.0\lib\net45\Moq.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="nunit.framework, Version=3.13.1.0, Culture=neutral, PublicKeyToken=2638cd05610744eb, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\NUnit.3.13.1\lib\net45\nunit.framework.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Configuration" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Runtime.CompilerServices.Unsafe, Version=4.0.4.1, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Runtime.CompilerServices.Unsafe.4.5.3\lib\net461\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Threading.Tasks.Extensions, Version=4.2.0.1, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Threading.Tasks.Extensions.4.5.4\lib\net461\System.Threading.Tasks.Extensions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="SwitchUnitTests.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\LynxAstro.DewController.Switch\LynxAstro.DewController.Switch.csproj">
|
||||
<Project>{64308775-bd4a-469c-bcab-3ed830b811af}</Project>
|
||||
<Name>LynxAstro.DewController.Switch</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\LynxAstro.DewController\LynxAstro.DewController.csproj">
|
||||
<Project>{c708e487-e3a9-4073-a545-294b88674225}</Project>
|
||||
<Name>LynxAstro.DewController</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('..\packages\NUnit.3.13.1\build\NUnit.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\NUnit.3.13.1\build\NUnit.props'))" />
|
||||
</Target>
|
||||
</Project>
|
||||
@@ -0,0 +1,36 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("LynxAstro.DewController.Switch.UnitTests")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("LynxAstro.DewController.Switch.UnitTests")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2021")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("afa5a4a4-188c-4180-b910-7c5ba7d5c11f")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
@@ -0,0 +1,27 @@
|
||||
using ASCOM.LynxAstro.DewController;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace LynxAstro.DewController.Switch.UnitTests
|
||||
{
|
||||
[TestFixture]
|
||||
public class SwitchUnitTests
|
||||
{
|
||||
private ASCOM.LynxAstro.DewController.Switch _switch;
|
||||
private Mock<ISharedResourcesWrapper> _sharedResourcesWrapperMock;
|
||||
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
_sharedResourcesWrapperMock = new Mock<ISharedResourcesWrapper>();
|
||||
|
||||
_switch = new ASCOM.LynxAstro.DewController.Switch();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CheckThatClassCreatedProperly()
|
||||
{
|
||||
Assert.That(_switch, Is.Not.Null);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="ASCOM.Platform" version="6.5.2" targetFramework="net472" />
|
||||
<package id="Castle.Core" version="4.4.0" targetFramework="net472" />
|
||||
<package id="Moq" version="4.16.0" targetFramework="net472" />
|
||||
<package id="NUnit" version="3.13.1" targetFramework="net472" />
|
||||
<package id="System.Runtime.CompilerServices.Unsafe" version="4.5.3" targetFramework="net472" />
|
||||
<package id="System.Threading.Tasks.Extensions" version="4.5.4" targetFramework="net472" />
|
||||
</packages>
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 123 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 1.9 KiB |
Binary file not shown.
@@ -0,0 +1,151 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="12.0">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProductVersion>9.0.30729</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{64308775-BD4A-469C-BCAB-3ED830B811AF}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>ASCOM.LynxAstro.DewController</RootNamespace>
|
||||
<AssemblyName>ASCOM.LynxAstro.DewController.Switch</AssemblyName>
|
||||
<FileUpgradeFlags>
|
||||
</FileUpgradeFlags>
|
||||
<UpgradeBackupLocation>
|
||||
</UpgradeBackupLocation>
|
||||
<OldToolsVersion>3.5</OldToolsVersion>
|
||||
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
|
||||
<ApplicationIcon>ASCOM.ico</ApplicationIcon>
|
||||
<SignAssembly>true</SignAssembly>
|
||||
<AssemblyOriginatorKeyFile>ASCOMDriverTemplate.snk</AssemblyOriginatorKeyFile>
|
||||
<PublishUrl>publish\</PublishUrl>
|
||||
<Install>true</Install>
|
||||
<InstallFrom>Disk</InstallFrom>
|
||||
<UpdateEnabled>false</UpdateEnabled>
|
||||
<UpdateMode>Foreground</UpdateMode>
|
||||
<UpdateInterval>7</UpdateInterval>
|
||||
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
|
||||
<UpdatePeriodically>false</UpdatePeriodically>
|
||||
<UpdateRequired>false</UpdateRequired>
|
||||
<MapFileExtensions>true</MapFileExtensions>
|
||||
<ApplicationRevision>0</ApplicationRevision>
|
||||
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
|
||||
<IsWebBootstrapper>false</IsWebBootstrapper>
|
||||
<UseApplicationTrust>false</UseApplicationTrust>
|
||||
<BootstrapperEnabled>true</BootstrapperEnabled>
|
||||
<TargetFrameworkProfile>
|
||||
</TargetFrameworkProfile>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<RegisterForComInterop>true</RegisterForComInterop>
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<Prefer32Bit>false</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<RegisterForComInterop>false</RegisterForComInterop>
|
||||
<Prefer32Bit>false</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="ASCOM.Astrometry, Version=6.0.0.0, Culture=neutral, PublicKeyToken=565de7938946fba7, processorArchitecture=MSIL" />
|
||||
<Reference Include="ASCOM.Attributes, Version=6.0.0.0, Culture=neutral, PublicKeyToken=565de7938946fba7, processorArchitecture=MSIL" />
|
||||
<Reference Include="ASCOM.Controls, Version=6.0.0.0, Culture=neutral, PublicKeyToken=565de7938946fba7, processorArchitecture=MSIL" />
|
||||
<Reference Include="ASCOM.DeviceInterfaces, Version=6.0.0.0, Culture=neutral, PublicKeyToken=565de7938946fba7, processorArchitecture=MSIL" />
|
||||
<Reference Include="ASCOM.Exceptions, Version=6.0.0.0, Culture=neutral, PublicKeyToken=565de7938946fba7, processorArchitecture=MSIL" />
|
||||
<Reference Include="ASCOM.SettingsProvider, Version=6.0.0.0, Culture=neutral, PublicKeyToken=565de7938946fba7, processorArchitecture=MSIL" />
|
||||
<Reference Include="ASCOM.Utilities, Version=6.0.0.0, Culture=neutral, PublicKeyToken=565de7938946fba7, processorArchitecture=MSIL" />
|
||||
<Reference Include="ASCOM.Utilities.Video, Version=6.1.0.0, Culture=neutral, PublicKeyToken=565de7938946fba7, processorArchitecture=MSIL" />
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.configuration" />
|
||||
<Reference Include="System.Configuration.Install" />
|
||||
<Reference Include="System.Core">
|
||||
<RequiredTargetFramework>3.5</RequiredTargetFramework>
|
||||
</Reference>
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="System.Windows.Forms" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Switch.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Properties\Resources.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DesignTime>True</DesignTime>
|
||||
<DependentUpon>Resources.resx</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Properties\Settings.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
||||
<DependentUpon>Settings.settings</DependentUpon>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="Properties\Resources.resx">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="app.config" />
|
||||
<None Include="ASCOM.png" />
|
||||
<None Include="ASCOMDriverTemplate.snk" />
|
||||
<None Include="Properties\Settings.settings">
|
||||
<Generator>SettingsSingleFileGenerator</Generator>
|
||||
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
|
||||
</None>
|
||||
<Content Include="ASCOM.ico" />
|
||||
<Content Include="ReadMe.htm" />
|
||||
<None Include="Resources\ASCOM.bmp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<BootstrapperPackage Include="Microsoft.Net.Client.3.5">
|
||||
<Visible>False</Visible>
|
||||
<ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
|
||||
<Install>false</Install>
|
||||
</BootstrapperPackage>
|
||||
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
|
||||
<Visible>False</Visible>
|
||||
<ProductName>.NET Framework 3.5 SP1</ProductName>
|
||||
<Install>true</Install>
|
||||
</BootstrapperPackage>
|
||||
<BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
|
||||
<Visible>False</Visible>
|
||||
<ProductName>Windows Installer 3.1</ProductName>
|
||||
<Install>true</Install>
|
||||
</BootstrapperPackage>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\LynxAstro.DewController\LynxAstro.DewController.csproj">
|
||||
<Project>{c708e487-e3a9-4073-a545-294b88674225}</Project>
|
||||
<Name>LynxAstro.DewController</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<PropertyGroup>
|
||||
<PreBuildEvent>
|
||||
</PreBuildEvent>
|
||||
</PropertyGroup>
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
||||
@@ -0,0 +1,38 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
//
|
||||
// TODO - Add your authorship information here
|
||||
[assembly: AssemblyTitle("ASCOM.LynxAstro.DewController.Switch")]
|
||||
[assembly: AssemblyDescription("ASCOM Switch driver for LynxAstro.DewController")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("The ASCOM Initiative")]
|
||||
[assembly: AssemblyProduct("ASCOM Switch driver for LynxAstro.DewController")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2021 The ASCOM Initiative")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(true)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("a567b01c-a066-45ce-af3d-0192bad973ea")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Revision and Build Numbers
|
||||
// by using the '*' as shown below:
|
||||
//
|
||||
// TODO - Set your driver's version here
|
||||
[assembly: AssemblyVersion("6.5.1.0")]
|
||||
[assembly: AssemblyFileVersion("6.5.1.0")]
|
||||
@@ -0,0 +1,96 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.42000
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace ASCOM.LynxAstro.DewController.Properties
|
||||
{
|
||||
using System;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// A strongly-typed resource class, for looking up localized strings, etc.
|
||||
/// </summary>
|
||||
// This class was auto-generated by the StronglyTypedResourceBuilder
|
||||
// class via a tool like ResGen or Visual Studio.
|
||||
// To add or remove a member, edit your .ResX file then rerun ResGen
|
||||
// with the /str option, or rebuild your VS project.
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
internal class Resources
|
||||
{
|
||||
|
||||
private static global::System.Resources.ResourceManager resourceMan;
|
||||
|
||||
private static global::System.Globalization.CultureInfo resourceCulture;
|
||||
|
||||
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||
internal Resources()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the cached ResourceManager instance used by this class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Resources.ResourceManager ResourceManager
|
||||
{
|
||||
get
|
||||
{
|
||||
if (object.ReferenceEquals(resourceMan, null))
|
||||
{
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ASCOM.LynxAstro.DewController.Properties.Resources", typeof(Resources).Assembly);
|
||||
resourceMan = temp;
|
||||
}
|
||||
return resourceMan;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Overrides the current thread's CurrentUICulture property for all
|
||||
/// resource lookups using this strongly typed resource class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Globalization.CultureInfo Culture
|
||||
{
|
||||
get
|
||||
{
|
||||
return resourceCulture;
|
||||
}
|
||||
set
|
||||
{
|
||||
resourceCulture = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Drawing.Bitmap.
|
||||
/// </summary>
|
||||
internal static System.Drawing.Bitmap ASCOM
|
||||
{
|
||||
get
|
||||
{
|
||||
object obj = ResourceManager.GetObject("ASCOM", resourceCulture);
|
||||
return ((System.Drawing.Bitmap)(obj));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Drawing.Icon similar to (Icon).
|
||||
/// </summary>
|
||||
internal static System.Drawing.Icon DefaultIcon
|
||||
{
|
||||
get
|
||||
{
|
||||
object obj = ResourceManager.GetObject("DefaultIcon", resourceCulture);
|
||||
return ((System.Drawing.Icon)(obj));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<data name="ASCOM" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\ASCOM.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="DefaultIcon" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\ASCOM.ico;System.Drawing.Icon, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -0,0 +1,30 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.42000
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace ASCOM.LynxAstro.DewController.Properties
|
||||
{
|
||||
|
||||
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.4.0.0")]
|
||||
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
|
||||
{
|
||||
|
||||
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
|
||||
|
||||
public static Settings Default
|
||||
{
|
||||
get
|
||||
{
|
||||
return defaultInstance;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)">
|
||||
<Profiles />
|
||||
<Settings />
|
||||
</SettingsFile>
|
||||
@@ -0,0 +1,147 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=windows-1252">
|
||||
<TITLE>Untitled Document</TITLE>
|
||||
<META NAME="GENERATOR" CONTENT="OpenOffice.org 3.2 (Win32)">
|
||||
<META NAME="CREATED" CONTENT="0;0">
|
||||
<META NAME="CHANGEDBY" CONTENT="Chris Rowland">
|
||||
<META NAME="CHANGED" CONTENT="20110918;14150500">
|
||||
<STYLE TYPE="text/css">
|
||||
<!--
|
||||
@page { margin: 2cm }
|
||||
P { font-family: "Verdana", "Arial", "Helvetica", sans-serif; font-weight: normal }
|
||||
TD P { font-family: "Verdana", "Arial", "Helvetica", sans-serif; font-weight: normal }
|
||||
H3 { font-family: "Arial", "Helvetica", sans-serif }
|
||||
H2 { font-family: "Arial", "Helvetica", sans-serif }
|
||||
H4 { font-family: "Arial", "Helvetica", sans-serif }
|
||||
TD P.note { background: #33ffff; font-family: "Verdana", "Arial", "Helvetica", sans-serif; font-weight: normal }
|
||||
TD P.underline { font-family: "Verdana", "Arial", "Helvetica", sans-serif; font-weight: normal; text-decoration: underline }
|
||||
-->
|
||||
</STYLE>
|
||||
</HEAD>
|
||||
<BODY LANG="en-GB" DIR="LTR">
|
||||
<TABLE WIDTH=100% BORDER=0 CELLPADDING=4 CELLSPACING=0>
|
||||
<TR>
|
||||
<TD>
|
||||
<H2>ASCOM Switch Driver (C#)</H2>
|
||||
</TD>
|
||||
</TR>
|
||||
</TABLE>
|
||||
<P><BR><BR>
|
||||
</P>
|
||||
<H4>You have just created the skeleton of an ASCOM
|
||||
Switch driver in C#. It produces an in-process
|
||||
(assembly) based driver.</H4>
|
||||
<HR>
|
||||
<P CLASS="note">Prior to developing your first driver, please
|
||||
familiarize yourself with the <A HREF="https://ascom-standards.org/developer.html">developer
|
||||
information we've provided</A> at the ASCOM Initiative web site
|
||||
(internet required).
|
||||
</P>
|
||||
<P CLASS="underline">You must do the following in order to complete
|
||||
your implementation:</P>
|
||||
<OL>
|
||||
<LI><P STYLE="margin-bottom: 0cm">Switch to the Debug configuration
|
||||
and build the template now. It should build without errors.
|
||||
</P>
|
||||
<LI><P STYLE="margin-bottom: 0cm">Add a test project to the
|
||||
solution. There are templates that can be used to add either a
|
||||
console or a Windows Forms application:</P>
|
||||
</OL>
|
||||
<UL>
|
||||
<LI><P STYLE="margin-bottom: 0cm">Select the <FONT FACE="Consolas, monospace">ASCOM
|
||||
Test Forms App (CS)</FONT> or <FONT FACE="Consolas, monospace">ASCOM
|
||||
Test Console App (CS)</FONT> template.</P>
|
||||
<LI><P STYLE="margin-bottom: 0cm">Set a name for the test
|
||||
application and click on OK.</P>
|
||||
<LI><P STYLE="margin-bottom: 0cm">In the Wizard: set the same device
|
||||
type and model name as for the driver and select Create to build the
|
||||
test project.</P>
|
||||
<LI><P STYLE="margin-bottom: 0cm">Set the Test Application to Run at
|
||||
Startup.</P>
|
||||
<LI><P STYLE="margin-bottom: 0cm">Click on Debug and the test
|
||||
application should run. You should be able to select your
|
||||
application in the chooser. Selecting Properties should show the
|
||||
default setup dialog for your driver.</P>
|
||||
<LI><P STYLE="margin-bottom: 0cm">Trying to continue will generate
|
||||
errors because the additional properties have not been implemented.</P>
|
||||
</UL>
|
||||
<OL START=4>
|
||||
<LI><P STYLE="margin-bottom: 0cm">Go through the Driver.cs file and
|
||||
replace the System.NotImplemented exceptions with code to implement
|
||||
your driver's functionality. See the ASCOM ISwitchV2
|
||||
spec. If a property or method is not implemented in your driver the
|
||||
System.NotImplemented exception must be replaced by an
|
||||
ASCOM.PropertyNotImplemented or ASCOM.MethodNotImplemented
|
||||
exception.</P>
|
||||
<LI><P>Customize the Setup Dialog (SetupDialogForm) to provide the
|
||||
settings and other controls for your driver. You can bind settings
|
||||
directly to controls on your dialog form, there's no need to manage
|
||||
settings manually. A custom Settings class takes care of managing
|
||||
your settings behind the scenes.
|
||||
</P>
|
||||
</OL>
|
||||
<H3>Notes:</H3>
|
||||
<UL>
|
||||
<LI><P STYLE="margin-bottom: 0cm">Successfully building the driver,
|
||||
as well as using <FONT FACE="Lucida Console, Courier New, Courier, monospace">regasm</FONT>
|
||||
on the assembly, registers it for both COM and ASCOM (the Chooser).
|
||||
See the code in the ASCOM Registration region of Driver.vb.
|
||||
</P>
|
||||
<LI><P STYLE="margin-bottom: 0cm">Doing a Clean for the project, as
|
||||
well doing a <FONT FACE="Lucida Console, Courier New, Courier, monospace">regasm
|
||||
-u</FONT> on the assembly, unregisters it for both COM and ASCOM
|
||||
(the Chooser).
|
||||
</P>
|
||||
<LI><P>Place a breakpoint in your driver class constructor, then
|
||||
start debugging (go, F5). Your breakpoint will be hit when the test
|
||||
application creates an instance of your driver (after selecting it
|
||||
in the Chooser). You can now single step, examine variables, etc.
|
||||
Please review the test application and make changes and additions to
|
||||
activate various parts of your driver during debugging.</P>
|
||||
<LI><P>The project's Debug configuration is already configured (The
|
||||
test application creates an instance of your driver (after selecting
|
||||
it in the Chooser). You can now single step, examine variables, etc.
|
||||
Please review the test application and feel free to make changes and
|
||||
additions to activate various parts of your driver during debugging.
|
||||
</P>
|
||||
</UL>
|
||||
<DIV ALIGN=RIGHT>
|
||||
<TABLE WIDTH=100% BORDER=0 CELLPADDING=4 CELLSPACING=0>
|
||||
<TR>
|
||||
<TD>
|
||||
<TABLE WIDTH=100% BORDER=0 CELLPADDING=4 CELLSPACING=0>
|
||||
<TR>
|
||||
<TD>
|
||||
<H3>ASCOM Initiative</H3>
|
||||
</TD>
|
||||
<TD>
|
||||
<IMG SRC="ASCOM.png" NAME="graphics1" ALIGN=RIGHT WIDTH=48 HEIGHT=56 BORDER=0></TD>
|
||||
</TR>
|
||||
</TABLE>
|
||||
<P><BR><BR>
|
||||
</P>
|
||||
</TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD>
|
||||
<P>The ASCOM Initiative consists of a group of astronomy software
|
||||
developers and instrument vendors whose goals are to promote the
|
||||
driver/client model and scripting automation.
|
||||
</P>
|
||||
<P>See the <A HREF="https://ascom-standards.org/" TARGET="browser">ASCOM
|
||||
web site</A> for more information. Please participate in the
|
||||
<A HREF="https://ascomtalk.groups.io/g/Help/topics" TARGET="browser">ASCOM-Talk
|
||||
Groups.IO forum</A>.
|
||||
</P>
|
||||
</TD>
|
||||
</TR>
|
||||
</TABLE>
|
||||
</DIV>
|
||||
<P><BR><BR>
|
||||
</P><P>
|
||||
<BR><BR>
|
||||
</P>
|
||||
</BODY>
|
||||
</HTML>
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 3.3 KiB |
@@ -0,0 +1,695 @@
|
||||
#define Switch
|
||||
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using ASCOM.Utilities;
|
||||
using ASCOM.DeviceInterface;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
|
||||
namespace ASCOM.LynxAstro.DewController
|
||||
{
|
||||
//
|
||||
// Your driver's DeviceID is ASCOM.LynxAstro.DewController.Switch
|
||||
//
|
||||
// The Guid attribute sets the CLSID for ASCOM.LynxAstro.DewController.Switch
|
||||
// The ClassInterface/None attribute prevents an empty interface called
|
||||
// _LynxAstro.DewController from being created and used as the [default] interface
|
||||
//
|
||||
// TODO Replace the not implemented exceptions with code to implement the function or
|
||||
// throw the appropriate ASCOM exception.
|
||||
//
|
||||
|
||||
/// <summary>
|
||||
/// ASCOM Switch Driver for LynxAstro.DewController.
|
||||
/// </summary>
|
||||
[Guid("3a29744a-f33f-4843-a7e0-6938d9bd50ba")]
|
||||
[ProgId("ASCOM.LynxAstro.DewController.Switch")]
|
||||
[ServedClassName("LynxAstro.DewController")]
|
||||
[ClassInterface(ClassInterfaceType.None)]
|
||||
public class Switch : ISwitchV2
|
||||
{
|
||||
/// <summary>
|
||||
/// ASCOM DeviceID (COM ProgID) for this driver.
|
||||
/// The DeviceID is used by ASCOM applications to load the driver at runtime.
|
||||
/// </summary>
|
||||
internal static string DriverId = Marshal.GenerateProgIdForType(MethodBase.GetCurrentMethod().DeclaringType ?? throw new System.InvalidOperationException());
|
||||
|
||||
/// <summary>
|
||||
/// Driver description that displays in the ASCOM Chooser.
|
||||
/// </summary>
|
||||
private static string DriverDescription = "ASCOM Switch Driver for LynxAstro.DewController";
|
||||
|
||||
protected static string ComPort; // Variables to hold the currrent device configuration
|
||||
protected static TraceLogger Tl;
|
||||
|
||||
protected readonly ISharedResourcesWrapper SharedResourcesWrapper;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="LynxAstro.DewController"/> class.
|
||||
/// Must be public for COM registration.
|
||||
/// </summary>
|
||||
/// <param name="tl"></param>
|
||||
public Switch()
|
||||
{
|
||||
SharedResourcesWrapper = new SharedResourcesWrapper();
|
||||
|
||||
Initialise(nameof(Switch));
|
||||
}
|
||||
|
||||
public Switch(ISharedResourcesWrapper sharedResourcesWrapper)
|
||||
{
|
||||
SharedResourcesWrapper = sharedResourcesWrapper;
|
||||
|
||||
Initialise(nameof(Switch));
|
||||
}
|
||||
|
||||
|
||||
protected void Initialise(string className)
|
||||
{
|
||||
Tl = new TraceLogger("", $"LynxAstro.DewController.{className}");
|
||||
|
||||
ReadProfile(); // Read device configuration from the ASCOM Profile store
|
||||
|
||||
IsConnected = false; // Initialise connected to false
|
||||
|
||||
LogMessage(className, "Completed initialisation");
|
||||
LogMessage(className, $"Driver version: {DriverVersion}");
|
||||
}
|
||||
|
||||
//
|
||||
// PUBLIC COM INTERFACE ISwitchV2 IMPLEMENTATION
|
||||
//
|
||||
|
||||
#region Common properties and methods.
|
||||
|
||||
/// <summary>
|
||||
/// Displays the Setup Dialog form.
|
||||
/// If the user clicks the OK button to dismiss the form, then
|
||||
/// the new settings are saved, otherwise the old values are reloaded.
|
||||
/// THIS IS THE ONLY PLACE WHERE SHOWING USER INTERFACE IS ALLOWED!
|
||||
/// </summary>
|
||||
public void SetupDialog()
|
||||
{
|
||||
LogMessage("SetupDialog", "Opening setup dialog");
|
||||
SharedResourcesWrapper.SetupDialog();
|
||||
ReadProfile();
|
||||
LogMessage("SetupDialog", "complete");
|
||||
}
|
||||
|
||||
public ArrayList SupportedActions
|
||||
{
|
||||
get
|
||||
{
|
||||
Tl.LogMessage("SupportedActions Get", "Returning empty arraylist");
|
||||
return new ArrayList();
|
||||
}
|
||||
}
|
||||
|
||||
public string Action(string actionName, string actionParameters)
|
||||
{
|
||||
LogMessage("", "Action {0}, parameters {1} not implemented", actionName, actionParameters);
|
||||
throw new ASCOM.ActionNotImplementedException("Action " + actionName + " is not implemented by this driver");
|
||||
}
|
||||
|
||||
public void CommandBlind(string command, bool raw)
|
||||
{
|
||||
CheckConnected("CommandBlind");
|
||||
SharedResourcesWrapper.SendBlind(command);
|
||||
}
|
||||
|
||||
public bool CommandBool(string command, bool raw)
|
||||
{
|
||||
CheckConnected("CommandBool");
|
||||
throw new ASCOM.MethodNotImplementedException("CommandBool");
|
||||
}
|
||||
|
||||
public string CommandString(string command, bool raw)
|
||||
{
|
||||
CheckConnected("CommandString");
|
||||
return SharedResourcesWrapper.SendString(command);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
// Clean up the trace logger and util objects
|
||||
Tl.Enabled = false;
|
||||
Tl.Dispose();
|
||||
Tl = null;
|
||||
}
|
||||
|
||||
private string DecodeResult(string pattern, string encodedString)
|
||||
{
|
||||
var decodedString = encodedString.Substring(pattern.Length).TrimEnd('#');
|
||||
return decodedString;
|
||||
}
|
||||
|
||||
public bool Connected
|
||||
{
|
||||
get
|
||||
{
|
||||
LogMessage("Connected", "Get {0}", IsConnected);
|
||||
return IsConnected;
|
||||
}
|
||||
set
|
||||
{
|
||||
LogMessage("Connected", "Set {0}", value);
|
||||
if (value == IsConnected)
|
||||
return;
|
||||
|
||||
if (value)
|
||||
{
|
||||
try
|
||||
{
|
||||
ReadProfile();
|
||||
|
||||
LogMessage("Connected Set", "Connecting to port {0}", ComPort);
|
||||
var connectionInfo = SharedResourcesWrapper.Connect("Serial", DriverId, Tl);
|
||||
try
|
||||
{
|
||||
LogMessage("Connected Set", $"Connected to port {ComPort}. Version:{SharedResourcesWrapper.FirmwareVersion}");
|
||||
|
||||
IsConnected = true;
|
||||
|
||||
LogMessage("Connected Set", $"Connected OK.");
|
||||
|
||||
var maxSwitch = MaxSwitch;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
SharedResourcesWrapper.Disconnect("Serial", DriverId);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogMessage("Connected Set", "Error connecting to port {0} - {1}", ComPort, ex.Message);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LogMessage("Connected Set", "Disconnecting from port {0}", ComPort);
|
||||
SharedResourcesWrapper.Disconnect("Serial", DriverId);
|
||||
IsConnected = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public string Description
|
||||
{
|
||||
get
|
||||
{
|
||||
Tl.LogMessage("Description Get", DriverDescription);
|
||||
return DriverDescription;
|
||||
}
|
||||
}
|
||||
|
||||
public string DriverInfo
|
||||
{
|
||||
get
|
||||
{
|
||||
string driverInfo = $"{Description} .net driver. Version: {DriverVersion}";
|
||||
LogMessage("DriverInfo Get", driverInfo);
|
||||
return driverInfo;
|
||||
}
|
||||
}
|
||||
|
||||
public string DriverVersion
|
||||
{
|
||||
get
|
||||
{
|
||||
Version version = Assembly.GetExecutingAssembly().GetName().Version;
|
||||
string driverVersion = $"{version.Major}.{version.Minor}.{version.Build}.{version.Revision}";
|
||||
LogMessage("DriverVersion Get", driverVersion);
|
||||
return driverVersion;
|
||||
}
|
||||
}
|
||||
|
||||
public short InterfaceVersion
|
||||
{
|
||||
// set by the driver wizard
|
||||
get
|
||||
{
|
||||
LogMessage("InterfaceVersion Get", "2");
|
||||
return Convert.ToInt16("2");
|
||||
}
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
string name = "LynxAstro.DewController";
|
||||
Tl.LogMessage("Name Get", name);
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ISwitchV2 Implementation
|
||||
|
||||
private short numSwitch = 0;
|
||||
private List<string> switchNames = new List<string>();
|
||||
|
||||
/// <summary>
|
||||
/// The number of switches managed by this driver
|
||||
/// </summary>
|
||||
public short MaxSwitch
|
||||
{
|
||||
get
|
||||
{
|
||||
CheckConnected("MaxSwitch Get");
|
||||
|
||||
var result = SharedResourcesWrapper.SendString(":GD#");
|
||||
var decoded = DecodeResult(":GD", result);
|
||||
|
||||
this.numSwitch = short.Parse(decoded);
|
||||
|
||||
//Command: :GD#
|
||||
//Purpose: Get the device type, i.e.the number of channels the dew controller has.
|
||||
//Response: :GDX# where X is either 1 or 4 depending on the number of channels this device has
|
||||
|
||||
Tl.LogMessage("MaxSwitch Get", numSwitch.ToString());
|
||||
return this.numSwitch;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return the name of switch n
|
||||
/// </summary>
|
||||
/// <param name="id">The switch number to return</param>
|
||||
/// <returns>
|
||||
/// The name of the switch
|
||||
/// </returns>
|
||||
public string GetSwitchName(short id)
|
||||
{
|
||||
Validate("GetSwitchName", id);
|
||||
ReadProfile();
|
||||
|
||||
return switchNames.Count > id ? switchNames[id] : string.Empty;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets a switch name to a specified value
|
||||
/// </summary>
|
||||
/// <param name="id">The number of the switch whose name is to be set</param>
|
||||
/// <param name="name">The name of the switch</param>
|
||||
public void SetSwitchName(short id, string name)
|
||||
{
|
||||
Validate("SetSwitchName", id);
|
||||
ReadProfile();
|
||||
|
||||
while (id > switchNames.Count)
|
||||
switchNames.Add(string.Empty);
|
||||
|
||||
switchNames[id] = name;
|
||||
|
||||
WriteSwitchNames();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the switch description.
|
||||
/// </summary>
|
||||
/// <param name="id">The id.</param>
|
||||
/// <returns></returns>
|
||||
public string GetSwitchDescription(short id)
|
||||
{
|
||||
Validate("GetSwitchDescription", id);
|
||||
return "Control Knob";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reports if the specified switch can be written to.
|
||||
/// This is false if the switch cannot be written to, for example a limit switch or a sensor.
|
||||
/// The default is true.
|
||||
/// </summary>
|
||||
/// <param name="id">The number of the switch whose write state is to be returned</param><returns>
|
||||
/// <c>true</c> if the switch can be written to, otherwise <c>false</c>.
|
||||
/// </returns>
|
||||
/// <exception cref="MethodNotImplementedException">If the method is not implemented</exception>
|
||||
/// <exception cref="InvalidValueException">If id is outside the range 0 to MaxSwitch - 1</exception>
|
||||
public bool CanWrite(short id)
|
||||
{
|
||||
Validate("CanWrite", id);
|
||||
// default behavour is to report true
|
||||
Tl.LogMessage("CanWrite", string.Format("CanWrite({0}) - default true", id));
|
||||
return true;
|
||||
// implementation should report the correct behaviour
|
||||
//tl.LogMessage("CanWrite", string.Format("CanWrite({0}) - not implemented", id));
|
||||
//throw new MethodNotImplementedException("CanWrite");
|
||||
}
|
||||
|
||||
#region boolean switch members
|
||||
|
||||
/// <summary>
|
||||
/// Return the state of switch n
|
||||
/// a multi-value switch must throw a not implemented exception
|
||||
/// </summary>
|
||||
/// <param name="id">The switch number to return</param>
|
||||
/// <returns>
|
||||
/// True or false
|
||||
/// </returns>
|
||||
public bool GetSwitch(short id)
|
||||
{
|
||||
var value = GetSwitchValue(id);
|
||||
return value > 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets a switch to the specified state
|
||||
/// If the switch cannot be set then throws a MethodNotImplementedException.
|
||||
/// A multi-value switch must throw a not implemented exception
|
||||
/// setting it to false will set it to its minimum value.
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <param name="state"></param>
|
||||
public void SetSwitch(short id, bool state)
|
||||
{
|
||||
Validate("SetSwitch", id);
|
||||
if (!CanWrite(id))
|
||||
{
|
||||
var str = string.Format("SetSwitch({0}) - Cannot Write", id);
|
||||
Tl.LogMessage("SetSwitch", str);
|
||||
throw new MethodNotImplementedException(str);
|
||||
}
|
||||
SetSwitchValue(id, state ? 1023 : 0);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region analogue members
|
||||
|
||||
/// <summary>
|
||||
/// returns the maximum value for this switch
|
||||
/// boolean switches must return 1.0
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
public double MaxSwitchValue(short id)
|
||||
{
|
||||
Validate("MaxSwitchValue", id);
|
||||
// boolean switch implementation:
|
||||
return 1023;
|
||||
// or
|
||||
//tl.LogMessage("MaxSwitchValue", string.Format("MaxSwitchValue({0}) - not implemented", id));
|
||||
//throw new MethodNotImplementedException("MaxSwitchValue");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// returns the minimum value for this switch
|
||||
/// boolean switches must return 0.0
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
public double MinSwitchValue(short id)
|
||||
{
|
||||
Validate("MinSwitchValue", id);
|
||||
// boolean switch implementation:
|
||||
return 0;
|
||||
// or
|
||||
//tl.LogMessage("MinSwitchValue", string.Format("MinSwitchValue({0}) - not implemented", id));
|
||||
//throw new MethodNotImplementedException("MinSwitchValue");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// returns the step size that this switch supports. This gives the difference between
|
||||
/// successive values of the switch.
|
||||
/// The number of values is ((MaxSwitchValue - MinSwitchValue) / SwitchStep) + 1
|
||||
/// boolean switches must return 1.0, giving two states.
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
public double SwitchStep(short id)
|
||||
{
|
||||
Validate("SwitchStep", id);
|
||||
// boolean switch implementation:
|
||||
return 1;
|
||||
// or
|
||||
//tl.LogMessage("SwitchStep", string.Format("SwitchStep({0}) - not implemented", id));
|
||||
//throw new MethodNotImplementedException("SwitchStep");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// returns the analogue switch value for switch id
|
||||
/// boolean switches must throw a not implemented exception
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
public double GetSwitchValue(short id)
|
||||
{
|
||||
Validate("GetSwitchValue", id);
|
||||
Tl.LogMessage("GetSwitchValue", string.Format("GetSwitchValue({0}) - not implemented", id));
|
||||
|
||||
var channel = ChannelToLetter(id);
|
||||
|
||||
var encoded = SharedResourcesWrapper.SendString($":GC{channel}#");
|
||||
var decoded = DecodeResult(":GC", encoded);
|
||||
|
||||
return double.Parse(decoded.TrimStart(channel));
|
||||
//Command: :GCX# where X is the channel A, B, C or D to retrieve.
|
||||
//Purpose: Get the current power setting for a specific channel.
|
||||
//Response: :GCXVVVV# where X is the channel A, B, C or D returned and VVVV is the power level between 0 - 1023.
|
||||
//Possible Errors
|
||||
//:ER5# = Channel out of range, e.g. channel B on a 1 channel device.
|
||||
}
|
||||
|
||||
private char ChannelToLetter(short id)
|
||||
{
|
||||
UInt16 ord = (UInt16) 'A';
|
||||
ord += (ushort)id;
|
||||
return (char)ord;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// set the analogue value for this switch.
|
||||
/// If the switch cannot be set then throws a MethodNotImplementedException.
|
||||
/// If the value is not between the maximum and minimum then throws an InvalidValueException
|
||||
/// boolean switches must throw a not implemented exception.
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <param name="value"></param>
|
||||
public void SetSwitchValue(short id, double value)
|
||||
{
|
||||
Validate("SetSwitchValue", id, value);
|
||||
if (!CanWrite(id))
|
||||
{
|
||||
Tl.LogMessage("SetSwitchValue", string.Format("SetSwitchValue({0}) - Cannot write", id));
|
||||
throw new ASCOM.MethodNotImplementedException(string.Format("SetSwitchValue({0}) - Cannot write", id));
|
||||
}
|
||||
//Tl.LogMessage("SetSwitchValue", string.Format("SetSwitchValue({0}) = {1} - not implemented", id, value));
|
||||
//throw new MethodNotImplementedException("SetSwitchValue");
|
||||
|
||||
|
||||
//Command: :SCXVVVV# where X is the channel A, B, C or D to set and VVVV is the power level
|
||||
//between 0 - 1023.The power level must be 4 digits long so pad with leading zeros if necessary.
|
||||
//Purpose: Set the current power setting for a specific channel.
|
||||
//Response: :SC1# indicates success. Run a GA or GC command to verify.
|
||||
//Possible Errors
|
||||
//:ER4# = Not enough data received - make sure you zero pad the power level.
|
||||
//:ER5# = Channel or power level out of range, e.g. channel B on a 1 channel device or power above 1023.
|
||||
|
||||
var channel = ChannelToLetter(id);
|
||||
|
||||
var encoded = SharedResourcesWrapper.SendString($":SC{channel}{value:0000}#");
|
||||
var decoded = DecodeResult(":SC", encoded);
|
||||
|
||||
if (decoded != "1")
|
||||
{
|
||||
throw new InvalidValueException($"Unable to set switch {{id}} to value {value}");
|
||||
}
|
||||
//return double.Parse(decoded.TrimStart(channel));
|
||||
}
|
||||
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
#region private methods
|
||||
|
||||
/// <summary>
|
||||
/// Checks that the switch id is in range and throws an InvalidValueException if it isn't
|
||||
/// </summary>
|
||||
/// <param name="message">The message.</param>
|
||||
/// <param name="id">The id.</param>
|
||||
private void Validate(string message, short id)
|
||||
{
|
||||
if (id < 0 || id >= numSwitch)
|
||||
{
|
||||
Tl.LogMessage(message, string.Format("Switch {0} not available, range is 0 to {1}", id, numSwitch - 1));
|
||||
throw new InvalidValueException(message, id.ToString(), string.Format("0 to {0}", numSwitch - 1));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks that the switch id and value are in range and throws an
|
||||
/// InvalidValueException if they are not.
|
||||
/// </summary>
|
||||
/// <param name="message">The message.</param>
|
||||
/// <param name="id">The id.</param>
|
||||
/// <param name="value">The value.</param>
|
||||
private void Validate(string message, short id, double value)
|
||||
{
|
||||
Validate(message, id);
|
||||
var min = MinSwitchValue(id);
|
||||
var max = MaxSwitchValue(id);
|
||||
if (value < min || value > max)
|
||||
{
|
||||
Tl.LogMessage(message, string.Format("Value {1} for Switch {0} is out of the allowed range {2} to {3}", id, value, min, max));
|
||||
throw new InvalidValueException(message, value.ToString(), string.Format("Switch({0}) range {1} to {2}", id, min, max));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks that the number of states for the switch is correct and throws a methodNotImplemented exception if not.
|
||||
/// Boolean switches must have 2 states and multi-value switches more than 2.
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
/// <param name="id"></param>
|
||||
/// <param name="expectBoolean"></param>
|
||||
//private void Validate(string message, short id, bool expectBoolean)
|
||||
//{
|
||||
// Validate(message, id);
|
||||
// var ns = (int)(((MaxSwitchValue(id) - MinSwitchValue(id)) / SwitchStep(id)) + 1);
|
||||
// if ((expectBoolean && ns != 2) || (!expectBoolean && ns <= 2))
|
||||
// {
|
||||
// tl.LogMessage(message, string.Format("Switch {0} has the wriong number of states", id, ns));
|
||||
// throw new MethodNotImplementedException(string.Format("{0}({1})", message, id));
|
||||
// }
|
||||
//}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Private properties and methods
|
||||
// here are some useful properties and methods that can be used as required
|
||||
// to help with driver development
|
||||
|
||||
#region ASCOM Registration
|
||||
|
||||
// Register or unregister driver for ASCOM. This is harmless if already
|
||||
// registered or unregistered.
|
||||
//
|
||||
/// <summary>
|
||||
/// Register or unregister the driver with the ASCOM Platform.
|
||||
/// This is harmless if the driver is already registered/unregistered.
|
||||
/// </summary>
|
||||
/// <param name="bRegister">If <c>true</c>, registers the driver, otherwise unregisters it.</param>
|
||||
private static void RegUnregASCOM(bool bRegister)
|
||||
{
|
||||
using (var P = new ASCOM.Utilities.Profile())
|
||||
{
|
||||
P.DeviceType = "Switch";
|
||||
if (bRegister)
|
||||
{
|
||||
P.Register(DriverId, DriverDescription);
|
||||
}
|
||||
else
|
||||
{
|
||||
P.Unregister(DriverId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This function registers the driver with the ASCOM Chooser and
|
||||
/// is called automatically whenever this class is registered for COM Interop.
|
||||
/// </summary>
|
||||
/// <param name="t">Type of the class being registered, not used.</param>
|
||||
/// <remarks>
|
||||
/// This method typically runs in two distinct situations:
|
||||
/// <list type="numbered">
|
||||
/// <item>
|
||||
/// In Visual Studio, when the project is successfully built.
|
||||
/// For this to work correctly, the option <c>Register for COM Interop</c>
|
||||
/// must be enabled in the project settings.
|
||||
/// </item>
|
||||
/// <item>During setup, when the installer registers the assembly for COM Interop.</item>
|
||||
/// </list>
|
||||
/// This technique should mean that it is never necessary to manually register a driver with ASCOM.
|
||||
/// </remarks>
|
||||
[ComRegisterFunction]
|
||||
public static void RegisterASCOM(Type t)
|
||||
{
|
||||
RegUnregASCOM(true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This function unregisters the driver from the ASCOM Chooser and
|
||||
/// is called automatically whenever this class is unregistered from COM Interop.
|
||||
/// </summary>
|
||||
/// <param name="t">Type of the class being registered, not used.</param>
|
||||
/// <remarks>
|
||||
/// This method typically runs in two distinct situations:
|
||||
/// <list type="numbered">
|
||||
/// <item>
|
||||
/// In Visual Studio, when the project is cleaned or prior to rebuilding.
|
||||
/// For this to work correctly, the option <c>Register for COM Interop</c>
|
||||
/// must be enabled in the project settings.
|
||||
/// </item>
|
||||
/// <item>During uninstall, when the installer unregisters the assembly from COM Interop.</item>
|
||||
/// </list>
|
||||
/// This technique should mean that it is never necessary to manually unregister a driver from ASCOM.
|
||||
/// </remarks>
|
||||
[ComUnregisterFunction]
|
||||
public static void UnregisterASCOM(Type t)
|
||||
{
|
||||
RegUnregASCOM(false);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
protected bool IsConnected { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Use this function to throw an exception if we aren't connected to the hardware
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
private void CheckConnected(string message)
|
||||
{
|
||||
if (!IsConnected)
|
||||
{
|
||||
throw new ASCOM.NotConnectedException(message);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read the device configuration from the ASCOM Profile store
|
||||
/// </summary>
|
||||
protected void ReadProfile()
|
||||
{
|
||||
var profileProperties = SharedResourcesWrapper.ReadProfile();
|
||||
Tl.Enabled = profileProperties.TraceLogger;
|
||||
ComPort = profileProperties.ComPort;
|
||||
|
||||
switchNames.Clear();
|
||||
switchNames.AddRange(profileProperties.SwitchNames);
|
||||
|
||||
LogMessage("ReadProfile", $"Trace logger enabled: {Tl.Enabled}");
|
||||
LogMessage("ReadProfile", $"Com Port: {ComPort}");
|
||||
|
||||
}
|
||||
|
||||
protected void WriteSwitchNames()
|
||||
{
|
||||
var profileProperties = SharedResourcesWrapper.ReadProfile();
|
||||
|
||||
profileProperties.SwitchNames.Clear();
|
||||
profileProperties.SwitchNames.AddRange(switchNames);
|
||||
|
||||
SharedResourcesWrapper.WriteProfile(profileProperties);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Log helper function that takes formatted strings and arguments
|
||||
/// </summary>
|
||||
/// <param name="identifier"></param>
|
||||
/// <param name="message"></param>
|
||||
/// <param name="args"></param>
|
||||
internal void LogMessage(string identifier, string message, params object[] args)
|
||||
{
|
||||
var msg = string.Format(message, args);
|
||||
Tl.LogMessage(identifier, msg);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0"?>
|
||||
<configuration>
|
||||
<configSections>
|
||||
<sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<section name="ASCOM.DeviceName.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false"/>
|
||||
</sectionGroup>
|
||||
</configSections>
|
||||
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2"/></startup></configuration>
|
||||
@@ -0,0 +1,64 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
|
||||
<ProductVersion>8.0.30703</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{D5207217-61C7-4E94-8097-91DBACE57D2A}</ProjectGuid>
|
||||
<OutputType>Exe</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>ASCOM.LynxAstro.DewController</RootNamespace>
|
||||
<AssemblyName>ASCOM.LynxAstro.DewController.TestConsole</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
|
||||
<TargetFrameworkProfile>
|
||||
</TargetFrameworkProfile>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<Prefer32Bit>false</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<Prefer32Bit>false</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="ASCOM.DeviceInterfaces, Version=6.0.0.0, Culture=neutral, PublicKeyToken=565de7938946fba7, processorArchitecture=MSIL" />
|
||||
<Reference Include="ASCOM.DriverAccess, Version=6.0.0.0, Culture=neutral, PublicKeyToken=565de7938946fba7, processorArchitecture=MSIL" />
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="app.config" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
||||
@@ -0,0 +1,78 @@
|
||||
// This implements a console application that can be used to test an ASCOM driver
|
||||
//
|
||||
|
||||
// This is used to define code in the template that is specific to one class implementation
|
||||
// unused code can be deleted and this definition removed.
|
||||
|
||||
#define Switch
|
||||
// remove this to bypass the code that uses the chooser to select the driver
|
||||
//#define UseChooser
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace ASCOM
|
||||
{
|
||||
class Program
|
||||
{
|
||||
static void Main(string[] args)
|
||||
{
|
||||
// Uncomment the code that's required
|
||||
#if UseChooser
|
||||
// choose the device
|
||||
string id = ASCOM.DriverAccess.Switch.Choose("");
|
||||
if (string.IsNullOrEmpty(id))
|
||||
return;
|
||||
// create this device
|
||||
ASCOM.DriverAccess.Switch device = new ASCOM.DriverAccess.Switch(id);
|
||||
#else
|
||||
// this can be replaced by this code, it avoids the chooser and creates the driver class directly.
|
||||
ASCOM.DriverAccess.Switch device = new ASCOM.DriverAccess.Switch("ASCOM.LynxAstro.DewController.Switch");
|
||||
#endif
|
||||
// now run some tests, adding code to your driver so that the tests will pass.
|
||||
// these first tests are common to all drivers.
|
||||
Console.WriteLine("name " + device.Name);
|
||||
Console.WriteLine("description " + device.Description);
|
||||
Console.WriteLine("DriverInfo " + device.DriverInfo);
|
||||
Console.WriteLine("driverVersion " + device.DriverVersion);
|
||||
|
||||
// TODO add more code to test the driver.
|
||||
device.Connected = true;
|
||||
|
||||
Console.WriteLine("Number of switches: " + device.MaxSwitch);
|
||||
|
||||
for (short i = 0; i < device.MaxSwitch; i++)
|
||||
{
|
||||
var min = device.MinSwitchValue(i);
|
||||
var max = device.MaxSwitchValue(i);
|
||||
var step = device.SwitchStep(i);
|
||||
|
||||
var value = device.GetSwitchValue(i);
|
||||
|
||||
Console.WriteLine($"switch {i}: {min} - {max} stepsize {step}: {value}");
|
||||
}
|
||||
|
||||
for (short i = 0; i < device.MaxSwitch; i++)
|
||||
{
|
||||
device.SetSwitchValue(i, 500);
|
||||
}
|
||||
|
||||
for (short i = 0; i < device.MaxSwitch; i++)
|
||||
{
|
||||
var min = device.MinSwitchValue(i);
|
||||
var max = device.MaxSwitchValue(i);
|
||||
var step = device.SwitchStep(i);
|
||||
|
||||
var value = device.GetSwitchValue(i);
|
||||
|
||||
Console.WriteLine($"switch {i}: {min} - {max} stepsize {step}: {value}");
|
||||
}
|
||||
|
||||
device.Connected = false;
|
||||
Console.WriteLine("Press Enter to finish");
|
||||
Console.ReadLine();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("LynxAstro.DewController Test Application")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("ASCOM Initiative")]
|
||||
[assembly: AssemblyProduct("LynxAstro.DewController")]
|
||||
[assembly: AssemblyCopyright("Copyright © ASCOM Initiative 2014")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("c7008f94-e3b9-4481-b720-3b56557860c6")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
|
||||
[assembly: AssemblyVersion("6.4.0.0")]
|
||||
[assembly: AssemblyFileVersion("6.4.0.0")]
|
||||
@@ -0,0 +1,3 @@
|
||||
<?xml version="1.0"?>
|
||||
<configuration>
|
||||
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2"/></startup></configuration>
|
||||
@@ -0,0 +1,115 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="..\packages\NUnit.3.13.1\build\NUnit.props" Condition="Exists('..\packages\NUnit.3.13.1\build\NUnit.props')" />
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{BDED8EBB-7F9F-4710-8B74-59298C2DFCAD}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>LynxAstro.DewController.UnitTests</RootNamespace>
|
||||
<AssemblyName>LynxAstro.DewController.UnitTests</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<Deterministic>true</Deterministic>
|
||||
<NuGetPackageImportStamp>
|
||||
</NuGetPackageImportStamp>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="ASCOM.Astrometry, Version=6.0.0.0, Culture=neutral, PublicKeyToken=565de7938946fba7, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\ASCOM.Platform.6.5.2\lib\net40\ASCOM.Astrometry.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="ASCOM.Attributes, Version=6.0.0.0, Culture=neutral, PublicKeyToken=565de7938946fba7, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\ASCOM.Platform.6.5.2\lib\net40\ASCOM.Attributes.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="ASCOM.Cache, Version=6.0.0.0, Culture=neutral, PublicKeyToken=565de7938946fba7, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\ASCOM.Platform.6.5.2\lib\net40\ASCOM.Cache.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="ASCOM.Controls, Version=6.0.0.0, Culture=neutral, PublicKeyToken=565de7938946fba7, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\ASCOM.Platform.6.5.2\lib\net40\ASCOM.Controls.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="ASCOM.DeviceInterfaces, Version=6.0.0.0, Culture=neutral, PublicKeyToken=565de7938946fba7, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\ASCOM.Platform.6.5.2\lib\net40\ASCOM.DeviceInterfaces.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="ASCOM.DriverAccess, Version=6.0.0.0, Culture=neutral, PublicKeyToken=565de7938946fba7, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\ASCOM.Platform.6.5.2\lib\net40\ASCOM.DriverAccess.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="ASCOM.Exceptions, Version=6.0.0.0, Culture=neutral, PublicKeyToken=565de7938946fba7, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\ASCOM.Platform.6.5.2\lib\net40\ASCOM.Exceptions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="ASCOM.Internal.Extensions, Version=6.0.0.0, Culture=neutral, PublicKeyToken=565de7938946fba7, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\ASCOM.Platform.6.5.2\lib\net40\ASCOM.Internal.Extensions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="ASCOM.SettingsProvider, Version=6.0.0.0, Culture=neutral, PublicKeyToken=565de7938946fba7, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\ASCOM.Platform.6.5.2\lib\net40\ASCOM.SettingsProvider.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="ASCOM.Utilities, Version=6.0.0.0, Culture=neutral, PublicKeyToken=565de7938946fba7, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\ASCOM.Platform.6.5.2\lib\net40\ASCOM.Utilities.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="ASCOM.Utilities.Video, Version=6.1.0.0, Culture=neutral, PublicKeyToken=565de7938946fba7, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\ASCOM.Platform.6.5.2\lib\net40\ASCOM.Utilities.Video.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Castle.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Castle.Core.4.4.0\lib\net45\Castle.Core.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Moq, Version=4.16.0.0, Culture=neutral, PublicKeyToken=69f491c39445e920, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Moq.4.16.0\lib\net45\Moq.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="nunit.framework, Version=3.13.1.0, Culture=neutral, PublicKeyToken=2638cd05610744eb, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\NUnit.3.13.1\lib\net45\nunit.framework.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Configuration" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Runtime.CompilerServices.Unsafe, Version=4.0.4.1, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Runtime.CompilerServices.Unsafe.4.5.3\lib\net461\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Threading.Tasks.Extensions, Version=4.2.0.1, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Threading.Tasks.Extensions.4.5.4\lib\net461\System.Threading.Tasks.Extensions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="SharedResourcesUnitTests.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\LynxAstro.DewController\LynxAstro.DewController.csproj">
|
||||
<Project>{c708e487-e3a9-4073-a545-294b88674225}</Project>
|
||||
<Name>LynxAstro.DewController</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('..\packages\NUnit.3.13.1\build\NUnit.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\NUnit.3.13.1\build\NUnit.props'))" />
|
||||
</Target>
|
||||
</Project>
|
||||
@@ -0,0 +1,35 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("LynxAstro.DewController.UnitTests")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("LynxAstro.DewController.UnitTests")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2021")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("bded8ebb-7f9f-4710-8b74-59298c2dfcad")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
@@ -0,0 +1,189 @@
|
||||
using System;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using ASCOM.LynxAstro.DewController;
|
||||
using ASCOM.Utilities.Interfaces;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace LynxAstro.DewController.UnitTests
|
||||
{
|
||||
[TestFixture]
|
||||
public class SharedResourcesUnitTests
|
||||
{
|
||||
private Mock<ISerial> _serialMock;
|
||||
private Mock<ITraceLogger> _traceLoggerMock;
|
||||
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
_serialMock = new Mock<ISerial>();
|
||||
_serialMock.SetupAllProperties();
|
||||
|
||||
_traceLoggerMock = new Mock<ITraceLogger>();
|
||||
|
||||
SharedResources.SharedSerial = _serialMock.Object;
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CheckThatSerialPortIsSetToUseMock()
|
||||
{
|
||||
Assert.That(SharedResources.SharedSerial, Is.EqualTo(_serialMock.Object));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SendBlind_WhenCalled_Then_ClearsBuffersAndSendsMessage()
|
||||
{
|
||||
var expectedMessage = "Test";
|
||||
|
||||
SharedResources.SendBlind(expectedMessage);
|
||||
|
||||
_serialMock.Verify(x => x.ClearBuffers(), Times.Once);
|
||||
_serialMock.Verify(x => x.Transmit(expectedMessage), Times.Once);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SendChar_WhenCalled_ThenSendsMessageAndReadsExpectedNumberOfCharacters()
|
||||
{
|
||||
var expectedMessage = "Test";
|
||||
var expectedResult = "A";
|
||||
|
||||
_serialMock.Setup(x => x.ReceiveCounted(1)).Returns(expectedResult);
|
||||
|
||||
var result = SharedResources.SendChar(expectedMessage);
|
||||
|
||||
_serialMock.Verify(x => x.ClearBuffers(), Times.Once);
|
||||
_serialMock.Verify(x => x.Transmit(expectedMessage), Times.Once);
|
||||
_serialMock.Verify(x => x.ReceiveCounted(1), Times.Once);
|
||||
Assert.That(result, Is.EqualTo(expectedResult));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SendString_WhenCalled_ThenSendsMessageAndReadsResultUntilTerminatorFound()
|
||||
{
|
||||
var expectedMessage = "Test";
|
||||
var expectedResult = "TestMessage#";
|
||||
|
||||
_serialMock.Setup(x => x.ReceiveTerminated("#")).Returns(expectedResult);
|
||||
|
||||
var result = SharedResources.SendString(expectedMessage);
|
||||
|
||||
_serialMock.Verify(x => x.ClearBuffers(), Times.Once);
|
||||
_serialMock.Verify(x => x.Transmit(expectedMessage), Times.Once);
|
||||
_serialMock.Verify(x => x.ReceiveTerminated("#"), Times.Once);
|
||||
Assert.That(result, Is.EqualTo(expectedResult.TrimEnd('#')));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ReadTerminated_WhenCalled_ThenReadsResultUntilTerminatorFound()
|
||||
{
|
||||
var expectedResult = "TestMessage#";
|
||||
|
||||
_serialMock.Setup(x => x.ReceiveTerminated("#")).Returns(expectedResult);
|
||||
|
||||
var result = SharedResources.ReadTerminated();
|
||||
|
||||
_serialMock.Verify(x => x.ReceiveTerminated("#"), Times.Once);
|
||||
Assert.That(result, Is.EqualTo(expectedResult));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ReadCharacters_WhenCalled_ThenReadsSpecificNumberOfCharacters()
|
||||
{
|
||||
var numberOfCharacters = 5;
|
||||
|
||||
SharedResources.ReadCharacters(numberOfCharacters);
|
||||
|
||||
_serialMock.Verify(x => x.ReceiveCounted(numberOfCharacters), Times.Once);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void WriteProfile_WhenCalled_WritesExpectedProfileSettings()
|
||||
{
|
||||
string DriverId = "ASCOM.MeadeGeneric.Telescope";
|
||||
|
||||
Mock<IProfileWrapper> profileWrapperMock = new Mock<IProfileWrapper>();
|
||||
profileWrapperMock.SetupAllProperties();
|
||||
|
||||
IProfileWrapper profeWrapper = profileWrapperMock.Object;
|
||||
|
||||
Mock<IProfileFactory> profileFactoryMock = new Mock<IProfileFactory>();
|
||||
profileFactoryMock.Setup(x => x.Create()).Returns(profileWrapperMock.Object);
|
||||
|
||||
SharedResources.ProfileFactory = profileFactoryMock.Object;
|
||||
|
||||
var profileProperties = new ProfileProperties
|
||||
{
|
||||
TraceLogger = false,
|
||||
ComPort = "TestComPort"
|
||||
};
|
||||
|
||||
SharedResources.WriteProfile(profileProperties);
|
||||
|
||||
Assert.That(profeWrapper.DeviceType, Is.EqualTo("Telescope"));
|
||||
profileWrapperMock.Verify(x => x.WriteValue(DriverId, "Trace Level", profileProperties.TraceLogger.ToString()), Times.Once);
|
||||
profileWrapperMock.Verify(x => x.WriteValue(DriverId, "COM Port", profileProperties.ComPort), Times.Once);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ReadProfile_WhenCalled_ReturnsExpectedDefaultValues()
|
||||
{
|
||||
string DriverId = "ASCOM.MeadeGeneric.Telescope";
|
||||
|
||||
string ComPortDefault = "COM1";
|
||||
string TraceStateDefault = "false";
|
||||
string GuideRateProfileNameDefault = "10.077939"; //67% of sidereal rate
|
||||
string PrecisionDefault = "Unchanged";
|
||||
string GuidingStyleDefault = "Auto";
|
||||
string BacklashCompensationDefault = "3000";
|
||||
string ReverseFocuserDiectionDefault = "true";
|
||||
|
||||
Mock<IProfileWrapper> profileWrapperMock = new Mock<IProfileWrapper>();
|
||||
profileWrapperMock.SetupAllProperties();
|
||||
|
||||
profileWrapperMock.Setup(x => x.GetValue(DriverId, "Trace Level", string.Empty, TraceStateDefault))
|
||||
.Returns(() =>
|
||||
TraceStateDefault);
|
||||
profileWrapperMock.Setup(x => x.GetValue(DriverId, "COM Port", string.Empty, ComPortDefault))
|
||||
.Returns(ComPortDefault);
|
||||
profileWrapperMock
|
||||
.Setup(x => x.GetValue(DriverId, "Guide Rate Arc Seconds Per Second", string.Empty,
|
||||
GuideRateProfileNameDefault)).Returns(GuideRateProfileNameDefault);
|
||||
profileWrapperMock.Setup(x => x.GetValue(DriverId, "Precision", string.Empty, PrecisionDefault))
|
||||
.Returns(PrecisionDefault);
|
||||
profileWrapperMock.Setup(x => x.GetValue(DriverId, "Guiding Style", string.Empty, GuidingStyleDefault))
|
||||
.Returns(GuidingStyleDefault);
|
||||
profileWrapperMock.Setup(x =>
|
||||
x.GetValue(DriverId, "Backlash Compensation", string.Empty, BacklashCompensationDefault))
|
||||
.Returns(BacklashCompensationDefault);
|
||||
profileWrapperMock.Setup(x =>
|
||||
x.GetValue(DriverId, "Reverse Focuser Direction", string.Empty, ReverseFocuserDiectionDefault))
|
||||
.Returns(() => ReverseFocuserDiectionDefault);
|
||||
|
||||
profileWrapperMock.Setup(x =>
|
||||
x.GetValue(DriverId, It.IsRegex("^SwitchName_[0-9{1}]$"), string.Empty, It.IsAny<string>()))
|
||||
.Returns((string driverId, string name, string subKey, string defaultValue) => defaultValue);
|
||||
|
||||
IProfileWrapper profeWrapper = profileWrapperMock.Object;
|
||||
|
||||
Mock<IProfileFactory> profileFactoryMock = new Mock<IProfileFactory>();
|
||||
profileFactoryMock.Setup(x => x.Create()).Returns(profileWrapperMock.Object);
|
||||
|
||||
SharedResources.ProfileFactory = profileFactoryMock.Object;
|
||||
|
||||
var profileProperties = SharedResources.ReadProfile();
|
||||
|
||||
Assert.That(profeWrapper.DeviceType, Is.EqualTo("Telescope"));
|
||||
Assert.That(profileProperties.ComPort, Is.EqualTo(ComPortDefault));
|
||||
Assert.That(profileProperties.TraceLogger, Is.EqualTo(bool.Parse(TraceStateDefault)));
|
||||
}
|
||||
|
||||
[TestCase("TCP")]
|
||||
[TestCase("Carrier Pigeon")]
|
||||
public void Connect_WhenDeviceIdIsNotSerial_ThenThrowsException(string deviceId)
|
||||
{
|
||||
var result = Assert.Throws<ArgumentException>(() => { SharedResources.Connect(deviceId, string.Empty, _traceLoggerMock.Object); });
|
||||
|
||||
Assert.That(result.Message, Is.EqualTo($"deviceId {deviceId} not currently supported"));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="ASCOM.Platform" version="6.5.2" targetFramework="net472" />
|
||||
<package id="Castle.Core" version="4.4.0" targetFramework="net472" />
|
||||
<package id="Moq" version="4.16.0" targetFramework="net472" />
|
||||
<package id="NUnit" version="3.13.1" targetFramework="net472" />
|
||||
<package id="System.Runtime.CompilerServices.Unsafe" version="4.5.3" targetFramework="net472" />
|
||||
<package id="System.Threading.Tasks.Extensions" version="4.5.4" targetFramework="net472" />
|
||||
</packages>
|
||||
@@ -0,0 +1,88 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.29905.134
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LynxAstro.DewController", "LynxAstro.DewController\LynxAstro.DewController.csproj", "{C708E487-E3A9-4073-A545-294B88674225}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LynxAstro.DewController.Switch", "LynxAstro.DewController.Switch\LynxAstro.DewController.Switch.csproj", "{64308775-BD4A-469C-BCAB-3ED830B811AF}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "UnitTests", "UnitTests", "{7CAA050A-2EB3-4A21-8A75-131EB0AC9778}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LynxAstro.DewController.UnitTests", "LynxAstro.DewController.UnitTests\LynxAstro.DewController.UnitTests.csproj", "{BDED8EBB-7F9F-4710-8B74-59298C2DFCAD}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LynxAstro.DewController.Switch.UnitTests", "LynxAstro.DewController.Switch.UnitTests\LynxAstro.DewController.Switch.UnitTests.csproj", "{AFA5A4A4-188C-4180-B910-7C5BA7D5C11F}"
|
||||
EndProject
|
||||
Project("{930C7802-8A8C-48F9-8165-68863BCCD9DD}") = "LynxAstro.DewController.Setup", "LynxAstro.DewController.Setup\LynxAstro.DewController.Setup.wixproj", "{1073A462-D9A4-4C72-9C3F-A345B307153A}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Test Console", "Test Console", "{9B4388AE-0FB9-4C65-9C3F-000CE932E110}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LynxAstro.DewController.TestConsole", "LynxAstro.DewController.TestConsole\LynxAstro.DewController.TestConsole.csproj", "{D5207217-61C7-4E94-8097-91DBACE57D2A}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Debug|x86 = Debug|x86
|
||||
Release|Any CPU = Release|Any CPU
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{C708E487-E3A9-4073-A545-294B88674225}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{C708E487-E3A9-4073-A545-294B88674225}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{C708E487-E3A9-4073-A545-294B88674225}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{C708E487-E3A9-4073-A545-294B88674225}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{C708E487-E3A9-4073-A545-294B88674225}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{C708E487-E3A9-4073-A545-294B88674225}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{C708E487-E3A9-4073-A545-294B88674225}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{C708E487-E3A9-4073-A545-294B88674225}.Release|x86.Build.0 = Release|Any CPU
|
||||
{64308775-BD4A-469C-BCAB-3ED830B811AF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{64308775-BD4A-469C-BCAB-3ED830B811AF}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{64308775-BD4A-469C-BCAB-3ED830B811AF}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{64308775-BD4A-469C-BCAB-3ED830B811AF}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{64308775-BD4A-469C-BCAB-3ED830B811AF}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{64308775-BD4A-469C-BCAB-3ED830B811AF}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{64308775-BD4A-469C-BCAB-3ED830B811AF}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{64308775-BD4A-469C-BCAB-3ED830B811AF}.Release|x86.Build.0 = Release|Any CPU
|
||||
{BDED8EBB-7F9F-4710-8B74-59298C2DFCAD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{BDED8EBB-7F9F-4710-8B74-59298C2DFCAD}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{BDED8EBB-7F9F-4710-8B74-59298C2DFCAD}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{BDED8EBB-7F9F-4710-8B74-59298C2DFCAD}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{BDED8EBB-7F9F-4710-8B74-59298C2DFCAD}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{BDED8EBB-7F9F-4710-8B74-59298C2DFCAD}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{BDED8EBB-7F9F-4710-8B74-59298C2DFCAD}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{BDED8EBB-7F9F-4710-8B74-59298C2DFCAD}.Release|x86.Build.0 = Release|Any CPU
|
||||
{AFA5A4A4-188C-4180-B910-7C5BA7D5C11F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{AFA5A4A4-188C-4180-B910-7C5BA7D5C11F}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{AFA5A4A4-188C-4180-B910-7C5BA7D5C11F}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{AFA5A4A4-188C-4180-B910-7C5BA7D5C11F}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{AFA5A4A4-188C-4180-B910-7C5BA7D5C11F}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{AFA5A4A4-188C-4180-B910-7C5BA7D5C11F}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{AFA5A4A4-188C-4180-B910-7C5BA7D5C11F}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{AFA5A4A4-188C-4180-B910-7C5BA7D5C11F}.Release|x86.Build.0 = Release|Any CPU
|
||||
{1073A462-D9A4-4C72-9C3F-A345B307153A}.Debug|Any CPU.ActiveCfg = Debug|x86
|
||||
{1073A462-D9A4-4C72-9C3F-A345B307153A}.Debug|Any CPU.Build.0 = Debug|x86
|
||||
{1073A462-D9A4-4C72-9C3F-A345B307153A}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{1073A462-D9A4-4C72-9C3F-A345B307153A}.Debug|x86.Build.0 = Debug|x86
|
||||
{1073A462-D9A4-4C72-9C3F-A345B307153A}.Release|Any CPU.ActiveCfg = Release|x86
|
||||
{1073A462-D9A4-4C72-9C3F-A345B307153A}.Release|x86.ActiveCfg = Release|x86
|
||||
{1073A462-D9A4-4C72-9C3F-A345B307153A}.Release|x86.Build.0 = Release|x86
|
||||
{D5207217-61C7-4E94-8097-91DBACE57D2A}.Debug|Any CPU.ActiveCfg = Debug|x86
|
||||
{D5207217-61C7-4E94-8097-91DBACE57D2A}.Debug|Any CPU.Build.0 = Debug|x86
|
||||
{D5207217-61C7-4E94-8097-91DBACE57D2A}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{D5207217-61C7-4E94-8097-91DBACE57D2A}.Debug|x86.Build.0 = Debug|x86
|
||||
{D5207217-61C7-4E94-8097-91DBACE57D2A}.Release|Any CPU.ActiveCfg = Release|x86
|
||||
{D5207217-61C7-4E94-8097-91DBACE57D2A}.Release|x86.ActiveCfg = Release|x86
|
||||
{D5207217-61C7-4E94-8097-91DBACE57D2A}.Release|x86.Build.0 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(NestedProjects) = preSolution
|
||||
{BDED8EBB-7F9F-4710-8B74-59298C2DFCAD} = {7CAA050A-2EB3-4A21-8A75-131EB0AC9778}
|
||||
{AFA5A4A4-188C-4180-B910-7C5BA7D5C11F} = {7CAA050A-2EB3-4A21-8A75-131EB0AC9778}
|
||||
{D5207217-61C7-4E94-8097-91DBACE57D2A} = {9B4388AE-0FB9-4C65-9C3F-000CE932E110}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {343D05C4-AD6F-4A05-A971-ECAABF3294AF}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
@@ -0,0 +1,91 @@
|
||||
using System;
|
||||
using System.Reflection;
|
||||
|
||||
namespace ASCOM.LynxAstro.DewController
|
||||
{
|
||||
public class AssemblyInfo
|
||||
{
|
||||
// The assembly information values.
|
||||
//public readonly string Title = string.Empty;
|
||||
//public readonly string Description = string.Empty;
|
||||
//public readonly string Company = string.Empty;
|
||||
public readonly string Product = string.Empty;
|
||||
//public readonly string Copyright = string.Empty;
|
||||
//public readonly string Trademark = string.Empty;
|
||||
public readonly string AssemblyVersion;
|
||||
//public readonly string FileVersion = string.Empty;
|
||||
//public readonly string Guid = string.Empty;
|
||||
//public readonly string NeutralLanguage = string.Empty;
|
||||
//public readonly bool IsComVisible;
|
||||
|
||||
// Return a particular assembly attribute value.
|
||||
private T GetAssemblyAttribute<T>(Assembly assembly)
|
||||
where T : Attribute
|
||||
{
|
||||
// Get attributes of this type.
|
||||
object[] attributes = assembly.GetCustomAttributes(typeof(T), true);
|
||||
|
||||
// If we didn't get anything, return null.
|
||||
if (attributes.Length == 0)
|
||||
return null;
|
||||
|
||||
// Convert the first attribute value into
|
||||
// the desired type and return it.
|
||||
return (T)attributes[0];
|
||||
}
|
||||
|
||||
// Constructors.
|
||||
public AssemblyInfo()
|
||||
: this(Assembly.GetExecutingAssembly())
|
||||
{
|
||||
}
|
||||
|
||||
private AssemblyInfo(Assembly assembly)
|
||||
{
|
||||
// Get values from the assembly.
|
||||
//var titleAttr = GetAssemblyAttribute<AssemblyTitleAttribute>(assembly);
|
||||
//if (titleAttr != null)
|
||||
// Title = titleAttr.Title;
|
||||
|
||||
//var assemblyAttr = GetAssemblyAttribute<AssemblyDescriptionAttribute>(assembly);
|
||||
//if (assemblyAttr != null)
|
||||
// Description = assemblyAttr.Description;
|
||||
|
||||
//var companyAttr =GetAssemblyAttribute<AssemblyCompanyAttribute>(assembly);
|
||||
//if (companyAttr != null)
|
||||
// Company = companyAttr.Company;
|
||||
|
||||
var productAttr = GetAssemblyAttribute<AssemblyProductAttribute>(assembly);
|
||||
if (productAttr != null)
|
||||
Product = productAttr.Product;
|
||||
|
||||
//var copyrightAttr = GetAssemblyAttribute<AssemblyCopyrightAttribute>(assembly);
|
||||
//if (copyrightAttr != null)
|
||||
// Copyright = copyrightAttr.Copyright;
|
||||
|
||||
//var trademarkAttr = GetAssemblyAttribute<AssemblyTrademarkAttribute>(assembly);
|
||||
//if (trademarkAttr != null)
|
||||
// Trademark = trademarkAttr.Trademark;
|
||||
|
||||
var version = assembly.GetName().Version;
|
||||
AssemblyVersion = $"{version.Major}.{version.Minor}.{version.Build}.{version.Revision}";
|
||||
|
||||
|
||||
//var fileVersionAttr = GetAssemblyAttribute<AssemblyFileVersionAttribute>(assembly);
|
||||
//if (fileVersionAttr != null) FileVersion =
|
||||
// fileVersionAttr.Version;
|
||||
|
||||
//var guidAttr = GetAssemblyAttribute<GuidAttribute>(assembly);
|
||||
//if (guidAttr != null)
|
||||
// Guid = guidAttr.Value;
|
||||
|
||||
//var languageAttr = GetAssemblyAttribute<NeutralResourcesLanguageAttribute>(assembly);
|
||||
//if (languageAttr != null)
|
||||
// NeutralLanguage = languageAttr.CultureName;
|
||||
|
||||
//var comAttr = GetAssemblyAttribute<ComVisibleAttribute>(assembly);
|
||||
//if (comAttr != null)
|
||||
// IsComVisible = comAttr.Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,244 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Collections;
|
||||
|
||||
namespace ASCOM.LynxAstro.DewController
|
||||
{
|
||||
|
||||
#region C# Definition of IClassFactory
|
||||
//
|
||||
// Provide a definition of theCOM IClassFactory interface.
|
||||
//
|
||||
[
|
||||
ComImport, // This interface originated from COM.
|
||||
ComVisible(false), // Must not be exposed to COM!!!
|
||||
InterfaceType(ComInterfaceType.InterfaceIsIUnknown), // Indicate that this interface is not IDispatch-based.
|
||||
Guid("00000001-0000-0000-C000-000000000046") // This GUID is the actual GUID of IClassFactory.
|
||||
]
|
||||
public interface IClassFactory
|
||||
{
|
||||
void CreateInstance(IntPtr pUnkOuter, ref Guid riid, out IntPtr ppvObject);
|
||||
void LockServer(bool fLock);
|
||||
}
|
||||
#endregion
|
||||
|
||||
//
|
||||
// Universal ClassFactory. Given a type as a parameter of the
|
||||
// constructor, it implements IClassFactory for any interface
|
||||
// that the class implements. Magic!!!
|
||||
//
|
||||
public class ClassFactory : IClassFactory
|
||||
{
|
||||
|
||||
#region Access to ole32.dll functions for class factories
|
||||
|
||||
// Define two common GUID objects for public usage.
|
||||
public static Guid IID_IUnknown = new Guid("{00000000-0000-0000-C000-000000000046}");
|
||||
public static Guid IID_IDispatch = new Guid("{00020400-0000-0000-C000-000000000046}");
|
||||
|
||||
[Flags]
|
||||
enum CLSCTX : uint
|
||||
{
|
||||
CLSCTX_INPROC_SERVER = 0x1,
|
||||
CLSCTX_INPROC_HANDLER = 0x2,
|
||||
CLSCTX_LOCAL_SERVER = 0x4,
|
||||
CLSCTX_INPROC_SERVER16 = 0x8,
|
||||
CLSCTX_REMOTE_SERVER = 0x10,
|
||||
CLSCTX_INPROC_HANDLER16 = 0x20,
|
||||
CLSCTX_RESERVED1 = 0x40,
|
||||
CLSCTX_RESERVED2 = 0x80,
|
||||
CLSCTX_RESERVED3 = 0x100,
|
||||
CLSCTX_RESERVED4 = 0x200,
|
||||
CLSCTX_NO_CODE_DOWNLOAD = 0x400,
|
||||
CLSCTX_RESERVED5 = 0x800,
|
||||
CLSCTX_NO_CUSTOM_MARSHAL = 0x1000,
|
||||
CLSCTX_ENABLE_CODE_DOWNLOAD = 0x2000,
|
||||
CLSCTX_NO_FAILURE_LOG = 0x4000,
|
||||
CLSCTX_DISABLE_AAA = 0x8000,
|
||||
CLSCTX_ENABLE_AAA = 0x10000,
|
||||
CLSCTX_FROM_DEFAULT_CONTEXT = 0x20000,
|
||||
CLSCTX_INPROC = CLSCTX_INPROC_SERVER | CLSCTX_INPROC_HANDLER,
|
||||
CLSCTX_SERVER = CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER | CLSCTX_REMOTE_SERVER,
|
||||
CLSCTX_ALL = CLSCTX_SERVER | CLSCTX_INPROC_HANDLER
|
||||
}
|
||||
|
||||
[Flags]
|
||||
enum REGCLS : uint
|
||||
{
|
||||
REGCLS_SINGLEUSE = 0,
|
||||
REGCLS_MULTIPLEUSE = 1,
|
||||
REGCLS_MULTI_SEPARATE = 2,
|
||||
REGCLS_SUSPENDED = 4,
|
||||
REGCLS_SURROGATE = 8
|
||||
}
|
||||
//
|
||||
// CoRegisterClassObject() is used to register a Class Factory
|
||||
// into COM's internal table of Class Factories.
|
||||
//
|
||||
[DllImport("ole32.dll")]
|
||||
static extern int CoRegisterClassObject(
|
||||
[In] ref Guid rclsid,
|
||||
[MarshalAs(UnmanagedType.IUnknown)] object pUnk,
|
||||
uint dwClsContext,
|
||||
uint flags,
|
||||
out uint lpdwRegister);
|
||||
//
|
||||
// Called by a COM EXE Server that can register multiple class objects
|
||||
// to inform COM about all registered classes, and permits activation
|
||||
// requests for those class objects.
|
||||
// This function causes OLE to inform the SCM about all the registered
|
||||
// classes, and begins letting activation requests into the server process.
|
||||
//
|
||||
[DllImport("ole32.dll")]
|
||||
static extern int CoResumeClassObjects();
|
||||
//
|
||||
// Prevents any new activation requests from the SCM on all class objects
|
||||
// registered within the process. Even though a process may call this API,
|
||||
// the process still must call CoRevokeClassObject for each CLSID it has
|
||||
// registered, in the apartment it registered in.
|
||||
//
|
||||
[DllImport("ole32.dll")]
|
||||
static extern int CoSuspendClassObjects();
|
||||
//
|
||||
// CoRevokeClassObject() is used to unregister a Class Factory
|
||||
// from COM's internal table of Class Factories.
|
||||
//
|
||||
[DllImport("ole32.dll")]
|
||||
static extern int CoRevokeClassObject(uint dwRegister);
|
||||
#endregion
|
||||
|
||||
#region Constructor and Private ClassFactory Data
|
||||
|
||||
protected Type m_ClassType;
|
||||
protected Guid m_ClassId;
|
||||
protected ArrayList m_InterfaceTypes;
|
||||
protected uint m_ClassContext;
|
||||
protected uint m_Flags;
|
||||
protected UInt32 m_locked = 0;
|
||||
protected uint m_Cookie;
|
||||
protected string m_progid;
|
||||
|
||||
public ClassFactory(Type type)
|
||||
{
|
||||
if (type == null)
|
||||
throw new ArgumentNullException("type");
|
||||
m_ClassType = type;
|
||||
|
||||
//PWGS Get the ProgID from the MetaData
|
||||
m_progid = Marshal.GenerateProgIdForType(type);
|
||||
m_ClassId = Marshal.GenerateGuidForType(type); // Should be nailed down by [Guid(...)]
|
||||
m_ClassContext = (uint)CLSCTX.CLSCTX_LOCAL_SERVER; // Default
|
||||
m_Flags = (uint)REGCLS.REGCLS_MULTIPLEUSE | // Default
|
||||
(uint)REGCLS.REGCLS_SUSPENDED;
|
||||
m_InterfaceTypes = new ArrayList();
|
||||
foreach (Type T in type.GetInterfaces()) // Save all of the implemented interfaces
|
||||
m_InterfaceTypes.Add(T);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Common ClassFactory Methods
|
||||
public uint ClassContext
|
||||
{
|
||||
get { return m_ClassContext; }
|
||||
set { m_ClassContext = value; }
|
||||
}
|
||||
|
||||
public Guid ClassId
|
||||
{
|
||||
get { return m_ClassId; }
|
||||
set { m_ClassId = value; }
|
||||
}
|
||||
|
||||
public uint Flags
|
||||
{
|
||||
get { return m_Flags; }
|
||||
set { m_Flags = value; }
|
||||
}
|
||||
|
||||
public bool RegisterClassObject()
|
||||
{
|
||||
// Register the class factory
|
||||
int i = CoRegisterClassObject
|
||||
(
|
||||
ref m_ClassId,
|
||||
this,
|
||||
m_ClassContext,
|
||||
m_Flags,
|
||||
out m_Cookie
|
||||
);
|
||||
return (i == 0);
|
||||
}
|
||||
|
||||
public bool RevokeClassObject()
|
||||
{
|
||||
int i = CoRevokeClassObject(m_Cookie);
|
||||
return (i == 0);
|
||||
}
|
||||
|
||||
public static bool ResumeClassObjects()
|
||||
{
|
||||
int i = CoResumeClassObjects();
|
||||
return (i == 0);
|
||||
}
|
||||
|
||||
public static bool SuspendClassObjects()
|
||||
{
|
||||
int i = CoSuspendClassObjects();
|
||||
return (i == 0);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region IClassFactory Implementations
|
||||
//
|
||||
// Implement creation of the type and interface.
|
||||
//
|
||||
void IClassFactory.CreateInstance(IntPtr pUnkOuter, ref Guid riid, out IntPtr ppvObject)
|
||||
{
|
||||
IntPtr nullPtr = new IntPtr(0);
|
||||
ppvObject = nullPtr;
|
||||
|
||||
//
|
||||
// Handle specific requests for implemented interfaces
|
||||
//
|
||||
foreach (Type iType in m_InterfaceTypes)
|
||||
{
|
||||
if (riid == Marshal.GenerateGuidForType(iType))
|
||||
{
|
||||
ppvObject = Marshal.GetComInterfaceForObject(Activator.CreateInstance(m_ClassType), iType);
|
||||
return;
|
||||
}
|
||||
}
|
||||
//
|
||||
// Handle requests for IDispatch or IUnknown on the class
|
||||
//
|
||||
if (riid == IID_IDispatch)
|
||||
{
|
||||
ppvObject = Marshal.GetIDispatchForObject(Activator.CreateInstance(m_ClassType));
|
||||
return;
|
||||
}
|
||||
else if (riid == IID_IUnknown)
|
||||
{
|
||||
ppvObject = Marshal.GetIUnknownForObject(Activator.CreateInstance(m_ClassType));
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
// Oops, some interface that the class doesn't implement
|
||||
//
|
||||
throw new COMException("No interface", unchecked((int)0x80004002));
|
||||
}
|
||||
}
|
||||
|
||||
void IClassFactory.LockServer(bool bLock)
|
||||
{
|
||||
if (bLock)
|
||||
Server.CountLock();
|
||||
else
|
||||
Server.UncountLock();
|
||||
// Always attempt to see if we need to shutdown this server application.
|
||||
Server.ExitIf();
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
namespace ASCOM.LynxAstro.DewController
|
||||
{
|
||||
public class ConnectionInfo
|
||||
{
|
||||
//public int Connections { get; set; }
|
||||
public int SameDevice { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
using System;
|
||||
using System.Threading;
|
||||
|
||||
namespace ASCOM.LynxAstro.DewController
|
||||
{
|
||||
/// <summary>
|
||||
/// Summary description for GarbageCollection.
|
||||
/// </summary>
|
||||
class GarbageCollection
|
||||
{
|
||||
protected bool m_bContinueThread;
|
||||
protected bool m_GCWatchStopped;
|
||||
protected int m_iInterval;
|
||||
protected ManualResetEvent m_EventThreadEnded;
|
||||
|
||||
public GarbageCollection(int iInterval)
|
||||
{
|
||||
m_bContinueThread = true;
|
||||
m_GCWatchStopped = false;
|
||||
m_iInterval = iInterval;
|
||||
m_EventThreadEnded = new ManualResetEvent(false);
|
||||
}
|
||||
|
||||
public void GCWatch()
|
||||
{
|
||||
// Pause for a moment to provide a delay to make threads more apparent.
|
||||
while (ContinueThread())
|
||||
{
|
||||
GC.Collect();
|
||||
Thread.Sleep(m_iInterval);
|
||||
}
|
||||
m_EventThreadEnded.Set();
|
||||
}
|
||||
|
||||
protected bool ContinueThread()
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
return m_bContinueThread;
|
||||
}
|
||||
}
|
||||
|
||||
public void StopThread()
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
m_bContinueThread = false;
|
||||
}
|
||||
}
|
||||
|
||||
public void WaitForThreadToStop()
|
||||
{
|
||||
m_EventThreadEnded.WaitOne();
|
||||
m_EventThreadEnded.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
namespace ASCOM.LynxAstro.DewController
|
||||
{
|
||||
public interface IProfileFactory
|
||||
{
|
||||
IProfileWrapper Create();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
using System;
|
||||
using ASCOM.Utilities.Interfaces;
|
||||
|
||||
namespace ASCOM.LynxAstro.DewController
|
||||
{
|
||||
public interface IProfileWrapper : IProfile, IProfileExtra, IDisposable
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
using System;
|
||||
using ASCOM.Utilities.Interfaces;
|
||||
|
||||
namespace ASCOM.LynxAstro.DewController
|
||||
{
|
||||
public interface ISharedResourcesWrapper
|
||||
{
|
||||
ConnectionInfo Connect(string deviceId, string driverId, ITraceLogger traceLogger);
|
||||
void Disconnect(string deviceId, string driverId);
|
||||
|
||||
string FirmwareVersion { get; }
|
||||
|
||||
void Lock(Action action);
|
||||
T Lock<T>(Func<T> func);
|
||||
|
||||
string SendString(string message);
|
||||
void SendBlind(string message);
|
||||
string SendChar(string message);
|
||||
|
||||
string ReadTerminated();
|
||||
|
||||
ProfileProperties ReadProfile();
|
||||
|
||||
void SetupDialog();
|
||||
void WriteProfile(ProfileProperties profileProperties);
|
||||
void ReadCharacters(int throwAwayCharacters);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,640 @@
|
||||
//
|
||||
// ASCOM.LynxAstro.DewController Local COM Server
|
||||
//
|
||||
// This is the core of a managed COM Local Server, capable of serving
|
||||
// multiple instances of multiple interfaces, within a single
|
||||
// executable. This implementes the equivalent functionality of VB6
|
||||
// which has been extensively used in ASCOM for drivers that provide
|
||||
// multiple interfaces to multiple clients (e.g. Meade Telescope
|
||||
// and Focuser) as well as hubs (e.g., POTH).
|
||||
//
|
||||
// Written by: Robert B. Denny (Version 1.0.1, 29-May-2007)
|
||||
// Modified by Chris Rowland and Peter Simpson to allow use with multiple devices of the same type March 2011
|
||||
//
|
||||
//
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Windows.Forms;
|
||||
using System.Collections;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Reflection;
|
||||
using ASCOM.Utilities;
|
||||
using Microsoft.Win32;
|
||||
using System.Threading;
|
||||
using System.Security.Principal;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace ASCOM.LynxAstro.DewController
|
||||
{
|
||||
public static class Server
|
||||
{
|
||||
|
||||
#region Access to kernel32.dll, user32.dll, and ole32.dll functions
|
||||
[Flags]
|
||||
enum CLSCTX : uint
|
||||
{
|
||||
CLSCTX_INPROC_SERVER = 0x1,
|
||||
CLSCTX_INPROC_HANDLER = 0x2,
|
||||
CLSCTX_LOCAL_SERVER = 0x4,
|
||||
CLSCTX_INPROC_SERVER16 = 0x8,
|
||||
CLSCTX_REMOTE_SERVER = 0x10,
|
||||
CLSCTX_INPROC_HANDLER16 = 0x20,
|
||||
CLSCTX_RESERVED1 = 0x40,
|
||||
CLSCTX_RESERVED2 = 0x80,
|
||||
CLSCTX_RESERVED3 = 0x100,
|
||||
CLSCTX_RESERVED4 = 0x200,
|
||||
CLSCTX_NO_CODE_DOWNLOAD = 0x400,
|
||||
CLSCTX_RESERVED5 = 0x800,
|
||||
CLSCTX_NO_CUSTOM_MARSHAL = 0x1000,
|
||||
CLSCTX_ENABLE_CODE_DOWNLOAD = 0x2000,
|
||||
CLSCTX_NO_FAILURE_LOG = 0x4000,
|
||||
CLSCTX_DISABLE_AAA = 0x8000,
|
||||
CLSCTX_ENABLE_AAA = 0x10000,
|
||||
CLSCTX_FROM_DEFAULT_CONTEXT = 0x20000,
|
||||
CLSCTX_INPROC = CLSCTX_INPROC_SERVER | CLSCTX_INPROC_HANDLER,
|
||||
CLSCTX_SERVER = CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER | CLSCTX_REMOTE_SERVER,
|
||||
CLSCTX_ALL = CLSCTX_SERVER | CLSCTX_INPROC_HANDLER
|
||||
}
|
||||
|
||||
[Flags]
|
||||
enum COINIT : uint
|
||||
{
|
||||
/// Initializes the thread for multi-threaded object concurrency.
|
||||
COINIT_MULTITHREADED = 0x0,
|
||||
/// Initializes the thread for apartment-threaded object concurrency.
|
||||
COINIT_APARTMENTTHREADED = 0x2,
|
||||
/// Disables DDE for Ole1 support.
|
||||
COINIT_DISABLE_OLE1DDE = 0x4,
|
||||
/// Trades memory for speed.
|
||||
COINIT_SPEED_OVER_MEMORY = 0x8
|
||||
}
|
||||
|
||||
[Flags]
|
||||
enum REGCLS : uint
|
||||
{
|
||||
REGCLS_SINGLEUSE = 0,
|
||||
REGCLS_MULTIPLEUSE = 1,
|
||||
REGCLS_MULTI_SEPARATE = 2,
|
||||
REGCLS_SUSPENDED = 4,
|
||||
REGCLS_SURROGATE = 8
|
||||
}
|
||||
|
||||
|
||||
// CoInitializeEx() can be used to set the apartment model
|
||||
// of individual threads.
|
||||
[DllImport("ole32.dll")]
|
||||
static extern int CoInitializeEx(IntPtr pvReserved, uint dwCoInit);
|
||||
|
||||
// CoUninitialize() is used to uninitialize a COM thread.
|
||||
[DllImport("ole32.dll")]
|
||||
static extern void CoUninitialize();
|
||||
|
||||
// PostThreadMessage() allows us to post a Windows Message to
|
||||
// a specific thread (identified by its thread id).
|
||||
// We will need this API to post a WM_QUIT message to the main
|
||||
// thread in order to terminate this application.
|
||||
[DllImport("user32.dll")]
|
||||
static extern bool PostThreadMessage(uint idThread, uint Msg, UIntPtr wParam,
|
||||
IntPtr lParam);
|
||||
|
||||
// GetCurrentThreadId() allows us to obtain the thread id of the
|
||||
// calling thread. This allows us to post the WM_QUIT message to
|
||||
// the main thread.
|
||||
[DllImport("kernel32.dll")]
|
||||
static extern uint GetCurrentThreadId();
|
||||
#endregion
|
||||
|
||||
#region Private Data
|
||||
private static int objsInUse; // Keeps a count on the total number of objects alive.
|
||||
private static int serverLocks; // Keeps a lock count on this application.
|
||||
private static frmMain s_MainForm = null; // Reference to our main form
|
||||
private static ArrayList s_ComObjectAssys; // Dynamically loaded assemblies containing served COM objects
|
||||
private static ArrayList s_ComObjectTypes; // Served COM object types
|
||||
private static ArrayList s_ClassFactories; // Served COM object class factories
|
||||
private static string s_appId = "{34e5f3f3-29e4-4d87-b861-c079485a5c97}"; // Our AppId
|
||||
private static readonly Object lockObject = new object();
|
||||
#endregion
|
||||
|
||||
// This property returns the main thread's id.
|
||||
public static uint MainThreadId { get; private set; } // Stores the main thread's thread id.
|
||||
|
||||
// Used to tell if started by COM or manually
|
||||
public static bool StartedByCOM { get; private set; } // True if server started by COM (-embedding)
|
||||
|
||||
|
||||
#region Server Lock, Object Counting, and AutoQuit on COM startup
|
||||
// Returns the total number of objects alive currently.
|
||||
public static int ObjectsCount
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (lockObject)
|
||||
{
|
||||
return objsInUse;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This method performs a thread-safe incrementation of the objects count.
|
||||
public static int CountObject()
|
||||
{
|
||||
// Increment the global count of objects.
|
||||
return Interlocked.Increment(ref objsInUse);
|
||||
}
|
||||
|
||||
// This method performs a thread-safe decrementation the objects count.
|
||||
public static int UncountObject()
|
||||
{
|
||||
// Decrement the global count of objects.
|
||||
return Interlocked.Decrement(ref objsInUse);
|
||||
}
|
||||
|
||||
// Returns the current server lock count.
|
||||
public static int ServerLockCount
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (lockObject)
|
||||
{
|
||||
return serverLocks;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This method performs a thread-safe incrementation the
|
||||
// server lock count.
|
||||
public static int CountLock()
|
||||
{
|
||||
// Increment the global lock count of this server.
|
||||
return Interlocked.Increment(ref serverLocks);
|
||||
}
|
||||
|
||||
// This method performs a thread-safe decrementation the
|
||||
// server lock count.
|
||||
public static int UncountLock()
|
||||
{
|
||||
// Decrement the global lock count of this server.
|
||||
return Interlocked.Decrement(ref serverLocks);
|
||||
}
|
||||
|
||||
// AttemptToTerminateServer() will check to see if the objects count and the server
|
||||
// lock count have both dropped to zero.
|
||||
//
|
||||
// If so, and if we were started by COM, we post a WM_QUIT message to the main thread's
|
||||
// message loop. This will cause the message loop to exit and hence the termination
|
||||
// of this application. If hand-started, then just trace that it WOULD exit now.
|
||||
//
|
||||
public static void ExitIf()
|
||||
{
|
||||
lock (lockObject)
|
||||
{
|
||||
if ((ObjectsCount <= 0) && (ServerLockCount <= 0))
|
||||
{
|
||||
if (StartedByCOM)
|
||||
{
|
||||
UIntPtr wParam = new UIntPtr(0);
|
||||
IntPtr lParam = new IntPtr(0);
|
||||
PostThreadMessage(MainThreadId, 0x0012, wParam, lParam);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
// -----------------
|
||||
// PRIVATE FUNCTIONS
|
||||
// -----------------
|
||||
|
||||
#region Dynamic Driver Assembly Loader
|
||||
//
|
||||
// Load the assemblies that contain the classes that we will serve
|
||||
// via COM. These will be located in the same folder as
|
||||
// our executable.
|
||||
//
|
||||
private static bool LoadComObjectAssemblies()
|
||||
{
|
||||
s_ComObjectAssys = new ArrayList();
|
||||
s_ComObjectTypes = new ArrayList();
|
||||
|
||||
// put everything into one folder, the same as the server.
|
||||
string assyPath = Assembly.GetEntryAssembly().Location;
|
||||
assyPath = Path.GetDirectoryName(assyPath);
|
||||
|
||||
DirectoryInfo d = new DirectoryInfo(assyPath);
|
||||
foreach (FileInfo fi in d.GetFiles("*.dll"))
|
||||
{
|
||||
string aPath = fi.FullName;
|
||||
//
|
||||
// First try to load the assembly and get the types for
|
||||
// the class and the class factory. If this doesn't work ????
|
||||
//
|
||||
try
|
||||
{
|
||||
Assembly so = Assembly.LoadFrom(aPath);
|
||||
//PWGS Get the types in the assembly
|
||||
Type[] types = so.GetTypes();
|
||||
foreach (Type type in types)
|
||||
{
|
||||
// PWGS Now checks the type rather than the assembly
|
||||
// Check to see if the type has the ServedClassName attribute, only use it if it does.
|
||||
MemberInfo info = type;
|
||||
|
||||
object[] attrbutes = info.GetCustomAttributes(typeof(ServedClassNameAttribute), false);
|
||||
if (attrbutes.Length > 0)
|
||||
{
|
||||
//MessageBox.Show("Adding Type: " + type.Name + " " + type.FullName);
|
||||
s_ComObjectTypes.Add(type); //PWGS - much simpler
|
||||
s_ComObjectAssys.Add(so);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (BadImageFormatException)
|
||||
{
|
||||
// Probably an attempt to load a Win32 DLL (i.e. not a .net assembly)
|
||||
// Just swallow the exception and continue to the next item.
|
||||
continue;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
MessageBox.Show("Failed to load served COM class assembly " + fi.Name + " - " + e.Message,
|
||||
"LynxAstro.DewController", MessageBoxButtons.OK, MessageBoxIcon.Stop);
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
return true;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region COM Registration and Unregistration
|
||||
//
|
||||
// Test if running elevated
|
||||
//
|
||||
private static bool IsAdministrator
|
||||
{
|
||||
get
|
||||
{
|
||||
WindowsIdentity i = WindowsIdentity.GetCurrent();
|
||||
WindowsPrincipal p = new WindowsPrincipal(i);
|
||||
return p.IsInRole(WindowsBuiltInRole.Administrator);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Elevate by re-running ourselves with elevation dialog
|
||||
//
|
||||
private static void ElevateSelf(string arg)
|
||||
{
|
||||
ProcessStartInfo si = new ProcessStartInfo();
|
||||
si.Arguments = arg;
|
||||
si.WorkingDirectory = Environment.CurrentDirectory;
|
||||
si.FileName = Application.ExecutablePath;
|
||||
si.Verb = "runas";
|
||||
try { Process.Start(si); }
|
||||
catch (System.ComponentModel.Win32Exception)
|
||||
{
|
||||
MessageBox.Show("The LynxAstro.DewController was not " + (arg == "/register" ? "registered" : "unregistered") +
|
||||
" because you did not allow it.", "LynxAstro.DewController", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show(ex.ToString(), "LynxAstro.DewController", MessageBoxButtons.OK, MessageBoxIcon.Stop);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Do everything to register this for COM. Never use REGASM on
|
||||
// this exe assembly! It would create InProcServer32 entries
|
||||
// which would prevent proper activation!
|
||||
//
|
||||
// Using the list of COM object types generated during dynamic
|
||||
// assembly loading, it registers each one for COM as served by our
|
||||
// exe/local server, as well as registering it for ASCOM. It also
|
||||
// adds DCOM info for the local server itself, so it can be activated
|
||||
// via an outboiud connection from TheSky.
|
||||
//
|
||||
private static void RegisterObjects()
|
||||
{
|
||||
if (!IsAdministrator)
|
||||
{
|
||||
ElevateSelf("/register");
|
||||
return;
|
||||
}
|
||||
//
|
||||
// If reached here, we're running elevated
|
||||
//
|
||||
|
||||
Assembly assy = Assembly.GetExecutingAssembly();
|
||||
Attribute attr = Attribute.GetCustomAttribute(assy, typeof(AssemblyTitleAttribute));
|
||||
string assyTitle = ((AssemblyTitleAttribute)attr).Title;
|
||||
attr = Attribute.GetCustomAttribute(assy, typeof(AssemblyDescriptionAttribute));
|
||||
string assyDescription = ((AssemblyDescriptionAttribute)attr).Description;
|
||||
|
||||
//
|
||||
// Local server's DCOM/AppID information
|
||||
//
|
||||
try
|
||||
{
|
||||
//
|
||||
// HKCR\APPID\appid
|
||||
//
|
||||
using (RegistryKey key = Registry.ClassesRoot.CreateSubKey("APPID\\" + s_appId))
|
||||
{
|
||||
key.SetValue(null, assyDescription);
|
||||
key.SetValue("AppID", s_appId);
|
||||
key.SetValue("AuthenticationLevel", 1, RegistryValueKind.DWord);
|
||||
key.SetValue("RunAs", "Interactive User", RegistryValueKind.String); // Added to ensure that only one copy of the local server runs if the user uses both elevated and non-elevated clients concurrently
|
||||
}
|
||||
//
|
||||
// HKCR\APPID\exename.ext
|
||||
//
|
||||
using (RegistryKey key = Registry.ClassesRoot.CreateSubKey(string.Format("APPID\\{0}",
|
||||
Application.ExecutablePath.Substring(Application.ExecutablePath.LastIndexOf('\\') + 1))))
|
||||
{
|
||||
key.SetValue("AppID", s_appId);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show("Error while registering the server:\n" + ex.ToString(),
|
||||
"LynxAstro.DewController", MessageBoxButtons.OK, MessageBoxIcon.Stop);
|
||||
return;
|
||||
}
|
||||
finally
|
||||
{
|
||||
}
|
||||
|
||||
//
|
||||
// For each of the driver assemblies
|
||||
//
|
||||
foreach (Type type in s_ComObjectTypes)
|
||||
{
|
||||
bool bFail = false;
|
||||
try
|
||||
{
|
||||
//
|
||||
// HKCR\CLSID\clsid
|
||||
//
|
||||
string clsid = Marshal.GenerateGuidForType(type).ToString("B");
|
||||
string progid = Marshal.GenerateProgIdForType(type);
|
||||
//PWGS Generate device type from the Class name
|
||||
string deviceType = type.Name;
|
||||
|
||||
using (RegistryKey key = Registry.ClassesRoot.CreateSubKey(string.Format("CLSID\\{0}", clsid)))
|
||||
{
|
||||
key.SetValue(null, progid); // Could be assyTitle/Desc??, but .NET components show ProgId here
|
||||
key.SetValue("AppId", s_appId);
|
||||
using (RegistryKey key2 = key.CreateSubKey("Implemented Categories"))
|
||||
{
|
||||
key2.CreateSubKey("{62C8FE65-4EBB-45e7-B440-6E39B2CDBF29}");
|
||||
}
|
||||
using (RegistryKey key2 = key.CreateSubKey("ProgId"))
|
||||
{
|
||||
key2.SetValue(null, progid);
|
||||
}
|
||||
key.CreateSubKey("Programmable");
|
||||
using (RegistryKey key2 = key.CreateSubKey("LocalServer32"))
|
||||
{
|
||||
key2.SetValue(null, Application.ExecutablePath);
|
||||
}
|
||||
}
|
||||
//
|
||||
// HKCR\CLSID\progid
|
||||
//
|
||||
using (RegistryKey key = Registry.ClassesRoot.CreateSubKey(progid))
|
||||
{
|
||||
key.SetValue(null, assyTitle);
|
||||
using (RegistryKey key2 = key.CreateSubKey("CLSID"))
|
||||
{
|
||||
key2.SetValue(null, clsid);
|
||||
}
|
||||
}
|
||||
//
|
||||
// ASCOM
|
||||
//
|
||||
assy = type.Assembly;
|
||||
|
||||
// Pull the display name from the ServedClassName attribute.
|
||||
attr = Attribute.GetCustomAttribute(type, typeof(ServedClassNameAttribute)); //PWGS Changed to search type for attribute rather than assembly
|
||||
string chooserName = ((ServedClassNameAttribute)attr).DisplayName ?? "MultiServer";
|
||||
using (var P = new Profile())
|
||||
{
|
||||
P.DeviceType = deviceType;
|
||||
P.Register(progid, chooserName);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show("Error while registering the server:\n" + ex.ToString(),
|
||||
"LynxAstro.DewController", MessageBoxButtons.OK, MessageBoxIcon.Stop);
|
||||
bFail = true;
|
||||
}
|
||||
finally
|
||||
{
|
||||
}
|
||||
if (bFail) break;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Remove all traces of this from the registry.
|
||||
//
|
||||
// **TODO** If the above does AppID/DCOM stuff, this would have
|
||||
// to remove that stuff too.
|
||||
//
|
||||
private static void UnregisterObjects()
|
||||
{
|
||||
if (!IsAdministrator)
|
||||
{
|
||||
ElevateSelf("/unregister");
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Local server's DCOM/AppID information
|
||||
//
|
||||
Registry.ClassesRoot.DeleteSubKey(string.Format("APPID\\{0}", s_appId), false);
|
||||
Registry.ClassesRoot.DeleteSubKey(string.Format("APPID\\{0}",
|
||||
Application.ExecutablePath.Substring(Application.ExecutablePath.LastIndexOf('\\') + 1)), false);
|
||||
|
||||
//
|
||||
// For each of the driver assemblies
|
||||
//
|
||||
foreach (Type type in s_ComObjectTypes)
|
||||
{
|
||||
string clsid = Marshal.GenerateGuidForType(type).ToString("B");
|
||||
string progid = Marshal.GenerateProgIdForType(type);
|
||||
string deviceType = type.Name;
|
||||
//
|
||||
// Best efforts
|
||||
//
|
||||
//
|
||||
// HKCR\progid
|
||||
//
|
||||
Registry.ClassesRoot.DeleteSubKey(String.Format("{0}\\CLSID", progid), false);
|
||||
Registry.ClassesRoot.DeleteSubKey(progid, false);
|
||||
//
|
||||
// HKCR\CLSID\clsid
|
||||
//
|
||||
Registry.ClassesRoot.DeleteSubKey(String.Format("CLSID\\{0}\\Implemented Categories\\{{62C8FE65-4EBB-45e7-B440-6E39B2CDBF29}}", clsid), false);
|
||||
Registry.ClassesRoot.DeleteSubKey(String.Format("CLSID\\{0}\\Implemented Categories", clsid), false);
|
||||
Registry.ClassesRoot.DeleteSubKey(String.Format("CLSID\\{0}\\ProgId", clsid), false);
|
||||
Registry.ClassesRoot.DeleteSubKey(String.Format("CLSID\\{0}\\LocalServer32", clsid), false);
|
||||
Registry.ClassesRoot.DeleteSubKey(String.Format("CLSID\\{0}\\Programmable", clsid), false);
|
||||
Registry.ClassesRoot.DeleteSubKey(String.Format("CLSID\\{0}", clsid), false);
|
||||
try
|
||||
{
|
||||
//
|
||||
// ASCOM
|
||||
//
|
||||
using (var P = new Profile())
|
||||
{
|
||||
P.DeviceType = deviceType;
|
||||
P.Unregister(progid);
|
||||
}
|
||||
}
|
||||
catch (Exception) { }
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Class Factory Support
|
||||
//
|
||||
// On startup, we register the class factories of the COM objects
|
||||
// that we serve. This requires the class facgtory name to be
|
||||
// equal to the served class name + "ClassFactory".
|
||||
//
|
||||
private static bool RegisterClassFactories()
|
||||
{
|
||||
s_ClassFactories = new ArrayList();
|
||||
foreach (Type type in s_ComObjectTypes)
|
||||
{
|
||||
ClassFactory factory = new ClassFactory(type); // Use default context & flags
|
||||
s_ClassFactories.Add(factory);
|
||||
if (!factory.RegisterClassObject())
|
||||
{
|
||||
MessageBox.Show("Failed to register class factory for " + type.Name,
|
||||
"LynxAstro.DewController", MessageBoxButtons.OK, MessageBoxIcon.Stop);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
ClassFactory.ResumeClassObjects(); // Served objects now go live
|
||||
return true;
|
||||
}
|
||||
|
||||
private static void RevokeClassFactories()
|
||||
{
|
||||
ClassFactory.SuspendClassObjects(); // Prevent race conditions
|
||||
foreach (ClassFactory factory in s_ClassFactories)
|
||||
factory.RevokeClassObject();
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Command Line Arguments
|
||||
//
|
||||
// ProcessArguments() will process the command-line arguments
|
||||
// If the return value is true, we carry on and start this application.
|
||||
// If the return value is false, we terminate this application immediately.
|
||||
//
|
||||
private static bool ProcessArguments(string[] args)
|
||||
{
|
||||
bool bRet = true;
|
||||
|
||||
//
|
||||
//**TODO** -Embedding is "ActiveX start". Prohibit non_AX starting?
|
||||
//
|
||||
if (args.Length > 0)
|
||||
{
|
||||
|
||||
switch (args[0].ToLower())
|
||||
{
|
||||
case "-embedding":
|
||||
StartedByCOM = true; // Indicate COM started us
|
||||
break;
|
||||
|
||||
case "-register":
|
||||
case @"/register":
|
||||
case "-regserver": // Emulate VB6
|
||||
case @"/regserver":
|
||||
RegisterObjects(); // Register each served object
|
||||
bRet = false;
|
||||
break;
|
||||
|
||||
case "-unregister":
|
||||
case @"/unregister":
|
||||
case "-unregserver": // Emulate VB6
|
||||
case @"/unregserver":
|
||||
UnregisterObjects(); //Unregister each served object
|
||||
bRet = false;
|
||||
break;
|
||||
|
||||
default:
|
||||
MessageBox.Show("Unknown argument: " + args[0] + "\nValid are : -register, -unregister and -embedding",
|
||||
"LynxAstro.DewController", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
StartedByCOM = false;
|
||||
|
||||
return bRet;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region SERVER ENTRY POINT (main)
|
||||
//
|
||||
// ==================
|
||||
// SERVER ENTRY POINT
|
||||
// ==================
|
||||
//
|
||||
[STAThread]
|
||||
static void Main(string[] args)
|
||||
{
|
||||
if (!LoadComObjectAssemblies()) return; // Load served COM class assemblies, get types
|
||||
|
||||
if (!ProcessArguments(args)) return; // Register/Unregister
|
||||
|
||||
// Initialize critical member variables.
|
||||
objsInUse = 0;
|
||||
serverLocks = 0;
|
||||
MainThreadId = GetCurrentThreadId();
|
||||
Thread.CurrentThread.Name = "Main Thread";
|
||||
|
||||
Application.EnableVisualStyles();
|
||||
Application.SetCompatibleTextRenderingDefault(false);
|
||||
s_MainForm = new frmMain();
|
||||
if (StartedByCOM) s_MainForm.WindowState = FormWindowState.Minimized;
|
||||
|
||||
// Register the class factories of the served objects
|
||||
RegisterClassFactories();
|
||||
|
||||
// Start up the garbage collection thread.
|
||||
GarbageCollection GarbageCollector = new GarbageCollection(1000);
|
||||
Thread GCThread = new Thread(new ThreadStart(GarbageCollector.GCWatch));
|
||||
GCThread.Name = "Garbage Collection Thread";
|
||||
GCThread.Start();
|
||||
|
||||
//
|
||||
// Start the message loop. This serializes incoming calls to our
|
||||
// served COM objects, making this act like the VB6 equivalent!
|
||||
//
|
||||
try
|
||||
{
|
||||
Application.Run(s_MainForm);
|
||||
}
|
||||
finally
|
||||
{
|
||||
// Revoke the class factories immediately.
|
||||
// Don't wait until the thread has stopped before
|
||||
// we perform revocation!!!
|
||||
RevokeClassFactories();
|
||||
|
||||
// Now stop the Garbage Collector thread.
|
||||
GarbageCollector.StopThread();
|
||||
GarbageCollector.WaitForThreadToStop();
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,191 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="12.0">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProductVersion>8.0.50727</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{C708E487-E3A9-4073-A545-294B88674225}</ProjectGuid>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>ASCOM.LynxAstro.DewController</RootNamespace>
|
||||
<AssemblyName>ASCOM.LynxAstro.DewController.Server</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
|
||||
<FileUpgradeFlags>
|
||||
</FileUpgradeFlags>
|
||||
<OldToolsVersion>2.0</OldToolsVersion>
|
||||
<UpgradeBackupLocation />
|
||||
<TargetFrameworkProfile />
|
||||
<IsWebBootstrapper>false</IsWebBootstrapper>
|
||||
<PublishUrl>publish\</PublishUrl>
|
||||
<Install>true</Install>
|
||||
<InstallFrom>Disk</InstallFrom>
|
||||
<UpdateEnabled>false</UpdateEnabled>
|
||||
<UpdateMode>Foreground</UpdateMode>
|
||||
<UpdateInterval>7</UpdateInterval>
|
||||
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
|
||||
<UpdatePeriodically>false</UpdatePeriodically>
|
||||
<UpdateRequired>false</UpdateRequired>
|
||||
<MapFileExtensions>true</MapFileExtensions>
|
||||
<ApplicationRevision>0</ApplicationRevision>
|
||||
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
|
||||
<UseApplicationTrust>false</UseApplicationTrust>
|
||||
<BootstrapperEnabled>true</BootstrapperEnabled>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
<Prefer32Bit>false</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<Prefer32Bit>false</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<SignAssembly>true</SignAssembly>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<AssemblyOriginatorKeyFile>LocalServer.snk</AssemblyOriginatorKeyFile>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="ASCOM.Astrometry, Version=6.0.0.0, Culture=neutral, PublicKeyToken=565de7938946fba7, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\ASCOM.Platform.6.5.2\lib\net40\ASCOM.Astrometry.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="ASCOM.Attributes, Version=6.0.0.0, Culture=neutral, PublicKeyToken=565de7938946fba7, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\ASCOM.Platform.6.5.2\lib\net40\ASCOM.Attributes.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="ASCOM.Cache, Version=6.0.0.0, Culture=neutral, PublicKeyToken=565de7938946fba7, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\ASCOM.Platform.6.5.2\lib\net40\ASCOM.Cache.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="ASCOM.Controls, Version=6.0.0.0, Culture=neutral, PublicKeyToken=565de7938946fba7, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\ASCOM.Platform.6.5.2\lib\net40\ASCOM.Controls.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="ASCOM.DeviceInterfaces, Version=6.0.0.0, Culture=neutral, PublicKeyToken=565de7938946fba7, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\ASCOM.Platform.6.5.2\lib\net40\ASCOM.DeviceInterfaces.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="ASCOM.DriverAccess, Version=6.0.0.0, Culture=neutral, PublicKeyToken=565de7938946fba7, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\ASCOM.Platform.6.5.2\lib\net40\ASCOM.DriverAccess.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="ASCOM.Exceptions, Version=6.0.0.0, Culture=neutral, PublicKeyToken=565de7938946fba7, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\ASCOM.Platform.6.5.2\lib\net40\ASCOM.Exceptions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="ASCOM.Internal.Extensions, Version=6.0.0.0, Culture=neutral, PublicKeyToken=565de7938946fba7, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\ASCOM.Platform.6.5.2\lib\net40\ASCOM.Internal.Extensions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="ASCOM.SettingsProvider, Version=6.0.0.0, Culture=neutral, PublicKeyToken=565de7938946fba7, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\ASCOM.Platform.6.5.2\lib\net40\ASCOM.SettingsProvider.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="ASCOM.Utilities, Version=6.0.0.0, Culture=neutral, PublicKeyToken=565de7938946fba7, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\ASCOM.Platform.6.5.2\lib\net40\ASCOM.Utilities.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="ASCOM.Utilities.Video, Version=6.1.0.0, Culture=neutral, PublicKeyToken=565de7938946fba7, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\ASCOM.Platform.6.5.2\lib\net40\ASCOM.Utilities.Video.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="JetBrains.Annotations, Version=2020.3.0.0, Culture=neutral, PublicKeyToken=1010a0d8d6380325, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\JetBrains.Annotations.2020.3.0\lib\net20\JetBrains.Annotations.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="System.Windows.Forms" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="AssemblyInfo.cs" />
|
||||
<Compile Include="ClassFactory.cs" />
|
||||
<Compile Include="ConnectionInfo.cs" />
|
||||
<Compile Include="frmMain.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="frmMain.Designer.cs">
|
||||
<DependentUpon>frmMain.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="GarbageCollection.cs" />
|
||||
<Compile Include="IProfileFactory.cs" />
|
||||
<Compile Include="IProfileWrapper.cs" />
|
||||
<Compile Include="ISharedResourcesWrapper.cs" />
|
||||
<Compile Include="LocalServer.cs" />
|
||||
<Compile Include="ProfileFactory.cs" />
|
||||
<Compile Include="ProfileProperties.cs" />
|
||||
<Compile Include="ProfileWrapper.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="SharedResourcesWrapper.cs" />
|
||||
<EmbeddedResource Include="frmMain.resx">
|
||||
<SubType>Designer</SubType>
|
||||
<DependentUpon>frmMain.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<Compile Include="Properties\Resources.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DesignTime>True</DesignTime>
|
||||
<DependentUpon>Resources.resx</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="ReferenceCountedObject.cs" />
|
||||
<Compile Include="SetupDialogForm.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="SetupDialogForm.designer.cs">
|
||||
<DependentUpon>SetupDialogForm.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="SharedResources.cs" />
|
||||
<EmbeddedResource Include="Properties\Resources.resx">
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="SetupDialogForm.resx">
|
||||
<DependentUpon>SetupDialogForm.cs</DependentUpon>
|
||||
<SubType>Designer</SubType>
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Resources\ASCOM.png" />
|
||||
<Content Include="ReadMe.htm" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="app.config" />
|
||||
<None Include="LocalServer.snk" />
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<BootstrapperPackage Include="Microsoft.Net.Client.3.5">
|
||||
<Visible>False</Visible>
|
||||
<ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
|
||||
<Install>false</Install>
|
||||
</BootstrapperPackage>
|
||||
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
|
||||
<Visible>False</Visible>
|
||||
<ProductName>.NET Framework 3.5 SP1</ProductName>
|
||||
<Install>true</Install>
|
||||
</BootstrapperPackage>
|
||||
<BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
|
||||
<Visible>False</Visible>
|
||||
<ProductName>Windows Installer 3.1</ProductName>
|
||||
<Install>true</Install>
|
||||
</BootstrapperPackage>
|
||||
</ItemGroup>
|
||||
<ItemGroup />
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
<PropertyGroup>
|
||||
<PreBuildEvent>
|
||||
</PreBuildEvent>
|
||||
<PostBuildEvent>
|
||||
</PostBuildEvent>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,10 @@
|
||||
namespace ASCOM.LynxAstro.DewController
|
||||
{
|
||||
public class ProfileFactory : IProfileFactory
|
||||
{
|
||||
public IProfileWrapper Create()
|
||||
{
|
||||
return new ProfileWrapper();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace ASCOM.LynxAstro.DewController
|
||||
{
|
||||
public class ProfileProperties
|
||||
{
|
||||
// properies that are part of the profile
|
||||
public string ComPort { get; set; }
|
||||
public bool TraceLogger { get; set; }
|
||||
public List<string> SwitchNames { get; set; } = new List<string>();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,132 @@
|
||||
using System.Collections;
|
||||
using ASCOM.Utilities;
|
||||
|
||||
namespace ASCOM.LynxAstro.DewController
|
||||
{
|
||||
public class ProfileWrapper : IProfileWrapper
|
||||
{
|
||||
private readonly Profile _profile = new Profile();
|
||||
|
||||
public ArrayList RegisteredDevices(string deviceType)
|
||||
{
|
||||
return _profile.RegisteredDevices(deviceType);
|
||||
}
|
||||
|
||||
public bool IsRegistered(string driverId)
|
||||
{
|
||||
return _profile.IsRegistered(driverId);
|
||||
}
|
||||
|
||||
public void Register(string driverId, string descriptiveName)
|
||||
{
|
||||
_profile.Register(driverId, descriptiveName);
|
||||
}
|
||||
|
||||
public void Unregister(string driverId)
|
||||
{
|
||||
_profile.Unregister(driverId);
|
||||
}
|
||||
|
||||
public string GetValue(string driverId, string name, string subKey, string defaultValue)
|
||||
{
|
||||
return _profile.GetValue(driverId, name, subKey, defaultValue);
|
||||
}
|
||||
|
||||
public void WriteValue(string driverId, string name, string value, string subKey)
|
||||
{
|
||||
_profile.WriteValue(driverId, name, value);
|
||||
}
|
||||
|
||||
public ArrayList Values(string driverId, string subKey)
|
||||
{
|
||||
return _profile.Values(driverId, subKey);
|
||||
}
|
||||
|
||||
public void DeleteValue(string driverId, string name, string subKey)
|
||||
{
|
||||
_profile.DeleteValue(driverId, name, subKey);
|
||||
}
|
||||
|
||||
public void CreateSubKey(string driverId, string subKey)
|
||||
{
|
||||
_profile.CreateSubKey(driverId, subKey);
|
||||
}
|
||||
|
||||
public ArrayList SubKeys(string driverId, string subKey)
|
||||
{
|
||||
return _profile.SubKeys(driverId, subKey);
|
||||
}
|
||||
|
||||
public void DeleteSubKey(string driverId, string subKey)
|
||||
{
|
||||
_profile.DeleteSubKey(driverId, subKey);
|
||||
}
|
||||
|
||||
public string GetProfileXML(string deviceId)
|
||||
{
|
||||
return _profile.GetProfileXML(deviceId);
|
||||
}
|
||||
|
||||
public void SetProfileXML(string deviceId, string xml)
|
||||
{
|
||||
_profile.SetProfileXML(deviceId, xml);
|
||||
}
|
||||
|
||||
public string DeviceType
|
||||
{
|
||||
get => _profile.DeviceType;
|
||||
set => _profile.DeviceType = value;
|
||||
}
|
||||
public ArrayList RegisteredDeviceTypes => _profile.RegisteredDeviceTypes;
|
||||
|
||||
public void MigrateProfile(string currentPlatformVersion)
|
||||
{
|
||||
_profile.MigrateProfile(currentPlatformVersion);
|
||||
}
|
||||
|
||||
public void DeleteValue(string driverId, string name)
|
||||
{
|
||||
_profile.DeleteValue(driverId, name);
|
||||
}
|
||||
|
||||
public string GetValue(string driverId, string name)
|
||||
{
|
||||
return _profile.GetValue(driverId, name);
|
||||
}
|
||||
|
||||
public string GetValue(string driverId, string name, string subKey)
|
||||
{
|
||||
return _profile.GetValue(driverId, name, subKey);
|
||||
}
|
||||
|
||||
public ArrayList SubKeys(string driverId)
|
||||
{
|
||||
return _profile.SubKeys(driverId);
|
||||
}
|
||||
|
||||
public ArrayList Values(string driverId)
|
||||
{
|
||||
return _profile.Values(driverId);
|
||||
}
|
||||
|
||||
public void WriteValue(string driverId, string name, string value)
|
||||
{
|
||||
_profile.WriteValue(driverId, name, value);
|
||||
}
|
||||
|
||||
public ASCOMProfile GetProfile(string driverId)
|
||||
{
|
||||
return _profile.GetProfile(driverId);
|
||||
}
|
||||
|
||||
public void SetProfile(string driverId, ASCOMProfile xmlProfileKey)
|
||||
{
|
||||
_profile.SetProfile(driverId, xmlProfileKey);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_profile.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("ASCOM LynxAstro.DewController server")]
|
||||
[assembly: AssemblyDescription("ASCOM multi-interface server for LynxAstro.DewController")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("ASCOM Initiative")]
|
||||
[assembly: AssemblyProduct("")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2021, colin")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
[assembly: AssemblyVersion("6.4.0.0")]
|
||||
[assembly: AssemblyFileVersion("6.4.0.0")]
|
||||
|
||||
[assembly: ComVisibleAttribute(false)]
|
||||
@@ -0,0 +1,82 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.42000
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace ASCOM.LynxAstro.DewController.Properties {
|
||||
using System;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// A strongly-typed resource class, for looking up localized strings, etc.
|
||||
/// </summary>
|
||||
// This class was auto-generated by the StronglyTypedResourceBuilder
|
||||
// class via a tool like ResGen or Visual Studio.
|
||||
// To add or remove a member, edit your .ResX file then rerun ResGen
|
||||
// with the /str option, or rebuild your VS project.
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
internal class Resources {
|
||||
|
||||
private static global::System.Resources.ResourceManager resourceMan;
|
||||
|
||||
private static global::System.Globalization.CultureInfo resourceCulture;
|
||||
|
||||
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||
internal Resources() {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the cached ResourceManager instance used by this class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Resources.ResourceManager ResourceManager {
|
||||
get {
|
||||
if (object.ReferenceEquals(resourceMan, null)) {
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ASCOM.LynxAstro.DewController.Properties.Resources", typeof(Resources).Assembly);
|
||||
resourceMan = temp;
|
||||
}
|
||||
return resourceMan;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Overrides the current thread's CurrentUICulture property for all
|
||||
/// resource lookups using this strongly typed resource class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Globalization.CultureInfo Culture {
|
||||
get {
|
||||
return resourceCulture;
|
||||
}
|
||||
set {
|
||||
resourceCulture = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Drawing.Bitmap.
|
||||
/// </summary>
|
||||
internal static System.Drawing.Bitmap ASCOM {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("ASCOM", resourceCulture);
|
||||
return ((System.Drawing.Bitmap)(obj));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to {0} Settings ({1}).
|
||||
/// </summary>
|
||||
internal static string SetupDialogForm_SetupDialogForm__0__Settings___1__ {
|
||||
get {
|
||||
return ResourceManager.GetString("SetupDialogForm_SetupDialogForm__0__Settings___1__", resourceCulture);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<data name="ASCOM" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\ASCOM.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="SetupDialogForm_SetupDialogForm__0__Settings___1__" xml:space="preserve">
|
||||
<value>{0} Settings ({1})</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -0,0 +1,666 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=windows-1252"/>
|
||||
<TITLE>Untitled Document</TITLE>
|
||||
<META NAME="GENERATOR" CONTENT="OpenOffice.org 3.2 (Win32)"/>
|
||||
<META NAME="CREATED" CONTENT="0;0"/>
|
||||
<META NAME="CHANGEDBY" CONTENT="Chris Rowland"/>
|
||||
<META NAME="CHANGED" CONTENT="20110422;10442800"/>
|
||||
<META NAME="CHANGEDBY" CONTENT="Chris Rowland"/>
|
||||
<STYLE TYPE="text/css">
|
||||
<!--
|
||||
@page { margin: 2cm }
|
||||
P { font-family: "Verdana", "Arial", "Helvetica", sans-serif; font-weight: normal }
|
||||
TD P { font-family: "Verdana", "Arial", "Helvetica", sans-serif; font-weight: normal }
|
||||
H3 { font-family: "Arial", "Helvetica", sans-serif }
|
||||
H2 { font-family: "Arial", "Helvetica", sans-serif }
|
||||
H4 { font-family: "Arial", "Helvetica", sans-serif }
|
||||
PRE { margin-left: 0.18cm; margin-right: 0.18cm; margin-top: 0.18cm; margin-bottom: 0.18cm; background: #ccffff }
|
||||
PRE.western { font-weight: normal }
|
||||
PRE.cjk { font-family: "NSimSun", monospace; font-weight: normal }
|
||||
PRE.ctl { font-weight: normal }
|
||||
EM.underline { text-decoration: underline }
|
||||
-->
|
||||
</STYLE>
|
||||
</HEAD>
|
||||
<BODY LANG="en-GB" DIR="LTR">
|
||||
<TABLE WIDTH="100%" BORDER="0" CELLPADDING="4" CELLSPACING="0" STYLE="page-break-before: always">
|
||||
<TR>
|
||||
<TD>
|
||||
<H2>
|
||||
ASCOM LocalServer (singleton) Host
|
||||
</H2>
|
||||
</TD>
|
||||
</TR>
|
||||
</TABLE>
|
||||
<P>
|
||||
<BR/>
|
||||
<BR/>
|
||||
|
||||
</P>
|
||||
<H4>
|
||||
You have just created a local server (singleton) host for one or
|
||||
more ASCOM driver classes.
|
||||
</H4>
|
||||
<HR/>
|
||||
<P>
|
||||
This project implements an ASCOM host server for one or more
|
||||
driver classes in a single-instance executable. It can be used to
|
||||
serve multiple instances of a single driver class (hub), provide
|
||||
driver services for multiple devices (e.g., Telescope and Focuser) to
|
||||
multiple applications and allow multiple devices of the same type to
|
||||
be connected. In the latter scenario, the multiple driver classes
|
||||
will often share one or more resources such as the serial connection
|
||||
and a microcontroller in the combined device. From the client's
|
||||
perspective, using the drivers served by the local server is exactly
|
||||
the same as if the drivers are loaded into the client's process space
|
||||
(in-proc servers).
|
||||
</P>
|
||||
<P STYLE="margin-left: 0.42cm; margin-right: 0.42cm; border: 1px solid #000000; padding: 0.21cm">
|
||||
<STRONG>
|
||||
<SPAN STYLE="background: #ffee88">NOTE:</SPAN>
|
||||
</STRONG>
|
||||
<SPAN STYLE="background: #ffee88">
|
||||
Unless you are prepared to handle all of the timing issues that arise
|
||||
when multiple clients are accessing the properties and methods of
|
||||
your driver(s), stop now. Just because the local server serializes
|
||||
the calls to your driver(s)' properties and methods does not mean
|
||||
that there will be no timing or concurrency issues.<BR/>
|
||||
<BR/>For
|
||||
example, suppose the hub serves instances of a Telescope driver. One
|
||||
client sets the TargetRightAscension property, then another sets
|
||||
TargetRightAscension to a different value, then the first client sets
|
||||
TargetDeclination, then the first client calls SlewToTarget()
|
||||
followed by the second client calling SlewToTarget(). Besides the
|
||||
first client's slew command sending the scope to the wrong (and
|
||||
possibly dangerous) coordinates, there is the problem of the second
|
||||
client trying to slew a slewing scope. Local server drivers are
|
||||
tricky to get right. There is no such thing as "ignorance is
|
||||
bliss" here.
|
||||
|
||||
</SPAN>
|
||||
</P>
|
||||
<P STYLE="margin-left: 0.42cm; margin-right: 0.42cm; border: 1px solid #000000; padding: 0.21cm">
|
||||
<SPAN STYLE="background: #ffee88">
|
||||
This implementation has changed
|
||||
from what was defined for Platform 5.5 as follows:
|
||||
</SPAN>
|
||||
</P>
|
||||
<P STYLE="margin-left: 0.42cm; margin-right: 0.42cm; border: 1px solid #000000; padding: 0.21cm">
|
||||
<SPAN STYLE="background: #ffee88">
|
||||
The drivers are now installed in
|
||||
the same folder as the local server executable. This makes deployment
|
||||
cleaner because the whole driver can exist in a single folder
|
||||
independently of other drivers.
|
||||
</SPAN>
|
||||
</P>
|
||||
<P STYLE="margin-left: 0.42cm; margin-right: 0.42cm; border: 1px solid #000000; padding: 0.21cm">
|
||||
<SPAN STYLE="background: #ffee88">
|
||||
The ProgId and friendly name as
|
||||
displayed by the Chooser are defined using attributes. This allows
|
||||
driver dlls to be identified clearly and so avoids confusion with
|
||||
other dlls that may be required such as interop dlls.
|
||||
</SPAN>
|
||||
</P>
|
||||
<P STYLE="margin-left: 0.42cm; margin-right: 0.42cm; border: 1px solid #000000; padding: 0.21cm">
|
||||
<SPAN STYLE="background: #ffee88">
|
||||
Some changes have been made that
|
||||
will facilitate generating multiple drivers of the same type.
|
||||
</SPAN>
|
||||
</P>
|
||||
<P STYLE="margin-left: 0.42cm; margin-right: 0.42cm; border: 1px solid #000000; padding: 0.21cm">
|
||||
<SPAN STYLE="background: #ffee88">
|
||||
I've put some additional advice and
|
||||
comments in the notes below <I>in italics.</I>
|
||||
</SPAN>
|
||||
</P>
|
||||
<P>
|
||||
You're probably anxious to get going, but you really should read
|
||||
through the <A HREF="#theory">Theory of Operation</A> and <A HREF="#details">
|
||||
Detailed
|
||||
Use and Deployment
|
||||
</A> below.
|
||||
</P>
|
||||
<P>You must do the following in order to complete your local server:</P>
|
||||
<OL>
|
||||
<LI>
|
||||
<P STYLE="margin-bottom: 0cm">
|
||||
In the local server's project
|
||||
properties, Application tab, change BOTH the AssemblyName and the
|
||||
default assembly name to ASCOM.xxx (e.g., ASCOM.SuperScope). <I>
|
||||
This
|
||||
may be done by default now.
|
||||
</I>
|
||||
</P>
|
||||
</LI>
|
||||
<LI>
|
||||
<P STYLE="margin-bottom: 0cm">
|
||||
Add one or more driver skeleton
|
||||
projects using the in-proc templates. You may use either the C# or
|
||||
VB templates. Project name is not important (not used in ProgID)
|
||||
choose something like TelescopeDriver. You will be changing the
|
||||
substituted project name in these projects below. If you ensure that
|
||||
the LocalServer and all the driver projects have the same NameSpace
|
||||
e.g. ASCOM.SuperScope the renaming in section 6a will not be
|
||||
required.
|
||||
</P>
|
||||
</LI>
|
||||
<LI>
|
||||
<P STYLE="margin-bottom: 0cm">
|
||||
Develop and debug these driver
|
||||
projects as normal in-process assemblies. This will be much simpler
|
||||
because the driver and test code can be debugged in the same
|
||||
process.
|
||||
</P>
|
||||
</LI>
|
||||
<LI>
|
||||
<P STYLE="margin-bottom: 0cm">
|
||||
Build the LocalServer.
|
||||
</P>
|
||||
</LI>
|
||||
<LI>
|
||||
<P STYLE="margin-bottom: 0cm">
|
||||
Set a reference to the local
|
||||
server <STRONG>project</STRONG> in each of the driver skeleton
|
||||
projects.
|
||||
</P>
|
||||
</LI>
|
||||
<LI>
|
||||
<P STYLE="margin-bottom: 0cm">In each skeleton driver project:</P>
|
||||
<OL TYPE="a">
|
||||
<LI>
|
||||
<P STYLE="margin-bottom: 0cm">
|
||||
Do a Find In Files for the
|
||||
project name of the skeleton driver (e.g., TelescopeDriver) and
|
||||
change it to match the project name of your local server (e.g.
|
||||
SuperScope). You don't have to do this in the ReadMe.html file.
|
||||
Everywhere else, however, is IMPORTANT. This sets the correct
|
||||
namespace, progID, etc. If you're a bit more brave, you can use
|
||||
Replace in Files. <I>
|
||||
This may not be needed if the correct
|
||||
namespace and naming conventions have been followed when the
|
||||
drivers and local server were generated.
|
||||
</I>
|
||||
</P>
|
||||
</LI>
|
||||
<LI>
|
||||
<P STYLE="margin-bottom: 0cm">
|
||||
In project properties,
|
||||
Application tab, change the assembly name to
|
||||
ASCOM.<EM CLASS="underline">localserverprojectname</EM>.<EM>drivertype</EM>,
|
||||
(e.g., ASCOM.SuperScope.Telescope).
|
||||
</P>
|
||||
</LI>
|
||||
<LI>
|
||||
<P STYLE="margin-bottom: 0cm">
|
||||
In project properties,
|
||||
Application tab, click Assembly Information...
|
||||
</P>
|
||||
<UL>
|
||||
<LI>
|
||||
<P STYLE="margin-bottom: 0cm">
|
||||
Assure that Make assembly COM
|
||||
visible is <STRONG>on</STRONG> (it should already be on).
|
||||
</P>
|
||||
</LI>
|
||||
<LI>
|
||||
<P STYLE="margin-bottom: 0cm">
|
||||
Edit the Product Name to be the
|
||||
"friendly name" of your driver as will be shown in the
|
||||
Chooser. <I>
|
||||
Not used now, use the ServedClassName attribute
|
||||
instead.
|
||||
</I>
|
||||
</P>
|
||||
</LI>
|
||||
</UL>
|
||||
</LI>
|
||||
<LI>
|
||||
<P STYLE="margin-bottom: 0cm">
|
||||
In project properties, Build tab,
|
||||
turn <STRONG>off</STRONG> Register for COM Interop.
|
||||
</P>
|
||||
</LI>
|
||||
<LI>
|
||||
<P>
|
||||
Modify the driver class declaration to inherit from
|
||||
ReferenceCountedObjectBase. Examples:<BR/>C#:
|
||||
</P>
|
||||
<PRE CLASS="western">
|
||||
public class Telescope :
|
||||
ReferenceCountedObjectBase,
|
||||
ITelescope
|
||||
</PRE>
|
||||
<P>
|
||||
VB:
|
||||
</P>
|
||||
<PRE CLASS="western">
|
||||
Public Class Telescope
|
||||
'==================================
|
||||
Inherits ReferenceCountedObjectBase
|
||||
Implements ITelescope
|
||||
'==================================
|
||||
</PRE>
|
||||
</LI>
|
||||
<LI>
|
||||
<P STYLE="margin-bottom: 0cm">
|
||||
In driver.cs/driver.vb, remove
|
||||
the entire ASCOM Registration region
|
||||
</P>
|
||||
</LI>
|
||||
<LI>
|
||||
<P STYLE="margin-bottom: 0cm">
|
||||
In driver.cs/driver.vb, remove
|
||||
the private strings for driver ID and driver description. <I>
|
||||
They
|
||||
may be needed internally, and if so should be set from the
|
||||
associated attributes, ServedClassName for the description and
|
||||
ProgId for the driver Id.
|
||||
</I>
|
||||
</P>
|
||||
</LI>
|
||||
<LI>
|
||||
<P STYLE="margin-bottom: 0cm">
|
||||
Modify the class attributes by
|
||||
adding the ServedClassName and ProgID attributes. The
|
||||
ServedClassName attribute must be the friendly name shown as the
|
||||
device name in the Chooser and the ProgId the progid of the driver
|
||||
e.g. ASCOM.SuperScope.Telescope. The class header should look like
|
||||
this:
|
||||
</P>
|
||||
<P STYLE="margin-bottom: 0cm">C#:</P>
|
||||
<PRE CLASS="western" STYLE="margin-right: 0.16cm">
|
||||
<FONT FACE="Consolas" SIZE="2" STYLE="font-size: 9pt">
|
||||
[<FONT COLOR="#2b91af">Guid</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#a31515">"0AE8B38D-10A1-4A8D-A5B7-1B050F74B48B"</FONT><FONT COLOR="#000000">)] // set by the template</FONT>
|
||||
<FONT COLOR="#000000">[</FONT><FONT COLOR="#2b91af">ProgId</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#a31515">"ASCOM.SuperScope.Telescope"</FONT><FONT COLOR="#000000">)]</FONT>
|
||||
<FONT COLOR="#000000">[</FONT><FONT COLOR="#2b91af">ServedClassName</FONT><FONT COLOR="#000000"> (</FONT><FONT COLOR="#a31515">"Super Scope Telescope"</FONT><FONT COLOR="#000000">)]</FONT>
|
||||
<FONT COLOR="#000000">[</FONT><FONT COLOR="#2b91af">ClassInterface</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#2b91af">ClassInterfaceType</FONT><FONT COLOR="#000000">.None)]</FONT>
|
||||
<FONT COLOR="#0000ff">public </FONT><FONT COLOR="#0000ff">class </FONT><FONT COLOR="#2b91af">Telescope </FONT><FONT COLOR="#000000">: </FONT><FONT COLOR="#2b91af">ReferenceCountedObjectBase</FONT><FONT COLOR="#000000"> , </FONT><FONT COLOR="#2b91af">ITelescope</FONT>
|
||||
</FONT>
|
||||
</PRE>
|
||||
</LI>
|
||||
</OL>
|
||||
</LI>
|
||||
</OL>
|
||||
<P STYLE="margin-bottom: 0cm">
|
||||
<BR/>
|
||||
</P>
|
||||
<OL>
|
||||
<OL TYPE="a">
|
||||
<P>VB:</P>
|
||||
<PRE CLASS="western">
|
||||
<FONT FACE="Consolas" SIZE="2" STYLE="font-size: 9pt">
|
||||
<Guid(“<FONT COLOR="#a31515">0AE8B38D-10A1-4A8D-A5B7-1B050F74B48B</FONT>”)>
|
||||
<ProgId(“ASCOM.SuperScope.Telescope”)>
|
||||
<ServedClassName(“Super Scope Telescope”)>
|
||||
Public Class Telescope
|
||||
'==================================
|
||||
Inherits ReferenceCountedObjectBase
|
||||
Implements ITelescope
|
||||
'==================================
|
||||
</FONT>
|
||||
</PRE>
|
||||
</OL>
|
||||
</OL>
|
||||
<P STYLE="margin-left: 2.5cm">
|
||||
Add the following line to the driver
|
||||
constructor, this sets the driver ID using the ProgId Attribute:
|
||||
</P>
|
||||
<OL>
|
||||
<OL TYPE="a">
|
||||
<P>C#</P>
|
||||
<PRE CLASS="western">
|
||||
<FONT FACE="Consolas" SIZE="2" STYLE="font-size: 9pt">
|
||||
s_csDriverID = <FONT COLOR="#2b91af">Marshal</FONT><FONT COLOR="#000000">.GenerateProgIdForType(</FONT><FONT COLOR="#0000ff">this</FONT><FONT COLOR="#000000">.GetType());</FONT>
|
||||
</FONT>
|
||||
</PRE>
|
||||
<P>VB:</P>
|
||||
<PRE CLASS="western">
|
||||
<FONT FACE="Consolas" SIZE="2" STYLE="font-size: 9pt">
|
||||
s_csDriverID = <FONT COLOR="#2b91af">Marshal</FONT><FONT COLOR="#000000">.GenerateProgIdForType(</FONT><FONT COLOR="#0000ff">Me</FONT><FONT COLOR="#000000">.GetType())</FONT>
|
||||
</FONT>
|
||||
</PRE>
|
||||
</OL>
|
||||
<LI>
|
||||
<P STYLE="margin-bottom: 0cm">
|
||||
Unless you're writing a
|
||||
single-driver hub, you will have two or more driver types (e.g.
|
||||
Telescope and Focuser) and thus two or more driver assembly projects
|
||||
added. Presumably, these drivers need to share some resources (e.g.
|
||||
a single COM port via Helper.Serial). <U>
|
||||
Put shared resources into
|
||||
the SharedResources class provided
|
||||
</U>. There are some examples that
|
||||
should give a clue, modify and delete these as required.
|
||||
</P>
|
||||
</LI>
|
||||
<LI>
|
||||
<P STYLE="margin-bottom: 0cm">
|
||||
A shared serial port is already
|
||||
provided (see SharedResources.cs) as <FONT FACE="Lucida Console, Courier New, Courier, monospace">SharedResources.SharedSerial</FONT>
|
||||
and it is an ASCOM Helper Serial object. You may wish to define
|
||||
additional shared resources in static member variables with public
|
||||
static accessor properties as is already done for SharedSerial.
|
||||
Unfortunately, if you are a Visual Basic programmer, you will have
|
||||
to make these additions in C#.
|
||||
</P>
|
||||
</LI>
|
||||
<LI>
|
||||
<P STYLE="margin-bottom: 0cm">
|
||||
If you are writing a hub and don't
|
||||
need the serial port, in SharedResources.cs you can remove the
|
||||
public static SharedSerial property, the m_SharedSerial member in
|
||||
the private data region, and the line in main that initializes it.
|
||||
If you don't need any other shared resources for your hub, then you
|
||||
can remove the SharedResources.cs file completely.
|
||||
</P>
|
||||
</LI>
|
||||
<LI>
|
||||
<P STYLE="margin-bottom: 0cm">
|
||||
If you modified the LocalServer,
|
||||
build it again now. This will refresh the stuff that's visible to
|
||||
the drivers.
|
||||
</P>
|
||||
</LI>
|
||||
<LI>
|
||||
<P STYLE="margin-bottom: 0cm">
|
||||
Build the driver skeletons to
|
||||
verify that you got all of the namespace and other variable changes.
|
||||
</P>
|
||||
</LI>
|
||||
<LI>
|
||||
<P>
|
||||
The local server dynamically loads the driver assemblies from
|
||||
the same folder as the local server executable. <BR/>
|
||||
<BR/>During
|
||||
development, you'll need to add a post-build task to each of your
|
||||
driver assembly projects which puts a copy of the driver assembly
|
||||
into the local server executable folder. Here is an example:
|
||||
</P>
|
||||
<PRE CLASS="western"> copy "$(TargetPath)" "$(SolutionDir)\SuperScope\$(OutDir)\$(TargetFileName)"</PRE>
|
||||
<P STYLE="margin-bottom: 0cm">
|
||||
This assumes that the server project is called “SuperScope”,
|
||||
and handles using the debug or release build.<BR/>
|
||||
Note the quotes for
|
||||
possible path elements with spaces in them. <I>
|
||||
An alternative is to
|
||||
set the build path to the required destination instead of the
|
||||
default path.
|
||||
</I>
|
||||
</P>
|
||||
</LI>
|
||||
<LI>
|
||||
<P STYLE="margin-bottom: 0cm">
|
||||
<I>
|
||||
Make sure the drivers are
|
||||
registered through the local server by running it with the /register
|
||||
parameter, see below for details.
|
||||
</I>
|
||||
</P>
|
||||
</LI>
|
||||
<LI>
|
||||
<P STYLE="margin-bottom: 0cm">
|
||||
<SPAN STYLE="background: #ffff00">IMPORTANT:</SPAN>
|
||||
With a local server based driver (or hub) it is possible for
|
||||
multiple clients to control the device(s). It is up to you to
|
||||
safeguard against abuse. <I>
|
||||
The sort of thing that's needed is to
|
||||
have a counter of the number of connections to a device, the
|
||||
connection is only fully broken when the number of connections is
|
||||
zero. You may also need code to prevent several drivers from talking
|
||||
to the hardware at the same time, the lock pattern is useful for
|
||||
that.
|
||||
</I>
|
||||
</P>
|
||||
</LI>
|
||||
<LI>
|
||||
<P>
|
||||
You may want to add controls and/or status information to the
|
||||
main form frmMain of the local server. Please resist the temptation
|
||||
to turn the local server's main form into a graphical device control
|
||||
panel. Instead, make a separate application that uses the served
|
||||
driver(s). <U>A driver is not a program!</U>
|
||||
</P>
|
||||
</LI>
|
||||
</OL>
|
||||
<H3>Notes</H3>
|
||||
<UL>
|
||||
<LI>
|
||||
<P STYLE="margin-bottom: 0cm">
|
||||
The local server handles all of
|
||||
the registration and unregistration for each of its served driver
|
||||
classes, including the ASCOM Chooser info and the DCOM/AppID info
|
||||
needed for activation from TheSky. By running the server from a
|
||||
command line and giving /register or /unregister as the command line
|
||||
option, it will register or unregister all served classes
|
||||
(respectively). <SPAN STYLE="background: #ffff00">
|
||||
Never use REGASM
|
||||
on the local server executable!
|
||||
</SPAN> <I>
|
||||
This can be done in the
|
||||
Visual Studio IDE by setting the server project to run as startup
|
||||
and setting the command line argument to /register in Debug –
|
||||
Start Options.
|
||||
</I>
|
||||
</P>
|
||||
</LI>
|
||||
<LI>
|
||||
<P STYLE="margin-bottom: 0cm">
|
||||
When you make the installer for
|
||||
your local server based driver/hub, do not let it register the
|
||||
executable for COM. Instead, have it activate the installed local
|
||||
server with the /register option.
|
||||
</P>
|
||||
</LI>
|
||||
<LI>
|
||||
<P>
|
||||
The ASCOM registration uses the ServedClassName attribute as
|
||||
the friendly name that will show in the chooser and the ProgId
|
||||
attribute as the driver Id.
|
||||
</P>
|
||||
</LI>
|
||||
<LI>
|
||||
<P>
|
||||
The best deployment way is to install all the files in a
|
||||
folder that's a sub folder of the main driver, so the SuperScope
|
||||
driver files will be in the folder ...\ASCOM\Telescope\SuperScope.
|
||||
This can be done in the Inno script by changing the DefaultDirName
|
||||
like this:<BR/>
|
||||
DefaultDirName="{cf}\ASCOM\Telescope\SuperScope"<BR/>then
|
||||
the files can all be installed with DestDir: {app};
|
||||
</P>
|
||||
</LI>
|
||||
</UL>
|
||||
<H3>
|
||||
<A NAME="theory"></A>Theory of Operation
|
||||
</H3>
|
||||
<P>
|
||||
The local server is an executable which can provide multiple
|
||||
instances of multiple drivers to multiple clients. This capability is
|
||||
needed for two applications:
|
||||
</P>
|
||||
<UL>
|
||||
<LI>
|
||||
<P STYLE="margin-bottom: 0cm">
|
||||
A hub, which allows multiple
|
||||
clients to share a single device
|
||||
</P>
|
||||
</LI>
|
||||
<LI>
|
||||
<P>
|
||||
A device which provides multiple services, such as a
|
||||
telescope which has a focuser built-in where both the telescope and
|
||||
focuser are controlled by the same serial connection and different
|
||||
client programs need to control to the focuser and telescope.
|
||||
</P>
|
||||
</LI>
|
||||
</UL>
|
||||
<P>
|
||||
By simply dropping suitably developed driver assemblies into the
|
||||
same folder as the local server executable, the local server will
|
||||
find them and register them for COM and ASCOM and serve any number of
|
||||
instances of the drivers' interfaces to any number of client
|
||||
programs. It does this by locating and loading the driver assemblies,
|
||||
analysing them to detect their classes and interfaces, and
|
||||
implementing a class factory that can create instances of them for
|
||||
clients.
|
||||
</P>
|
||||
<P>
|
||||
A driver is an assembly which contains a class that <EM>implements</EM>
|
||||
one of the ASCOM standard driver interfaces and <EM>inherits</EM> the
|
||||
ReferenceCountedObjectBase class of the local server. Apart from
|
||||
that, driver assemblies are identical to those that are used
|
||||
in-process (DLL-type). The instructions above detail the steps needed
|
||||
to convert an in-process driver into one that can be served by the
|
||||
local server.
|
||||
</P>
|
||||
<P>
|
||||
The name of the local server is important, so we provide it as a
|
||||
<EM>template</EM> from which you can create a local server for your
|
||||
produce. To make this clear, let's assume that your company AlphaTech
|
||||
produces a telescope system which contains a microcontroller that is
|
||||
able to control not only the telescope mount, but also a focuser and
|
||||
a camera rotator. The mount, focuser, and rotator are all controlled
|
||||
via commands sent through a common serial line connecting the
|
||||
computer to the microcontroller, so you need a local server. In
|
||||
ASCOM, then, you probably want your system to appear as
|
||||
AlphaTech.Telescope, AlphaTech.Focuser, and AlphaTech.Rotator. Then
|
||||
you would name the local server AlphaTech. Be sure to give this due
|
||||
consideration before creating the template, the project name is the
|
||||
name of your local server. <I>
|
||||
Is this still correct? I get the
|
||||
impression that ASCOM.AlphaTech.Server would be OK.
|
||||
</I>
|
||||
</P>
|
||||
<P>
|
||||
The fact that driver classes inherit from the local server's
|
||||
ReferenceCountedObjectBase class allows the local server to maintain
|
||||
a reference count on the driver class. If a client creates an
|
||||
instance of a served driver, the local server automatically starts up
|
||||
and provides an instance of the class to the client. Once started the
|
||||
local server can provide additional instances of any of its served
|
||||
driver classes. If the reference count of all served classes drops to
|
||||
zero as a result of clients releasing their instances, the local
|
||||
server will automatically exit.
|
||||
</P>
|
||||
<P>
|
||||
Registration services provided include not only the basic COM
|
||||
class registration, but also DCOM/AppID info needed to use the served
|
||||
classes from outbound connections from Software Bisque's TheSky. It
|
||||
also registers the served classes for the ASCOM Chooser. The
|
||||
"friendly" name of each served driver that appears in the
|
||||
chooser comes from the driver's ServedClassName attribute. This also
|
||||
used to identify a driver so that non driver dlls, such as Interop
|
||||
dlls can be ignored. The COM ProgID for each served driver is
|
||||
specified in the ProgId attribute - ASCOM.<EM>localservername</EM>.<EM>drivertype</EM>,
|
||||
for example, ASCOM.AlphaTech.Telescope, where AlphaTech is the local
|
||||
server name and Telescope is the type of the driver. Unregistering
|
||||
removes all of this information from the system. Specifying the
|
||||
ProgId as an attribute allows multiple driver assemblies to be
|
||||
generated using the same source and namespace. This is used to
|
||||
provide multiple instances of the same driver, each with a different
|
||||
ProgId and so able to be registered separately.
|
||||
</P>
|
||||
<P>
|
||||
Driver DLLs are identified for registering/unregistering because
|
||||
they contain a type with the ServedClassName attribute. Only these
|
||||
will be registered for Com and ASCOM. This has changed; in Platform
|
||||
5 there was no attribute and the local server attempted to register
|
||||
all dlls. The new behaviour allows support dlls such as interop dlls
|
||||
to be included without them being registered incorrectly. There was
|
||||
also an interim version where the ServedClassName attribute was on
|
||||
the assembly, not the class. <I>
|
||||
All these previous versions, and the
|
||||
new drivers will operate together with Platform 6, the changes are
|
||||
local to the individual drivers.
|
||||
</I>
|
||||
</P>
|
||||
<H3>
|
||||
<A NAME="details"></A>Detailed Use and Deployment
|
||||
</H3>
|
||||
<P>
|
||||
Once you have built your local server and the served driver class
|
||||
assemblies, here's how to use it. To register the served classes,
|
||||
activate the local server from a shell command line with the option
|
||||
/register (or /regserver, for VB6 compatibility):
|
||||
</P>
|
||||
<PRE CLASS="western">
|
||||
C:\xxx> <EM>localserver</EM>.exe /register
|
||||
</PRE>
|
||||
<P>
|
||||
To unregister the local server and its drivers, activate the local
|
||||
server from a shell command line with the option /unregister (or
|
||||
/unregserver for VB6 compatibility):
|
||||
</P>
|
||||
<PRE CLASS="western">
|
||||
C:\xxx> <EM>localserver</EM>.exe /unregister
|
||||
</PRE>
|
||||
<P>
|
||||
When the operating system starts the local server in response to a
|
||||
client creating one of it's served driver classes, the command option
|
||||
/embedding is included. The local server's code detects this and sets
|
||||
a variable that you can use.
|
||||
</P>
|
||||
<P STYLE="margin-bottom: 0cm">
|
||||
When deploying a hub or set of drivers
|
||||
with the local server, you'll have to arrange for the local server
|
||||
and the driver assemblies to be placed together in a folder in the
|
||||
ASCOM driver folder. Any support files, such as Interop DLLs can be
|
||||
put in the same fiolder. That's all you need to do, the local server
|
||||
will find them in the same folder as it is located in.
|
||||
</P>
|
||||
<DIV ALIGN="RIGHT">
|
||||
<TABLE WIDTH="100"% BORDER="0" CELLPADDING="4" CELLSPACING="0">
|
||||
<TR>
|
||||
<TD>
|
||||
<TABLE WIDTH="100"% BORDER="0" CELLPADDING="4" CELLSPACING="0">
|
||||
<TR>
|
||||
<TD>
|
||||
<H3>ASCOM Initiative</H3>
|
||||
</TD>
|
||||
<TD>
|
||||
<IMG SRC="ASCOM.png" NAME="graphics1" ALIGN="RIGHT" WIDTH="48" HEIGHT="56" BORDER="0"/>
|
||||
</TD>
|
||||
</TR>
|
||||
</TABLE>
|
||||
<P>
|
||||
<BR/>
|
||||
<BR/>
|
||||
|
||||
</P>
|
||||
</TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD>
|
||||
<P>
|
||||
The ASCOM Initiative consists of a group of astronomy software
|
||||
developers and instrument vendors whose goals are to promote the
|
||||
driver/client model and scripting automation.
|
||||
</P>
|
||||
<P>
|
||||
See the <A HREF="http://ascom-standards.org/" TARGET="browser">
|
||||
ASCOM
|
||||
web site
|
||||
</A> for more information. Please participate in the
|
||||
<A HREF="https://ascomtalk.groups.io/g/Help/topics" TARGET="browser">
|
||||
ASCOM-Talk
|
||||
Group
|
||||
</A>.
|
||||
</P>
|
||||
</TD>
|
||||
</TR>
|
||||
</TABLE>
|
||||
</DIV>
|
||||
<P>
|
||||
<BR/>
|
||||
<BR/>
|
||||
|
||||
</P>
|
||||
<P>
|
||||
<BR/>
|
||||
<BR/>
|
||||
|
||||
</P>
|
||||
</BODY>
|
||||
</HTML>
|
||||
@@ -0,0 +1,23 @@
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace ASCOM.LynxAstro.DewController
|
||||
{
|
||||
[ComVisible(false)]
|
||||
public class ReferenceCountedObjectBase
|
||||
{
|
||||
public ReferenceCountedObjectBase()
|
||||
{
|
||||
// We increment the global count of objects.
|
||||
Server.CountObject();
|
||||
}
|
||||
|
||||
~ReferenceCountedObjectBase()
|
||||
{
|
||||
// We decrement the global count of objects.
|
||||
Server.UncountObject();
|
||||
// We then immediately test to see if we the conditions
|
||||
// are right to attempt to terminate this server application.
|
||||
Server.ExitIf();
|
||||
}
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 1.9 KiB |
@@ -0,0 +1,89 @@
|
||||
using System;
|
||||
using System.IO.Ports;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Windows.Forms;
|
||||
using ASCOM.LynxAstro.DewController.Properties;
|
||||
|
||||
namespace ASCOM.LynxAstro.DewController
|
||||
{
|
||||
|
||||
[ComVisible(false)] // Form not registered for COM!
|
||||
public partial class SetupDialogForm : Form
|
||||
{
|
||||
public SetupDialogForm()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
var assemblyInfo = new AssemblyInfo();
|
||||
|
||||
Text = string.Format(Resources.SetupDialogForm_SetupDialogForm__0__Settings___1__, assemblyInfo.Product, assemblyInfo.AssemblyVersion);
|
||||
}
|
||||
|
||||
private void cmdOK_Click(object sender, EventArgs e) // OK button event handler
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private void cmdCancel_Click(object sender, EventArgs e) // Cancel button event handler
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
private void BrowseToAscom(object sender, EventArgs e) // Click on ASCOM logo event handler
|
||||
{
|
||||
try
|
||||
{
|
||||
System.Diagnostics.Process.Start("https://ascom-standards.org/");
|
||||
}
|
||||
catch (System.ComponentModel.Win32Exception noBrowser)
|
||||
{
|
||||
if (noBrowser.ErrorCode == -2147467259)
|
||||
MessageBox.Show(noBrowser.Message);
|
||||
}
|
||||
catch (System.Exception other)
|
||||
{
|
||||
MessageBox.Show(other.Message);
|
||||
}
|
||||
}
|
||||
|
||||
public void SetProfile(ProfileProperties profileProperties)
|
||||
{
|
||||
chkTrace.Checked = profileProperties.TraceLogger;
|
||||
// set the list of com ports to those that are currently available
|
||||
comboBoxComPort.Items.Clear();
|
||||
comboBoxComPort.Items.AddRange(SerialPort.GetPortNames().ToArray<object>()); // use System.IO because it's static
|
||||
// select the current port if possible
|
||||
if (comboBoxComPort.Items.Contains(profileProperties.ComPort))
|
||||
{
|
||||
comboBoxComPort.SelectedItem = profileProperties.ComPort;
|
||||
}
|
||||
}
|
||||
|
||||
public ProfileProperties GetProfile()
|
||||
{
|
||||
var profileProperties = new ProfileProperties
|
||||
{
|
||||
TraceLogger = chkTrace.Checked,
|
||||
ComPort = comboBoxComPort.SelectedItem.ToString(),
|
||||
};
|
||||
|
||||
return profileProperties;
|
||||
}
|
||||
|
||||
public void SetReadOnlyMode()
|
||||
{
|
||||
foreach (Control control in Controls)
|
||||
{
|
||||
control.Enabled = false;
|
||||
}
|
||||
|
||||
cmdCancel.Enabled = true;
|
||||
//cmdOK.Enabled = false;
|
||||
//comboBoxComPort.Enabled = false;
|
||||
//chkTrace.Enabled = false;
|
||||
//txtGuideRate.Enabled = false;
|
||||
//cboPrecision.Enabled = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
+149
@@ -0,0 +1,149 @@
|
||||
namespace ASCOM.LynxAstro.DewController
|
||||
{
|
||||
partial class SetupDialogForm
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.cmdOK = new System.Windows.Forms.Button();
|
||||
this.cmdCancel = new System.Windows.Forms.Button();
|
||||
this.label1 = new System.Windows.Forms.Label();
|
||||
this.picASCOM = new System.Windows.Forms.PictureBox();
|
||||
this.label2 = new System.Windows.Forms.Label();
|
||||
this.chkTrace = new System.Windows.Forms.CheckBox();
|
||||
this.comboBoxComPort = new System.Windows.Forms.ComboBox();
|
||||
((System.ComponentModel.ISupportInitialize)(this.picASCOM)).BeginInit();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// cmdOK
|
||||
//
|
||||
this.cmdOK.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.cmdOK.DialogResult = System.Windows.Forms.DialogResult.OK;
|
||||
this.cmdOK.Location = new System.Drawing.Point(281, 112);
|
||||
this.cmdOK.Name = "cmdOK";
|
||||
this.cmdOK.Size = new System.Drawing.Size(59, 24);
|
||||
this.cmdOK.TabIndex = 0;
|
||||
this.cmdOK.Text = "OK";
|
||||
this.cmdOK.UseVisualStyleBackColor = true;
|
||||
this.cmdOK.Click += new System.EventHandler(this.cmdOK_Click);
|
||||
//
|
||||
// cmdCancel
|
||||
//
|
||||
this.cmdCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.cmdCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
|
||||
this.cmdCancel.Location = new System.Drawing.Point(281, 142);
|
||||
this.cmdCancel.Name = "cmdCancel";
|
||||
this.cmdCancel.Size = new System.Drawing.Size(59, 25);
|
||||
this.cmdCancel.TabIndex = 1;
|
||||
this.cmdCancel.Text = "Cancel";
|
||||
this.cmdCancel.UseVisualStyleBackColor = true;
|
||||
this.cmdCancel.Click += new System.EventHandler(this.cmdCancel_Click);
|
||||
//
|
||||
// label1
|
||||
//
|
||||
this.label1.Location = new System.Drawing.Point(12, 9);
|
||||
this.label1.Name = "label1";
|
||||
this.label1.Size = new System.Drawing.Size(123, 31);
|
||||
this.label1.TabIndex = 2;
|
||||
this.label1.Text = "Construct your driver\'s setup dialog here.";
|
||||
//
|
||||
// picASCOM
|
||||
//
|
||||
this.picASCOM.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.picASCOM.Cursor = System.Windows.Forms.Cursors.Hand;
|
||||
this.picASCOM.Image = global::ASCOM.LynxAstro.DewController.Properties.Resources.ASCOM;
|
||||
this.picASCOM.Location = new System.Drawing.Point(292, 9);
|
||||
this.picASCOM.Name = "picASCOM";
|
||||
this.picASCOM.Size = new System.Drawing.Size(48, 56);
|
||||
this.picASCOM.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize;
|
||||
this.picASCOM.TabIndex = 3;
|
||||
this.picASCOM.TabStop = false;
|
||||
this.picASCOM.Click += new System.EventHandler(this.BrowseToAscom);
|
||||
this.picASCOM.DoubleClick += new System.EventHandler(this.BrowseToAscom);
|
||||
//
|
||||
// label2
|
||||
//
|
||||
this.label2.AutoSize = true;
|
||||
this.label2.Location = new System.Drawing.Point(13, 90);
|
||||
this.label2.Name = "label2";
|
||||
this.label2.Size = new System.Drawing.Size(58, 13);
|
||||
this.label2.TabIndex = 5;
|
||||
this.label2.Text = "Comm Port";
|
||||
//
|
||||
// chkTrace
|
||||
//
|
||||
this.chkTrace.AutoSize = true;
|
||||
this.chkTrace.Location = new System.Drawing.Point(77, 118);
|
||||
this.chkTrace.Name = "chkTrace";
|
||||
this.chkTrace.Size = new System.Drawing.Size(69, 17);
|
||||
this.chkTrace.TabIndex = 6;
|
||||
this.chkTrace.Text = "Trace on";
|
||||
this.chkTrace.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// comboBoxComPort
|
||||
//
|
||||
this.comboBoxComPort.FormattingEnabled = true;
|
||||
this.comboBoxComPort.Location = new System.Drawing.Point(77, 87);
|
||||
this.comboBoxComPort.Name = "comboBoxComPort";
|
||||
this.comboBoxComPort.Size = new System.Drawing.Size(90, 21);
|
||||
this.comboBoxComPort.TabIndex = 7;
|
||||
//
|
||||
// SetupDialogForm
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(350, 175);
|
||||
this.Controls.Add(this.comboBoxComPort);
|
||||
this.Controls.Add(this.chkTrace);
|
||||
this.Controls.Add(this.label2);
|
||||
this.Controls.Add(this.picASCOM);
|
||||
this.Controls.Add(this.label1);
|
||||
this.Controls.Add(this.cmdCancel);
|
||||
this.Controls.Add(this.cmdOK);
|
||||
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
|
||||
this.MaximizeBox = false;
|
||||
this.MinimizeBox = false;
|
||||
this.Name = "SetupDialogForm";
|
||||
this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide;
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
|
||||
this.Text = "LynxAstro.DewController Setup";
|
||||
((System.ComponentModel.ISupportInitialize)(this.picASCOM)).EndInit();
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.Button cmdOK;
|
||||
private System.Windows.Forms.Button cmdCancel;
|
||||
private System.Windows.Forms.Label label1;
|
||||
private System.Windows.Forms.PictureBox picASCOM;
|
||||
private System.Windows.Forms.Label label2;
|
||||
private System.Windows.Forms.CheckBox chkTrace;
|
||||
private System.Windows.Forms.ComboBox comboBoxComPort;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
||||
@@ -0,0 +1,379 @@
|
||||
//
|
||||
// ================
|
||||
// Shared Resources
|
||||
// ================
|
||||
//
|
||||
// This class is a container for all shared resources that may be needed
|
||||
// by the drivers served by the Local Server.
|
||||
//
|
||||
// NOTES:
|
||||
//
|
||||
// * ALL DECLARATIONS MUST BE STATIC HERE!! INSTANCES OF THIS CLASS MUST NEVER BE CREATED!
|
||||
//
|
||||
// Written by: Bob Denny 29-May-2007
|
||||
// Modified by Chris Rowland and Peter Simpson to hamdle multiple hardware devices March 2011
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Windows.Forms;
|
||||
using ASCOM.Utilities;
|
||||
using ASCOM.Utilities.Interfaces;
|
||||
using JetBrains.Annotations;
|
||||
|
||||
namespace ASCOM.LynxAstro.DewController
|
||||
{
|
||||
/// <summary>
|
||||
/// The resources shared by all drivers and devices, in this example it's a serial port with a shared SendMessage method
|
||||
/// an idea for locking the message and handling connecting is given.
|
||||
/// In reality extensive changes will probably be needed.
|
||||
/// Multiple drivers means that several applications connect to the same hardware device, aka a hub.
|
||||
/// Multiple devices means that there are more than one instance of the hardware, such as two focusers.
|
||||
/// In this case there needs to be multiple instances of the hardware connector, each with it's own connection count.
|
||||
/// </summary>
|
||||
public static class SharedResources
|
||||
{
|
||||
// object used for locking to prevent multiple drivers accessing common code at the same time
|
||||
private static readonly object LockObject = new object();
|
||||
|
||||
// Shared serial port. This will allow multiple drivers to use one single serial port.
|
||||
private static ISerial _sSharedSerial; // Shared serial port
|
||||
|
||||
//
|
||||
// Public access to shared resources
|
||||
//
|
||||
|
||||
#region single serial port connector
|
||||
|
||||
//
|
||||
// this region shows a way that a single serial port could be connected to by multiple
|
||||
// drivers.
|
||||
//
|
||||
// Connected is used to handle the connections to the port.
|
||||
//
|
||||
// SendMessage is a way that messages could be sent to the hardware without
|
||||
// conflicts between different drivers.
|
||||
//
|
||||
// All this is for a single connection, multiple connections would need multiple ports
|
||||
// and a way to handle connecting and disconnection from them - see the
|
||||
// multi driver handling section for ideas.
|
||||
//
|
||||
|
||||
/// <summary>
|
||||
/// Shared serial port. Do not directly access this method.
|
||||
/// </summary>
|
||||
public static ISerial SharedSerial
|
||||
{
|
||||
get => _sSharedSerial ?? (_sSharedSerial = new Serial());
|
||||
set => _sSharedSerial = value;
|
||||
}
|
||||
|
||||
public static IProfileFactory ProfileFactory
|
||||
{
|
||||
get => _profileFactory ?? (_profileFactory = new ProfileFactory());
|
||||
set => _profileFactory = value;
|
||||
}
|
||||
|
||||
//todo add code to ensure that there is a minimum gap between commands. 5ms as default.
|
||||
public static void SendBlind(string message)
|
||||
{
|
||||
lock (LockObject)
|
||||
{
|
||||
SharedSerial.ClearBuffers();
|
||||
SharedSerial.Transmit(message);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Example of a shared SendMessage method, the lock
|
||||
/// prevents different drivers tripping over one another.
|
||||
/// It needs error handling and assumes that the message will be sent unchanged
|
||||
/// and that the reply will always be terminated by a "#" character.
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
/// <returns></returns>
|
||||
public static string SendString(string message)
|
||||
{
|
||||
lock (LockObject)
|
||||
{
|
||||
SharedSerial.ClearBuffers();
|
||||
SharedSerial.Transmit(message);
|
||||
return SharedSerial.ReceiveTerminated("#").TrimEnd('#');
|
||||
}
|
||||
}
|
||||
|
||||
public static string SendChar(string message)
|
||||
{
|
||||
lock (LockObject)
|
||||
{
|
||||
SharedSerial.ClearBuffers();
|
||||
SharedSerial.Transmit(message);
|
||||
return SharedSerial.ReceiveCounted(1);
|
||||
}
|
||||
}
|
||||
|
||||
public static string ReadTerminated()
|
||||
{
|
||||
lock (LockObject)
|
||||
{
|
||||
return SharedSerial.ReceiveTerminated("#");
|
||||
}
|
||||
}
|
||||
|
||||
public static void ReadCharacters(int throwAwayCharacters)
|
||||
{
|
||||
lock (LockObject)
|
||||
{
|
||||
SharedSerial.ReceiveCounted(throwAwayCharacters);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Profile
|
||||
|
||||
private const string DriverId = "ASCOM.MeadeGeneric.Telescope";
|
||||
|
||||
// Constants used for Profile persistence
|
||||
private const string ComPortProfileName = "COM Port";
|
||||
private const string TraceStateProfileName = "Trace Level";
|
||||
private const string SwitchNameProfileName = "SwitchName_{0}";
|
||||
|
||||
public static void WriteProfile(ProfileProperties profileProperties)
|
||||
{
|
||||
lock (LockObject)
|
||||
{
|
||||
using (IProfileWrapper driverProfile = ProfileFactory.Create())
|
||||
{
|
||||
driverProfile.DeviceType = "Telescope";
|
||||
driverProfile.WriteValue(DriverId, TraceStateProfileName, profileProperties.TraceLogger.ToString());
|
||||
driverProfile.WriteValue(DriverId, ComPortProfileName, profileProperties.ComPort);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private const string ComPortDefault = "COM1";
|
||||
private const string TraceStateDefault = "false";
|
||||
|
||||
private const string noSwitchValue = "no_switch_value";
|
||||
|
||||
public static ProfileProperties ReadProfile()
|
||||
{
|
||||
lock (LockObject)
|
||||
{
|
||||
ProfileProperties profileProperties = new ProfileProperties();
|
||||
using (IProfileWrapper driverProfile = ProfileFactory.Create())
|
||||
{
|
||||
driverProfile.DeviceType = "Telescope";
|
||||
profileProperties.ComPort = driverProfile.GetValue(DriverId, ComPortProfileName, string.Empty, ComPortDefault);
|
||||
profileProperties.TraceLogger = Convert.ToBoolean(driverProfile.GetValue(DriverId, TraceStateProfileName, string.Empty, TraceStateDefault));
|
||||
|
||||
var switchNo = 0;
|
||||
var finished = false;
|
||||
profileProperties.SwitchNames.Clear();
|
||||
do
|
||||
{
|
||||
var switchName = string.Format(SwitchNameProfileName, switchNo);
|
||||
var switchValue = driverProfile.GetValue(DriverId, switchName, string.Empty, noSwitchValue);
|
||||
|
||||
finished = switchValue == noSwitchValue;
|
||||
|
||||
if (!finished)
|
||||
profileProperties.SwitchNames.Add(switchValue);
|
||||
|
||||
} while (!finished);
|
||||
|
||||
}
|
||||
|
||||
return profileProperties;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region SetupDialog
|
||||
|
||||
public static void SetupDialog()
|
||||
{
|
||||
var profileProperties = ReadProfile();
|
||||
|
||||
using (SetupDialogForm f = new SetupDialogForm())
|
||||
{
|
||||
f.SetProfile(profileProperties);
|
||||
|
||||
if (IsConnected())
|
||||
{
|
||||
f.SetReadOnlyMode();
|
||||
}
|
||||
|
||||
var result = f.ShowDialog();
|
||||
if (result == DialogResult.OK)
|
||||
{
|
||||
profileProperties = f.GetProfile();
|
||||
|
||||
WriteProfile(profileProperties); // Persist device configuration values to the ASCOM Profile store
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Multi Driver handling
|
||||
|
||||
public static string FirmwareVersion { get; private set; } = string.Empty;
|
||||
|
||||
// this section illustrates how multiple drivers could be handled,
|
||||
// it's for drivers where multiple connections to the hardware can be made and ensures that the
|
||||
// hardware is only disconnected from when all the connected devices have disconnected.
|
||||
|
||||
// It is NOT a complete solution! This is to give ideas of what can - or should be done.
|
||||
//
|
||||
// An alternative would be to move the hardware control here, handle connecting and disconnecting,
|
||||
// and provide the device with a suitable connection to the hardware.
|
||||
//
|
||||
/// <summary>
|
||||
/// dictionary carrying device connections.
|
||||
/// The Key is the connection number that identifies the device, it could be the COM port name,
|
||||
/// USB ID or IP Address, the Value is the DeviceHardware class
|
||||
/// </summary>
|
||||
private static readonly Dictionary<string, DeviceHardware> ConnectedDevices = new Dictionary<string, DeviceHardware>();
|
||||
|
||||
private static readonly Dictionary<string, DeviceHardware> ConnectedDeviceIds = new Dictionary<string, DeviceHardware>();
|
||||
private static IProfileFactory _profileFactory;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// This is called in the driver Connect(true) property,
|
||||
/// it add the device id to the list of devices if it's not there and increments the device count.
|
||||
/// </summary>
|
||||
/// <param name="deviceId"></param>
|
||||
/// <param name="driverId"></param>
|
||||
/// <param name="traceLogger"></param>
|
||||
public static ConnectionInfo Connect(string deviceId, string driverId, ITraceLogger traceLogger)
|
||||
{
|
||||
lock (LockObject)
|
||||
{
|
||||
if (!ConnectedDevices.ContainsKey(deviceId))
|
||||
ConnectedDevices.Add(deviceId, new DeviceHardware());
|
||||
|
||||
if (!ConnectedDeviceIds.ContainsKey(driverId))
|
||||
ConnectedDeviceIds.Add(driverId, new DeviceHardware());
|
||||
|
||||
if (deviceId == "Serial")
|
||||
{
|
||||
if (ConnectedDevices[deviceId].Count == 0)
|
||||
{
|
||||
var profileProperties = ReadProfile();
|
||||
SharedSerial.PortName = profileProperties.ComPort;
|
||||
//SharedSerial.DTREnable = profileProperties.RtsDtrEnabled;
|
||||
//SharedSerial.RTSEnable = profileProperties.RtsDtrEnabled;
|
||||
SharedSerial.DataBits = 8;
|
||||
SharedSerial.StopBits = SerialStopBits.One;
|
||||
SharedSerial.Parity = SerialParity.None;
|
||||
SharedSerial.Speed = SerialSpeed.ps9600;
|
||||
SharedSerial.Handshake = SerialHandshake.None;
|
||||
SharedSerial.Connected = true;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var encodedString = SendString(":GV#");
|
||||
FirmwareVersion = DecodeResult(":GV", encodedString );
|
||||
//Command: :GV#
|
||||
//Purpose: Get the devices firmware version.
|
||||
//Response: :GVXXXXXXXX# where X is a version string, e.g. 1.0.
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
traceLogger.LogIssue("Connect", $"Error getting telescope information \"{ex.Message}\" setting to LX200 Classic mode.");
|
||||
FirmwareVersion = "Unknown";
|
||||
}
|
||||
}
|
||||
else
|
||||
throw new ArgumentException($"deviceId {deviceId} not currently supported");
|
||||
|
||||
ConnectedDevices[deviceId].Count++; // increment the value
|
||||
ConnectedDeviceIds[driverId].Count++; // increment the value
|
||||
|
||||
return new ConnectionInfo
|
||||
{
|
||||
//Connections = ConnectedDevices[deviceId].Count,
|
||||
SameDevice = ConnectedDeviceIds[driverId].Count
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
private static string DecodeResult(string pattern, string encodedString)
|
||||
{
|
||||
var decodedString = encodedString.Substring( pattern.Length ).TrimEnd('#');
|
||||
return decodedString;
|
||||
}
|
||||
|
||||
public static void Disconnect(string deviceId, string driverId)
|
||||
{
|
||||
lock (LockObject)
|
||||
{
|
||||
if (ConnectedDevices.ContainsKey(deviceId))
|
||||
{
|
||||
ConnectedDevices[deviceId].Count--;
|
||||
if (ConnectedDevices[deviceId].Count <= 0)
|
||||
{
|
||||
ConnectedDevices.Remove(deviceId);
|
||||
if (deviceId == "Serial")
|
||||
{
|
||||
SharedSerial.Connected = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ConnectedDeviceIds.ContainsKey(driverId))
|
||||
{
|
||||
ConnectedDeviceIds[driverId].Count--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static bool IsConnected()
|
||||
{
|
||||
foreach (var device in ConnectedDevices)
|
||||
{
|
||||
if (device.Value.Count > 0)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public static void Lock(Action action)
|
||||
{
|
||||
lock (LockObject)
|
||||
{
|
||||
action();
|
||||
}
|
||||
}
|
||||
|
||||
public static T Lock<T>(Func<T> func)
|
||||
{
|
||||
lock (LockObject)
|
||||
{
|
||||
return func();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Skeleton of a hardware class, all this does is hold a count of the connections,
|
||||
/// in reality extra code will be needed to handle the hardware in some way
|
||||
/// </summary>
|
||||
private class DeviceHardware
|
||||
{
|
||||
internal int Count { set; get; }
|
||||
|
||||
internal DeviceHardware()
|
||||
{
|
||||
Count = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
using System;
|
||||
using ASCOM.Utilities.Interfaces;
|
||||
|
||||
namespace ASCOM.LynxAstro.DewController
|
||||
{
|
||||
public class SharedResourcesWrapper : ISharedResourcesWrapper
|
||||
{
|
||||
public ConnectionInfo Connect(string deviceId, string driverId, ITraceLogger traceLogger)
|
||||
{
|
||||
return SharedResources.Connect(deviceId, driverId, traceLogger);
|
||||
}
|
||||
|
||||
public void Disconnect(string deviceId, string driverId)
|
||||
{
|
||||
SharedResources.Disconnect(deviceId, driverId);
|
||||
}
|
||||
|
||||
public string FirmwareVersion => SharedResources.FirmwareVersion;
|
||||
|
||||
public void Lock(Action action)
|
||||
{
|
||||
SharedResources.Lock(action);
|
||||
}
|
||||
|
||||
public T Lock<T>(Func<T> func)
|
||||
{
|
||||
return SharedResources.Lock(func);
|
||||
}
|
||||
|
||||
public string SendString(string message)
|
||||
{
|
||||
return SharedResources.SendString(message);
|
||||
}
|
||||
|
||||
public void SendBlind(string message)
|
||||
{
|
||||
SharedResources.SendBlind(message);
|
||||
}
|
||||
|
||||
public string SendChar(string message)
|
||||
{
|
||||
return SharedResources.SendChar(message);
|
||||
}
|
||||
|
||||
public string ReadTerminated()
|
||||
{
|
||||
return SharedResources.ReadTerminated();
|
||||
}
|
||||
|
||||
public void ReadCharacters(int throwAwayCharacters)
|
||||
{
|
||||
SharedResources.ReadCharacters(throwAwayCharacters);
|
||||
}
|
||||
|
||||
public ProfileProperties ReadProfile()
|
||||
{
|
||||
return SharedResources.ReadProfile();
|
||||
}
|
||||
|
||||
public void SetupDialog()
|
||||
{
|
||||
SharedResources.SetupDialog();
|
||||
}
|
||||
|
||||
public void WriteProfile(ProfileProperties profileProperties)
|
||||
{
|
||||
SharedResources.WriteProfile(profileProperties);
|
||||
}
|
||||
}
|
||||
}
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
using System;
|
||||
|
||||
namespace ASCOM.LynxAstro.DewController
|
||||
{
|
||||
partial class frmMain
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.label1 = new System.Windows.Forms.Label();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// label1
|
||||
//
|
||||
this.label1.Location = new System.Drawing.Point(12, 10);
|
||||
this.label1.Name = "label1";
|
||||
this.label1.Size = new System.Drawing.Size(199, 33);
|
||||
this.label1.TabIndex = 0;
|
||||
this.label1.Text = "This is an ASCOM driver, not a program for you to use.";
|
||||
//
|
||||
// frmMain
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(233, 52);
|
||||
this.Controls.Add(this.label1);
|
||||
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow;
|
||||
this.Name = "frmMain";
|
||||
this.Text = "LynxAstro.DewController Driver Server";
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.Label label1;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace ASCOM.LynxAstro.DewController
|
||||
{
|
||||
public partial class frmMain : Form
|
||||
{
|
||||
delegate void SetTextCallback(string text);
|
||||
|
||||
public frmMain()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
||||
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="ASCOM.Platform" version="6.5.2" targetFramework="net472" />
|
||||
<package id="JetBrains.Annotations" version="2020.3.0" targetFramework="net472" />
|
||||
</packages>
|
||||
Reference in New Issue
Block a user