diff --git a/ASCOM.DSLR.TestAppForm/ASCOM.DSLR.TestAppForm.csproj b/ASCOM.DSLR.TestAppForm/ASCOM.DSLR.TestAppForm.csproj
index e839aaf..e398bad 100644
--- a/ASCOM.DSLR.TestAppForm/ASCOM.DSLR.TestAppForm.csproj
+++ b/ASCOM.DSLR.TestAppForm/ASCOM.DSLR.TestAppForm.csproj
@@ -27,6 +27,7 @@
prompt
4
false
+ true
x86
@@ -40,17 +41,30 @@
AnyCPU
- bin\Debug\
+ ..\bin\
false
+ true
AnyCPU
bin\Release\
false
+
+ ASCOM.DSLR.Program
+
+
+
+ app.manifest
+
+
+ ASCOM.ico
+
+
+
@@ -87,6 +101,7 @@
Designer
+
SettingsSingleFileGenerator
@@ -104,13 +119,18 @@
ASCOM.DSLR
+
+
+
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}.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ASCOM.DSLR.TestAppForm/packages.config b/ASCOM.DSLR.TestAppForm/packages.config
index 076a52e..8db3468 100644
--- a/ASCOM.DSLR.TestAppForm/packages.config
+++ b/ASCOM.DSLR.TestAppForm/packages.config
@@ -1,4 +1,5 @@
+
\ No newline at end of file
diff --git a/ASCOM.DSLR.sln b/ASCOM.DSLR.sln
index 01ab652..3d60d03 100644
--- a/ASCOM.DSLR.sln
+++ b/ASCOM.DSLR.sln
@@ -1,95 +1,267 @@
Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio 15
-VisualStudioVersion = 15.0.27130.2010
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.30204.135
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ASCOM.DSLR", "ASCOM.DSLR\ASCOM.DSLR.csproj", "{64308775-BD4A-469C-BCAB-3ED830B811AF}"
+ ProjectSection(ProjectDependencies) = postProject
+ {7EB5D33D-E000-4766-9119-EDA40D04AF74} = {7EB5D33D-E000-4766-9119-EDA40D04AF74}
+ EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ASCOM.DSLR.TestAppForm", "ASCOM.DSLR.TestAppForm\ASCOM.DSLR.TestAppForm.csproj", "{8E8D406C-1838-4914-867D-AB602D0EAF3E}"
+ ProjectSection(ProjectDependencies) = postProject
+ {7EB5D33D-E000-4766-9119-EDA40D04AF74} = {7EB5D33D-E000-4766-9119-EDA40D04AF74}
+ EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EDSDKLib", "EDSDKLib\EDSDKLib.csproj", "{15E99248-6161-46A4-9183-609CA62406A6}"
+ ProjectSection(ProjectDependencies) = postProject
+ {7EB5D33D-E000-4766-9119-EDA40D04AF74} = {7EB5D33D-E000-4766-9119-EDA40D04AF74}
+ EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OTelescope.API", "OTelescope.API\OTelescope.API.csproj", "{B7E42253-59AB-4CE0-B1E7-43FC61F4CD07}"
+ ProjectSection(ProjectDependencies) = postProject
+ {7EB5D33D-E000-4766-9119-EDA40D04AF74} = {7EB5D33D-E000-4766-9119-EDA40D04AF74}
+ EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Registrar", "Registrar\Registrar.csproj", "{2F2993A5-1A52-4BFE-8A09-86B7BB97820C}"
ProjectSection(ProjectDependencies) = postProject
{64308775-BD4A-469C-BCAB-3ED830B811AF} = {64308775-BD4A-469C-BCAB-3ED830B811AF}
EndProjectSection
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CameraControl.Devices", "DigiCamControl\CameraControl.Devices\CameraControl.Devices.csproj", "{E8572D8B-C987-4D20-BD88-1F8925A64A82}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Canon.Eos.Framework", "DigiCamControl\Canon.Eos.Framework\Canon.Eos.Framework.csproj", "{F809DBB6-E0E8-47A8-92ED-C24575576A5D}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PortableDeviceLib", "DigiCamControl\PortableDeviceLib\PortableDeviceLib.csproj", "{E9F048C1-C6A0-4CCD-BE57-4E76A7F8B32D}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "DigiCamControl", "DigiCamControl", "{4FC379CE-DD0C-4628-9639-E232474A1F70}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Logging", "ErrorLogging\Logging.csproj", "{7EB5D33D-E000-4766-9119-EDA40D04AF74}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "nikoncswrapper", "nikoncswrapper\nikoncswrapper.csproj", "{AADE1DF5-4C46-4760-B72B-474D90336F5B}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ClearDSLRSCProfile", "ClearDSLRProfile\ClearDSLRSCProfile.csproj", "{8C96928D-E6B9-46E4-BA5B-BB0BBA4A7C60}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Capture.Workflow|Any CPU = Capture.Workflow|Any CPU
+ Capture.Workflow|x64 = Capture.Workflow|x64
Capture.Workflow|x86 = Capture.Workflow|x86
Debug|Any CPU = Debug|Any CPU
+ Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
+ Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{64308775-BD4A-469C-BCAB-3ED830B811AF}.Capture.Workflow|Any CPU.ActiveCfg = Release|Any CPU
{64308775-BD4A-469C-BCAB-3ED830B811AF}.Capture.Workflow|Any CPU.Build.0 = Release|Any CPU
+ {64308775-BD4A-469C-BCAB-3ED830B811AF}.Capture.Workflow|x64.ActiveCfg = Debug|Any CPU
+ {64308775-BD4A-469C-BCAB-3ED830B811AF}.Capture.Workflow|x64.Build.0 = Debug|Any CPU
{64308775-BD4A-469C-BCAB-3ED830B811AF}.Capture.Workflow|x86.ActiveCfg = Release|x86
{64308775-BD4A-469C-BCAB-3ED830B811AF}.Capture.Workflow|x86.Build.0 = Release|x86
{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|x64.ActiveCfg = Debug|Any CPU
+ {64308775-BD4A-469C-BCAB-3ED830B811AF}.Debug|x64.Build.0 = Debug|Any CPU
{64308775-BD4A-469C-BCAB-3ED830B811AF}.Debug|x86.ActiveCfg = Debug|x86
{64308775-BD4A-469C-BCAB-3ED830B811AF}.Debug|x86.Build.0 = Debug|x86
{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|x64.ActiveCfg = Release|Any CPU
+ {64308775-BD4A-469C-BCAB-3ED830B811AF}.Release|x64.Build.0 = Release|Any CPU
{64308775-BD4A-469C-BCAB-3ED830B811AF}.Release|x86.ActiveCfg = Release|x86
{64308775-BD4A-469C-BCAB-3ED830B811AF}.Release|x86.Build.0 = Release|x86
{8E8D406C-1838-4914-867D-AB602D0EAF3E}.Capture.Workflow|Any CPU.ActiveCfg = Release|Any CPU
{8E8D406C-1838-4914-867D-AB602D0EAF3E}.Capture.Workflow|Any CPU.Build.0 = Release|Any CPU
+ {8E8D406C-1838-4914-867D-AB602D0EAF3E}.Capture.Workflow|x64.ActiveCfg = Debug|Any CPU
+ {8E8D406C-1838-4914-867D-AB602D0EAF3E}.Capture.Workflow|x64.Build.0 = Debug|Any CPU
{8E8D406C-1838-4914-867D-AB602D0EAF3E}.Capture.Workflow|x86.ActiveCfg = Release|x86
{8E8D406C-1838-4914-867D-AB602D0EAF3E}.Capture.Workflow|x86.Build.0 = Release|x86
{8E8D406C-1838-4914-867D-AB602D0EAF3E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8E8D406C-1838-4914-867D-AB602D0EAF3E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {8E8D406C-1838-4914-867D-AB602D0EAF3E}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {8E8D406C-1838-4914-867D-AB602D0EAF3E}.Debug|x64.Build.0 = Debug|Any CPU
{8E8D406C-1838-4914-867D-AB602D0EAF3E}.Debug|x86.ActiveCfg = Debug|x86
{8E8D406C-1838-4914-867D-AB602D0EAF3E}.Debug|x86.Build.0 = Debug|x86
{8E8D406C-1838-4914-867D-AB602D0EAF3E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8E8D406C-1838-4914-867D-AB602D0EAF3E}.Release|Any CPU.Build.0 = Release|Any CPU
+ {8E8D406C-1838-4914-867D-AB602D0EAF3E}.Release|x64.ActiveCfg = Release|Any CPU
+ {8E8D406C-1838-4914-867D-AB602D0EAF3E}.Release|x64.Build.0 = Release|Any CPU
{8E8D406C-1838-4914-867D-AB602D0EAF3E}.Release|x86.ActiveCfg = Release|x86
{8E8D406C-1838-4914-867D-AB602D0EAF3E}.Release|x86.Build.0 = Release|x86
{15E99248-6161-46A4-9183-609CA62406A6}.Capture.Workflow|Any CPU.ActiveCfg = Release|Any CPU
{15E99248-6161-46A4-9183-609CA62406A6}.Capture.Workflow|Any CPU.Build.0 = Release|Any CPU
+ {15E99248-6161-46A4-9183-609CA62406A6}.Capture.Workflow|x64.ActiveCfg = Debug|Any CPU
+ {15E99248-6161-46A4-9183-609CA62406A6}.Capture.Workflow|x64.Build.0 = Debug|Any CPU
{15E99248-6161-46A4-9183-609CA62406A6}.Capture.Workflow|x86.ActiveCfg = Release|x86
{15E99248-6161-46A4-9183-609CA62406A6}.Capture.Workflow|x86.Build.0 = Release|x86
{15E99248-6161-46A4-9183-609CA62406A6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{15E99248-6161-46A4-9183-609CA62406A6}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {15E99248-6161-46A4-9183-609CA62406A6}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {15E99248-6161-46A4-9183-609CA62406A6}.Debug|x64.Build.0 = Debug|Any CPU
{15E99248-6161-46A4-9183-609CA62406A6}.Debug|x86.ActiveCfg = Debug|x86
{15E99248-6161-46A4-9183-609CA62406A6}.Debug|x86.Build.0 = Debug|x86
{15E99248-6161-46A4-9183-609CA62406A6}.Release|Any CPU.ActiveCfg = Release|Any CPU
{15E99248-6161-46A4-9183-609CA62406A6}.Release|Any CPU.Build.0 = Release|Any CPU
+ {15E99248-6161-46A4-9183-609CA62406A6}.Release|x64.ActiveCfg = Release|Any CPU
+ {15E99248-6161-46A4-9183-609CA62406A6}.Release|x64.Build.0 = Release|Any CPU
{15E99248-6161-46A4-9183-609CA62406A6}.Release|x86.ActiveCfg = Release|x86
{15E99248-6161-46A4-9183-609CA62406A6}.Release|x86.Build.0 = Release|x86
{B7E42253-59AB-4CE0-B1E7-43FC61F4CD07}.Capture.Workflow|Any CPU.ActiveCfg = Release|Any CPU
{B7E42253-59AB-4CE0-B1E7-43FC61F4CD07}.Capture.Workflow|Any CPU.Build.0 = Release|Any CPU
+ {B7E42253-59AB-4CE0-B1E7-43FC61F4CD07}.Capture.Workflow|x64.ActiveCfg = Debug|Any CPU
+ {B7E42253-59AB-4CE0-B1E7-43FC61F4CD07}.Capture.Workflow|x64.Build.0 = Debug|Any CPU
{B7E42253-59AB-4CE0-B1E7-43FC61F4CD07}.Capture.Workflow|x86.ActiveCfg = Release|x86
{B7E42253-59AB-4CE0-B1E7-43FC61F4CD07}.Capture.Workflow|x86.Build.0 = Release|x86
{B7E42253-59AB-4CE0-B1E7-43FC61F4CD07}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B7E42253-59AB-4CE0-B1E7-43FC61F4CD07}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B7E42253-59AB-4CE0-B1E7-43FC61F4CD07}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {B7E42253-59AB-4CE0-B1E7-43FC61F4CD07}.Debug|x64.Build.0 = Debug|Any CPU
{B7E42253-59AB-4CE0-B1E7-43FC61F4CD07}.Debug|x86.ActiveCfg = Debug|x86
{B7E42253-59AB-4CE0-B1E7-43FC61F4CD07}.Debug|x86.Build.0 = Debug|x86
{B7E42253-59AB-4CE0-B1E7-43FC61F4CD07}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B7E42253-59AB-4CE0-B1E7-43FC61F4CD07}.Release|Any CPU.Build.0 = Release|Any CPU
+ {B7E42253-59AB-4CE0-B1E7-43FC61F4CD07}.Release|x64.ActiveCfg = Release|Any CPU
+ {B7E42253-59AB-4CE0-B1E7-43FC61F4CD07}.Release|x64.Build.0 = Release|Any CPU
{B7E42253-59AB-4CE0-B1E7-43FC61F4CD07}.Release|x86.ActiveCfg = Release|x86
{B7E42253-59AB-4CE0-B1E7-43FC61F4CD07}.Release|x86.Build.0 = Release|x86
{2F2993A5-1A52-4BFE-8A09-86B7BB97820C}.Capture.Workflow|Any CPU.ActiveCfg = Debug|Any CPU
{2F2993A5-1A52-4BFE-8A09-86B7BB97820C}.Capture.Workflow|Any CPU.Build.0 = Debug|Any CPU
+ {2F2993A5-1A52-4BFE-8A09-86B7BB97820C}.Capture.Workflow|x64.ActiveCfg = Release|Any CPU
+ {2F2993A5-1A52-4BFE-8A09-86B7BB97820C}.Capture.Workflow|x64.Build.0 = Release|Any CPU
{2F2993A5-1A52-4BFE-8A09-86B7BB97820C}.Capture.Workflow|x86.ActiveCfg = Release|Any CPU
{2F2993A5-1A52-4BFE-8A09-86B7BB97820C}.Capture.Workflow|x86.Build.0 = Release|Any CPU
{2F2993A5-1A52-4BFE-8A09-86B7BB97820C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2F2993A5-1A52-4BFE-8A09-86B7BB97820C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {2F2993A5-1A52-4BFE-8A09-86B7BB97820C}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {2F2993A5-1A52-4BFE-8A09-86B7BB97820C}.Debug|x64.Build.0 = Debug|Any CPU
{2F2993A5-1A52-4BFE-8A09-86B7BB97820C}.Debug|x86.ActiveCfg = Debug|Any CPU
{2F2993A5-1A52-4BFE-8A09-86B7BB97820C}.Debug|x86.Build.0 = Debug|Any CPU
{2F2993A5-1A52-4BFE-8A09-86B7BB97820C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2F2993A5-1A52-4BFE-8A09-86B7BB97820C}.Release|Any CPU.Build.0 = Release|Any CPU
+ {2F2993A5-1A52-4BFE-8A09-86B7BB97820C}.Release|x64.ActiveCfg = Release|Any CPU
+ {2F2993A5-1A52-4BFE-8A09-86B7BB97820C}.Release|x64.Build.0 = Release|Any CPU
{2F2993A5-1A52-4BFE-8A09-86B7BB97820C}.Release|x86.ActiveCfg = Release|Any CPU
{2F2993A5-1A52-4BFE-8A09-86B7BB97820C}.Release|x86.Build.0 = Release|Any CPU
+ {E8572D8B-C987-4D20-BD88-1F8925A64A82}.Capture.Workflow|Any CPU.ActiveCfg = Capture.Workflow|Any CPU
+ {E8572D8B-C987-4D20-BD88-1F8925A64A82}.Capture.Workflow|Any CPU.Build.0 = Capture.Workflow|Any CPU
+ {E8572D8B-C987-4D20-BD88-1F8925A64A82}.Capture.Workflow|x64.ActiveCfg = Capture.Workflow|x64
+ {E8572D8B-C987-4D20-BD88-1F8925A64A82}.Capture.Workflow|x64.Build.0 = Capture.Workflow|x64
+ {E8572D8B-C987-4D20-BD88-1F8925A64A82}.Capture.Workflow|x86.ActiveCfg = Capture.Workflow|x86
+ {E8572D8B-C987-4D20-BD88-1F8925A64A82}.Capture.Workflow|x86.Build.0 = Capture.Workflow|x86
+ {E8572D8B-C987-4D20-BD88-1F8925A64A82}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {E8572D8B-C987-4D20-BD88-1F8925A64A82}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {E8572D8B-C987-4D20-BD88-1F8925A64A82}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {E8572D8B-C987-4D20-BD88-1F8925A64A82}.Debug|x64.Build.0 = Debug|Any CPU
+ {E8572D8B-C987-4D20-BD88-1F8925A64A82}.Debug|x86.ActiveCfg = Debug|x86
+ {E8572D8B-C987-4D20-BD88-1F8925A64A82}.Debug|x86.Build.0 = Debug|x86
+ {E8572D8B-C987-4D20-BD88-1F8925A64A82}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {E8572D8B-C987-4D20-BD88-1F8925A64A82}.Release|Any CPU.Build.0 = Release|Any CPU
+ {E8572D8B-C987-4D20-BD88-1F8925A64A82}.Release|x64.ActiveCfg = Release|x64
+ {E8572D8B-C987-4D20-BD88-1F8925A64A82}.Release|x64.Build.0 = Release|x64
+ {E8572D8B-C987-4D20-BD88-1F8925A64A82}.Release|x86.ActiveCfg = Release|x86
+ {E8572D8B-C987-4D20-BD88-1F8925A64A82}.Release|x86.Build.0 = Release|x86
+ {F809DBB6-E0E8-47A8-92ED-C24575576A5D}.Capture.Workflow|Any CPU.ActiveCfg = Capture.Workflow|Any CPU
+ {F809DBB6-E0E8-47A8-92ED-C24575576A5D}.Capture.Workflow|Any CPU.Build.0 = Capture.Workflow|Any CPU
+ {F809DBB6-E0E8-47A8-92ED-C24575576A5D}.Capture.Workflow|x64.ActiveCfg = Capture.Workflow|x64
+ {F809DBB6-E0E8-47A8-92ED-C24575576A5D}.Capture.Workflow|x64.Build.0 = Capture.Workflow|x64
+ {F809DBB6-E0E8-47A8-92ED-C24575576A5D}.Capture.Workflow|x86.ActiveCfg = Capture.Workflow|x86
+ {F809DBB6-E0E8-47A8-92ED-C24575576A5D}.Capture.Workflow|x86.Build.0 = Capture.Workflow|x86
+ {F809DBB6-E0E8-47A8-92ED-C24575576A5D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {F809DBB6-E0E8-47A8-92ED-C24575576A5D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {F809DBB6-E0E8-47A8-92ED-C24575576A5D}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {F809DBB6-E0E8-47A8-92ED-C24575576A5D}.Debug|x64.Build.0 = Debug|Any CPU
+ {F809DBB6-E0E8-47A8-92ED-C24575576A5D}.Debug|x86.ActiveCfg = Debug|x86
+ {F809DBB6-E0E8-47A8-92ED-C24575576A5D}.Debug|x86.Build.0 = Debug|x86
+ {F809DBB6-E0E8-47A8-92ED-C24575576A5D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {F809DBB6-E0E8-47A8-92ED-C24575576A5D}.Release|Any CPU.Build.0 = Release|Any CPU
+ {F809DBB6-E0E8-47A8-92ED-C24575576A5D}.Release|x64.ActiveCfg = Release|x64
+ {F809DBB6-E0E8-47A8-92ED-C24575576A5D}.Release|x64.Build.0 = Release|x64
+ {F809DBB6-E0E8-47A8-92ED-C24575576A5D}.Release|x86.ActiveCfg = Release|x86
+ {F809DBB6-E0E8-47A8-92ED-C24575576A5D}.Release|x86.Build.0 = Release|x86
+ {E9F048C1-C6A0-4CCD-BE57-4E76A7F8B32D}.Capture.Workflow|Any CPU.ActiveCfg = Capture.Workflow|Any CPU
+ {E9F048C1-C6A0-4CCD-BE57-4E76A7F8B32D}.Capture.Workflow|Any CPU.Build.0 = Capture.Workflow|Any CPU
+ {E9F048C1-C6A0-4CCD-BE57-4E76A7F8B32D}.Capture.Workflow|x64.ActiveCfg = Capture.Workflow|x64
+ {E9F048C1-C6A0-4CCD-BE57-4E76A7F8B32D}.Capture.Workflow|x64.Build.0 = Capture.Workflow|x64
+ {E9F048C1-C6A0-4CCD-BE57-4E76A7F8B32D}.Capture.Workflow|x86.ActiveCfg = Capture.Workflow|x86
+ {E9F048C1-C6A0-4CCD-BE57-4E76A7F8B32D}.Capture.Workflow|x86.Build.0 = Capture.Workflow|x86
+ {E9F048C1-C6A0-4CCD-BE57-4E76A7F8B32D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {E9F048C1-C6A0-4CCD-BE57-4E76A7F8B32D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {E9F048C1-C6A0-4CCD-BE57-4E76A7F8B32D}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {E9F048C1-C6A0-4CCD-BE57-4E76A7F8B32D}.Debug|x64.Build.0 = Debug|Any CPU
+ {E9F048C1-C6A0-4CCD-BE57-4E76A7F8B32D}.Debug|x86.ActiveCfg = Debug|x86
+ {E9F048C1-C6A0-4CCD-BE57-4E76A7F8B32D}.Debug|x86.Build.0 = Debug|x86
+ {E9F048C1-C6A0-4CCD-BE57-4E76A7F8B32D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {E9F048C1-C6A0-4CCD-BE57-4E76A7F8B32D}.Release|Any CPU.Build.0 = Release|Any CPU
+ {E9F048C1-C6A0-4CCD-BE57-4E76A7F8B32D}.Release|x64.ActiveCfg = Release|x64
+ {E9F048C1-C6A0-4CCD-BE57-4E76A7F8B32D}.Release|x64.Build.0 = Release|x64
+ {E9F048C1-C6A0-4CCD-BE57-4E76A7F8B32D}.Release|x86.ActiveCfg = Release|x86
+ {E9F048C1-C6A0-4CCD-BE57-4E76A7F8B32D}.Release|x86.Build.0 = Release|x86
+ {7EB5D33D-E000-4766-9119-EDA40D04AF74}.Capture.Workflow|Any CPU.ActiveCfg = Release|Any CPU
+ {7EB5D33D-E000-4766-9119-EDA40D04AF74}.Capture.Workflow|Any CPU.Build.0 = Release|Any CPU
+ {7EB5D33D-E000-4766-9119-EDA40D04AF74}.Capture.Workflow|x64.ActiveCfg = Release|Any CPU
+ {7EB5D33D-E000-4766-9119-EDA40D04AF74}.Capture.Workflow|x64.Build.0 = Release|Any CPU
+ {7EB5D33D-E000-4766-9119-EDA40D04AF74}.Capture.Workflow|x86.ActiveCfg = Release|Any CPU
+ {7EB5D33D-E000-4766-9119-EDA40D04AF74}.Capture.Workflow|x86.Build.0 = Release|Any CPU
+ {7EB5D33D-E000-4766-9119-EDA40D04AF74}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {7EB5D33D-E000-4766-9119-EDA40D04AF74}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {7EB5D33D-E000-4766-9119-EDA40D04AF74}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {7EB5D33D-E000-4766-9119-EDA40D04AF74}.Debug|x64.Build.0 = Debug|Any CPU
+ {7EB5D33D-E000-4766-9119-EDA40D04AF74}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {7EB5D33D-E000-4766-9119-EDA40D04AF74}.Debug|x86.Build.0 = Debug|Any CPU
+ {7EB5D33D-E000-4766-9119-EDA40D04AF74}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {7EB5D33D-E000-4766-9119-EDA40D04AF74}.Release|Any CPU.Build.0 = Release|Any CPU
+ {7EB5D33D-E000-4766-9119-EDA40D04AF74}.Release|x64.ActiveCfg = Release|Any CPU
+ {7EB5D33D-E000-4766-9119-EDA40D04AF74}.Release|x64.Build.0 = Release|Any CPU
+ {7EB5D33D-E000-4766-9119-EDA40D04AF74}.Release|x86.ActiveCfg = Release|Any CPU
+ {7EB5D33D-E000-4766-9119-EDA40D04AF74}.Release|x86.Build.0 = Release|Any CPU
+ {AADE1DF5-4C46-4760-B72B-474D90336F5B}.Capture.Workflow|Any CPU.ActiveCfg = Release|Any CPU
+ {AADE1DF5-4C46-4760-B72B-474D90336F5B}.Capture.Workflow|Any CPU.Build.0 = Release|Any CPU
+ {AADE1DF5-4C46-4760-B72B-474D90336F5B}.Capture.Workflow|x64.ActiveCfg = Release|Any CPU
+ {AADE1DF5-4C46-4760-B72B-474D90336F5B}.Capture.Workflow|x64.Build.0 = Release|Any CPU
+ {AADE1DF5-4C46-4760-B72B-474D90336F5B}.Capture.Workflow|x86.ActiveCfg = Release|Any CPU
+ {AADE1DF5-4C46-4760-B72B-474D90336F5B}.Capture.Workflow|x86.Build.0 = Release|Any CPU
+ {AADE1DF5-4C46-4760-B72B-474D90336F5B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {AADE1DF5-4C46-4760-B72B-474D90336F5B}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {AADE1DF5-4C46-4760-B72B-474D90336F5B}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {AADE1DF5-4C46-4760-B72B-474D90336F5B}.Debug|x64.Build.0 = Debug|Any CPU
+ {AADE1DF5-4C46-4760-B72B-474D90336F5B}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {AADE1DF5-4C46-4760-B72B-474D90336F5B}.Debug|x86.Build.0 = Debug|Any CPU
+ {AADE1DF5-4C46-4760-B72B-474D90336F5B}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {AADE1DF5-4C46-4760-B72B-474D90336F5B}.Release|Any CPU.Build.0 = Release|Any CPU
+ {AADE1DF5-4C46-4760-B72B-474D90336F5B}.Release|x64.ActiveCfg = Release|Any CPU
+ {AADE1DF5-4C46-4760-B72B-474D90336F5B}.Release|x64.Build.0 = Release|Any CPU
+ {AADE1DF5-4C46-4760-B72B-474D90336F5B}.Release|x86.ActiveCfg = Release|Any CPU
+ {AADE1DF5-4C46-4760-B72B-474D90336F5B}.Release|x86.Build.0 = Release|Any CPU
+ {8C96928D-E6B9-46E4-BA5B-BB0BBA4A7C60}.Capture.Workflow|Any CPU.ActiveCfg = Release|Any CPU
+ {8C96928D-E6B9-46E4-BA5B-BB0BBA4A7C60}.Capture.Workflow|Any CPU.Build.0 = Release|Any CPU
+ {8C96928D-E6B9-46E4-BA5B-BB0BBA4A7C60}.Capture.Workflow|x64.ActiveCfg = Release|Any CPU
+ {8C96928D-E6B9-46E4-BA5B-BB0BBA4A7C60}.Capture.Workflow|x64.Build.0 = Release|Any CPU
+ {8C96928D-E6B9-46E4-BA5B-BB0BBA4A7C60}.Capture.Workflow|x86.ActiveCfg = Release|Any CPU
+ {8C96928D-E6B9-46E4-BA5B-BB0BBA4A7C60}.Capture.Workflow|x86.Build.0 = Release|Any CPU
+ {8C96928D-E6B9-46E4-BA5B-BB0BBA4A7C60}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {8C96928D-E6B9-46E4-BA5B-BB0BBA4A7C60}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {8C96928D-E6B9-46E4-BA5B-BB0BBA4A7C60}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {8C96928D-E6B9-46E4-BA5B-BB0BBA4A7C60}.Debug|x64.Build.0 = Debug|Any CPU
+ {8C96928D-E6B9-46E4-BA5B-BB0BBA4A7C60}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {8C96928D-E6B9-46E4-BA5B-BB0BBA4A7C60}.Debug|x86.Build.0 = Debug|Any CPU
+ {8C96928D-E6B9-46E4-BA5B-BB0BBA4A7C60}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {8C96928D-E6B9-46E4-BA5B-BB0BBA4A7C60}.Release|Any CPU.Build.0 = Release|Any CPU
+ {8C96928D-E6B9-46E4-BA5B-BB0BBA4A7C60}.Release|x64.ActiveCfg = Release|Any CPU
+ {8C96928D-E6B9-46E4-BA5B-BB0BBA4A7C60}.Release|x64.Build.0 = Release|Any CPU
+ {8C96928D-E6B9-46E4-BA5B-BB0BBA4A7C60}.Release|x86.ActiveCfg = Release|Any CPU
+ {8C96928D-E6B9-46E4-BA5B-BB0BBA4A7C60}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
+ GlobalSection(NestedProjects) = preSolution
+ {E8572D8B-C987-4D20-BD88-1F8925A64A82} = {4FC379CE-DD0C-4628-9639-E232474A1F70}
+ {F809DBB6-E0E8-47A8-92ED-C24575576A5D} = {4FC379CE-DD0C-4628-9639-E232474A1F70}
+ {E9F048C1-C6A0-4CCD-BE57-4E76A7F8B32D} = {4FC379CE-DD0C-4628-9639-E232474A1F70}
+ EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {AB1F058A-E42A-455B-A367-CDFF8B8BD485}
EndGlobalSection
diff --git a/ASCOM.DSLR/ASCOM.DSLR.csproj b/ASCOM.DSLR/ASCOM.DSLR.csproj
index 90d4b53..364f321 100644
--- a/ASCOM.DSLR/ASCOM.DSLR.csproj
+++ b/ASCOM.DSLR/ASCOM.DSLR.csproj
@@ -17,7 +17,7 @@
3.5
v4.6
ASCOM.ico
- true
+ false
ASCOMDriverTemplate.snk
publish\
true
@@ -56,6 +56,7 @@
..\bin\
false
true
+ false
AnyCPU
@@ -63,6 +64,7 @@
false
true
+
@@ -72,6 +74,9 @@
+
+ ..\packages\Rssdp.4.0.0\lib\net45\Rssdp.dll
+
@@ -82,6 +87,7 @@
+
@@ -97,9 +103,14 @@
+
+
+
+
+
@@ -119,6 +130,7 @@
Settings.settings
+
Form
@@ -141,6 +153,111 @@
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
Designer
@@ -152,19 +269,271 @@
Settings.Designer.cs
-
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
Always
Always
-
+
+ Always
+
+
Always
Always
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
@@ -184,10 +553,22 @@
+
+ {e8572d8b-c987-4d20-bd88-1f8925a64a82}
+ CameraControl.Devices
+
{15e99248-6161-46a4-9183-609ca62406a6}
EDSDKLib
+
+ {7eb5d33d-e000-4766-9119-eda40d04af74}
+ Logging
+
+
+ {aade1df5-4c46-4760-b72b-474d90336f5b}
+ nikoncswrapper
+
{b7e42253-59ab-4ce0-b1e7-43fc61f4cd07}
OTelescope.API
@@ -198,12 +579,12 @@
-
+
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}.
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/DSLR.Camera Setup.exe b/DSLR.Camera Setup.exe
index 7e34f55..478f088 100644
Binary files a/DSLR.Camera Setup.exe and b/DSLR.Camera Setup.exe differ
diff --git a/DSLR.Camera Setup.iss b/DSLR.Camera Setup.iss
index a768632..4fcc605 100644
--- a/DSLR.Camera Setup.iss
+++ b/DSLR.Camera Setup.iss
@@ -1,18 +1,23 @@
;
; Script generated by the ASCOM Driver Installer Script Generator 6.2.0.0
; Generated by Volodymyr Torkalo on 03.01.2018 (UTC)
+; Fixed by Cesar Mattos on 05.05.2020 (CST)
;
+
+#define ApplicationVersion GetFileVersion("bin\ASCOM.DSLR.Camera.dll")
+
+
[Setup]
AppID={{64931281-9e67-4d94-bc2a-083a023714fd}
AppName=ASCOM DSLR.Camera Camera Driver
AppVerName=ASCOM DSLR.Camera Camera Driver {#ApplicationVersion}
AppVersion={#ApplicationVersion}
-AppPublisher=Volodymyr Torkalo
-AppPublisherURL=mailto:Torkalo@gmail.com
+AppPublisher=Cesar Mattos
+AppPublisherURL=mailto:cesar.mattos@gmail.com
AppSupportURL=http://tech.groups.yahoo.com/group/ASCOM-Talk/
AppUpdatesURL=http://ascom-standards.org/
VersionInfoVersion={#ApplicationVersion}
-MinVersion=0,5.0.2195sp4
+MinVersion=0,6.0
DefaultDirName="{cf}\ASCOM\Camera\ASCOM.DSLR.Camera"
DisableDirPage=yes
DisableProgramGroupPage=yes
@@ -33,33 +38,219 @@ Name: "english"; MessagesFile: "compiler:Default.isl"
Name: "{cf}\ASCOM\Uninstall\Camera\DSLR.Camera"
; TODO: Add subfolders below {app} as needed (e.g. Name: "{app}\MyFolder")
+[Icons]
+Name: "{userdesktop}\ASCOMDSLRTest"; Filename: "{app}\ASCOM.DSLR.Test.exe"
+Name: "{userdesktop}\ClearDSLRSCProfile"; Filename: "{app}\ClearDSLRSCProfile.exe"
+
[Files]
Source: "bin\ASCOM.DSLR.Camera.dll"; DestDir: "{app}"
;Source: "bin\ReadMe.htm"; DestDir: "{app}"; Flags: isreadme
-Source: "bin\libraw.dll"; DestDir: "{app}"
-Source: "bin\EDSDK.dll"; DestDir: "{app}"
+Source: "bin\SDK\X64\libraw.dll"; DestDir: "{app}\SDK\X64\"
+Source: "bin\SDK\X64\EDSDK.dll"; DestDir: "{app}\SDK\X64\"
+Source: "bin\SDK\X86\libraw.dll"; DestDir: "{app}\SDK\X86\"
+Source: "bin\SDK\X86\EDSDK.dll"; DestDir: "{app}\SDK\X86\"
Source: "bin\EDSDKLib.dll"; DestDir: "{app}"
Source: "bin\exiftool.exe"; DestDir: "{app}"
+Source: "bin\Registrar.exe"; DestDir: "{app}"
Source: "bin\OTelescope.API.dll"; DestDir: "{app}"
+Source: "bin\Nlog.dll"; DestDir: "{app}"
+Source: "bin\ErrorLogging.dll"; DestDir: "{app}"
+Source: "bin\ClearDSLRSCProfile.exe"; DestDir: "{app}"
;Source: "bin\Newtonsoft.Json.dll"; DestDir: "{app}"
+;Nikon and Pentax
+Source: "bin\CameraControl.Devices.dll"; DestDir: "{app}"
+Source: "bin\Canon.Eos.Framework.dll"; DestDir: "{app}"
+Source: "bin\Interop.PortableDeviceApiLib.dll"; DestDir: "{app}"
+Source: "bin\Interop.PortableDeviceTypesLib.dll"; DestDir: "{app}"
+Source: "bin\Newtonsoft.Json.dll"; DestDir: "{app}"
+Source: "bin\PortableDeviceLib.dll"; DestDir: "{app}"
+Source: "bin\Rssdp.dll"; DestDir: "{app}"
+Source: "bin\websocket-sharp.dll"; DestDir: "{app}"
+Source: "bin\Accord.dll"; DestDir: "{app}"
+Source: "bin\Accord.Video.DirectShow.dll"; DestDir: "{app}"
+Source: "bin\Accord.Video.dll"; DestDir: "{app}"
+Source: "bin\nikoncswrapper.dll"; DestDir: "{app}"
+
+
+
+Source: "pktriggercord\zlib1.dll"; DestDir: "{app}/pktriggercord"
+Source: "pktriggercord\pktriggercord_commandline.html"; DestDir: "{app}/pktriggercord"
+Source: "pktriggercord\pktriggercord-cli.exe"; DestDir: "{app}/pktriggercord"
+Source: "pktriggercord\pktriggercord.ui"; DestDir: "{app}/pktriggercord"
+Source: "pktriggercord\pktriggercord.exe"; DestDir: "{app}/pktriggercord"
+Source: "pktriggercord\libpng16-16.dll"; DestDir: "{app}/pktriggercord"
+Source: "pktriggercord\libpixman-1-0.dll"; DestDir: "{app}/pktriggercord"
+Source: "pktriggercord\libpangowin32-1.0-0.dll"; DestDir: "{app}/pktriggercord"
+Source: "pktriggercord\libpangocairo-1.0-0.dll"; DestDir: "{app}/pktriggercord"
+Source: "pktriggercord\libpango-1.0-0.dll"; DestDir: "{app}/pktriggercord"
+Source: "pktriggercord\libintl-8.dll"; DestDir: "{app}/pktriggercord"
+Source: "pktriggercord\libgtk-win32-2.0-0.dll"; DestDir: "{app}/pktriggercord"
+Source: "pktriggercord\libgobject-2.0-0.dll"; DestDir: "{app}/pktriggercord"
+Source: "pktriggercord\libgmodule-2.0-0.dll"; DestDir: "{app}/pktriggercord"
+Source: "pktriggercord\libglib-2.0-0.dll"; DestDir: "{app}/pktriggercord"
+Source: "pktriggercord\libgio-2.0-0.dll"; DestDir: "{app}/pktriggercord"
+Source: "pktriggercord\libgdk_pixbuf-2.0-0.dll"; DestDir: "{app}/pktriggercord"
+Source: "pktriggercord\libgdk-win32-2.0-0.dll"; DestDir: "{app}/pktriggercord"
+Source: "pktriggercord\libgcc_s_sjlj-1.dll"; DestDir: "{app}/pktriggercord"
+Source: "pktriggercord\libffi-6.dll"; DestDir: "{app}/pktriggercord"
+Source: "pktriggercord\libcairo-2.dll"; DestDir: "{app}/pktriggercord"
+Source: "pktriggercord\libatk-1.0-0.dll"; DestDir: "{app}/pktriggercord"
+Source: "pktriggercord\iconv.dll"; DestDir: "{app}/pktriggercord"
+Source: "pktriggercord\COPYING"; DestDir: "{app}/pktriggercord"
+Source: "pktriggercord\Changelog"; DestDir: "{app}/pktriggercord"
+Source: "pktriggercord\pentax_settings.json"; DestDir: "{app}/pktriggercord"
+
+;New NikonSDK
+;X64
+Source: "bin\SDK\X64\Nikon\Type0001\NkdPTP.dll"; DestDir: "{app}\SDK\X64\Nikon\Type0001\"
+Source: "bin\SDK\X64\Nikon\Type0002\NkdPTP.dll"; DestDir: "{app}\SDK\X64\Nikon\Type0002\"
+Source: "bin\SDK\X64\Nikon\Type0003\NkdPTP.dll"; DestDir: "{app}\SDK\X64\Nikon\Type0003\"
+Source: "bin\SDK\X64\Nikon\Type0004\NkdPTP.dll"; DestDir: "{app}\SDK\X64\Nikon\Type0004\"
+Source: "bin\SDK\X64\Nikon\Type0005\NkdPTP.dll"; DestDir: "{app}\SDK\X64\Nikon\Type0005\"
+Source: "bin\SDK\X64\Nikon\Type0006\NkdPTP.dll"; DestDir: "{app}\SDK\X64\Nikon\Type0006\"
+Source: "bin\SDK\X64\Nikon\Type0007\NkdPTP.dll"; DestDir: "{app}\SDK\X64\Nikon\Type0007\"
+Source: "bin\SDK\X64\Nikon\Type0008\NkdPTP.dll"; DestDir: "{app}\SDK\X64\Nikon\Type0008\"
+Source: "bin\SDK\X64\Nikon\Type0009\NkdPTP.dll"; DestDir: "{app}\SDK\X64\Nikon\Type0009\"
+Source: "bin\SDK\X64\Nikon\Type0010\NkdPTP.dll"; DestDir: "{app}\SDK\X64\Nikon\Type0010\"
+Source: "bin\SDK\X64\Nikon\Type0011\NkdPTP.dll"; DestDir: "{app}\SDK\X64\Nikon\Type0011\"
+Source: "bin\SDK\X64\Nikon\Type0012\NkdPTP.dll"; DestDir: "{app}\SDK\X64\Nikon\Type0012\"
+Source: "bin\SDK\X64\Nikon\Type0013\NkdPTP.dll"; DestDir: "{app}\SDK\X64\Nikon\Type0013\"
+Source: "bin\SDK\X64\Nikon\Type0014\NkdPTP.dll"; DestDir: "{app}\SDK\X64\Nikon\Type0014\"
+Source: "bin\SDK\X64\Nikon\Type0015\NkdPTP.dll"; DestDir: "{app}\SDK\X64\Nikon\Type0015\"
+Source: "bin\SDK\X64\Nikon\Type0016\NkdPTP.dll"; DestDir: "{app}\SDK\X64\Nikon\Type0016\"
+Source: "bin\SDK\X64\Nikon\Type0017\NkdPTP.dll"; DestDir: "{app}\SDK\X64\Nikon\Type0017\"
+Source: "bin\SDK\X64\Nikon\Type0018\NkdPTP.dll"; DestDir: "{app}\SDK\X64\Nikon\Type0018\"
+Source: "bin\SDK\X64\Nikon\Type0019\NkdPTP.dll"; DestDir: "{app}\SDK\X64\Nikon\Type0019\"
+Source: "bin\SDK\X64\Nikon\Type0020\NkdPTP.dll"; DestDir: "{app}\SDK\X64\Nikon\Type0020\"
+Source: "bin\SDK\X64\Nikon\Type0021\NkdPTP.dll"; DestDir: "{app}\SDK\X64\Nikon\Type0021\"
+Source: "bin\SDK\X64\Nikon\Type0022\NkdPTP.dll"; DestDir: "{app}\SDK\X64\Nikon\Type0022\"
+Source: "bin\SDK\X64\Nikon\Type0023\NkdPTP.dll"; DestDir: "{app}\SDK\X64\Nikon\Type0023\"
+Source: "bin\SDK\X64\Nikon\Type0024\NkdPTP.dll"; DestDir: "{app}\SDK\X64\Nikon\Type0024\"
+Source: "bin\SDK\X64\Nikon\Type0025\NkdPTP.dll"; DestDir: "{app}\SDK\X64\Nikon\Type0025\"
+Source: "bin\SDK\X64\Nikon\Type0026\NkdPTP.dll"; DestDir: "{app}\SDK\X64\Nikon\Type0026\"
+Source: "bin\SDK\X64\Nikon\Type0027\NkdPTP.dll"; DestDir: "{app}\SDK\X64\Nikon\Type0027\"
+Source: "bin\SDK\X64\Nikon\Type0001\Type0001.md3"; DestDir: "{app}\SDK\X64\Nikon\Type0001\"
+Source: "bin\SDK\X64\Nikon\Type0002\Type0002.md3"; DestDir: "{app}\SDK\X64\Nikon\Type0002\"
+Source: "bin\SDK\X64\Nikon\Type0003\Type0003.md3"; DestDir: "{app}\SDK\X64\Nikon\Type0003\"
+Source: "bin\SDK\X64\Nikon\Type0004\Type0004.md3"; DestDir: "{app}\SDK\X64\Nikon\Type0004\"
+Source: "bin\SDK\X64\Nikon\Type0005\Type0005.md3"; DestDir: "{app}\SDK\X64\Nikon\Type0005\"
+Source: "bin\SDK\X64\Nikon\Type0006\Type0006.md3"; DestDir: "{app}\SDK\X64\Nikon\Type0006\"
+Source: "bin\SDK\X64\Nikon\Type0007\Type0007.md3"; DestDir: "{app}\SDK\X64\Nikon\Type0007\"
+Source: "bin\SDK\X64\Nikon\Type0008\Type0008.md3"; DestDir: "{app}\SDK\X64\Nikon\Type0008\"
+Source: "bin\SDK\X64\Nikon\Type0009\Type0009.md3"; DestDir: "{app}\SDK\X64\Nikon\Type0009\"
+Source: "bin\SDK\X64\Nikon\Type0010\Type0010.md3"; DestDir: "{app}\SDK\X64\Nikon\Type0010\"
+Source: "bin\SDK\X64\Nikon\Type0011\Type0011.md3"; DestDir: "{app}\SDK\X64\Nikon\Type0011\"
+Source: "bin\SDK\X64\Nikon\Type0012\Type0012.md3"; DestDir: "{app}\SDK\X64\Nikon\Type0012\"
+Source: "bin\SDK\X64\Nikon\Type0013\Type0013.md3"; DestDir: "{app}\SDK\X64\Nikon\Type0013\"
+Source: "bin\SDK\X64\Nikon\Type0014\Type0014.md3"; DestDir: "{app}\SDK\X64\Nikon\Type0014\"
+Source: "bin\SDK\X64\Nikon\Type0015\Type0015.md3"; DestDir: "{app}\SDK\X64\Nikon\Type0015\"
+Source: "bin\SDK\X64\Nikon\Type0016\Type0016.md3"; DestDir: "{app}\SDK\X64\Nikon\Type0016\"
+Source: "bin\SDK\X64\Nikon\Type0017\Type0017.md3"; DestDir: "{app}\SDK\X64\Nikon\Type0017\"
+Source: "bin\SDK\X64\Nikon\Type0018\Type0018.md3"; DestDir: "{app}\SDK\X64\Nikon\Type0018\"
+Source: "bin\SDK\X64\Nikon\Type0019\Type0019.md3"; DestDir: "{app}\SDK\X64\Nikon\Type0019\"
+Source: "bin\SDK\X64\Nikon\Type0020\Type0020.md3"; DestDir: "{app}\SDK\X64\Nikon\Type0020\"
+Source: "bin\SDK\X64\Nikon\Type0021\Type0021.md3"; DestDir: "{app}\SDK\X64\Nikon\Type0021\"
+Source: "bin\SDK\X64\Nikon\Type0022\Type0022.md3"; DestDir: "{app}\SDK\X64\Nikon\Type0022\"
+Source: "bin\SDK\X64\Nikon\Type0023\Type0023.md3"; DestDir: "{app}\SDK\X64\Nikon\Type0023\"
+Source: "bin\SDK\X64\Nikon\Type0024\Type0024.md3"; DestDir: "{app}\SDK\X64\Nikon\Type0024\"
+Source: "bin\SDK\X64\Nikon\Type0025\Type0025.md3"; DestDir: "{app}\SDK\X64\Nikon\Type0025\"
+Source: "bin\SDK\X64\Nikon\Type0026\Type0026.md3"; DestDir: "{app}\SDK\X64\Nikon\Type0026\"
+Source: "bin\SDK\X64\Nikon\Type0027\Type0027.md3"; DestDir: "{app}\SDK\X64\Nikon\Type0027\"
+;X86
+Source: "bin\SDK\X86\Nikon\Type0001\NkdPTP.dll"; DestDir: "{app}\SDK\X86\Nikon\Type0001\"
+Source: "bin\SDK\X86\Nikon\Type0002\NkdPTP.dll"; DestDir: "{app}\SDK\X86\Nikon\Type0002\"
+Source: "bin\SDK\X86\Nikon\Type0003\NkdPTP.dll"; DestDir: "{app}\SDK\X86\Nikon\Type0003\"
+Source: "bin\SDK\X86\Nikon\Type0004\NkdPTP.dll"; DestDir: "{app}\SDK\X86\Nikon\Type0004\"
+Source: "bin\SDK\X86\Nikon\Type0005\NkdPTP.dll"; DestDir: "{app}\SDK\X86\Nikon\Type0005\"
+Source: "bin\SDK\X86\Nikon\Type0006\NkdPTP.dll"; DestDir: "{app}\SDK\X86\Nikon\Type0006\"
+Source: "bin\SDK\X86\Nikon\Type0007\NkdPTP.dll"; DestDir: "{app}\SDK\X86\Nikon\Type0007\"
+Source: "bin\SDK\X86\Nikon\Type0008\NkdPTP.dll"; DestDir: "{app}\SDK\X86\Nikon\Type0008\"
+Source: "bin\SDK\X86\Nikon\Type0009\NkdPTP.dll"; DestDir: "{app}\SDK\X86\Nikon\Type0009\"
+Source: "bin\SDK\X86\Nikon\Type0010\NkdPTP.dll"; DestDir: "{app}\SDK\X86\Nikon\Type0010\"
+Source: "bin\SDK\X86\Nikon\Type0011\NkdPTP.dll"; DestDir: "{app}\SDK\X86\Nikon\Type0011\"
+Source: "bin\SDK\X86\Nikon\Type0012\NkdPTP.dll"; DestDir: "{app}\SDK\X86\Nikon\Type0012\"
+Source: "bin\SDK\X86\Nikon\Type0013\NkdPTP.dll"; DestDir: "{app}\SDK\X86\Nikon\Type0013\"
+Source: "bin\SDK\X86\Nikon\Type0014\NkdPTP.dll"; DestDir: "{app}\SDK\X86\Nikon\Type0014\"
+Source: "bin\SDK\X86\Nikon\Type0015\NkdPTP.dll"; DestDir: "{app}\SDK\X86\Nikon\Type0015\"
+Source: "bin\SDK\X86\Nikon\Type0016\NkdPTP.dll"; DestDir: "{app}\SDK\X86\Nikon\Type0016\"
+Source: "bin\SDK\X86\Nikon\Type0017\NkdPTP.dll"; DestDir: "{app}\SDK\X86\Nikon\Type0017\"
+Source: "bin\SDK\X86\Nikon\Type0018\NkdPTP.dll"; DestDir: "{app}\SDK\X86\Nikon\Type0018\"
+Source: "bin\SDK\X86\Nikon\Type0019\NkdPTP.dll"; DestDir: "{app}\SDK\X86\Nikon\Type0019\"
+Source: "bin\SDK\X86\Nikon\Type0020\NkdPTP.dll"; DestDir: "{app}\SDK\X86\Nikon\Type0020\"
+Source: "bin\SDK\X86\Nikon\Type0021\NkdPTP.dll"; DestDir: "{app}\SDK\X86\Nikon\Type0021\"
+Source: "bin\SDK\X86\Nikon\Type0022\NkdPTP.dll"; DestDir: "{app}\SDK\X86\Nikon\Type0022\"
+Source: "bin\SDK\X86\Nikon\Type0023\NkdPTP.dll"; DestDir: "{app}\SDK\X86\Nikon\Type0023\"
+Source: "bin\SDK\X86\Nikon\Type0024\NkdPTP.dll"; DestDir: "{app}\SDK\X86\Nikon\Type0024\"
+Source: "bin\SDK\X86\Nikon\Type0025\NkdPTP.dll"; DestDir: "{app}\SDK\X86\Nikon\Type0025\"
+Source: "bin\SDK\X86\Nikon\Type0026\NkdPTP.dll"; DestDir: "{app}\SDK\X86\Nikon\Type0026\"
+Source: "bin\SDK\X86\Nikon\Type0027\NkdPTP.dll"; DestDir: "{app}\SDK\X86\Nikon\Type0027\"
+Source: "bin\SDK\X86\Nikon\D40_Mod\NkdPTP.dll"; DestDir: "{app}\SDK\X86\Nikon\D40_Mod\"
+Source: "bin\SDK\X86\Nikon\D40_Mod\NkdPTPDi.dll"; DestDir: "{app}\SDK\X86\Nikon\D40_Mod\"
+Source: "bin\SDK\X86\Nikon\D60_Mod\NkdPTP.dll"; DestDir: "{app}\SDK\X86\Nikon\D60_Mod\"
+Source: "bin\SDK\X86\Nikon\D80_Mod\NkdPTP.dll"; DestDir: "{app}\SDK\X86\Nikon\D80_Mod\"
+Source: "bin\SDK\X86\Nikon\D200_Mod\NkdPTP.dll"; DestDir: "{app}\SDK\X86\Nikon\D200_Mod\"
+Source: "bin\SDK\X86\Nikon\Type0001\Type0001.md3"; DestDir: "{app}\SDK\X86\Nikon\Type0001\"
+Source: "bin\SDK\X86\Nikon\Type0002\Type0002.md3"; DestDir: "{app}\SDK\X86\Nikon\Type0002\"
+Source: "bin\SDK\X86\Nikon\Type0003\Type0003.md3"; DestDir: "{app}\SDK\X86\Nikon\Type0003\"
+Source: "bin\SDK\X86\Nikon\Type0004\Type0004.md3"; DestDir: "{app}\SDK\X86\Nikon\Type0004\"
+Source: "bin\SDK\X86\Nikon\Type0005\Type0005.md3"; DestDir: "{app}\SDK\X86\Nikon\Type0005\"
+Source: "bin\SDK\X86\Nikon\Type0006\Type0006.md3"; DestDir: "{app}\SDK\X86\Nikon\Type0006\"
+Source: "bin\SDK\X86\Nikon\Type0007\Type0007.md3"; DestDir: "{app}\SDK\X86\Nikon\Type0007\"
+Source: "bin\SDK\X86\Nikon\Type0008\Type0008.md3"; DestDir: "{app}\SDK\X86\Nikon\Type0008\"
+Source: "bin\SDK\X86\Nikon\Type0009\Type0009.md3"; DestDir: "{app}\SDK\X86\Nikon\Type0009\"
+Source: "bin\SDK\X86\Nikon\Type0010\Type0010.md3"; DestDir: "{app}\SDK\X86\Nikon\Type0010\"
+Source: "bin\SDK\X86\Nikon\Type0011\Type0011.md3"; DestDir: "{app}\SDK\X86\Nikon\Type0011\"
+Source: "bin\SDK\X86\Nikon\Type0012\Type0012.md3"; DestDir: "{app}\SDK\X86\Nikon\Type0012\"
+Source: "bin\SDK\X86\Nikon\Type0013\Type0013.md3"; DestDir: "{app}\SDK\X86\Nikon\Type0013\"
+Source: "bin\SDK\X86\Nikon\Type0014\Type0014.md3"; DestDir: "{app}\SDK\X86\Nikon\Type0014\"
+Source: "bin\SDK\X86\Nikon\Type0015\Type0015.md3"; DestDir: "{app}\SDK\X86\Nikon\Type0015\"
+Source: "bin\SDK\X86\Nikon\Type0016\Type0016.md3"; DestDir: "{app}\SDK\X86\Nikon\Type0016\"
+Source: "bin\SDK\X86\Nikon\Type0017\Type0017.md3"; DestDir: "{app}\SDK\X86\Nikon\Type0017\"
+Source: "bin\SDK\X86\Nikon\Type0018\Type0018.md3"; DestDir: "{app}\SDK\X86\Nikon\Type0018\"
+Source: "bin\SDK\X86\Nikon\Type0019\Type0019.md3"; DestDir: "{app}\SDK\X86\Nikon\Type0019\"
+Source: "bin\SDK\X86\Nikon\Type0020\Type0020.md3"; DestDir: "{app}\SDK\X86\Nikon\Type0020\"
+Source: "bin\SDK\X86\Nikon\Type0021\Type0021.md3"; DestDir: "{app}\SDK\X86\Nikon\Type0021\"
+Source: "bin\SDK\X86\Nikon\Type0022\Type0022.md3"; DestDir: "{app}\SDK\X86\Nikon\Type0022\"
+Source: "bin\SDK\X86\Nikon\Type0023\Type0023.md3"; DestDir: "{app}\SDK\X86\Nikon\Type0023\"
+Source: "bin\SDK\X86\Nikon\Type0024\Type0024.md3"; DestDir: "{app}\SDK\X86\Nikon\Type0024\"
+Source: "bin\SDK\X86\Nikon\Type0025\Type0025.md3"; DestDir: "{app}\SDK\X86\Nikon\Type0025\"
+Source: "bin\SDK\X86\Nikon\Type0026\Type0026.md3"; DestDir: "{app}\SDK\X86\Nikon\Type0026\"
+Source: "bin\SDK\X86\Nikon\Type0027\Type0027.md3"; DestDir: "{app}\SDK\X86\Nikon\Type0027\"
+Source: "bin\SDK\X86\Nikon\D40_Mod\D40_Mod.md3"; DestDir: "{app}\SDK\X86\Nikon\D40_Mod\"
+Source: "bin\SDK\X86\Nikon\D60_Mod\D40_Mod.md3"; DestDir: "{app}\SDK\X86\Nikon\D60_Mod\"
+Source: "bin\SDK\X86\Nikon\D80_Mod\D80_Mod.md3"; DestDir: "{app}\SDK\X86\Nikon\D80_Mod\"
+Source: "bin\SDK\X86\Nikon\D200_Mod\D200_Mod.md3"; DestDir: "{app}\SDK\X86\Nikon\D200_Mod\"
+
+Source: "bin\ASCOM.DSLR.Test.exe"; DestDir: "{app}"
+
+;VC Runtime 2019
+Source: "Redist\VC_redist.x86.exe"; DestDir: {tmp}
+Source: "Redist\VC_redist.x64.exe"; DestDir: {tmp}
; Only if driver is .NET
[Run]
; Only for .NET assembly/in-proc drivers
Filename: "{dotnet4032}\regasm.exe"; Parameters: "/codebase ""{app}\ASCOM.DSLR.Camera.dll"""; Flags: runhidden 32bit
-;Filename: "{dotnet4064}\regasm.exe"; Parameters: "/codebase ""{app}\ASCOM.DSLR.Camera.dll"""; Flags: runhidden 64bit; Check: IsWin64
-
+Filename: "{dotnet4064}\regasm.exe"; Parameters: "/codebase ""{app}\ASCOM.DSLR.Camera.dll"""; Flags: runhidden 64bit; Check: IsWin64
+Filename: "{tmp}\VC_redist.x86.exe"; Parameters: "/q /norestart"; \
+ Check: VC2019RedistNeedsInstall('x86'); \
+ Flags: waituntilterminated; StatusMsg: "Installing VC++ 2019 redistributables..."
+
+Filename: "{tmp}\VC_redist.x64.exe"; Parameters: "/q /norestart"; \
+ Check: IsWin64 and VC2019RedistNeedsInstall('x64'); \
+ Flags: waituntilterminated; StatusMsg: "Installing VC++ 2019 redistributables..."
; Only if driver is .NET
[UninstallRun]
; Only for .NET assembly/in-proc drivers
Filename: "{dotnet4032}\regasm.exe"; Parameters: "-u ""{app}\ASCOM.DSLR.Camera.dll"""; Flags: runhidden 32bit
-; This helps to give a clean uninstall
-;Filename: "{dotnet4064}\regasm.exe"; Parameters: "/codebase ""{app}\ASCOM.DSLR.Camera.dll"""; Flags: runhidden 64bit; Check: IsWin64
-;Filename: "{dotnet4064}\regasm.exe"; Parameters: "-u ""{app}\ASCOM.DSLR.Camera.dll"""; Flags: runhidden 64bit; Check: IsWin64
+Filename: "{dotnet4064}\regasm.exe"; Parameters: "-u ""{app}\ASCOM.DSLR.Camera.dll"""; Flags: runhidden 64bit; Check: IsWin64
+[UninstallDelete]
+Type: files; Name: "{app}\SDK\X86\EDSDK.dll"
+Type: files; Name: "{app}\SDK\X86\Nlog.dll"
[CODE]
//
@@ -113,4 +304,16 @@ begin
end
end;
end;
-
+//Runtime Function
+function VC2019RedistNeedsInstall(Arch: string): Boolean;
+var
+ Version: String;
+begin
+ if RegQueryStringValue(
+ HKEY_LOCAL_MACHINE, 'SOFTWARE\Microsoft\VisualStudio\14.0\VC\Runtimes\' + Arch,
+ 'Version', Version) then
+ begin
+ Log('VC Redist Version check : found ' + Version);
+ Result := (CompareStr(Version, 'v14.26.28720.03')<0);
+ end;
+end;
\ No newline at end of file
diff --git a/DigiCamControl/CameraControl.Devices/BaseCameraDevice.cs b/DigiCamControl/CameraControl.Devices/BaseCameraDevice.cs
new file mode 100644
index 0000000..ada6b9d
--- /dev/null
+++ b/DigiCamControl/CameraControl.Devices/BaseCameraDevice.cs
@@ -0,0 +1,631 @@
+#region Licence
+
+// Distributed under MIT License
+// ===========================================================
+//
+// digiCamControl - DSLR camera remote control open source software
+// Copyright (C) 2014 Duka Istvan
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY,FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH
+// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#endregion
+
+#region
+
+using System;
+using System.Collections.Generic;
+using CameraControl.Devices.Classes;
+using System.Text;
+
+#endregion
+
+namespace CameraControl.Devices
+{
+ public class BaseCameraDevice : BaseFieldClass, ICameraDevice
+ {
+ #region Implementation of ICameraDevice
+
+ protected List Capabilities = new List();
+ protected object Locker = new object(); // object used to lock multi threaded methods
+
+ private bool _haveLiveView;
+
+ private bool _isBusy;
+
+ public bool IsBusy
+ {
+ get { return _isBusy; }
+ set
+ {
+ _isBusy = value;
+ NotifyPropertyChanged("IsBusy");
+ }
+ }
+
+ public virtual bool HaveLiveView
+ {
+ get { return _haveLiveView; }
+ set
+ {
+ _haveLiveView = value;
+ NotifyPropertyChanged("HaveLiveView");
+ }
+ }
+
+ private bool _captureInSdRam;
+
+ public virtual bool CaptureInSdRam
+ {
+ get { return _captureInSdRam; }
+ set
+ {
+ _captureInSdRam = value;
+ NotifyPropertyChanged("CaptureInSdRam");
+ }
+ }
+
+ private PropertyValue _isoNumber;
+
+ public virtual PropertyValue IsoNumber
+ {
+ get { return _isoNumber; }
+ set
+ {
+ _isoNumber = value;
+ NotifyPropertyChanged("IsoNumber");
+ }
+ }
+
+ private PropertyValue _shutterSpeed;
+
+ public virtual PropertyValue ShutterSpeed
+ {
+ get { return _shutterSpeed; }
+ set
+ {
+ _shutterSpeed = value;
+ NotifyPropertyChanged("ShutterSpeed");
+ }
+ }
+
+ private PropertyValue _mode;
+
+ public virtual PropertyValue Mode
+ {
+ get { return _mode; }
+ set
+ {
+ _mode = value;
+ NotifyPropertyChanged("Mode");
+ }
+ }
+
+ private PropertyValue _fNumber;
+
+ public virtual PropertyValue FNumber
+ {
+ get { return _fNumber; }
+ set
+ {
+ _fNumber = value;
+ NotifyPropertyChanged("FNumber");
+ }
+ }
+
+ private PropertyValue _whiteBalance;
+
+ public virtual PropertyValue WhiteBalance
+ {
+ get { return _whiteBalance; }
+ set
+ {
+ _whiteBalance = value;
+ NotifyPropertyChanged("WhiteBalance");
+ }
+ }
+
+ private PropertyValue _exposureCompensation;
+
+ public virtual PropertyValue ExposureCompensation
+ {
+ get { return _exposureCompensation; }
+ set
+ {
+ _exposureCompensation = value;
+ NotifyPropertyChanged("ExposureCompensation");
+ }
+ }
+
+ private PropertyValue _compressionSetting;
+
+ public virtual PropertyValue CompressionSetting
+ {
+ get { return _compressionSetting; }
+ set
+ {
+ _compressionSetting = value;
+ NotifyPropertyChanged("CompressionSetting");
+ }
+ }
+
+ private PropertyValue _exposureMeteringMode;
+
+ public virtual PropertyValue ExposureMeteringMode
+ {
+ get { return _exposureMeteringMode; }
+ set
+ {
+ _exposureMeteringMode = value;
+ NotifyPropertyChanged("ExposureMeteringMode");
+ }
+ }
+
+ private PropertyValue _focusMode;
+
+ public virtual PropertyValue FocusMode
+ {
+ get
+ {
+ return _focusMode;
+ }
+ set
+ {
+ _focusMode = value;
+ NotifyPropertyChanged("FocusMode");
+ }
+ }
+
+ private DateTime _dateTime;
+
+ public virtual DateTime DateTime
+ {
+ get { return _dateTime; }
+ set
+ {
+ _dateTime = value;
+ NotifyPropertyChanged("DateTime");
+ }
+ }
+
+ public string PortName { get; set; }
+
+ private string _deviceName;
+
+ private bool _isChecked;
+
+ public virtual bool IsChecked
+ {
+ get { return _isChecked; }
+ set
+ {
+ _isChecked = value;
+ NotifyPropertyChanged("IsChecked");
+ }
+ }
+
+ private object _attachedPhotoSession;
+
+ public virtual object AttachedPhotoSession
+ {
+ get { return _attachedPhotoSession; }
+ set
+ {
+ _attachedPhotoSession = value;
+ NotifyPropertyChanged("AttachedPhotoSession");
+ }
+ }
+
+ public virtual string DeviceName
+ {
+ get { return _deviceName; }
+ set
+ {
+ _deviceName = value;
+ NotifyPropertyChanged("DeviceName");
+ }
+ }
+
+ private string _manufacturer;
+
+ public virtual string Manufacturer
+ {
+ get { return _manufacturer; }
+ set
+ {
+ _manufacturer = value;
+ NotifyPropertyChanged("Manufacturer");
+ }
+ }
+
+ private string _serialNumber;
+
+ public virtual string SerialNumber
+ {
+ get { return _serialNumber; }
+ set
+ {
+ _serialNumber = value;
+ NotifyPropertyChanged("SerialNumber");
+ }
+ }
+
+ private string _displayName;
+
+ public virtual string DisplayName
+ {
+ get
+ {
+ if (string.IsNullOrEmpty(_displayName))
+ return DeviceName + " (" + SerialNumber + ")";
+ return _displayName;
+ }
+ set
+ {
+ _displayName = value;
+ NotifyPropertyChanged("DisplayName");
+ }
+ }
+
+
+ private int _exposureStatus;
+
+ public virtual int ExposureStatus
+ {
+ get { return _exposureStatus; }
+ set
+ {
+ _exposureStatus = value;
+ NotifyPropertyChanged("ExposureStatus");
+ }
+ }
+
+ public bool PreventShutDown
+ {
+ get { return _preventShutDown; }
+ set
+ {
+ _preventShutDown = value;
+ NotifyPropertyChanged("PreventShutDown");
+ }
+ }
+
+ private bool _isConnected;
+
+ public virtual bool IsConnected
+ {
+ get { return _isConnected; }
+ set
+ {
+ _isConnected = value;
+ NotifyPropertyChanged("IsConnected");
+ }
+ }
+
+
+ private int _battery;
+
+ public virtual int Battery
+ {
+ get { return _battery; }
+ set
+ {
+ _battery = value;
+ NotifyPropertyChanged("Battery");
+ }
+ }
+
+ private uint _transferProgress;
+
+ public uint TransferProgress
+ {
+ get { return _transferProgress; }
+ set
+ {
+ _transferProgress = value;
+ NotifyPropertyChanged("TransferProgress");
+ }
+ }
+
+ public virtual bool GetCapability(CapabilityEnum capabilityEnum)
+ {
+ return Capabilities.Contains(capabilityEnum);
+ }
+
+ public virtual PropertyValue LiveViewImageZoomRatio { get; set; }
+
+ public virtual bool Init(DeviceDescriptor deviceDescriptor)
+ {
+ return true;
+ }
+
+ public virtual void StartLiveView()
+ {
+ }
+
+ public virtual void StopLiveView()
+ {
+ }
+
+ public virtual string GetLiveViewStream()
+ {
+ throw new NotImplementedException();
+ }
+
+ public virtual LiveViewData GetLiveViewImage()
+ {
+ return null;
+ }
+
+ public virtual void AutoFocus()
+ {
+ }
+
+ public virtual int Focus(int step)
+ {
+ return 0;
+ }
+
+ public virtual void Focus(int x, int y)
+ {
+ }
+
+ public virtual void Focus(FocusDirection direction, FocusAmount amount)
+ {
+ throw new NotImplementedException();
+ }
+
+ public virtual void CapturePhotoNoAf()
+ {
+ }
+
+ public virtual void CapturePhoto()
+ {
+ }
+
+ public virtual void StartRecordMovie()
+ {
+ }
+
+ public virtual void StopRecordMovie()
+ {
+ }
+
+ public virtual string GetProhibitionCondition(OperationEnum operationEnum)
+ {
+ return "";
+ }
+
+ public virtual bool GetStatus(OperationEnum operationEnum)
+ {
+ throw new NotImplementedException();
+ }
+
+ public virtual void EndBulbMode()
+ {
+ }
+
+ public virtual void StartBulbMode()
+ {
+ }
+
+ public virtual void LockCamera()
+ {
+ }
+
+ public virtual void UnLockCamera()
+ {
+ }
+
+ public virtual void Close()
+ {
+ }
+
+ public virtual void StartZoom(ZoomDirection direction)
+ {
+ throw new NotImplementedException();
+ }
+
+ public virtual void StopZoom(ZoomDirection direction)
+ {
+ throw new NotImplementedException();
+ }
+
+ public virtual void ResetDevice()
+ {
+
+ }
+
+ public virtual void ReleaseResurce(object o)
+ {
+
+ }
+
+ public virtual void TransferFileThumb(object o, string filename)
+ {
+ TransferFile(o, filename);
+ }
+
+ public virtual void ReadDeviceProperties(uint prop)
+ {
+ }
+
+ public virtual void TransferFile(object o, string filename)
+ {
+ }
+
+ public virtual void TransferFile(object o, System.IO.Stream stream)
+ {
+ }
+
+ public void OnCaptureCompleted(object sender, EventArgs args)
+ {
+ if (CaptureCompleted != null)
+ {
+ CaptureCompleted(sender, args);
+ }
+ }
+
+ public void OnPhotoCapture(object sender, PhotoCapturedEventArgs args)
+ {
+ if (PhotoCaptured != null)
+ {
+ PhotoCaptured(sender, args);
+ }
+ }
+
+ public void OnCameraDisconnected(object sender, DisconnectCameraEventArgs eventHandler)
+ {
+ if (CameraDisconnected != null)
+ {
+ CameraDisconnected(sender, eventHandler);
+ }
+ }
+
+ public event PhotoCapturedEventHandler PhotoCaptured;
+ public event EventHandler CaptureCompleted;
+ public event CameraDisconnectedEventHandler CameraDisconnected;
+ public event CameraDeviceManager.CameraConnectedEventHandler CameraInitDone;
+
+ public void OnCameraInitDone()
+ {
+ try
+ {
+ CameraDeviceManager.CameraConnectedEventHandler handler = CameraInitDone;
+ if (handler != null) handler(this);
+ }
+ catch (Exception ex)
+ {
+ Log.Error("OnCameraInitDone", ex);
+ }
+ }
+
+ private AsyncObservableCollection> _advancedProperties;
+ private AsyncObservableCollection> _properties;
+ private bool _preventShutDown;
+
+ public AsyncObservableCollection> AdvancedProperties
+ {
+ get { return _advancedProperties; }
+ set
+ {
+ _advancedProperties = value;
+ NotifyPropertyChanged("AdvancedProperties");
+ }
+ }
+
+ public AsyncObservableCollection> Properties
+ {
+ get { return _properties; }
+ set
+ {
+ _properties = value;
+ NotifyPropertyChanged("Properties");
+ }
+ }
+
+ public virtual AsyncObservableCollection GetObjects(object storageId, bool loadThumbs)
+ {
+ throw new NotImplementedException();
+ }
+
+ public virtual void FormatStorage(object storageId)
+ {
+ throw new NotImplementedException();
+ }
+
+ public virtual bool DeleteObject(DeviceObject deviceObject)
+ {
+ throw new NotImplementedException();
+ }
+
+ ///
+ /// Sets the in comment field.
+ ///
+ ///
+ /// The comment.
+ public virtual void SetCameraField(CameraFieldType cameraFieldType, string comment)
+ {
+ }
+
+ public virtual void WaitForReady()
+ {
+
+ }
+
+ #endregion
+
+ public BaseCameraDevice()
+ {
+ IsChecked = true;
+ AdvancedProperties = new AsyncObservableCollection>();
+ Properties = new AsyncObservableCollection>();
+ Capabilities = new List();
+ }
+
+ public override string ToString()
+ {
+ return DisplayName;
+ }
+
+ public virtual string ToStringCameraData()
+ {
+ // return DisplayName;
+ StringBuilder c = new StringBuilder("\n\nPost shot camera data:\n");
+ try
+ {
+ if (PortName != null)
+ c.AppendFormat("Port: {0}\n", PortName);
+ c.AppendFormat(" {0}{1}", String.IsNullOrWhiteSpace(Manufacturer) ? "" : "(" + Manufacturer + ") ", DeviceName);
+ c.AppendFormat("\n\tSerial number........ {0}", SerialNumber);
+ c.AppendFormat("\n\tBusy..................{0}", IsBusy ? "Yes" : "No");
+ c.AppendFormat("\n\tHave LiveView.........{0}", HaveLiveView ? "Yes" : "No");
+ c.AppendFormat("\n\tCapture SDRam.........{0}", CaptureInSdRam ? "Yes" : "No");
+ c.AppendFormat("\n\tIs Connected..........{0}", IsConnected ? "Yes" : "No");
+ c.AppendFormat("\n\tMode..................{0}, {1} focus", Mode?.Value, FocusMode?.Value);
+ c.AppendFormat("\n\texposure..............{0} f{1} +/-{2}, ISO{3}",
+ ShutterSpeed.Value,
+ FNumber.Value,
+ ExposureCompensation.Value,
+ IsoNumber.Value);
+ c.AppendFormat("\n\tmetering mode.........{0}", ExposureMeteringMode.Value);
+ c.AppendFormat("\n\twhite balance.........{0}", WhiteBalance.Value);
+ c.AppendFormat("\n\tTransfer progress.....{0}%", TransferProgress);
+
+ c.AppendFormat("\n\tExposure status.......{0}", ExposureStatus);
+ c.AppendFormat("\n\tBattery...............{0}%", Battery);
+ c.AppendFormat("\n\tCompression...........{0}%", CompressionSetting);
+
+ if (Capabilities.Count > 0)
+ {
+ c.Append(String.Format("\n\tCapabilities ({0} present of {1}):", Capabilities.Count, Enum.GetValues(typeof(CapabilityEnum)).Length));
+ foreach (CapabilityEnum x in Enum.GetValues(typeof(CapabilityEnum)))
+ {
+ c.AppendFormat("\n\t {0,-20}{1}", x.ToString(""), Capabilities.Contains(x) ? "Yes" : "No");
+ }
+ }
+
+ }
+ catch (Exception ex)
+ {
+ }
+
+ return c.ToString();
+ }
+ }
+}
\ No newline at end of file
diff --git a/DigiCamControl/CameraControl.Devices/BaseMTPCamera.cs b/DigiCamControl/CameraControl.Devices/BaseMTPCamera.cs
new file mode 100644
index 0000000..ac315a7
--- /dev/null
+++ b/DigiCamControl/CameraControl.Devices/BaseMTPCamera.cs
@@ -0,0 +1,708 @@
+#region Licence
+
+// Distributed under MIT License
+// ===========================================================
+//
+// digiCamControl - DSLR camera remote control open source software
+// Copyright (C) 2014 Duka Istvan
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY,FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH
+// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#endregion
+
+#region
+
+using System;
+using System.Globalization;
+using System.IO;
+using System.Runtime.InteropServices;
+using System.Text;
+using System.Threading;
+using CameraControl.Devices.Classes;
+using CameraControl.Devices.TransferProtocol;
+using CameraControl.Devices.Xml;
+using PortableDeviceLib;
+using Timer = System.Timers.Timer;
+
+#endregion
+
+namespace CameraControl.Devices
+{
+ public class DeviceEventArgs : EventArgs
+ {
+ public uint Code { get; set; }
+ }
+
+ public class BaseMTPCamera : BaseCameraDevice
+ {
+ ///
+ /// The number of times to retry failed transfers.
+ ///
+ public const int TransferRetries = 10;
+
+ public delegate void DeviceEventHandler(object sender, DeviceEventArgs eventArgs);
+
+ public event DeviceEventHandler DeviceEvent;
+
+ public void OnDeviceEvent(DeviceEventArgs eventargs)
+ {
+ DeviceEventHandler handler = DeviceEvent;
+ if (handler != null) handler(this, eventargs);
+ }
+
+ protected const string AppName = "CameraControl";
+ protected const int AppMajorVersionNumber = 1;
+ protected const int AppMinorVersionNumber = 0;
+
+ // common MTP commands
+ public const uint CONST_CMD_GetDevicePropValue = 0x1015;
+ public const uint CONST_CMD_SetDevicePropValue = 0x1016;
+ public const uint CONST_CMD_GetDevicePropDesc = 0x1014;
+ public const uint CONST_CMD_GetObject = 0x1009;
+ public const uint CONST_CMD_GetObjectHandles = 0x1007;
+ public const uint CONST_CMD_GetObjectInfo = 0x1008;
+ public const uint CONST_CMD_GetThumb = 0x100A;
+ public const uint CONST_CMD_DeleteObject = 0x100B;
+ public const uint CONST_CMD_InitiateCapture = 0x100E;
+ public const uint CONST_CMD_FormatStore = 0x100F;
+ public const uint CONST_CMD_GetStorageIDs = 0x1004;
+
+ public const uint CONST_Event_ObjectAdded = 0x4002;
+ public const uint CONST_Event_ObjectAddedInSdram = 0xC101;
+
+ public const uint CONST_PROP_BatteryLevel = 0x5001;
+
+ private const int CONST_READY_TIME = 1;
+ private const int CONST_LOOP_TIME = 100;
+
+ protected ITransferProtocol StillImageDevice = null;
+ protected bool DeviceIsBusy = false;
+
+ ///
+ /// The timer for get periodically the event list
+ ///
+ protected Timer _timer = new Timer(1000 / 10);
+
+ ///
+ /// Variable to check if event processing is in progress
+ ///
+ protected bool _eventIsbusy = false;
+
+ public override bool Init(DeviceDescriptor deviceDescriptor)
+ {
+ StillImageDevice = deviceDescriptor.StillImageDevice;
+ StillImageDevice imageDevice = StillImageDevice as StillImageDevice;
+ if (imageDevice != null)
+ imageDevice.DeviceEvent += StillImageDevice_DeviceEvent;
+ IsConnected = true;
+ DeviceName = StillImageDevice.Model;
+ Manufacturer = StillImageDevice.Manufacturer;
+ var data = StillImageDevice.ExecuteReadData(CONST_CMD_GetDevicePropValue,
+ CONST_PROP_BatteryLevel);
+ if (data.Data != null && data.Data.Length > 0)
+ Battery = data.Data[0];
+ return true;
+ }
+
+ public override void CapturePhoto()
+ {
+ Monitor.Enter(Locker);
+ try
+ {
+ IsBusy = true;
+ ErrorCodes.GetException(ExecuteWithNoData(CONST_CMD_InitiateCapture));
+ }
+ catch (COMException comException)
+ {
+ IsBusy = false;
+ ErrorCodes.GetException(comException);
+ }
+ catch
+ {
+ IsBusy = false;
+ throw;
+ }
+ finally
+ {
+ Monitor.Exit(Locker);
+ }
+ }
+
+ public void StopEventTimer()
+ {
+ while (_eventIsbusy)
+ {
+ }
+ _timer.Stop();
+ }
+
+ public void StartEventTimer()
+ {
+ _timer.Start();
+ }
+
+ private void StillImageDevice_DeviceEvent(object sender, PortableDeviceEventArgs e)
+ {
+ if (e.EventType.EventGuid == PortableDeviceGuids.WPD_EVENT_DEVICE_REMOVED)
+ {
+ _timer.Stop();
+ StillImageDevice.Disconnect();
+ StillImageDevice.IsConnected = false;
+ IsConnected = false;
+ OnCameraDisconnected(this, new DisconnectCameraEventArgs { StillImageDevice = StillImageDevice });
+ }
+ }
+
+ public override bool DeleteObject(DeviceObject deviceObject)
+ {
+ uint res = ExecuteWithNoData(CONST_CMD_DeleteObject, (uint)deviceObject.Handle);
+ return res == 0 || res == ErrorCodes.MTP_OK;
+ }
+
+ public override AsyncObservableCollection GetObjects(object storageId, bool loadThumbs)
+ {
+ AsyncObservableCollection res = new AsyncObservableCollection();
+ MTPDataResponse response = ExecuteReadDataEx(CONST_CMD_GetObjectHandles, 0xFFFFFFFF);
+ if (response.Data == null)
+ {
+ Log.Debug("Get object error :" + response.ErrorCode.ToString("X"));
+ ErrorCodes.GetException(response.ErrorCode);
+ return res;
+ }
+ int objCount = BitConverter.ToInt32(response.Data, 0);
+ for (int i = 0; i < objCount; i++)
+ {
+ DeviceObject deviceObject = new DeviceObject();
+ uint handle = BitConverter.ToUInt32(response.Data, 4 * i + 4);
+ deviceObject.Handle = handle;
+ MTPDataResponse objectdata = ExecuteReadDataEx(CONST_CMD_GetObjectInfo, handle);
+ if (objectdata.Data != null)
+ {
+ uint objFormat = BitConverter.ToUInt16(objectdata.Data, 4);
+ if (objFormat == 0x3000 || objFormat == 0x3801 || objFormat == 0x3800)
+ {
+ deviceObject.FileName = Encoding.Unicode.GetString(objectdata.Data, 53, 12 * 2);
+ if (deviceObject.FileName.Contains("\0"))
+ deviceObject.FileName = deviceObject.FileName.Split('\0')[0];
+ try
+ {
+ string datesrt = Encoding.Unicode.GetString(objectdata.Data, 53 + (12 * 2) + 3, 30);
+ //datesrt = datesrt.Replace("T", "");
+ DateTime date = DateTime.MinValue;
+ if (DateTime.TryParseExact(datesrt, "yyyyMMddTHHmmss", CultureInfo.InvariantCulture,
+ DateTimeStyles.None, out date))
+ {
+ deviceObject.FileDate = date;
+ }
+ }
+ catch (Exception)
+ {
+ }
+
+ if (loadThumbs)
+ {
+ MTPDataResponse thumbdata = ExecuteReadDataEx(CONST_CMD_GetThumb, handle);
+ deviceObject.ThumbData = thumbdata.Data;
+ }
+ res.Add(deviceObject);
+ }
+ }
+ }
+ return res;
+ }
+
+ ///
+ /// Transfers the file and saves it to the specified filename.
+ ///
+ /// The object handle.
+ /// The filename.
+ public override void TransferFile(object o, string filename)
+ {
+ using (var fs = File.Open(filename, FileMode.Create))
+ {
+ TransferFile(o, fs);
+ }
+ }
+
+ ///
+ /// Transfers the file and writes it to the specified stream.
+ ///
+ /// The object handle.
+ /// The stream.
+ public override void TransferFile(object o, Stream stream)
+ {
+ // Sanity checks.
+ if (!stream.CanWrite)
+ throw new ArgumentException("Specified stream is not writable.", "stream");
+ lock (Locker)
+ {
+
+ string s = o as string;
+ if (s != null)
+ {
+ ((StillImageDevice)StillImageDevice).SaveFile(s, stream);
+ return;
+ }
+ int retryes = TransferRetries;
+ _timer.Stop();
+ MTPDataResponse result = new MTPDataResponse();
+ //=================== managed file write
+ do
+ {
+ try
+ {
+ //using (MemoryStream mStream = new MemoryStream())
+ //{
+
+ result = StillImageDevice.ExecuteReadBigData(CONST_CMD_GetObject, stream,
+ (total, current) =>
+ {
+ double i = (double) current / total;
+ TransferProgress =
+ Convert.ToUInt32(i * 100);
+ }, Convert.ToUInt32(o));
+ //if (result != null && result.Data != null)
+ //{
+ // stream.Write(result.Data, 0, result.Data.Length);
+ //}
+ //stream.Write(mStream.ToArray(), 0, (int)mStream.Length);
+ break;
+ //}
+ }
+ catch (COMException ex)
+ {
+ Log.Error("Transfer error", ex);
+ Thread.Sleep(200);
+ retryes--;
+ }
+
+ } while (retryes > 0);
+
+ //==================================================================
+ //=================== direct file write
+ //StillImageDevice.ExecuteReadBigDataWriteToFile(CONST_CMD_GetObject,
+ // Convert.ToInt32(o), -1,
+ // (total, current) =>
+ // {
+ // double i = (double)current / total;
+ // TransferProgress =
+ // Convert.ToUInt32(i * 100);
+
+ // }, filename);
+
+ //==================================================================
+ _timer.Start();
+ TransferProgress = 0;
+ }
+ }
+
+ public override void FormatStorage(object storageId)
+ {
+ MTPDataResponse response = ExecuteReadDataEx(CONST_CMD_GetStorageIDs);
+ if (response.Data.Length > 4)
+ {
+ int objCount = BitConverter.ToInt32(response.Data, 0);
+ for (int i = 0; i < objCount; i++)
+ {
+ uint handle = BitConverter.ToUInt32(response.Data, 4 * i + 4);
+ ErrorCodes.GetException(ExecuteWithNoData(CONST_CMD_FormatStore, handle));
+ }
+ }
+ }
+
+ public MTPDataResponse ExecuteReadDataEx(uint code, uint param1, uint param2)
+ {
+ return ExecuteReadDataEx(code, param1, param2, CONST_LOOP_TIME, 0);
+ }
+
+ public uint ExecuteWithNoData(uint code, uint param1)
+ {
+ return ExecuteWithNoData(code, param1, CONST_LOOP_TIME, 0);
+ }
+
+ public uint ExecuteWithNoData(uint code, uint param1, uint param2, uint param3)
+ {
+ return ExecuteWithNoData(code, param1, param2, param3, CONST_LOOP_TIME, 0);
+ }
+
+ public uint ExecuteWithNoData(uint code)
+ {
+ return ExecuteWithNoData(code, CONST_LOOP_TIME, 0);
+ }
+
+
+ public uint ExecuteWithNoData(uint code, uint param1, int loop, int counter)
+ {
+ uint res = 0;
+ bool allok;
+ do
+ {
+ allok = true;
+ res = StillImageDevice.ExecuteWithNoData(code, param1);
+ if ((res == ErrorCodes.MTP_Device_Busy || res == PortableDeviceErrorCodes.ERROR_BUSY) && counter < loop)
+ {
+ Thread.Sleep(CONST_READY_TIME);
+ counter++;
+ allok = false;
+ }
+ } while (!allok);
+ return res;
+ }
+
+ public uint ExecuteWithNoData(uint code, uint param1, uint param2, uint param3, int loop, int counter)
+ {
+ uint res = 0;
+ bool allok;
+ do
+ {
+ allok = true;
+ res = StillImageDevice.ExecuteWithNoData(code, param1, param2, param3);
+ if ((res == ErrorCodes.MTP_Device_Busy || res == PortableDeviceErrorCodes.ERROR_BUSY) && counter < loop)
+ {
+ Thread.Sleep(CONST_READY_TIME);
+ counter++;
+ allok = false;
+ }
+ } while (!allok);
+ return res;
+ }
+
+ public uint ExecuteWithNoData(uint code, int loop, int counter)
+ {
+ uint res = 0;
+ bool allok;
+ do
+ {
+ allok = true;
+ res = StillImageDevice.ExecuteWithNoData(code);
+ if ((res == ErrorCodes.MTP_Device_Busy || res == PortableDeviceErrorCodes.ERROR_BUSY) && counter < loop)
+ {
+ Thread.Sleep(CONST_READY_TIME);
+ counter++;
+ allok = false;
+ }
+ } while (!allok);
+ return res;
+ }
+
+ public uint ExecuteWithNoData(uint code, uint param1, uint param2)
+ {
+ uint res = StillImageDevice.ExecuteWithNoData(code, param1, param2);
+ return res;
+ }
+
+ public MTPDataResponse ExecuteReadDataEx(uint code, uint param1, uint param2, int loop, int counter)
+ {
+ DeviceIsBusy = true;
+ MTPDataResponse res = new MTPDataResponse();
+ bool allok;
+ do
+ {
+ allok = true;
+ res = StillImageDevice.ExecuteReadData(code, param1, param2);
+ if ((res.ErrorCode == ErrorCodes.MTP_Device_Busy || res.ErrorCode == PortableDeviceErrorCodes.ERROR_BUSY) &&
+ counter < loop)
+ {
+ Thread.Sleep(CONST_READY_TIME);
+ counter++;
+ allok = false;
+ }
+ } while (!allok);
+ DeviceIsBusy = false;
+ return res;
+ }
+
+ public MTPDataResponse ExecuteReadDataEx(uint code, uint param1, uint param2, uint param3, int loop, int counter)
+ {
+ DeviceIsBusy = true;
+ MTPDataResponse res = new MTPDataResponse();
+ bool allok;
+ do
+ {
+ allok = true;
+ res = StillImageDevice.ExecuteReadData(code, param1, param2, param3);
+ if ((res.ErrorCode == ErrorCodes.MTP_Device_Busy || res.ErrorCode == PortableDeviceErrorCodes.ERROR_BUSY) &&
+ counter < loop)
+ {
+ Thread.Sleep(CONST_READY_TIME);
+ counter++;
+ allok = false;
+ }
+ } while (!allok);
+ DeviceIsBusy = false;
+ return res;
+ }
+
+ public MTPDataResponse ExecuteReadDataEx(uint code, uint param1)
+ {
+ int counter = 0;
+ DeviceIsBusy = true;
+ MTPDataResponse res = new MTPDataResponse();
+ bool allok;
+ do
+ {
+ res = StillImageDevice.ExecuteReadData(code, param1);
+ allok = true;
+ if ((res.ErrorCode == ErrorCodes.MTP_Device_Busy || res.ErrorCode == PortableDeviceErrorCodes.ERROR_BUSY) &&
+ counter < CONST_LOOP_TIME)
+ {
+ Thread.Sleep(CONST_READY_TIME);
+ counter++;
+ allok = false;
+ }
+ } while (!allok);
+ DeviceIsBusy = false;
+ return res;
+ }
+
+ public MTPDataResponse ExecuteReadDataEx(uint code)
+ {
+ int counter = 0;
+ DeviceIsBusy = true;
+ MTPDataResponse res = new MTPDataResponse();
+ bool allok;
+ do
+ {
+ res = StillImageDevice.ExecuteReadData(code);
+ allok = true;
+ if ((res.ErrorCode == ErrorCodes.MTP_Device_Busy || res.ErrorCode == PortableDeviceErrorCodes.ERROR_BUSY) &&
+ counter < CONST_LOOP_TIME)
+ {
+ Thread.Sleep(CONST_READY_TIME);
+ counter++;
+ allok = false;
+ }
+ } while (!allok);
+ DeviceIsBusy = false;
+ return res;
+ }
+
+
+ public void SetProperty(uint code, byte[] data, uint param1)
+ {
+ bool timerstate = _timer.Enabled;
+ _timer.Stop();
+ bool retry = false;
+ int retrynum = 0;
+ //DeviceReady();
+ do
+ {
+ if (retrynum > 5)
+ {
+ return;
+ }
+ try
+ {
+ retry = false;
+ uint resp = StillImageDevice.ExecuteWriteData(code, data, param1);
+ if (resp != 0 || resp != ErrorCodes.MTP_OK)
+ {
+ //Console.WriteLine("Retry ...." + resp.ToString("X"));
+ if (resp == ErrorCodes.MTP_Device_Busy || resp == 0x800700AA)
+ {
+ Thread.Sleep(50);
+ retry = true;
+ retrynum++;
+ }
+ else
+ {
+ ErrorCodes.GetException(resp);
+ }
+ }
+ }
+ catch (Exception exception)
+ {
+ Log.Debug("Error set property :" + param1.ToString("X"), exception);
+ }
+ } while (retry);
+ if (timerstate)
+ _timer.Start();
+ }
+
+ public void SetProperty(uint code, byte[] data, uint param1, uint param2)
+ {
+ bool timerstate = _timer.Enabled;
+ _timer.Stop();
+ bool retry = false;
+ int retrynum = 0;
+ //DeviceReady();
+ do
+ {
+ if (retrynum > 5)
+ {
+ return;
+ }
+ try
+ {
+ retry = false;
+ uint resp = StillImageDevice.ExecuteWriteData(code, data, param1, param2);
+ if (resp != 0 || resp != ErrorCodes.MTP_OK)
+ {
+ //Console.WriteLine("Retry ...." + resp.ToString("X"));
+ if (resp == ErrorCodes.MTP_Device_Busy || resp == 0x800700AA)
+ {
+ Thread.Sleep(50);
+ retry = true;
+ retrynum++;
+ }
+ else
+ {
+ ErrorCodes.GetException(resp);
+ }
+ }
+ }
+ catch (Exception exception)
+ {
+ Log.Debug("Error set property :" + param1.ToString("X"), exception);
+ }
+ } while (retry);
+ if (timerstate)
+ _timer.Start();
+ }
+
+ public void SetProperty(uint code, byte[] data, uint param1, uint param2, uint param3)
+ {
+ bool timerstate = _timer.Enabled;
+ _timer.Stop();
+ bool retry = false;
+ int retrynum = 0;
+ //DeviceReady();
+ do
+ {
+ if (retrynum > 5)
+ {
+ return;
+ }
+ try
+ {
+ retry = false;
+ uint resp = StillImageDevice.ExecuteWriteData(code, data, param1, param2, param3);
+ if (resp != 0 || resp != ErrorCodes.MTP_OK)
+ {
+ //Console.WriteLine("Retry ...." + resp.ToString("X"));
+ if (resp == ErrorCodes.MTP_Device_Busy || resp == 0x800700AA)
+ {
+ Thread.Sleep(100);
+ retry = true;
+ retrynum++;
+ }
+ else
+ {
+ ErrorCodes.GetException(resp);
+ }
+ }
+ }
+ catch (Exception exception)
+ {
+ Log.Debug("Error set property :" + param1.ToString("X"), exception);
+ }
+ } while (retry);
+ if (timerstate)
+ _timer.Start();
+ }
+
+ public static short ToInt16(byte[] value, int startIndex)
+ {
+ int i = (short)(value[startIndex] << 8 | value[startIndex + 1]);
+ return (short)(i);
+ //return System.BitConverter.ToInt16(value.Reverse().ToArray(), value.Length - sizeof(Int16) - startIndex);
+ }
+
+ public static UInt16 ToUInt16(byte[] value, int startIndex)
+ {
+ uint i = (uint)(value[startIndex] << 8 | value[startIndex + 1]);
+ return (UInt16)(i);
+ //return System.BitConverter.ToInt16(value.Reverse().ToArray(), value.Length - sizeof(Int16) - startIndex);
+ }
+
+ public static int ToInt32(byte[] value, int startIndex)
+ {
+ int i = (value[startIndex] << 24 | value[startIndex + 1] << 16 | value[startIndex + 2] << 8 | value[startIndex + 3]);
+ return i;
+ //return System.BitConverter.ToInt16(value.Reverse().ToArray(), value.Length - sizeof(Int16) - startIndex);
+ }
+
+ public decimal ToDeciaml(byte[] value, int startIndex)
+ {
+ int i = ToUInt16(value, startIndex);
+ int d = ToUInt16(value, startIndex + 2);
+ if (d == 0 && i == 0)
+ return 0;
+ string s = i + "." + d;
+ return Convert.ToDecimal(s, new CultureInfo("en-US"));
+ }
+
+
+ protected XmlDeviceData LoadDeviceData(MTPDataResponse res)
+ {
+ XmlDeviceData deviceInfo = new XmlDeviceData();
+ ErrorCodes.GetException(res.ErrorCode);
+ deviceInfo.Manufacturer = Manufacturer;
+ int index = 2 + 4 + 2;
+ int vendorDescCount = res.Data[index];
+ index += vendorDescCount * 2;
+ index += 3;
+ int comandsCount = res.Data[index];
+ index += 2;
+ // load commands
+ for (int i = 0; i < comandsCount; i++)
+ {
+ index += 2;
+ deviceInfo.AvaiableCommands.Add(new XmlCommandDescriptor() { Code = BitConverter.ToUInt16(res.Data, index) });
+ }
+ index += 2;
+ int eventcount = res.Data[index];
+ index += 2;
+ // load events
+ for (int i = 0; i < eventcount; i++)
+ {
+ index += 2;
+ deviceInfo.AvaiableEvents.Add(new XmlEventDescriptor() { Code = BitConverter.ToUInt16(res.Data, index) });
+ }
+ index += 2;
+ int propertycount = res.Data[index];
+ index += 2;
+ // load properties codes
+ for (int i = 0; i < propertycount; i++)
+ {
+ index += 2;
+ deviceInfo.AvaiableProperties.Add(new XmlPropertyDescriptor() { Code = BitConverter.ToUInt16(res.Data, index) });
+ }
+ try
+ {
+ MTPDataResponse vendor_res = ExecuteReadDataEx(0x90CA);
+ if (vendor_res.Data.Length > 0)
+ {
+ index = 0;
+ propertycount = vendor_res.Data[index];
+ index += 2;
+ for (int i = 0; i < propertycount; i++)
+ {
+ index += 2;
+ deviceInfo.AvaiableProperties.Add(new XmlPropertyDescriptor() { Code = BitConverter.ToUInt16(vendor_res.Data, index) });
+ }
+ }
+ }
+ catch (Exception)
+ {
+ }
+ return deviceInfo;
+ }
+ }
+}
\ No newline at end of file
diff --git a/DigiCamControl/CameraControl.Devices/CameraControl.Devices.csproj b/DigiCamControl/CameraControl.Devices/CameraControl.Devices.csproj
new file mode 100644
index 0000000..e686327
--- /dev/null
+++ b/DigiCamControl/CameraControl.Devices/CameraControl.Devices.csproj
@@ -0,0 +1,312 @@
+
+
+
+ Debug
+ AnyCPU
+ 8.0.30703
+ 2.0
+ {E8572D8B-C987-4D20-BD88-1F8925A64A82}
+ Library
+ Properties
+ CameraControl.Devices
+ CameraControl.Devices
+ v4.6
+ 512
+
+
+
+
+
+ true
+ full
+ false
+ ..\..\bin\
+ DEBUG;TRACE
+ prompt
+ 4
+ false
+ AnyCPU
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+ false
+
+
+ true
+ bin\x86\Debug\
+ DEBUG;TRACE
+ full
+ x86
+ prompt
+ true
+ true
+ false
+ bin\x86\Debug\CameraControl.Devices.XML
+
+
+ bin\Release\
+ TRACE
+ true
+ none
+ x86
+ prompt
+ true
+ true
+ false
+
+
+ true
+ bin\Debug\
+ DEBUG;TRACE
+ full
+ x64
+ prompt
+ true
+ true
+ false
+
+
+ bin\x64\Release\
+ TRACE
+ true
+ x64
+ prompt
+ true
+ true
+ false
+ false
+
+
+ true
+ bin\Capture.Workflow\
+ DEBUG;TRACE
+ full
+ AnyCPU
+ prompt
+ MinimumRecommendedRules.ruleset
+
+
+ true
+ bin\x86\Capture.Workflow\
+ DEBUG;TRACE
+ full
+ x86
+ prompt
+ MinimumRecommendedRules.ruleset
+
+
+ true
+ bin\x64\Capture.Workflow\
+ DEBUG;TRACE
+ full
+ x64
+ prompt
+ MinimumRecommendedRules.ruleset
+
+
+ false
+
+
+ CameraControl.Devices.snk
+
+
+
+ ..\..\packages\Accord.3.8.2-alpha\lib\net46\Accord.dll
+
+
+ ..\..\packages\Accord.Video.3.8.0\lib\net46\Accord.Video.dll
+
+
+ ..\..\packages\Accord.Video.DirectShow.3.8.0\lib\net46\Accord.Video.DirectShow.dll
+
+
+ ..\..\refs\Interop.WIA.dll
+ True
+
+
+ ..\..\packages\Newtonsoft.Json.12.0.3\lib\net45\Newtonsoft.Json.dll
+ True
+
+
+
+
+ ..\..\packages\Rssdp.4.0.0\lib\net45\Rssdp.dll
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ..\..\packages\WebSocketSharp.1.0.3-rc11\lib\websocket-sharp.dll
+ True
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {F809DBB6-E0E8-47A8-92ED-C24575576A5D}
+ Canon.Eos.Framework
+
+
+ {E9F048C1-C6A0-4CCD-BE57-4E76A7F8B32D}
+ PortableDeviceLib
+ False
+
+
+
+
+
+
+
+
+
+
+
+ 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}.
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/DigiCamControl/CameraControl.Devices/CameraControl.Devices.snk b/DigiCamControl/CameraControl.Devices/CameraControl.Devices.snk
new file mode 100644
index 0000000..b86ef48
Binary files /dev/null and b/DigiCamControl/CameraControl.Devices/CameraControl.Devices.snk differ
diff --git a/DigiCamControl/CameraControl.Devices/CameraDeviceManager.cs b/DigiCamControl/CameraControl.Devices/CameraDeviceManager.cs
new file mode 100644
index 0000000..3a740d2
--- /dev/null
+++ b/DigiCamControl/CameraControl.Devices/CameraDeviceManager.cs
@@ -0,0 +1,1018 @@
+#region Licence
+
+// Distributed under MIT License
+// ===========================================================
+//
+// digiCamControl - DSLR camera remote control open source software
+// Copyright (C) 2014 Duka Istvan
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY,FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH
+// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#endregion
+
+#region
+
+using System;
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Runtime.ExceptionServices;
+using System.Threading;
+using CameraControl.Devices.Canon;
+using CameraControl.Devices.Classes;
+using CameraControl.Devices.Custom;
+using CameraControl.Devices.Nikon;
+using CameraControl.Devices.Others;
+using CameraControl.Devices.TransferProtocol;
+using CameraControl.Devices.TransferProtocol.DDServer;
+using CameraControl.Devices.TransferProtocol.PtpIp;
+using CameraControl.Devices.Wifi;
+using Canon.Eos.Framework;
+using PortableDeviceLib;
+using WIA;
+using Accord.Video.DirectShow;
+
+#endregion
+
+namespace CameraControl.Devices
+{
+ public class CameraDeviceManager : BaseFieldClass
+ {
+ private const string AppName = "CameraControl";
+ private const int AppMajorVersionNumber = 1;
+ private const int AppMinorVersionNumber = 0;
+ private bool _connectionInProgress = false;
+ private DeviceDescriptorEnumerator _deviceEnumerator;
+ private EosFramework _framework;
+ private object _locker = new object();
+ private List _deviceDescriptions = new List();
+
+ public ConcurrentDictionary LiveViewImage;
+ public ConcurrentDictionary LastCapturedImage;
+
+ ///
+ /// Gets or sets a value indicating whether use experimental drivers.
+ /// Experimental drivers isn't tested and may not implement all camera possibilities
+ ///
+ ///
+ /// true if [use experimental drivers]; otherwise, false.
+ ///
+ public bool UseExperimentalDrivers { get; set; }
+
+ public bool LoadWiaDevices { get; set; }
+
+ ///
+ /// Gets or sets the natively supported model dictionary.
+ /// This property is used to find the right driver for connected camera,
+ /// if model not found in this dictionary generic wia driver will used.
+ ///
+ ///
+ /// The device class.
+ ///
+ public static Dictionary DeviceClass { get; set; }
+ //Test
+ //public Dictionary CustomDeviceClass { get; set; }
+
+ public List WifiDeviceProviders { get; set; }
+
+ private ICameraDevice _selectedCameraDevice;
+
+ ///
+ /// Gets or sets the default selected camera device. When new camera connected this property set automatically to new device
+ ///
+ ///
+ /// The selected camera device.
+ ///
+ public ICameraDevice SelectedCameraDevice
+ {
+ get { return _selectedCameraDevice; }
+ set
+ {
+ ICameraDevice device = _selectedCameraDevice;
+ _selectedCameraDevice = value ?? (ConnectedDevices.Count > 0
+ ? ConnectedDevices[0]
+ : new NotConnectedCameraDevice());
+
+ CameraSelected?.Invoke(device, _selectedCameraDevice);
+
+ NotifyPropertyChanged("SelectedCameraDevice");
+ }
+ }
+
+ ///
+ /// If enabled the application will detect the connected webcams
+ ///
+ ///
+ /// true if [detect webcams]; otherwise, false.
+ ///
+ public bool DetectWebcams { get; set; }
+
+
+ public bool StartInNewThread { get; set; }
+
+ private AsyncObservableCollection _connectedDevices;
+
+ public AsyncObservableCollection ConnectedDevices
+ {
+ get { return _connectedDevices; }
+ set
+ {
+ _connectedDevices = value;
+ NotifyPropertyChanged("ConnectedDevices");
+ }
+ }
+
+ private void PopulateDeviceClass()
+ {
+
+ DeviceClass = new Dictionary
+ {
+ {"D200", typeof(NikonD40)},
+ {"D3", typeof(NikonD90)},
+ {"D3S", typeof(NikonD90)},
+ {"D3X", typeof(NikonD3X)},
+ {"D300", typeof(NikonD300)},
+ {"D300s", typeof(NikonD300)},
+ {"D300S", typeof(NikonD300)},
+ {"D3200", typeof(NikonD3200)},
+ {"D3300", typeof(NikonD3X00Base)},
+ {"D3400", typeof(NikonD3X00Base)},
+ {"D3500", typeof(NikonD3X00Base)},
+ {"D4", typeof(NikonD4)},
+ {"D4s", typeof(NikonD4)},
+ {"D4S", typeof(NikonD4)},
+ {"D40", typeof(NikonD40)},
+ {"D40X", typeof(NikonD40)},
+ {"D5", typeof(NikonD5)},
+ {"D50", typeof(NikonD40)},
+ {"D500", typeof(NikonD500)},
+ {"D5600", typeof(NikonD5200)},
+ {"D5500", typeof(NikonD5200)},
+ {"D5300", typeof(NikonD5200)},
+ {"D5200", typeof(NikonD5200)},
+ {"D5100", typeof(NikonD5100)},
+ {"D5000", typeof(NikonD90)},
+ {"D60", typeof(NikonD60)},
+ {"D610", typeof(NikonD600Base)},
+ {"D600", typeof(NikonD600)},
+ {"D70", typeof(NikonD40)},
+ {"D70s", typeof(NikonD40)},
+ {"D700", typeof(NikonD700)},
+ {"D750", typeof(NikonD750)},
+ {"D7000", typeof(NikonD7000)},
+ {"D7100", typeof(NikonD7100)},
+ {"D7200", typeof(NikonD7100)},
+ {"D7500", typeof(NikonD7500)},
+ {"D80", typeof(NikonD80)},
+ {"D800", typeof(NikonD800)},
+ {"D800E", typeof(NikonD800)},
+ {"D800e", typeof(NikonD800)},
+ {"D810", typeof(NikonD810)},
+ {"D810A", typeof(NikonD810)},
+ {"D810a", typeof(NikonD810)},
+ {"D850", typeof(NikonD850)},
+ {"D90", typeof(NikonD90)},
+ {"V1", typeof(NikonD5100)},
+ {"V2", typeof(NikonD5100)},
+ {"V3", typeof(NikonD600Base)},
+ {"J3", typeof(NikonD600Base)},
+ {"J4", typeof(NikonD600Base)},
+ {"J5", typeof(NikonD600Base)},
+ {"Df", typeof(NikonD600Base)},
+ {"L830", typeof(NikonL830)},
+ {"L840", typeof(NikonL830)},
+ {"Z 50", typeof(NikonZ6)},
+ {"Z 6", typeof(NikonZ6)},
+ {"Z 7", typeof(NikonZ7)},
+ //{"Canon EOS 5D Mark II", typeof (CanonSDKBase)},
+ {"MTP Sim", typeof(BaseMTPCamera)},
+ //{"D.*", typeof (NikonBase)},
+ // for mtp simulator
+ //{"Test Camera ", typeof (NikonBase)},
+ };
+ //if(UseExperimentalDrivers)
+ //{
+ // DeviceClass.Add("Canon EOS.*", typeof(CanonSDKBase));
+ //}
+ WifiDeviceProviders.Add(new DDServerProvider());
+ WifiDeviceProviders.Add(new PtpIpProvider());
+ WifiDeviceProviders.Add(new YiCameraProvider());
+ WifiDeviceProviders.Add(new SonyProvider());
+ WifiDeviceProviders.Add(new PanonoProvider());
+ WifiDeviceProviders.Add(new OscProvider());
+ //Test
+ /*foreach (var type in CustomDeviceClass)
+ {
+ DeviceClass.Add(type.Key, type.Value);
+ }*/
+ }
+
+ public CameraDeviceManager(string datafolder=null)
+ {
+ UseExperimentalDrivers = false;
+ LoadWiaDevices = true;
+ StartInNewThread = false;
+ DetectWebcams = false;
+ //Test
+ //CustomDeviceClass = new Dictionary();
+ SelectedCameraDevice = new NotConnectedCameraDevice();
+ ConnectedDevices = new AsyncObservableCollection();
+ _deviceEnumerator = new DeviceDescriptorEnumerator();
+ LiveViewImage = new ConcurrentDictionary();
+ LastCapturedImage = new ConcurrentDictionary();
+ WifiDeviceProviders = new List();
+
+
+ // prevent program crash in something wrong with wia
+ try
+ {
+ WiaDeviceManager = new DeviceManager();
+ WiaDeviceManager.RegisterEvent(Conts.wiaEventDeviceConnected, "*");
+ WiaDeviceManager.RegisterEvent(Conts.wiaEventDeviceDisconnected, "*");
+ WiaDeviceManager.OnEvent += DeviceManager_OnEvent;
+ Log.Error("Wia initialized");
+ }
+ catch (Exception exception)
+ {
+ Log.Error("Error initialize WIA", exception);
+ }
+ if (datafolder != null && Directory.Exists(datafolder))
+ {
+ try
+ {
+ var files = Directory.GetFiles(datafolder, "*.xml");
+ foreach (var file in files)
+ {
+ var device = DeviceDescription.Load(file);
+ if (device != null)
+ _deviceDescriptions.Add(device);
+ }
+ }
+ catch (Exception)
+ {
+ Log.Error("Error loading custom data");
+ }
+ }
+ }
+
+ private void InitCanon()
+ {
+ try
+ {
+ if (_framework == null)
+ {
+ _framework = new EosFramework();
+ _framework.CameraAdded += _framework_CameraAdded;
+ }
+ AddCanonCameras();
+ }
+ catch (Exception exception)
+ {
+ Log.Error("Unable init canon driver", exception);
+ /* Give specific guidance if the error is a missing DLL */
+ if ((exception.InnerException != null) && (exception.InnerException.Message != null) && (exception.InnerException.Message.Contains("EDSDK.dll")))
+ {
+ Console.WriteLine("\n**CRITICAL ERROR**\n\nCanon EOS camera library, EDSDK.dll is missing\nInstall it after downloading from Canon's site\n");
+ }
+ }
+ }
+
+ private void _framework_CameraAdded(object sender, EventArgs e)
+ {
+ AddCanonCameras();
+ }
+
+ public IEnumerable GetEosCameras()
+ {
+ using (EosCameraCollection cameras = _framework.GetCameraCollection())
+ return cameras.ToArray();
+ }
+
+ private void AddWebcameras()
+ {
+ try
+ {
+ List monikers = new List();
+ var loaclWebCamsCollection = new FilterInfoCollection(FilterCategory.VideoInputDevice);
+ foreach (Accord.Video.DirectShow.FilterInfo localcamera in loaclWebCamsCollection)
+ {
+ monikers.Add(localcamera.MonikerString);
+ bool added = false;
+ foreach (ICameraDevice device in ConnectedDevices)
+ {
+ WebCameraDevice webCamera = device as WebCameraDevice;
+ if (webCamera != null)
+ {
+ if (webCamera.PortName == localcamera.MonikerString)
+ {
+ added = true;
+ }
+ }
+ }
+
+ if (added)
+ continue;
+
+ WebCameraDevice camera = new WebCameraDevice();
+ camera.Init(localcamera.MonikerString);
+ camera.DeviceName = localcamera.Name;
+ camera.SerialNumber = localcamera.MonikerString;
+
+ ConnectedDevices.Add(camera);
+
+ SelectedCameraDevice = camera;
+
+ camera.PhotoCaptured += cameraDevice_PhotoCaptured;
+ camera.CameraDisconnected += cameraDevice_CameraDisconnected;
+
+ CameraConnected?.Invoke(camera);
+ }
+ //List devicesToDisconnect = ConnectedDevices.OfType()
+ // .Where(webCamera => !monikers.Contains(webCamera.PortName))
+ // .ToList();
+ //foreach (var webCamera in devicesToDisconnect)
+ //{
+ // cameraDevice_CameraDisconnected(webCamera, new DisconnectCameraEventArgs() { });
+ //}
+ }
+ catch (Exception ex)
+ {
+ Log.Error("Unable to connect to a webcamera", ex);
+ }
+
+ }
+
+ private void AddCanonCameras()
+ {
+ lock (_locker)
+ {
+ foreach (EosCamera eosCamera in GetEosCameras())
+ {
+ bool shouldbeadded =
+ ConnectedDevices.OfType().All(camera => camera.PortName != eosCamera.PortName);
+
+ if (shouldbeadded)
+ {
+ Log.Debug("New canon camera found !");
+ CanonSDKBase camera = new CanonSDKBase();
+ Log.Debug("Pas 1");
+ DeviceDescriptor descriptor = new DeviceDescriptor {EosCamera = eosCamera};
+ descriptor.CameraDevice = camera;
+ Log.Debug("Pas 2");
+ camera.Init(eosCamera);
+ Log.Debug("Pas 3");
+ ConnectedDevices.Add(camera);
+ Log.Debug("Pas 4");
+ _deviceEnumerator.Add(descriptor);
+ Log.Debug("Pas 5");
+ NewCameraConnected(camera);
+ Log.Debug("New canon camera found done!");
+ }
+ }
+ //Thread.Sleep(2500);
+ }
+ }
+
+ private ICameraDevice GetWiaIDevice(IDeviceInfo devInfo)
+ {
+ // if camera already is connected do nothing
+ if (_deviceEnumerator.GetByWiaId(devInfo.DeviceID) != null)
+ return _deviceEnumerator.GetByWiaId(devInfo.DeviceID).CameraDevice;
+ _deviceEnumerator.RemoveDisconnected();
+ DeviceDescriptor descriptor = new DeviceDescriptor {WiaDeviceInfo = devInfo, WiaId = devInfo.DeviceID};
+
+ ICameraDevice cameraDevice = new WiaCameraDevice();
+ bool isConnected = cameraDevice.Init(descriptor);
+
+ descriptor.CameraDevice = cameraDevice;
+ _deviceEnumerator.Add(descriptor);
+ ConnectedDevices.Add(cameraDevice);
+
+ if (isConnected)
+ {
+ NewCameraConnected(cameraDevice);
+ }
+ //ServiceProvider.DeviceManager.SelectedCameraDevice.ReadDeviceProperties(0);
+
+ return SelectedCameraDevice;
+ }
+
+ private void cameraDevice_CameraDisconnected(object sender, DisconnectCameraEventArgs e)
+ {
+ if (e.StillImageDevice != null)
+ {
+ DisconnectCamera(e.StillImageDevice);
+ }
+ if (e.EosCamera != null)
+ {
+ DisconnectCamera(e.EosCamera);
+ }
+ OnCameraDisconnected((ICameraDevice) sender);
+ }
+
+ ///
+ /// Raise CameraDisconnected event.
+ ///
+ /// The camera device.
+ public void OnCameraDisconnected(ICameraDevice cameraDevice)
+ {
+ if (CameraDisconnected != null)
+ CameraDisconnected(cameraDevice);
+ }
+
+ private void cameraDevice_PhotoCaptured(object sender, PhotoCapturedEventArgs eventArgs)
+ {
+ if (PhotoCaptured != null)
+ PhotoCaptured(sender, eventArgs);
+ }
+
+ public void OnPhotoCaptured(object sender, PhotoCapturedEventArgs eventArgs)
+ {
+ if (PhotoCaptured != null)
+ PhotoCaptured(sender, eventArgs);
+ }
+
+ private void ConnectDevices()
+ {
+ if (_connectionInProgress)
+ return;
+ _connectionInProgress = true;
+ if (PortableDeviceCollection.Instance == null)
+ {
+ PortableDeviceCollection.CreateInstance(AppName, AppMajorVersionNumber, AppMinorVersionNumber);
+ PortableDeviceCollection.Instance.AutoConnectToPortableDevice = false;
+ }
+ _deviceEnumerator.RemoveDisconnected();
+
+ Log.Debug("Connection device start" );
+ try
+ {
+ var devices = PortableDeviceCollection.Instance.Devices;
+ foreach (PortableDevice portableDevice in devices)
+ {
+ Log.Debug("Connection device " + portableDevice.DeviceId);
+ //TODO: avoid to load some mass storage in my computer need to find a general solution
+ if (!portableDevice.DeviceId.StartsWith("\\\\?\\usb") &&
+ !portableDevice.DeviceId.StartsWith("\\\\?\\comp"))
+ continue;
+ // ignore some Canon cameras
+ if (!SupportedCanonCamera(portableDevice.DeviceId))
+ continue;
+ portableDevice.ConnectToDevice(AppName, AppMajorVersionNumber, AppMinorVersionNumber);
+
+ if (_deviceEnumerator.GetByWpdId(portableDevice.DeviceId) == null &&
+ GetNativeDriver(portableDevice.Model) != null)
+ {
+ ICameraDevice cameraDevice;
+ DeviceDescriptor descriptor = new DeviceDescriptor {WpdId = portableDevice.DeviceId};
+ cameraDevice = (ICameraDevice) Activator.CreateInstance(GetNativeDriver(portableDevice.Model));
+ MtpProtocol device = new MtpProtocol(descriptor.WpdId);
+ device.ConnectToDevice(AppName, AppMajorVersionNumber, AppMinorVersionNumber);
+
+ descriptor.StillImageDevice = device;
+
+ cameraDevice.SerialNumber = StaticHelper.GetSerial(portableDevice.DeviceId);
+ cameraDevice.Init(descriptor);
+
+ if (string.IsNullOrWhiteSpace(cameraDevice.SerialNumber))
+ cameraDevice.SerialNumber = StaticHelper.GetSerial(portableDevice.DeviceId);
+
+ ConnectedDevices.Add(cameraDevice);
+ NewCameraConnected(cameraDevice);
+
+ descriptor.CameraDevice = cameraDevice;
+ _deviceEnumerator.Add(descriptor);
+ }
+
+ if (_deviceEnumerator.GetByWpdId(portableDevice.DeviceId) == null &&
+ GetNativeDriver(portableDevice.Model) == null)
+ {
+ var description = getDeviceDescription(portableDevice.Model);
+ if (description != null)
+ {
+ CustomDevice cameraDevice = new CustomDevice();
+ DeviceDescriptor descriptor = new DeviceDescriptor {WpdId = portableDevice.DeviceId};
+ MtpProtocol device = new MtpProtocol(descriptor.WpdId);
+ device.ConnectToDevice(AppName, AppMajorVersionNumber, AppMinorVersionNumber);
+
+ descriptor.StillImageDevice = device;
+
+ cameraDevice.SerialNumber = StaticHelper.GetSerial(portableDevice.DeviceId);
+ cameraDevice.Init(descriptor, description);
+
+ ConnectedDevices.Add(cameraDevice);
+ NewCameraConnected(cameraDevice);
+
+ descriptor.CameraDevice = cameraDevice;
+ _deviceEnumerator.Add(descriptor);
+ break;
+ }
+
+ }
+
+ }
+
+ }
+ catch (Exception exception)
+ {
+ Log.Error("Unable to connect to cameras ", exception);
+ }
+
+ _connectionInProgress = false;
+ }
+
+ private DeviceDescription getDeviceDescription(string model)
+ {
+ return _deviceDescriptions.FirstOrDefault(description => description.Model == model);
+ }
+
+ public void AddDevice(DeviceDescriptor descriptor)
+ {
+ _deviceEnumerator.RemoveDisconnected();
+ ConnectedDevices.Add(descriptor.CameraDevice);
+ NewCameraConnected(descriptor.CameraDevice);
+ _deviceEnumerator.Add(descriptor);
+ }
+
+ public void ConnectToServer(string s, int type)
+ {
+ if(string.IsNullOrEmpty(s))
+ return;
+
+ if (type == 0)
+ {
+ int port = 15740;
+ string ip = s;
+ if (s.Contains(":"))
+ {
+ ip = s.Split(':')[0];
+ int.TryParse(s.Split(':')[1], out port);
+ }
+ ConnectDevicesPtpIp(ip, port);
+ }
+
+ if (type == 1)
+ {
+ int port = 4757;
+ string ip = s;
+ if (s.Contains(":"))
+ {
+ ip = s.Split(':')[0];
+ int.TryParse(s.Split(':')[1], out port);
+ }
+ ConnectDevicesDDServer(ip, port);
+ }
+ }
+
+ public void ConnectDevicesDDServer(string ip, int port)
+ {
+ if (_connectionInProgress)
+ return;
+ try
+ {
+ _connectionInProgress = true;
+ _deviceEnumerator.RemoveDisconnected();
+ DdClient client = new DdClient();
+ if (!client.Open(ip, port))
+ throw new Exception("No server was found!");
+ var devices = client.GetDevices();
+ if (devices.Count == 0)
+ throw new Exception("No connected device was found!");
+
+ client.Connect(devices[0]);
+ DdServerProtocol protocol = new DdServerProtocol(client);
+
+ if (GetNativeDriver(protocol.Model) != null)
+ {
+ ICameraDevice cameraDevice;
+ DeviceDescriptor descriptor = new DeviceDescriptor {WpdId = "ddserver"};
+ cameraDevice = (ICameraDevice) Activator.CreateInstance(GetNativeDriver(protocol.Model));
+ descriptor.StillImageDevice = protocol;
+
+ //cameraDevice.SerialNumber = StaticHelper.GetSerial(portableDevice.DeviceId);
+ cameraDevice.Init(descriptor);
+ ConnectedDevices.Add(cameraDevice);
+ NewCameraConnected(cameraDevice);
+
+ descriptor.CameraDevice = cameraDevice;
+ _deviceEnumerator.Add(descriptor);
+ }
+ else
+ {
+ throw new Exception("Not Supported device " + protocol.Model);
+ }
+ }
+ finally
+ {
+ _connectionInProgress = false;
+ }
+ }
+
+ public void ConnectDevicesPtpIp(string ip, int port)
+ {
+ if (_connectionInProgress)
+ return;
+ try
+ {
+ _connectionInProgress = true;
+ _deviceEnumerator.RemoveDisconnected();
+
+ PtpIpClient client = new PtpIpClient();
+ if (!client.Open(ip, 15740))
+ throw new Exception("No server was found!");
+ PtpIpProtocol protocol = new PtpIpProtocol(client);
+ protocol.ExecuteWithNoData(0x1002, 1);
+
+ if (GetNativeDriver(protocol.Model) != null)
+ {
+ ICameraDevice cameraDevice;
+ DeviceDescriptor descriptor = new DeviceDescriptor { WpdId = "ptpip" };
+ cameraDevice = (ICameraDevice)Activator.CreateInstance(GetNativeDriver(protocol.Model));
+ descriptor.StillImageDevice = protocol;
+
+ //cameraDevice.SerialNumber = StaticHelper.GetSerial(portableDevice.DeviceId);
+ cameraDevice.Init(descriptor);
+ ConnectedDevices.Add(cameraDevice);
+ NewCameraConnected(cameraDevice);
+
+ descriptor.CameraDevice = cameraDevice;
+ _deviceEnumerator.Add(descriptor);
+ }
+ else
+ {
+ throw new Exception("Not Supported device " + protocol.Model);
+ }
+ }
+ finally
+ {
+ _connectionInProgress = false;
+ }
+ }
+
+ private bool SupportedCanonCamera(string id)
+ {
+ // isn't canon the manufacturer
+ if (!id.Contains("vid_04a9"))
+ return true;
+ return false;
+ }
+
+
+ private void NewCameraConnected(ICameraDevice cameraDevice)
+ {
+ const string usbPrefix = "\\\\?\\usb";
+
+ StaticHelper.Instance.SystemMessage = "New Camera is connected ! Driver :" + cameraDevice.DeviceName;
+ Log.Debug("===========Camera is connected==============");
+
+ if (cameraDevice.PortName != null && cameraDevice.PortName.Substring(0, usbPrefix.Length).Equals(usbPrefix))
+ {
+ string vid = "";
+ string pid = "";
+ char[] delimiterChars = { '#', '&', '_' };
+
+ string[] words = cameraDevice.PortName.Split(delimiterChars);
+
+ for (int i = 1; i < words.Length - 1; i++)
+ {
+ if (words[i].Equals("pid"))
+ pid = words[i + 1];
+ else if (words[i].Equals("vid"))
+ vid = words[i + 1];
+ }
+
+ if (!vid.Equals("") && !pid.Equals(""))
+ Log.Debug("USB : VID=" + vid + ", PID=" + pid);
+ }
+
+ Log.Debug("Driver :" + cameraDevice.GetType().Name);
+ Log.Debug("Name :" + cameraDevice.DeviceName);
+ Log.Debug("Manufacturer :" + cameraDevice.Manufacturer);
+ if (CameraConnected != null)
+ CameraConnected(cameraDevice);
+ SelectedCameraDevice = cameraDevice;
+ cameraDevice.PhotoCaptured += cameraDevice_PhotoCaptured;
+ cameraDevice.CameraDisconnected += cameraDevice_CameraDisconnected;
+ }
+
+ ///
+ /// Gets the native driver based on camera model.
+ ///
+ /// The model name.
+ /// If the model not supported return null else the driver type
+ public static Type GetNativeDriver(string model)
+ {
+ if (String.IsNullOrEmpty(model))
+ return null;
+ // first check if driver exist with same driver name
+ if (DeviceClass.ContainsKey(model))
+ return DeviceClass[model];
+ return null;
+ //// in driver not found will check with regex name
+ //return (from keyValuePair in DeviceClass
+ // let regex = new Regex(keyValuePair.Key)
+ // where regex.IsMatch(model)
+ // select keyValuePair.Value).FirstOrDefault();
+ }
+
+ [HandleProcessCorruptedStateExceptions]
+ public void DisconnectCamera(ICameraDevice cameraDevice)
+ {
+
+ cameraDevice.PhotoCaptured -= cameraDevice_PhotoCaptured;
+ cameraDevice.CameraDisconnected -= cameraDevice_CameraDisconnected;
+ ConnectedDevices.Remove(cameraDevice);
+ StaticHelper.Instance.SystemMessage = "Camera disconnected :" + cameraDevice.DeviceName;
+ Log.Debug("===========Camera disconnected==============");
+ Log.Debug("Name :" + cameraDevice.DeviceName);
+
+ cameraDevice.Close();
+ OnCameraDisconnected(cameraDevice);
+ }
+
+ private void DisconnectCamera(string wiaId)
+ {
+ DeviceDescriptor descriptor = _deviceEnumerator.GetByWiaId(wiaId);
+ if (descriptor != null)
+ {
+ descriptor.CameraDevice.PhotoCaptured -= cameraDevice_PhotoCaptured;
+ descriptor.CameraDevice.CameraDisconnected -= cameraDevice_CameraDisconnected;
+ ConnectedDevices.Remove(descriptor.CameraDevice);
+ StaticHelper.Instance.SystemMessage = "Camera disconnected :" + descriptor.CameraDevice.DeviceName;
+ Log.Debug("===========Camera disconnected==============");
+ Log.Debug("Name :" + descriptor.CameraDevice.DeviceName);
+
+ _deviceEnumerator.Remove(descriptor);
+ descriptor.CameraDevice.Close();
+ var wiaCameraDevice = descriptor.CameraDevice as WiaCameraDevice;
+ if (wiaCameraDevice != null)
+ {
+ OnCameraDisconnected(wiaCameraDevice);
+ }
+ if (PortableDeviceCollection.Instance != null)
+ PortableDeviceCollection.Instance.RefreshDevices();
+ }
+ }
+
+ private void DisconnectCamera(ITransferProtocol device)
+ {
+ DeviceDescriptor descriptor = _deviceEnumerator.GetByWpdId(device.DeviceId);
+ if (descriptor != null)
+ {
+ descriptor.CameraDevice.PhotoCaptured -= cameraDevice_PhotoCaptured;
+ descriptor.CameraDevice.CameraDisconnected -= cameraDevice_CameraDisconnected;
+ StaticHelper.Instance.SystemMessage = "Camera disconnected :" + descriptor.CameraDevice.DeviceName;
+ Log.Debug("===========Camera disconnected==============");
+ Log.Debug("Name :" + descriptor.CameraDevice.DeviceName);
+ PortableDeviceCollection.Instance.RemoveDevice(device.DeviceId);
+ device.IsConnected = false;
+ ConnectedDevices.Remove(descriptor.CameraDevice);
+ descriptor.CameraDevice.Close();
+ _deviceEnumerator.Remove(descriptor);
+ _deviceEnumerator.RemoveDisconnected();
+ }
+ RemoveDisconnected();
+ }
+
+ private void DisconnectCamera(EosCamera device)
+ {
+ DeviceDescriptor descriptor = _deviceEnumerator.GetByEosCamera(device);
+ if (descriptor != null)
+ {
+ descriptor.CameraDevice.PhotoCaptured -= cameraDevice_PhotoCaptured;
+ descriptor.CameraDevice.CameraDisconnected -= cameraDevice_CameraDisconnected;
+ StaticHelper.Instance.SystemMessage = "Camera disconnected :" + descriptor.CameraDevice.DeviceName;
+ Log.Debug("===========Camera disconnected==============");
+ Log.Debug("Name :" + descriptor.CameraDevice.DeviceName);
+ ConnectedDevices.Remove(descriptor.CameraDevice);
+ descriptor.CameraDevice.Close();
+ _deviceEnumerator.Remove(descriptor);
+ _deviceEnumerator.RemoveDisconnected();
+ }
+ RemoveDisconnected();
+ }
+
+ private void RemoveDisconnected()
+ {
+ List removedCameras = ConnectedDevices.Where(device => !device.IsConnected).ToList();
+ foreach (ICameraDevice device in removedCameras)
+ {
+ ConnectedDevices.Remove(device);
+ }
+ }
+
+ private DeviceManager WiaDeviceManager { get; set; }
+
+ ///
+ /// Gets or sets a value for disabling native drivers.
+ ///
+ ///
+ /// true all devices are loaded like WIA devices false If native driver are available for connected model the will be loaded that driver else will be loaded WIA driver.
+ ///
+ public bool DisableNativeDrivers { get; set; }
+
+
+ private void DeviceManager_OnEvent(string eventId, string deviceId, string itemId)
+ {
+ //if (!LoadWiaDevices)
+ // return;
+
+ if (eventId == Conts.wiaEventDeviceConnected)
+ {
+ if (StartInNewThread)
+ {
+ Thread _thread = new Thread(() => ConnectToCamera(true));
+ _thread.SetApartmentState(ApartmentState.MTA);
+ _thread.Start();
+ }
+ else
+ {
+ ConnectToCamera(true);
+ }
+ }
+ else if (eventId == Conts.wiaEventDeviceDisconnected)
+ {
+ DisconnectCamera(deviceId);
+ }
+ }
+
+
+ public bool ConnectToCamera()
+ {
+ if (UseExperimentalDrivers)
+ InitCanon();
+ return ConnectToCamera(true);
+ }
+
+ public void AddFakeCamera()
+ {
+ FakeCameraDevice device = new FakeCameraDevice();
+ ConnectedDevices.Add(device);
+ NewCameraConnected(device);
+ }
+
+ ///
+ /// Populate the ConnectedDevices list with connected cameras. This method will be called automatically every time new devices will be connected
+ /// Except Canon cameras that is handled by framework event handler
+ ///
+ ///
+ public bool ConnectToCamera(bool retry)
+ {
+ if (DeviceClass == null || DeviceClass.Count == 0)
+ PopulateDeviceClass();
+
+ if(DetectWebcams)
+ AddWebcameras();
+
+ if (!DisableNativeDrivers)
+ {
+ ConnectDevices();
+ }
+ else
+ {
+ Log.Debug("Native drivers are disabled !!!!");
+ }
+ // if canon camera is connected don't use wia driver
+ if (UseExperimentalDrivers && _framework != null && _framework.GetCameraCollection().Count > 0)
+ return true;
+
+ if (!LoadWiaDevices)
+ return true;
+
+ bool ret = false;
+ bool noDriversDetected = ConnectedDevices.Count == 0;
+ int retries = 0;
+ foreach (IDeviceInfo devInfo in new DeviceManager().DeviceInfos)
+ {
+ // Look for CameraDeviceType devices
+ string model = devInfo.Properties["Name"].get_Value();
+ // skip canon cameras
+ //if (!string.IsNullOrEmpty(model) && model.Contains("Canon"))
+ // continue;
+ if (getDeviceDescription(model) != null)
+ continue;
+
+ var nativeDriver = GetNativeDriver(model);
+ ret = nativeDriver != null;
+
+ if ((devInfo.Type == WiaDeviceType.CameraDeviceType || devInfo.Type == WiaDeviceType.VideoDeviceType)
+ && (nativeDriver == null || DisableNativeDrivers || noDriversDetected) && retries < 3)
+ {
+ do
+ {
+ Log.Debug("Wia Camera Found: " + model);
+ try
+ {
+ GetWiaIDevice(devInfo);
+ retries = 4;
+ ret = true;
+ }
+ catch (Exception exception)
+ {
+ Log.Error("Unable to connect to the camera", exception);
+ retries++;
+ if (retries < 3)
+ {
+ Log.Debug("Retrying");
+ StaticHelper.Instance.SystemMessage = "Unable to connect to the camera. Retrying";
+ }
+ else
+ {
+ StaticHelper.Instance.SystemMessage =
+ "Unable to connect to the camera. Please reconnect your camera !";
+ }
+ Thread.Sleep(1000);
+ }
+ } while (retries < 3);
+ }
+ }
+ return ret;
+ }
+
+ public void CloseAll()
+ {
+ foreach (
+ ICameraDevice connectedDevice in ConnectedDevices.Where(connectedDevice => connectedDevice.IsConnected))
+ {
+ connectedDevice.Close();
+ }
+ }
+
+ public event PhotoCapturedEventHandler PhotoCaptured;
+
+ public delegate void CameraConnectedEventHandler(ICameraDevice cameraDevice);
+
+ ///
+ /// Occurs when a new camera is connected.
+ ///
+ public event CameraConnectedEventHandler CameraConnected;
+
+ ///
+ /// Occurs when a camera disconnected.
+ ///
+ public event CameraConnectedEventHandler CameraDisconnected;
+
+ public delegate void CameraSelectedEventHandler(ICameraDevice oldcameraDevice, ICameraDevice newcameraDevice);
+
+ ///
+ /// Occurs when SelectedCameraDevice property changed.
+ ///
+ public event CameraSelectedEventHandler CameraSelected;
+
+
+ public void SelectNextCamera()
+ {
+ if (ConnectedDevices.Count == 0)
+ return;
+ int idx = 0;
+ for (int i = 0; i < ConnectedDevices.Count; i++)
+ {
+ var device = ConnectedDevices[i];
+ if (device == SelectedCameraDevice)
+ {
+ idx = i;
+ break;
+ }
+ }
+ idx++;
+ if (idx < ConnectedDevices.Count)
+ SelectedCameraDevice = ConnectedDevices[idx];
+ }
+
+ public void SelectPrevCamera()
+ {
+ if (ConnectedDevices.Count == 0)
+ return;
+ int idx = 0;
+ for (int i = 0; i < ConnectedDevices.Count; i++)
+ {
+ var device = ConnectedDevices[i];
+ if (device == SelectedCameraDevice)
+ {
+ idx = i;
+ break;
+ }
+ }
+ idx--;
+ if (idx >= 0)
+ SelectedCameraDevice = ConnectedDevices[idx];
+ }
+ }
+}
\ No newline at end of file
diff --git a/DigiCamControl/CameraControl.Devices/Canon/CanonBase.cs b/DigiCamControl/CameraControl.Devices/Canon/CanonBase.cs
new file mode 100644
index 0000000..6d79c14
--- /dev/null
+++ b/DigiCamControl/CameraControl.Devices/Canon/CanonBase.cs
@@ -0,0 +1,473 @@
+#region Licence
+
+// Distributed under MIT License
+// ===========================================================
+//
+// digiCamControl - DSLR camera remote control open source software
+// Copyright (C) 2014 Duka Istvan
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY,FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH
+// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#endregion
+
+#region
+
+using System;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+using System.Text;
+using System.Threading;
+using CameraControl.Devices.Classes;
+using PortableDeviceLib;
+using PortableDeviceLib.Model;
+
+#endregion
+
+namespace CameraControl.Devices.Canon
+{
+ public class CanonBase : BaseMTPCamera
+ {
+ public const int CONST_CMD_CANON_EOS_RemoteRelease = 0x910F;
+ public const int CONST_CMD_CANON_EOS_BulbStart = 0x9125;
+ public const int CONST_CMD_CANON_EOS_BulbEnd = 0x9126;
+ public const int CONST_CMD_CANON_EOS_SetEventMode = 0x9115;
+ public const int CONST_CMD_CANON_EOS_SetRemoteMode = 0x9114;
+ public const int CONST_CMD_CANON_EOS_GetEvent = 0x9116;
+ public const int CONST_CMD_CANON_EOS_DoAf = 0x9154;
+ public const int CONST_CMD_CANON_EOS_GetViewFinderData = 0x9153;
+ public const int CONST_CMD_CANON_EOS_GetObjectInfo = 0x9103;
+
+ public const int CONST_CMD_CANON_EOS_SetDevicePropValueEx = 0x9110;
+ public const int CONST_CMD_CANON_EOS_RequestDevicePropValue = 0x9109;
+
+ public const int CONST_PROP_EOS_ShutterSpeed = 0xD102;
+ public const int CONST_PROP_EOS_LiveView = 0xD1B0;
+
+ public const int CONST_Event_CANON_EOS_PropValueChanged = 0xc189;
+ public const int CONST_Event_CANON_EOS_ObjectAddedEx = 0xc181;
+
+ //private bool _eventIsbusy = false;
+
+ protected Dictionary _shutterTable = new Dictionary
+ {
+ {0, "30"},
+ {1, "25"},
+ {2, "20"},
+ {3, "15"},
+ {4, "13"},
+ {5, "10"},
+ {6, "8"},
+ {7, "6"},
+ {8, "5"},
+ {9, "4"},
+ {10, "3.2"},
+ {11, "2.5"},
+ {12, "2"},
+ {13, "1.6"},
+ {14, "1.3"},
+ {15, "1"},
+ {16, "0.8"},
+ {17, "0.6"},
+ {18, "0.5"},
+ {19, "0.4"},
+ {20, "0.3"},
+ {21, "1/4"},
+ {22, "1/5"},
+ {23, "1/6"},
+ {24, "1/8"},
+ {25, "1/10"},
+ {26, "1/13"},
+ {27, "1/15"},
+ {28, "1/20"},
+ {29, "1/25"},
+ {30, "1/30"},
+ {31, "1/40"},
+ {32, "1/50"},
+ {33, "1/60"},
+ {34, "1/80"},
+ {35, "1/100"},
+ {36, "1/125"},
+ {37, "1/160"},
+ {38, "1/200"},
+ {39, "1/250"},
+ {40, "1/320"},
+ {41, "1/400"},
+ {42, "1/500"},
+ {43, "1/640"},
+ {44, "1/800"},
+ {45, "1/1000"},
+ {46, "1/1250"},
+ {47, "1/1600"},
+ {48, "1/2000"},
+ {49, "1/2500"},
+ {50, "1/3200"},
+ {51, "1/4000"},
+ {52, "1/5000"},
+ {53, "1/6400"},
+ {54, "1/8000"}
+ };
+
+ public CanonBase()
+ {
+ _timer.AutoReset = true;
+ _timer.Elapsed += _timer_Elapsed;
+ }
+
+ private void _timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
+ {
+ _timer.Stop();
+ try
+ {
+ lock (Locker)
+ {
+ Thread thread = new Thread(getEvent);
+ thread.Start();
+ }
+ }
+ catch (Exception)
+ {
+ }
+ //
+ }
+
+
+ private void getEvent()
+ {
+ try
+ {
+ if (_eventIsbusy)
+ return;
+ _eventIsbusy = true;
+ //DeviceReady();
+ MTPDataResponse response = ExecuteReadDataEx(CONST_CMD_CANON_EOS_GetEvent);
+
+ if (response.Data == null)
+ {
+ Log.Debug("Get event error :" + response.ErrorCode.ToString("X"));
+ return;
+ }
+ int eventCount = BitConverter.ToInt16(response.Data, 0);
+ Log.Debug("Number of events " + eventCount);
+ if (eventCount > 0)
+ {
+ Console.WriteLine("Event queue length " + eventCount);
+ for (int i = 0; i < eventCount; i++)
+ {
+ try
+ {
+ uint eventCode = BitConverter.ToUInt16(response.Data, 6*i + 2);
+ ushort eventParam = BitConverter.ToUInt16(response.Data, 6*i + 4);
+ int longeventParam = BitConverter.ToInt32(response.Data, 6*i + 4);
+ switch (eventCode)
+ {
+ case CONST_Event_CANON_EOS_PropValueChanged:
+ Log.Debug("EOS property changed " + eventParam.ToString("X"));
+ //ReadDeviceProperties(eventParam);
+ break;
+ case CONST_Event_CANON_EOS_ObjectAddedEx:
+ case CONST_Event_ObjectAddedInSdram:
+ case CONST_Event_ObjectAdded:
+ {
+ try
+ {
+ MTPDataResponse objectdata =
+ ExecuteReadDataEx(CONST_CMD_CANON_EOS_GetObjectInfo,
+ (uint) longeventParam);
+ string filename = "DSC_0000.JPG";
+ if (objectdata.Data != null)
+ {
+ filename = Encoding.Unicode.GetString(objectdata.Data, 53, 12*2);
+ if (filename.Contains("\0"))
+ filename = filename.Split('\0')[0];
+ }
+ else
+ {
+ Log.Error("Error getting file name");
+ }
+ Log.Debug("File transfer " + filename);
+ PhotoCapturedEventArgs args = new PhotoCapturedEventArgs
+ {
+ WiaImageItem = null,
+ EventArgs =
+ new PortableDeviceEventArgs(new PortableDeviceEventType
+ ()
+ {
+ ObjectHandle
+ =
+ (
+ uint
+ )
+ longeventParam
+ }),
+ CameraDevice = this,
+ FileName = filename,
+ Handle = (uint) longeventParam
+ };
+ OnPhotoCapture(this, args);
+ }
+ catch (Exception exception)
+ {
+ Log.Error("Object added error", exception);
+ }
+ }
+ break;
+ //case CONST_Event_CaptureComplete:
+ //case CONST_Event_CaptureCompleteRecInSdram:
+ // {
+ // OnCaptureCompleted(this, new EventArgs());
+ // }
+ // break;
+ //case CONST_Event_ObsoleteEvent:
+ // break;
+ default:
+ //Console.WriteLine("Unknown event code " + eventCode.ToString("X"));
+ Log.Debug("Unknown event code :" + eventCode.ToString("X") + "|" +
+ longeventParam.ToString("X"));
+ break;
+ }
+ }
+ catch (Exception exception)
+ {
+ Log.Error("Event queue processing error ", exception);
+ }
+ }
+ }
+ }
+ catch (InvalidComObjectException)
+ {
+ return;
+ }
+ catch (Exception)
+ {
+ //Log.Error("Event exception ", exception);
+ }
+ _eventIsbusy = false;
+ _timer.Start();
+ }
+
+ public override bool Init(DeviceDescriptor deviceDescriptor)
+ {
+ StillImageDevice = deviceDescriptor.StillImageDevice;
+ //StillImageDevice.ConnectToDevice(AppName, AppMajorVersionNumber, AppMinorVersionNumber);
+ //StillImageDevice.DeviceEvent += _stillImageDevice_DeviceEvent;
+ DeviceName = StillImageDevice.Model;
+ Manufacturer = StillImageDevice.Manufacturer;
+ Capabilities.Add(CapabilityEnum.Bulb);
+ Capabilities.Add(CapabilityEnum.LiveView);
+ InitShutterSpeed();
+ IsConnected = true;
+ ExecuteWithNoData(CONST_CMD_CANON_EOS_SetRemoteMode, 1);
+ ExecuteWithNoData(CONST_CMD_CANON_EOS_SetEventMode, 1);
+ _timer.Start();
+ return true;
+ }
+
+ private void InitShutterSpeed()
+ {
+ ShutterSpeed = new PropertyValue();
+ ShutterSpeed.Name = "ShutterSpeed";
+ ShutterSpeed.ValueChanged += ShutterSpeed_ValueChanged;
+ ReInitShutterSpeed();
+ }
+
+ private void ReInitShutterSpeed()
+ {
+ lock (Locker)
+ {
+ try
+ {
+ //byte datasize = 4;
+ ShutterSpeed.Clear();
+ foreach (KeyValuePair keyValuePair in _shutterTable)
+ {
+ ShutterSpeed.AddValues(keyValuePair.Value, keyValuePair.Key);
+ }
+ //byte[] result = StillImageDevice.ExecuteReadData(CONST_CMD_GetDevicePropDesc, CONST_PROP_EOS_ShutterSpeed);
+ //int type = BitConverter.ToInt16(result, 2);
+ //byte formFlag = result[(2 * datasize) + 5];
+ //UInt32 defval = BitConverter.ToUInt32(result, datasize + 5);
+ //for (int i = 0; i < result.Length - ((2 * datasize) + 6 + 2); i += datasize)
+ //{
+ // UInt32 val = BitConverter.ToUInt32(result, ((2 * datasize) + 6 + 2) + i);
+ // ShutterSpeed.AddValues(_shutterTable.ContainsKey(val) ? _shutterTable[val] : val.ToString(), val);
+ //}
+ //ShutterSpeed.SetValue(defval);
+ }
+ catch (Exception ex)
+ {
+ Log.Debug("EOS Shutter speed init", ex);
+ }
+ }
+ }
+
+ private void ShutterSpeed_ValueChanged(object sender, string key, long val)
+ {
+ SetProperty(CONST_CMD_CANON_EOS_SetDevicePropValueEx, BitConverter.GetBytes(val),
+ CONST_PROP_EOS_ShutterSpeed);
+ SetEOSProperty(CONST_PROP_EOS_ShutterSpeed, (uint) val);
+ }
+
+ public override void CapturePhoto()
+ {
+ Monitor.Enter(Locker);
+ try
+ {
+ IsBusy = true;
+ ErrorCodes.GetException(ExecuteWithNoData(CONST_CMD_CANON_EOS_RemoteRelease));
+ }
+ catch (COMException comException)
+ {
+ IsBusy = false;
+ ErrorCodes.GetException(comException);
+ }
+ catch
+ {
+ IsBusy = false;
+ throw;
+ }
+ finally
+ {
+ Monitor.Exit(Locker);
+ }
+ }
+
+ private void _stillImageDevice_DeviceEvent(object sender, PortableDeviceEventArgs e)
+ {
+ if (e.EventType.EventGuid == PortableDeviceGuids.WPD_EVENT_DEVICE_REMOVED)
+ {
+ StillImageDevice.Disconnect();
+ StillImageDevice.IsConnected = false;
+ IsConnected = false;
+
+ OnCameraDisconnected(this, new DisconnectCameraEventArgs {StillImageDevice = StillImageDevice});
+ }
+ else
+ {
+ getEvent();
+ }
+ }
+
+ public override void StartBulbMode()
+ {
+ ErrorCodes.GetException(ExecuteWithNoData(CONST_CMD_CANON_EOS_BulbStart));
+ }
+
+ public override void EndBulbMode()
+ {
+ ErrorCodes.GetException(ExecuteWithNoData(CONST_CMD_CANON_EOS_BulbEnd));
+ }
+
+ public override LiveViewData GetLiveViewImage()
+ {
+ _timer.Stop();
+ LiveViewData viewData = new LiveViewData();
+ if (Monitor.TryEnter(Locker, 10))
+ {
+ try
+ {
+ //DeviceReady();
+ viewData.HaveFocusData = false;
+ MTPDataResponse response = ExecuteReadDataEx(CONST_CMD_CANON_EOS_GetViewFinderData, 0x00100000);
+ ErrorCodes.GetException(response.ErrorCode);
+ if (response.Data == null)
+ {
+ _timer.Start();
+ return null;
+ }
+ viewData.ImageDataPosition = 0;
+ viewData.ImageData = response.Data;
+ }
+ catch (Exception e)
+ {
+ Log.Error("Error get live view image ", e);
+ }
+ finally
+ {
+ Monitor.Exit(Locker);
+ }
+ }
+ _timer.Start();
+ return viewData;
+ }
+
+ public override void StartLiveView()
+ {
+ SetProperty(CONST_CMD_CANON_EOS_SetDevicePropValueEx, BitConverter.GetBytes(2),
+ CONST_PROP_EOS_LiveView);
+ SetEOSProperty(CONST_PROP_EOS_LiveView, (uint) 2);
+ }
+
+ public override void StopLiveView()
+ {
+ SetProperty(CONST_CMD_CANON_EOS_SetDevicePropValueEx, BitConverter.GetBytes(0),
+ CONST_PROP_EOS_LiveView);
+ SetEOSProperty(CONST_PROP_EOS_LiveView, (uint) 0);
+ }
+
+
+ public void SetEOSProperty(uint prop, uint val)
+ {
+ bool timerstate = _timer.Enabled;
+ _timer.Stop();
+ bool retry = false;
+ int retrynum = 0;
+ //DeviceReady();
+ do
+ {
+ if (retrynum > 5)
+ {
+ return;
+ }
+ try
+ {
+ retry = false;
+ uint resp = ExecuteWithNoData(CONST_CMD_CANON_EOS_SetDevicePropValueEx, 0x0000000C, (int) prop,
+ (int) val);
+
+ if (resp != 0 || resp != ErrorCodes.MTP_OK)
+ {
+ //Console.WriteLine("Retry ...." + resp.ToString("X"));
+ if (resp == ErrorCodes.MTP_Device_Busy || resp == 0x800700AA)
+ {
+ Thread.Sleep(100);
+ retry = true;
+ retrynum++;
+ }
+ else
+ {
+ ErrorCodes.GetException(resp);
+ }
+ }
+ }
+ catch (Exception exception)
+ {
+ Log.Debug("Error EOS set property :" + prop.ToString("X"), exception);
+ }
+ } while (retry);
+ if (timerstate)
+ _timer.Start();
+ }
+
+ public override string ToString()
+ {
+ /* Canon Base, just note it for now */
+ return base.ToString() + "\n\tType..................Canon (base)";
+ }
+ }
+}
\ No newline at end of file
diff --git a/DigiCamControl/CameraControl.Devices/Canon/CanonSDKBase.cs b/DigiCamControl/CameraControl.Devices/Canon/CanonSDKBase.cs
new file mode 100644
index 0000000..34d4a7a
--- /dev/null
+++ b/DigiCamControl/CameraControl.Devices/Canon/CanonSDKBase.cs
@@ -0,0 +1,1982 @@
+#region Licence
+
+// Distributed under MIT License
+// ===========================================================
+//
+// digiCamControl - DSLR camera remote control open source software
+// Copyright (C) 2014 Duka Istvan
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY,FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH
+// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#endregion
+
+#region
+
+using System;
+using System.Collections.Generic;
+using System.Drawing;
+using System.Drawing.Imaging;
+using System.IO;
+using System.Linq;
+using System.Runtime.InteropServices;
+using System.Text;
+using System.Threading;
+using System.Timers;
+using CameraControl.Devices.Classes;
+using Canon.Eos.Framework;
+using Canon.Eos.Framework.Eventing;
+using Canon.Eos.Framework.Internal;
+using Canon.Eos.Framework.Internal.SDK;
+
+#endregion
+
+namespace CameraControl.Devices.Canon
+{
+ public class CanonSDKBase : BaseMTPCamera
+ {
+ private EosLiveImageEventArgs _liveViewImageData = null;
+ private bool _recording = false;
+
+ public EosCamera Camera = null;
+ private System.Timers.Timer _shutdownTimer = new System.Timers.Timer(1000*60);
+
+ protected Dictionary _shutterTable = new Dictionary
+ {
+ {0x0C, "Bulb"},
+ {0x10, "30"},
+ {0x13, "25"},
+ {0x14, "20"},
+ {0x15, "20"},
+ {0x18, "15"},
+ {0x1B, "13"},
+ {0x1C, "10"},
+ {0x1D, "10"},
+ {0x20, "8"},
+ {0x23, "6"},
+ {0x24, "6"},
+ {0x25, "5"},
+ {0x28, "4"},
+ {0x2B, "3.2"},
+ {0x2C, "3"},
+ {0x2D, "2.5"},
+ {0x30, "2"},
+ {0x33, "1.6"},
+ {0x34, "1.5"},
+ {0x35, "1.3"},
+ {0x38, "1"},
+ {0x3B, "0.8"},
+ {0x3C, "0.7"},
+ {0x3D, "0.6"},
+ {0x40, "0.5"},
+ {0x43, "0.4"},
+ {0x44, "0.3"},
+ {0x45, "0.3"},
+ {0x48, "1/4"},
+ {0x4B, "1/5"},
+ {0x4C, "1/6"},
+ {0x4D, "1/5"},
+ {0x50, "1/8"},
+ {0x53, "1/10"},
+ {0x54, "1/10"},
+ {0x55, "1/13"},
+ {0x58, "1/15"},
+ {0x5B, "1/20"},
+ {0x5C, "1/20"},
+ {0x5D, "1/25"},
+ {0x60, "1/30"},
+ {0x63, "1/40"},
+ {0x64, "1/45"},
+ {0x65, "1/50"},
+ {0x68, "1/60"},
+ {0x6B, "1/80"},
+ {0x6C, "1/90"},
+ {0x6D, "1/100"},
+ {0x70, "1/125"},
+ {0x73, "1/160"},
+ {0x74, "1/180"},
+ {0x75, "1/200"},
+ {0x78, "1/250"},
+ {0x7B, "1/320"},
+ {0x7C, "1/350"},
+ {0x7D, "1/400"},
+ {0x80, "1/500"},
+ {0x83, "1/640"},
+ {0x84, "1/750"},
+ {0x85, "1/800"},
+ {0x88, "1/1000"},
+ {0x8B, "1/1250"},
+ {0x8C, "1/1500"},
+ {0x8D, "1/1600"},
+ {0x90, "1/2000"},
+ {0x93, "1/2500"},
+ {0x94, "1/3000"},
+ {0x95, "1/3200"},
+ {0x98, "1/4000"},
+ {0x9B, "1/5000"},
+ {0x9C, "1/6000"},
+ {0x9D, "1/6400"},
+ {0xA0, "1/8000"},
+ };
+
+ protected Dictionary _apertureTable = new Dictionary
+ {
+ {0x08, "1.0"},
+ {0x0B, "1.1"},
+ {0x0C, "1.2"},
+ {0x0D, "1.0"},
+ {0x10, "1.4"},
+ {0x13, "1.6"},
+ {0x14, "1.8"},
+ {0x15, "1.8"},
+ {0x18, "2.0"},
+ {0x1B, "2.2"},
+ {0x1C, "2.5"},
+ {0x1D, "2.5"},
+ {0x20, "2.8"},
+ {0x23, "3.2"},
+ {0x24, "3.5"},
+ {0x25, "3.5"},
+ {0x28, "4.0"},
+ {0x2B, "4.5"},
+ {0x2C, "4.5"},
+ {0x2D, "5.0"},
+ {0x30, "5.6"},
+ {0x33, "6.3"},
+ {0x34, "6.7"},
+ {0x35, "7.1"},
+ {0x38, "8.0"},
+ {0x3B, "9.0"},
+ {0x3C, "9.5"},
+ {0x3D, "10.0"},
+ {0x40, "11.0"},
+ {0x43, "13.0"},
+ {0x44, "13.0"},
+ {0x45, "14.0"},
+ {0x48, "16.0"},
+ {0x4B, "18.0"},
+ {0x4C, "19.0"},
+ {0x4D, "20.0"},
+ {0x50, "22.0"},
+ {0x53, "25.0"},
+ {0x54, "27.0"},
+ {0x55, "29.0"},
+ {0x58, "32.0"},
+ {0x5B, "36.0"},
+ {0x5C, "38.0"},
+ {0x5D, "40.0"},
+ {0x60, "45.0"},
+ {0x63, "51.0"},
+ {0x64, "54.0"},
+ {0x65, "57.0"},
+ {0x68, "64.0"},
+ {0x6B, "72.0"},
+ {0x6C, "76.0"},
+ {0x6D, "80.0"},
+ {0x70, "91.0"},
+ };
+
+ protected Dictionary _exposureModeTable = new Dictionary()
+ {
+ {0, "P"},
+ {1, "Tv"},
+ {2, "Av"},
+ {3, "M"},
+ {4, "Bulb"},
+ {5, "A-DEP"},
+ {6, "DEP"},
+ {7, "Camera settings registered"},
+ {8, "Lock"},
+ {9, "Auto"},
+ {10, "Night scene Portrait"},
+ {11, "Sport"},
+ {12, "Portrait"},
+ {13, "Landscape"},
+ {14, "Close-Up"},
+ {15, "Flash Off"},
+ {19, "Creative Auto"},
+ {21, "Photo in Movie"},
+ };
+
+ protected Dictionary _isoTable = new Dictionary()
+ {
+ {0x00000000, "Auto"},
+ {0x00000028, "6"},
+ {0x00000030, "12"},
+ {0x00000038, "25"},
+ {0x00000040, "50"},
+ {0x00000048, "100"},
+ {0x0000004B, "125"},
+ {0x0000004D, "160"},
+ {0x00000050, "200"},
+ {0x00000053, "250"},
+ {0x00000055, "320"},
+ {0x00000058, "400"},
+ {0x0000005B, "500"},
+ {0x0000005D, "640"},
+ {0x00000060, "800"},
+ {0x00000063, "1000"},
+ {0x00000065, "1250"},
+ {0x00000068, "1600"},
+ {0x00000070, "3200"},
+ {0x00000078, "6400"},
+ {0x00000080, "12800"},
+ {0x00000088, "25600"},
+ {0x00000090, "51200"},
+ {0x00000098, "102400"},
+ };
+
+ protected Dictionary _ec = new Dictionary()
+ {
+ {0x18, "+3.0"},
+ {0x15, "+2 2/3"},
+ {0x14, "+2.5"},
+ {0x13, "+2 1/3"},
+ {0x10, "+2.0"},
+ {0x0D, "+1 2/3"},
+ {0x0C, "+1.5"},
+ {0x0B, "+1 1/3"},
+ {0x08, "+1"},
+ {0x05, "+2/3"},
+ {0x04, "+0.5"},
+ {0x03, "+1/3"},
+ {0x00, "0.0"},
+ {0xFD, "-1/3"},
+ {0xFC, "-0.5"},
+ {0xFB, "-2/3"},
+ {0xF8, "-1"},
+ {0xF5, "-1 1/3"},
+ {0xF4, "-1.5"},
+ {0xF3, "-1 2/3"},
+ {0xF0, "-2"},
+ {0xED, "-2 1/3"},
+ {0xEC, "-2.5"},
+ {0xEB, "-3 2/3"},
+ {0xE8, "-3"},
+ };
+
+ protected Dictionary _wbTable = new Dictionary()
+ {
+ {0, "Auto"},
+ {1, "Daylight"},
+ {2, "Cloudy"},
+ {3, "Tungsten"},
+ {4, "Fluorescent"},
+ {5, "Flash"},
+ {6, "Manual"},
+ {8, "Shade"},
+ {9, "Color temperature"},
+ {10, "Custom white balance: PC-1"},
+ {11, "Custom white balance: PC-2"},
+ {12, "Custom white balance: PC-3"},
+ {15, "Manual 2"},
+ {16, "Manual 3"},
+ {18, "Manual 4"},
+ {19, "Manual 5"},
+ {20, "Custom white balance: PC-4"},
+ {21, "Custom white balance: PC-5"},
+ };
+
+ protected Dictionary _meteringTable = new Dictionary()
+ {
+ {1, "Spot metering"},
+ {3, "Evaluative metering"},
+ {4, "Partial metering"},
+ {5, "Center-weighted averaging metering"},
+ {0xFFFFFFFF, "Not valid/no settings changes"},
+ };
+
+ protected Dictionary _focusModeTable = new Dictionary()
+ {
+ {0, "One-Shot AF"},
+ {1, "AI Servo AF"},
+ {2, "AI Focus AF"},
+ {3, "Manual Focus"},
+ {0xFFFFFFFF, "Not valid/no settings changes"},
+ };
+
+ public CanonSDKBase()
+ {
+ }
+
+ public override bool CaptureInSdRam
+ {
+ get { return base.CaptureInSdRam; }
+ set
+ {
+ base.CaptureInSdRam = value;
+ try
+ {
+ if (IsConnected && Camera != null)
+ {
+ if (!base.CaptureInSdRam)
+ {
+ Camera.SavePicturesToCamera();
+ }
+ else
+ {
+ Camera.SavePicturesToHost(Path.GetTempPath());
+ }
+ }
+ }
+ catch (Exception exception)
+ {
+ Log.Error("Error set CaptureInSdram", exception);
+ }
+ }
+
+ }
+
+ private DateTime _dateTime;
+
+ public override DateTime DateTime
+ {
+ get { return _dateTime; }
+
+
+
+
+
+
+
+
+
+
+
+ set
+ {
+ _dateTime = value;
+
+
+ NotifyPropertyChanged("DateTime");
+
+
+
+
+
+
+ }
+ }
+
+ public bool Init(EosCamera camera)
+ {
+ try
+ {
+ PreventShutDown = true;
+ IsBusy = true;
+ Camera = camera;
+ Camera.IsErrorTolerantMode = false;
+ DeviceName = Camera.DeviceDescription;
+ PortName = camera.PortName;
+ Manufacturer = "Canon Inc.";
+ Camera.SetEventHandlers();
+ Camera.EnsureOpenSession();
+ Camera.Error += _camera_Error;
+ Camera.Shutdown += _camera_Shutdown;
+ Camera.LiveViewPaused += Camera_LiveViewPaused;
+ Camera.LiveViewUpdate += Camera_LiveViewUpdate;
+ Camera.PictureTaken += Camera_PictureTaken;
+ Capabilities.Add(CapabilityEnum.Bulb);
+ Capabilities.Add(CapabilityEnum.LiveView);
+ Capabilities.Add(CapabilityEnum.CaptureInRam);
+ Capabilities.Add(CapabilityEnum.RecordMovie);
+ Capabilities.Add(CapabilityEnum.SimpleManualFocus);
+ IsConnected = true;
+ LoadProperties();
+ Thread thread = new Thread(() =>
+ {
+ Thread.Sleep(200);
+ OnCameraInitDone();
+ });
+ thread.Start();
+ _shutdownTimer.Elapsed += _shutdownTimer_Elapsed;
+ return true;
+ }
+ catch (Exception exception)
+ {
+ Log.Error("Error initialize EOS camera object ", exception);
+ return false;
+ }
+ }
+
+ private void _shutdownTimer_Elapsed(object sender, ElapsedEventArgs e)
+ {
+ if (IsBusy)
+ return;
+ if (Monitor.TryEnter(Locker, 10))
+ {
+ try
+ {
+ Camera_WillShutdown(null, null);
+ }
+ finally
+ {
+ Monitor.Exit(Locker);
+ }
+ }
+ }
+
+ public void LoadProperties()
+ {
+ InitMode();
+ InitShutterSpeed();
+ InitFNumber();
+ InitIso();
+ InitEc();
+ InitWb();
+ InitMetering();
+ InitFocus();
+ InitOther();
+ InitCompression();
+ Battery = (int) Camera.BatteryLevel + 20;
+ IsBusy = false;
+ CaptureInSdRam = true;
+ Camera.PropertyChanged += Camera_PropertyChanged;
+ Camera.WillShutdown += Camera_WillShutdown;
+ SerialNumber = Camera.SerialNumber;
+ AddAditionalProps();
+ }
+
+ private void Camera_WillShutdown(object sender, EventArgs e)
+ {
+ try
+ {
+ if (PreventShutDown)
+ {
+ Camera.SendCommand(Edsdk.CameraCommand_ExtendShutDownTimer);
+ }
+ }
+ catch (Exception exception)
+ {
+ Log.Debug("PreventShutDown", exception);
+ }
+ }
+
+ public virtual void AddAditionalProps()
+ {
+ AdvancedProperties.Add(InitDriveMode());
+ //AdvancedProperties.Add(InitFlahEc());
+ AdvancedProperties.Add(InitBracket());
+ //AdvancedProperties.Add(InitAEBracket());
+ foreach (PropertyValue value in AdvancedProperties)
+ {
+ value.SetValue((long)Camera.GetProperty(value.Code), false);
+ }
+ }
+
+ private PropertyValue InitFlahEc()
+ {
+ PropertyValue res = new PropertyValue()
+ {
+ Name = "Flash Compensation",
+ IsEnabled = true,
+ Code = Edsdk.PropID_FlashCompensation,
+ SubType = typeof(UInt32),
+ DisableIfWrongValue = true
+ };
+
+ var data = GetSettingsList(Edsdk.PropID_FlashCompensation);
+
+ res.ValueChanged += FlashExposureCompensation_ValueChanged;
+ try
+ {
+ foreach (KeyValuePair keyValuePair in _ec)
+ {
+ if (data.Count == 0)
+ {
+ res.AddValues(keyValuePair.Value, (int)keyValuePair.Key);
+ }
+ else
+ {
+ if (data.Contains((int)keyValuePair.Key))
+ res.AddValues(keyValuePair.Value, (int)keyValuePair.Key);
+ }
+ }
+ res.ReloadValues();
+ res.IsEnabled = true;
+ res.SetValue((int)Camera.GetProperty(Edsdk.PropID_FlashCompensation), false);
+ }
+ catch (Exception exception)
+ {
+ Log.Debug("Error get EC", exception);
+ }
+ return res;
+ }
+
+ private void FlashExposureCompensation_ValueChanged(object sender, string key, long val)
+ {
+ try
+ {
+ Camera.SetProperty(Edsdk.PropID_FlashCompensation, val);
+ }
+ catch (Exception exception)
+ {
+ Log.Debug("Error set EC to camera", exception);
+ }
+ }
+
+ private PropertyValue InitDriveMode()
+ {
+ PropertyValue res = new PropertyValue()
+ {
+ Name = "Drive Mode",
+ IsEnabled = true,
+ Code = Edsdk.PropID_DriveMode,
+ SubType = typeof (UInt32),
+ DisableIfWrongValue = true
+ };
+ var r = Camera.GetPropertyDescription(Edsdk.PropID_DriveMode);
+ var rr = r.PropDesc.Take(r.NumElements).ToArray();
+ if (rr.Contains(0))
+ res.AddValues("Single-Frame Shooting", 0);
+ if (rr.Contains(1))
+ res.AddValues("Continuous Shooting", 1);
+ if (rr.Contains(2))
+ res.AddValues("Video", 2);
+ //res.AddValues("Not used", 3);
+ if (rr.Contains(4))
+ res.AddValues("High-Speed Continuous Shooting", 4);
+ if (rr.Contains(5))
+ res.AddValues("Low-Speed Continuous Shooting", 5);
+ if (rr.Contains(6))
+ res.AddValues("Silent single shooting", 6);
+ if (rr.Contains(7))
+ res.AddValues("10-Sec Self-Timer plus continuous shots", 7);
+ if (rr.Contains(10))
+ res.AddValues("10-Sec Self-Timer", 10);
+ if (rr.Contains(11))
+ res.AddValues("2-Sec Self-Timer", 11);
+ if (rr.Contains(12))
+ res.AddValues("14fps super high speed", 12);
+ if (rr.Contains(13))
+ res.AddValues("Silent single shooting", 13);
+ if (rr.Contains(14))
+ res.AddValues("Silent contin shooting", 14);
+ if (rr.Contains(15))
+ res.AddValues("Silent HS continuous", 15);
+ if (rr.Contains(16))
+ res.AddValues("Silent LS continuous", 16);
+ res.ReloadValues();
+ res.ValueChanged +=
+ (sender, key, val) => Camera.SetProperty(res.Code, val);
+ return res;
+ }
+
+ private PropertyValue InitFlash()
+ {
+ PropertyValue res = new PropertyValue()
+ {
+ Name = "Flash",
+ IsEnabled = true,
+ Code = Edsdk.PropID_FlashOn,
+ SubType = typeof(UInt32),
+ DisableIfWrongValue = true
+ };
+ res.AddValues("No flash", 0);
+ res.AddValues("Flash", 1);
+ res.ReloadValues();
+ res.ValueChanged +=
+ (sender, key, val) => Camera.SetProperty(res.Code, val);
+ return res;
+ }
+
+ private PropertyValue InitBracket()
+ {
+ PropertyValue res = new PropertyValue()
+ {
+ Name = "Bracketing",
+ IsEnabled = false,
+ Code = Edsdk.PropID_Bracket,
+ SubType = typeof(UInt32),
+ DisableIfWrongValue = true
+ };
+ res.AddValues("Bracket off", 0xFFFFFFFF);
+ res.AddValues("AE bracket", 1);
+ res.AddValues("ISO bracket", 2);
+ res.AddValues("WB bracket", 3);
+ res.AddValues("FE bracket", 4);
+ res.ReloadValues();
+ res.ValueChanged +=
+ (sender, key, val) => Camera.SetProperty(res.Code, val);
+ return res;
+ }
+
+ private PropertyValue InitAEBracket()
+ {
+ PropertyValue res = new PropertyValue()
+ {
+ Name = "AE Bracketing",
+ IsEnabled = true,
+ Code = Edsdk.PropID_AEBracket,
+ SubType = typeof(UInt32),
+ DisableIfWrongValue = true
+ };
+ var r = Camera.GetPropertyDescription(Edsdk.PropID_AEBracket);
+ res.AddValues("Bracket off", 0);
+ for (int i = 1; i < r.NumElements; i++)
+ {
+ res.AddValues("Step "+i, r.PropDesc[i]);
+ }
+ res.ReloadValues();
+ res.ValueChanged +=
+ (sender, key, val) =>
+ {
+ Camera.SetProperty(res.Code, val);
+ };
+ return res;
+ }
+ private void InitOther()
+ {
+ LiveViewImageZoomRatio = new PropertyValue {Name = "LiveViewImageZoomRatio"};
+ LiveViewImageZoomRatio.AddValues("All", 1);
+ LiveViewImageZoomRatio.AddValues("5x", 5);
+ //LiveViewImageZoomRatio.AddValues("10x", 10);
+ LiveViewImageZoomRatio.SetValue("All");
+ LiveViewImageZoomRatio.ReloadValues();
+ LiveViewImageZoomRatio.ValueChanged += LiveViewImageZoomRatio_ValueChanged;
+ }
+
+ private void InitCompression()
+ {
+ var data = GetSettingsList(Edsdk.PropID_ImageQuality);
+ CompressionSetting = new PropertyValue();
+ CompressionSetting.AddValues("Large Fine JPEG", (int) new EosImageQuality(){PrimaryCompressLevel = EosCompressLevel.Fine,PrimaryImageFormat = EosImageFormat.Jpeg,PrimaryImageSize = EosImageSize.Large,SecondaryCompressLevel = EosCompressLevel.Unknown,SecondaryImageFormat = EosImageFormat.Unknown, SecondaryImageSize = EosImageSize.Unknown}.ToBitMask());
+ CompressionSetting.AddValues("Large Normal JPEG", (int)new EosImageQuality() { PrimaryCompressLevel = EosCompressLevel.Normal, PrimaryImageFormat = EosImageFormat.Jpeg, PrimaryImageSize = EosImageSize.Large, SecondaryCompressLevel = EosCompressLevel.Unknown, SecondaryImageFormat = EosImageFormat.Unknown, SecondaryImageSize = EosImageSize.Unknown }.ToBitMask());
+ CompressionSetting.AddValues("Medium Fine JPEG", (int)new EosImageQuality() { PrimaryCompressLevel = EosCompressLevel.Fine, PrimaryImageFormat = EosImageFormat.Jpeg, PrimaryImageSize = EosImageSize.Middle, SecondaryCompressLevel = EosCompressLevel.Unknown, SecondaryImageFormat = EosImageFormat.Unknown, SecondaryImageSize = EosImageSize.Unknown }.ToBitMask());
+ CompressionSetting.AddValues("Medium Normal JPEG", (int)new EosImageQuality() { PrimaryCompressLevel = EosCompressLevel.Normal, PrimaryImageFormat = EosImageFormat.Jpeg, PrimaryImageSize = EosImageSize.Middle, SecondaryCompressLevel = EosCompressLevel.Unknown, SecondaryImageFormat = EosImageFormat.Unknown, SecondaryImageSize = EosImageSize.Unknown }.ToBitMask());
+ CompressionSetting.AddValues("Small Fine JPEG", (int)new EosImageQuality() { PrimaryCompressLevel = EosCompressLevel.Fine, PrimaryImageFormat = EosImageFormat.Jpeg, PrimaryImageSize = EosImageSize.Small2, SecondaryCompressLevel = EosCompressLevel.Unknown, SecondaryImageFormat = EosImageFormat.Unknown, SecondaryImageSize = EosImageSize.Unknown }.ToBitMask());
+ CompressionSetting.AddValues("Small Normal JPEG", (int)new EosImageQuality() { PrimaryCompressLevel = EosCompressLevel.Normal, PrimaryImageFormat = EosImageFormat.Jpeg, PrimaryImageSize = EosImageSize.Small2, SecondaryCompressLevel = EosCompressLevel.Unknown, SecondaryImageFormat = EosImageFormat.Unknown, SecondaryImageSize = EosImageSize.Unknown }.ToBitMask());
+ CompressionSetting.AddValues("Smaller JPEG", (int)new EosImageQuality() { PrimaryCompressLevel = EosCompressLevel.Fine, PrimaryImageFormat = EosImageFormat.Jpeg, PrimaryImageSize = EosImageSize.Small3, SecondaryCompressLevel = EosCompressLevel.Unknown, SecondaryImageFormat = EosImageFormat.Unknown, SecondaryImageSize = EosImageSize.Unknown }.ToBitMask());
+ CompressionSetting.AddValues("Tiny JPEG", (int)new EosImageQuality() { PrimaryCompressLevel = EosCompressLevel.Fine, PrimaryImageFormat = EosImageFormat.Jpeg, PrimaryImageSize = EosImageSize.Small4, SecondaryCompressLevel = EosCompressLevel.Unknown, SecondaryImageFormat = EosImageFormat.Unknown, SecondaryImageSize = EosImageSize.Unknown }.ToBitMask());
+ CompressionSetting.AddValues("RAW + Large Fine JPEG", (int)new EosImageQuality() {PrimaryImageFormat =EosImageFormat.Cr2,PrimaryCompressLevel = EosCompressLevel.Lossless, PrimaryImageSize = EosImageSize.Large, SecondaryImageSize =EosImageSize.Large,SecondaryCompressLevel = EosCompressLevel.Fine, SecondaryImageFormat = EosImageFormat.Jpeg }.ToBitMask());
+ CompressionSetting.AddValues("RAW", (int)new EosImageQuality() { PrimaryImageFormat = EosImageFormat.Cr2, PrimaryCompressLevel = EosCompressLevel.Lossless, PrimaryImageSize = EosImageSize.Large, SecondaryCompressLevel = EosCompressLevel.Unknown, SecondaryImageFormat = EosImageFormat.Unknown, SecondaryImageSize = EosImageSize.Unknown}.ToBitMask());
+ CompressionSetting.Filter(data.Select(i => (long) i).ToList());
+ CompressionSetting.SetValue((int) Camera.ImageQuality.ToBitMask());
+ CompressionSetting.ValueChanged += CompressionSetting_ValueChanged;
+ }
+
+ private void CompressionSetting_ValueChanged(object sender, string key, long val)
+ {
+ Camera.ImageQuality = EosImageQuality.Create(val);
+ }
+
+
+ private void LiveViewImageZoomRatio_ValueChanged(object sender, string key, long val)
+ {
+ Camera.SetProperty(Edsdk.PropID_Evf_Zoom, val);
+ //Camera.LiveViewqueue.Enqueue(() => Camera.SetProperty(Edsdk.PropID_Evf_Zoom, val));
+ }
+
+
+ private void Camera_PropertyChanged(object sender, EosPropertyEventArgs e)
+ {
+ if (IsBusy)
+ return;
+ lock (Locker)
+ {
+
+ try
+ {
+ // Log.Debug("Property changed " + e.PropertyId.ToString("X"));
+ switch (e.PropertyId)
+ {
+ case Edsdk.PropID_ExposureCompensation:
+ ExposureCompensation.SetValue((int) Camera.GetProperty(Edsdk.PropID_ExposureCompensation),
+ false);
+ break;
+ case Edsdk.PropID_AEMode:
+ ReInitFNumber(true);
+ ReInitShutterSpeed();
+ Mode.SetValue((uint)Camera.GetProperty(Edsdk.PropID_AEMode), false);
+ break;
+ case Edsdk.PropID_WhiteBalance:
+ WhiteBalance.SetValue(Camera.GetProperty(Edsdk.PropID_WhiteBalance), false);
+ break;
+ case Edsdk.PropID_ISOSpeed:
+ IsoNumber.SetValue(Camera.GetProperty(Edsdk.PropID_ISOSpeed), false);
+ break;
+ case Edsdk.PropID_Tv:
+ ShutterSpeed.SetValue(Camera.GetProperty(Edsdk.PropID_Tv), false);
+ break;
+ case Edsdk.PropID_Av:
+ FNumber.SetValue((int) Camera.GetProperty(Edsdk.PropID_Av), false);
+ break;
+ case Edsdk.PropID_MeteringMode:
+ ExposureMeteringMode.SetValue((int) Camera.GetProperty(Edsdk.PropID_MeteringMode), false);
+ break;
+ case Edsdk.PropID_AFMode:
+ FocusMode.SetValue((int) Camera.GetProperty(Edsdk.PropID_AFMode), false);
+ break;
+ case Edsdk.PropID_ImageQuality:
+ int i = (int) Camera.GetProperty(Edsdk.PropID_ImageQuality);
+ CompressionSetting.SetValue((int) Camera.ImageQuality.ToBitMask(), false);
+ break;
+ case Edsdk.PropID_BatteryLevel:
+ Battery = (int) Camera.BatteryLevel + 20;
+ break;
+ case Edsdk.PropID_AEBracketType:
+ int ae = (int)Camera.GetProperty(Edsdk.PropID_AEBracketType);
+ //ResetShutterButton();
+ break;
+ case Edsdk.PropID_Bracket:
+ int br = (int)Camera.GetProperty(Edsdk.PropID_Bracket);
+ //ResetShutterButton();
+ break;
+
+ case Edsdk.PropID_FocusInfo:
+ //ResetShutterButton();
+ break;
+ }
+ foreach (
+ PropertyValue advancedProperty in
+ AdvancedProperties.Where(advancedProperty => advancedProperty.Code == e.PropertyId))
+ {
+ advancedProperty.SetValue((long) Camera.GetProperty(advancedProperty.Code), false);
+ }
+ }
+ catch (Exception exception)
+ {
+ Log.Error("Error set property " + e.PropertyId.ToString("X"), exception);
+ }
+ }
+ }
+
+ private void Camera_PictureTaken(object sender, EosImageEventArgs e)
+ {
+ try
+ {
+ Log.Debug("Picture taken event received type" + e.GetType().ToString());
+ PhotoCapturedEventArgs args = new PhotoCapturedEventArgs
+ {
+ WiaImageItem = null,
+ //EventArgs =
+ // new PortableDeviceEventArgs(new PortableDeviceEventType()
+ // {
+ // ObjectHandle =
+ // (uint)longeventParam
+ // }),
+ CameraDevice = this,
+ FileName = "IMG0000.jpg",
+ Handle =e.Pointer.ToInt64() != 0?(object) e.Pointer: e
+ };
+
+ EosFileImageEventArgs file = e as EosFileImageEventArgs;
+ if (file != null)
+ {
+ args.FileName = Path.GetFileName(file.ImageFilePath);
+ }
+ EosMemoryImageEventArgs memory = e as EosMemoryImageEventArgs;
+ if (memory != null)
+ {
+ if (!string.IsNullOrEmpty(memory.FileName))
+ args.FileName = Path.GetFileName(memory.FileName);
+ }
+ OnPhotoCapture(this, args);
+ OnCaptureCompleted(this, new EventArgs());
+ }
+ catch (Exception exception)
+ {
+ Log.Error("EOS Picture taken event error", exception);
+ }
+ }
+
+ private void Camera_LiveViewUpdate(object sender, EosLiveImageEventArgs e)
+ {
+ _liveViewImageData = e;
+ }
+
+ private void Camera_LiveViewPaused(object sender, EventArgs e)
+ {
+ try
+ {
+ //Camera.ResetShutterButton();
+ //Camera.TakePictureNoAf();
+ //Camera.ResetShutterButton();
+ //Camera.ResumeLiveview();
+ }
+ catch (Exception exception)
+ {
+ IsBusy = false;
+ Log.Debug("Live view pause error", exception);
+ }
+ }
+
+ private void _camera_Shutdown(object sender, EventArgs e)
+ {
+ IsConnected = false;
+ OnCameraDisconnected(this, new DisconnectCameraEventArgs {StillImageDevice = null, EosCamera = Camera});
+ }
+
+ public override void Close()
+ {
+ HaveLiveView = false;
+ Camera.Error -= _camera_Error;
+ Camera.Shutdown -= _camera_Shutdown;
+ Camera.LiveViewPaused -= Camera_LiveViewPaused;
+ Camera.LiveViewUpdate -= Camera_LiveViewUpdate;
+ Camera.PictureTaken -= Camera_PictureTaken;
+ Camera.PropertyChanged -= Camera_PropertyChanged;
+ // this block the application
+ //Camera.Dispose();
+ Camera = null;
+ }
+
+
+ private void _camera_Error(object sender, EosExceptionEventArgs e)
+ {
+ try
+ {
+ Log.Error("Canon error", e.Exception);
+ StaticHelper.Instance.SystemMessage = e.Exception.Message;
+ }
+ catch (Exception exception)
+ {
+ Log.Error("Error get camera error", exception);
+ StaticHelper.Instance.SystemMessage = exception.Message;
+ }
+ }
+
+ public override bool Init(DeviceDescriptor deviceDescriptor)
+ {
+ //StillImageDevice = new StillImageDevice(deviceDescriptor.WpdId);
+ //StillImageDevice.ConnectToDevice(AppName, AppMajorVersionNumber, AppMinorVersionNumber);
+ //StillImageDevice.DeviceEvent += _stillImageDevice_DeviceEvent;
+ Capabilities.Add(CapabilityEnum.Bulb);
+ Capabilities.Add(CapabilityEnum.LiveView);
+
+ IsConnected = true;
+ return true;
+ }
+
+
+ private void InitShutterSpeed()
+ {
+ ShutterSpeed = new PropertyValue();
+ ShutterSpeed.Name = "ShutterSpeed";
+ ShutterSpeed.ValueChanged += ShutterSpeed_ValueChanged;
+ ReInitShutterSpeed();
+ }
+
+ private void ReInitShutterSpeed()
+ {
+ lock (Locker)
+ {
+ try
+ {
+ ShutterSpeed.Clear();
+ var data = GetSettingsList(Edsdk.PropID_Tv);
+ foreach (KeyValuePair keyValuePair in _shutterTable)
+ {
+ if (data.Count > 0)
+ {
+ if (data.Contains((int) keyValuePair.Key))
+ ShutterSpeed.AddValues(keyValuePair.Value, keyValuePair.Key);
+ }
+ else
+ {
+ ShutterSpeed.AddValues(keyValuePair.Value, keyValuePair.Key);
+ }
+ }
+ ShutterSpeed.ReloadValues();
+ long value = Camera.GetProperty(Edsdk.PropID_Tv);
+ if (value == 0)
+ {
+ ShutterSpeed.IsEnabled = false;
+ }
+ else
+ {
+ ShutterSpeed.IsEnabled = true;
+ ShutterSpeed.SetValue(Camera.GetProperty(Edsdk.PropID_Tv), false);
+ }
+ }
+ catch (Exception ex)
+ {
+ Log.Debug("EOS Shutter speed init", ex);
+ }
+ }
+ }
+
+ private void ShutterSpeed_ValueChanged(object sender, string key, long val)
+ {
+ try
+ {
+ Camera.SetProperty(Edsdk.PropID_Tv, val);
+ }
+ catch (Exception exception)
+ {
+ Log.Error("Error set property sP", exception);
+ }
+ }
+
+ #region F number
+
+ private void InitFNumber()
+ {
+ FNumber = new PropertyValue {IsEnabled = true, Name = "FNumber"};
+ FNumber.ValueChanged += FNumber_ValueChanged;
+ ReInitFNumber(true);
+ }
+
+ private void FNumber_ValueChanged(object sender, string key, long val)
+ {
+ try
+ {
+ Camera.SetProperty(Edsdk.PropID_Av, val);
+ }
+ catch (Exception exception)
+ {
+ Log.Error("Error set property AV", exception);
+ }
+ }
+
+ private void ReInitFNumber(bool trigervaluchange)
+ {
+ try
+ {
+ var data = GetSettingsList(Edsdk.PropID_Av);
+ long value = Camera.GetProperty(Edsdk.PropID_Av);
+ bool shouldinit = FNumber.Values.Count == 0;
+
+ if (data.Count > 0)
+ FNumber.Clear();
+
+ if (shouldinit && data.Count == 0)
+ {
+ foreach (KeyValuePair keyValuePair in _apertureTable)
+ {
+ FNumber.AddValues(keyValuePair.Value, keyValuePair.Key);
+ }
+ }
+ else
+ {
+ foreach (
+ KeyValuePair keyValuePair in
+ _apertureTable.Where(keyValuePair => data.Count > 0).Where(
+ keyValuePair => data.Contains(keyValuePair.Key)))
+ {
+ FNumber.AddValues(keyValuePair.Value, keyValuePair.Key);
+ }
+ }
+ FNumber.ReloadValues();
+ if (value == 0)
+ {
+ FNumber.IsEnabled = false;
+ }
+ else
+ {
+ FNumber.SetValue((int) value, false);
+ FNumber.IsEnabled = true;
+ }
+ }
+ catch (Exception ex)
+ {
+ Log.Debug("Error set aperture ", ex);
+ }
+ }
+
+ #endregion
+
+ private void InitIso()
+ {
+ IsoNumber = new PropertyValue();
+ IsoNumber.Name = "ISOSpeed";
+ IsoNumber.ValueChanged += IsoNumber_ValueChanged;
+ ReInitIso();
+ }
+
+ private void IsoNumber_ValueChanged(object sender, string key, long val)
+ {
+ try
+ {
+ Camera.PauseLiveview();
+ Camera.SetProperty(Edsdk.PropID_ISOSpeed, val);
+ Camera.ResumeLiveview();
+ }
+ catch (Exception exception)
+ {
+ Log.Debug("Error set ISO to camera", exception);
+ }
+ }
+
+ public List GetSettingsList(uint PropID)
+ {
+ if (Camera.Handle!= IntPtr.Zero)
+ {
+ //get the list of possible values
+ Edsdk.EdsPropertyDesc des = new Edsdk.EdsPropertyDesc();
+ var Error = Edsdk.EdsGetPropertyDesc(Camera.Handle, PropID, out des);
+ return des.PropDesc.Take(des.NumElements).ToList();
+ }
+ return new List();
+ }
+
+ private void ReInitIso()
+ {
+ try
+ {
+ var data = GetSettingsList(Edsdk.PropID_ISOSpeed);
+ long value = Camera.GetProperty(Edsdk.PropID_ISOSpeed);
+ bool shouldinit = IsoNumber.Values.Count == 0;
+
+ if (data.Count > 0)
+ IsoNumber.Clear();
+
+ if (shouldinit && data.Count == 0)
+ {
+ foreach (KeyValuePair keyValuePair in _isoTable)
+ {
+ IsoNumber.AddValues(keyValuePair.Value, (int) keyValuePair.Key);
+ }
+ }
+ else
+ {
+ foreach (
+ KeyValuePair keyValuePair in
+ _isoTable.Where(keyValuePair => data.Count > 0).Where(
+ keyValuePair => data.Contains((int) keyValuePair.Key)))
+ {
+ IsoNumber.AddValues(keyValuePair.Value, (int) keyValuePair.Key);
+ }
+ }
+ IsoNumber.ReloadValues();
+ IsoNumber.SetValue((int)value, false);
+ IsoNumber.IsEnabled = true;
+
+ }
+ catch (Exception ex)
+ {
+ Log.Debug("Error set iso ", ex);
+ }
+ }
+
+ private void InitMode()
+ {
+ Mode = new PropertyValue();
+ Mode.ValueChanged += Mode_ValueChanged;
+ try
+ {
+ foreach (KeyValuePair keyValuePair in _exposureModeTable)
+ {
+ Mode.AddValues(keyValuePair.Value, keyValuePair.Key);
+ }
+ Mode.ReloadValues();
+ Mode.SetValue((uint) Camera.GetProperty(Edsdk.PropID_AEMode), false);
+ Mode.IsEnabled = true;
+ }
+ catch (Exception ex)
+ {
+ Log.Debug("Error set aperture ", ex);
+ }
+ }
+
+ private void Mode_ValueChanged(object sender, string key, long val)
+ {
+ try
+ {
+ Camera.SetProperty(Edsdk.PropID_AEModeSelect, val);
+ //Camera.SetProperty(Edsdk.PropID_AEMode, val);
+ //Thread.Sleep(200);
+ //ReInitFNumber(true);
+ //ReInitShutterSpeed();
+ }
+ catch (Exception exception)
+ {
+ Log.Debug("Error set EC to camera", exception);
+ }
+ }
+
+ private void InitEc()
+ {
+ var data = GetSettingsList(Edsdk.PropID_ExposureCompensation);
+ ExposureCompensation = new PropertyValue();
+ ExposureCompensation.ValueChanged += ExposureCompensation_ValueChanged;
+ try
+ {
+ foreach (KeyValuePair keyValuePair in _ec)
+ {
+ if (data.Count == 0)
+ {
+ ExposureCompensation.AddValues(keyValuePair.Value, (int)keyValuePair.Key);
+ }
+ else
+ {
+ if (data.Contains((int)keyValuePair.Key))
+ ExposureCompensation.AddValues(keyValuePair.Value, (int)keyValuePair.Key);
+ }
+ }
+ ExposureCompensation.ReloadValues();
+ ExposureCompensation.IsEnabled = true;
+ ExposureCompensation.SetValue((int) Camera.GetProperty(Edsdk.PropID_ExposureCompensation), false);
+ }
+ catch (Exception exception)
+ {
+ Log.Debug("Error get EC", exception);
+ }
+ }
+
+ private void InitWb()
+ {
+ var data = GetSettingsList(Edsdk.PropID_WhiteBalance);
+ WhiteBalance = new PropertyValue();
+ WhiteBalance.ValueChanged += WhiteBalance_ValueChanged;
+ try
+ {
+ foreach (KeyValuePair keyValuePair in _wbTable)
+ {
+ if (data.Count > 0 && data.Contains((int) keyValuePair.Key))
+ WhiteBalance.AddValues(keyValuePair.Value, (int) keyValuePair.Key);
+ }
+ WhiteBalance.ReloadValues();
+ WhiteBalance.IsEnabled = true;
+ WhiteBalance.SetValue((long) Camera.GetProperty(Edsdk.PropID_WhiteBalance), false);
+ }
+ catch (Exception exception)
+ {
+ Log.Debug("Error get EC", exception);
+ }
+ }
+
+ private void WhiteBalance_ValueChanged(object sender, string key, long val)
+ {
+ try
+ {
+ Camera.SetProperty(Edsdk.PropID_WhiteBalance, val);
+ }
+ catch (Exception exception)
+ {
+ Log.Debug("Error set WB to camera", exception);
+ }
+ }
+
+ private void InitMetering()
+ {
+ var data = GetSettingsList(Edsdk.PropID_MeteringMode);
+ ExposureMeteringMode = new PropertyValue();
+ ExposureMeteringMode.ValueChanged += ExposureMeteringMode_ValueChanged;
+ try
+ {
+ foreach (KeyValuePair keyValuePair in _meteringTable)
+ {
+ if (data.Contains((int) keyValuePair.Key))
+ ExposureMeteringMode.AddValues(keyValuePair.Value, (int) keyValuePair.Key);
+ }
+ ExposureMeteringMode.ReloadValues();
+ ExposureMeteringMode.IsEnabled = true;
+ ExposureMeteringMode.SetValue((int) Camera.GetProperty(Edsdk.PropID_MeteringMode), false);
+ }
+ catch (Exception exception)
+ {
+ Log.Debug("Error get metering", exception);
+ }
+ }
+
+ private void InitFocus()
+ {
+ var data = GetSettingsList(Edsdk.PropID_AFMode);
+ FocusMode = new PropertyValue();
+ FocusMode.ValueChanged += FocusMode_ValueChanged;
+ try
+ {
+ foreach (KeyValuePair keyValuePair in _focusModeTable)
+ {
+ if (data.Contains((int) keyValuePair.Key))
+ FocusMode.AddValues(keyValuePair.Value, (int) keyValuePair.Key);
+ }
+ FocusMode.ReloadValues();
+ FocusMode.IsEnabled = true;
+ FocusMode.SetValue((int) Camera.GetProperty(Edsdk.PropID_AFMode), false);
+ }
+ catch (Exception exception)
+ {
+ Log.Debug("Error get focus mode", exception);
+ }
+ }
+
+ private void FocusMode_ValueChanged(object sender, string key, long val)
+ {
+ try
+ {
+ Camera.SetProperty(Edsdk.PropID_AFMode, val);
+ }
+ catch (Exception exception)
+ {
+ Log.Debug("Error set focus mode to camera", exception);
+ }
+ }
+
+ private void ExposureMeteringMode_ValueChanged(object sender, string key, long val)
+ {
+ try
+ {
+ Camera.SetProperty(Edsdk.PropID_MeteringMode, val);
+ }
+ catch (Exception exception)
+ {
+ Log.Debug("Error set metering mode to camera", exception);
+ }
+ }
+
+ private void ExposureCompensation_ValueChanged(object sender, string key, long val)
+ {
+ try
+ {
+ Camera.SetProperty(Edsdk.PropID_ExposureCompensation, val);
+ }
+ catch (Exception exception)
+ {
+ Log.Debug("Error set EC to camera", exception);
+ }
+ }
+
+ public override void CapturePhoto()
+ {
+ Log.Debug("EOS capture start");
+ Monitor.Enter(Locker);
+ try
+ {
+ IsBusy = true;
+ if (Camera.IsInHostLiveViewMode)
+ {
+ if (Camera.ImageQuality.SecondaryImageFormat != EosImageFormat.Unknown)
+ {
+ throw new Exception("RAW+JPG capture in live view not supported");
+ }
+ Camera.PauseLiveview();
+ Camera.ResetShutterButton();
+ ErrorCodes.GetCanonException(Camera.SendCommand(Edsdk.CameraCommand_TakePicture));
+ Camera.ResetShutterButton();
+ }
+ else
+ {
+ Camera.TakePicture();
+ }
+ }
+ catch (COMException comException)
+ {
+ IsBusy = false;
+ Camera.ResumeLiveview();
+ ErrorCodes.GetException(comException);
+ }
+ catch
+ {
+ Camera.ResumeLiveview();
+ IsBusy = false;
+ throw;
+ }
+ finally
+ {
+ Monitor.Exit(Locker);
+ }
+ Log.Debug("EOS capture end");
+ }
+
+ private uint ResetShutterButton()
+ {
+ Camera.SendCommand(Edsdk.CameraCommand_DoEvfAf, 0);
+ //ErrorCodes.GetCanonException(Camera.SendCommand(Edsdk.CameraCommand_DoEvfAf, 0));
+ return Camera.SendCommand(Edsdk.CameraCommand_PressShutterButton,
+ (int) Edsdk.EdsShutterButton.CameraCommand_ShutterButton_OFF);
+ }
+
+ public void PressButton()
+ {
+ ResetShutterButton();
+ ErrorCodes.GetCanonException(Camera.SendCommand(Edsdk.CameraCommand_PressShutterButton, (int)Edsdk.EdsShutterButton.CameraCommand_ShutterButton_Completely));
+ }
+
+ public void PressHalfButton()
+ {
+ ResetShutterButton();
+ ErrorCodes.GetCanonException(Camera.SendCommand(Edsdk.CameraCommand_PressShutterButton, (int)Edsdk.EdsShutterButton.CameraCommand_ShutterButton_Halfway));
+ }
+
+ public void ReleaseButton()
+ {
+ Camera.SendCommand(Edsdk.CameraCommand_PressShutterButton,(int)Edsdk.EdsShutterButton.CameraCommand_ShutterButton_OFF);
+ }
+
+
+ public override void CapturePhotoNoAf()
+ {
+ Log.Debug("EOS capture start");
+ Monitor.Enter(Locker);
+ try
+ {
+ if (Camera.IsInHostLiveViewMode && Camera.ImageQuality.SecondaryImageFormat != EosImageFormat.Unknown)
+ {
+ throw new Exception("RAW+JPG capture in live view not supported");
+ }
+ IsBusy = true;
+ Camera.PauseLiveview();
+ ErrorCodes.GetCanonException(ResetShutterButton());
+ ErrorCodes.GetCanonException(Camera.SendCommand(Edsdk.CameraCommand_PressShutterButton, (int)Edsdk.EdsShutterButton.CameraCommand_ShutterButton_Completely_NonAF));
+ ResetShutterButton();
+
+ //if (Camera.IsInHostLiveViewMode)
+ //{
+ // Camera.TakePictureInLiveview();
+ //}
+ //else
+ //{
+ // Camera.TakePicture();
+ //}
+ }
+ catch (COMException comException)
+ {
+ IsBusy = false;
+ ErrorCodes.GetException(comException);
+ }
+ catch
+ {
+ IsBusy = false;
+ throw;
+ }
+ finally
+ {
+ Monitor.Exit(Locker);
+ }
+ Log.Debug("EOS capture end");
+ }
+
+ public override void StartBulbMode()
+ {
+ Camera.BulbStart();
+ }
+
+ public override void EndBulbMode()
+ {
+ Camera.BulbEnd();
+ }
+
+ public override void StartRecordMovie()
+ {
+ lock (Locker)
+ {
+ _recording = true;
+ ResetShutterButton();
+ Camera.StartRecord();
+ }
+ }
+
+ public override void StopRecordMovie()
+ {
+ lock (Locker)
+ {
+ Camera.StopRecord();
+ _recording = false;
+ }
+ }
+
+ /*public override void Focus(int x, int y)
+ {
+ lock (Locker)
+ {
+ ResetShutterButton();
+ if (_liveViewImageData != null)
+ {
+ x -= (_liveViewImageData.ZommBounds.Width/2);
+ y -= (_liveViewImageData.ZommBounds.Height/2);
+ }
+ if (x < 0)
+ x = 0;
+ if (y < 0)
+ y = 0;
+ Camera.LiveViewqueue.Enqueue(
+ () =>
+ Camera.SetPropertyIntegerArrayData(Edsdk.PropID_Evf_ZoomPosition,
+ new uint[] {(uint) x, (uint) y}));
+ }
+ }*/
+
+ public override LiveViewData GetLiveViewImage()
+ {
+
+ LiveViewData viewData = new LiveViewData();
+ if (Monitor.TryEnter(Locker, 10))
+ {
+ try
+ {
+ if (Camera == null)
+ return viewData;
+ Camera.DownloadEvf();
+ if (_liveViewImageData != null)
+ {
+ //DeviceReady();
+ viewData.HaveFocusData = true;
+ viewData.ImageDataPosition = 0;
+ viewData.ImageData = _liveViewImageData.ImageData;
+ viewData.ImageHeight = _liveViewImageData.ImageSize.Height;
+ viewData.ImageWidth = _liveViewImageData.ImageSize.Width;
+ viewData.LiveViewImageHeight = 100;
+ viewData.LiveViewImageWidth = 100;
+ viewData.FocusX = _liveViewImageData.ZommBounds.X +
+ (_liveViewImageData.ZommBounds.Width / 2);
+ viewData.FocusY = _liveViewImageData.ZommBounds.Y +
+ (_liveViewImageData.ZommBounds.Height / 2);
+ viewData.FocusFrameXSize = _liveViewImageData.ZommBounds.Width;
+ viewData.FocusFrameYSize = _liveViewImageData.ZommBounds.Height;
+ viewData.MovieIsRecording = _recording;
+ }
+ }
+ catch (Exception)
+ {
+ //Log.Error("Error get live view image ", e);
+ }
+ finally
+ {
+ Monitor.Exit(Locker);
+ }
+ }
+ return viewData;
+ }
+
+ public override void StartLiveView()
+ {
+ _recording = false;
+ ResetShutterButton();
+ //if (!Camera.IsInLiveViewMode)
+ Camera.StartLiveView(EosLiveViewAutoFocus.LiveMode);
+ }
+
+ public void StartLiveViewCamera()
+ {
+ _recording = false;
+ ResetShutterButton();
+ //if (!Camera.IsInLiveViewMode)
+ Camera.StartLiveViewCamera();
+ }
+
+ public override void StopLiveView()
+ {
+ if (Camera == null)
+ return;
+ ResetShutterButton();
+ //if (Camera.IsInLiveViewMode)
+ Camera.StopLiveView();
+ }
+
+ public override void AutoFocus()
+ {
+ ResetShutterButton();
+ Camera.PauseLiveview();
+
+ try
+ {
+ ErrorCodes.GetCanonException(Camera.SendCommand(Edsdk.CameraCommand_DoEvfAf, 1));
+ // ErrorCodes.GetCanonException(
+ //Camera.SendCommand(Edsdk.CameraCommand_PressShutterButton,
+ // (int)Edsdk.EdsShutterButton.CameraCommand_ShutterButton_OFF));
+ // ErrorCodes.GetCanonException(
+ // Camera.SendCommand(Edsdk.CameraCommand_PressShutterButton,
+ // (int)Edsdk.EdsShutterButton.CameraCommand_ShutterButton_Halfway));
+ // ErrorCodes.GetCanonException(
+ // Camera.SendCommand(Edsdk.CameraCommand_PressShutterButton,
+ // (int)Edsdk.EdsShutterButton.CameraCommand_ShutterButton_OFF));
+
+ }
+ finally
+ {
+ Camera.ResumeLiveview();
+ }
+ }
+
+ public override int Focus(int step)
+ {
+ ResetShutterButton();
+
+ int focus = 0;
+ var res = Camera.SendCommand(Edsdk.CameraCommand_DriveLensEvf,
+ (int) (step < 0 ? Edsdk.EvfDriveLens_Near1 : Edsdk.EvfDriveLens_Far1));
+ //if (i%10 == 0)
+ // Camera.DownloadEvfInternal();
+ if (res == Edsdk.EDS_ERR_OK)
+ focus += step < 0 ? -1 : 1;
+
+ //Camera.SendCommand(Edsdk.CameraCommand_DoEvfAf, 0);
+ return focus;
+ }
+
+ public override void Focus(FocusDirection direction, FocusAmount amount)
+ {
+ ResetShutterButton();
+ switch (direction)
+ {
+ case FocusDirection.Far:
+ switch (amount)
+ {
+ case FocusAmount.Small:
+ Camera.SendCommand(Edsdk.CameraCommand_DriveLensEvf, (int) Edsdk.EvfDriveLens_Far1);
+ break;
+ case FocusAmount.Medium:
+ Camera.SendCommand(Edsdk.CameraCommand_DriveLensEvf, (int) Edsdk.EvfDriveLens_Far2);
+ break;
+ case FocusAmount.Large:
+ Camera.SendCommand(Edsdk.CameraCommand_DriveLensEvf, (int) Edsdk.EvfDriveLens_Far3);
+ break;
+ default:
+ throw new ArgumentOutOfRangeException(nameof(amount), amount, null);
+ }
+ break;
+ case FocusDirection.Near:
+ switch (amount)
+ {
+ case FocusAmount.Small:
+ Camera.SendCommand(Edsdk.CameraCommand_DriveLensEvf, (int)Edsdk.EvfDriveLens_Near1);
+ break;
+ case FocusAmount.Medium:
+ Camera.SendCommand(Edsdk.CameraCommand_DriveLensEvf, (int)Edsdk.EvfDriveLens_Near2);
+ break;
+ case FocusAmount.Large:
+ Camera.SendCommand(Edsdk.CameraCommand_DriveLensEvf, (int)Edsdk.EvfDriveLens_Near3);
+ break;
+ default:
+ throw new ArgumentOutOfRangeException(nameof(amount), amount, null);
+ }
+ break;
+
+ }
+ }
+
+ public override bool DeleteObject(DeviceObject deviceObject)
+ {
+ if (deviceObject.Handle is IntPtr)
+ {
+ Camera.DeleteItem((IntPtr)deviceObject.Handle);
+ }
+ return true;
+ }
+
+ public override void ReleaseResurce(object o)
+ {
+ if (o is IntPtr)
+ {
+ Edsdk.EdsRelease((IntPtr)o);
+ }
+ }
+
+ public override void TransferFileThumb(object o, string filename)
+ {
+ base.TransferFileThumb(o, filename);
+ }
+
+ public override void TransferFile(object o, string filename)
+ {
+ lock (Locker)
+ {
+ IsBusy = true;
+ if (o is IntPtr)
+ {
+ Log.Debug("Pointer file transfer started");
+ try
+ {
+ IsBusy = true;
+ Camera.PauseLiveview();
+ Log.Debug("Camera.PauseLiveview();");
+ var transporter = new EosImageTransporter();
+ transporter.ProgressEvent += (i) => TransferProgress = (uint) i;
+ Log.Debug("TransportAsFileName");
+ transporter.TransportAsFileName((IntPtr) o, filename, Camera.Handle);
+ Log.Debug("TransportAsFileName DONE");
+ Camera.ResumeLiveview();
+ Log.Debug("Camera.ResumeLiveview(); DONE");
+ }
+ catch (Exception exception)
+ {
+ Log.Error("Error transfer memory file", exception);
+ File.Delete(filename);
+ }
+ }
+ EosFileImageEventArgs file = o as EosFileImageEventArgs;
+ if (file != null)
+ {
+ Log.Debug("File transfer started");
+ try
+ {
+ if (File.Exists(file.ImageFilePath))
+ {
+ File.Copy(file.ImageFilePath, filename, true);
+ File.Delete(file.ImageFilePath);
+ }
+ else
+ {
+ Log.Error("Base file not found " + file.ImageFilePath);
+ }
+ }
+ catch (Exception exception)
+ {
+ Log.Error("Transfer error ", exception);
+ }
+ }
+ EosMemoryImageEventArgs memory = o as EosMemoryImageEventArgs;
+ if (memory != null)
+ {
+ Log.Debug("Memory file transfer started");
+ try
+ {
+ using (FileStream fileStream = File.Create(filename, (int) memory.ImageData.Length))
+ {
+ fileStream.Write(memory.ImageData, 0, memory.ImageData.Length);
+ }
+ }
+ catch (Exception exception)
+ {
+ Log.Error("Error transfer memory file", exception);
+ }
+ }
+ string fil = o as string;
+ if (fil != null)
+ {
+ GetFile(fil, filename);
+ }
+ }
+ }
+
+ public override string GetProhibitionCondition(OperationEnum operationEnum)
+ {
+ switch (operationEnum)
+ {
+ case OperationEnum.Capture:
+ break;
+ case OperationEnum.RecordMovie:
+ if (Camera.GetProperty(Edsdk.PropID_Record) == 4)
+ return "LabelRecordInProgres";
+ if (Camera.LiveViewDevice==EosLiveViewDevice.None)
+ return "LabelWrongLiveViewType";
+ break;
+ case OperationEnum.AutoFocus:
+ break;
+ case OperationEnum.ManualFocus:
+ break;
+ case OperationEnum.LiveView:
+ break;
+ default:
+ throw new ArgumentOutOfRangeException("operationEnum", operationEnum, null);
+ }
+ return "";
+ }
+
+ //private bool ArrayContainValue(IEnumerable data, uint value)
+ //{
+ // return ArrayContainValue(data, (int) value);
+ //}
+
+ //private bool ArrayContainValue(IEnumerable data, int value)
+ //{
+ // return data.Any(i => i == (int) value);
+ //}
+
+ public override AsyncObservableCollection GetObjects(object storageId, bool loadThumbs)
+ {
+ List list = new List();
+ int count = 0;
+ Edsdk.EdsGetChildCount(Camera.Handle, out count);
+ for (int i = 0; i < count; i++)
+ {
+ IntPtr volumePtr;
+ Edsdk.EdsGetChildAtIndex(Camera.Handle, i, out volumePtr);
+ Edsdk.EdsVolumeInfo vinfo;
+ Edsdk.EdsGetVolumeInfo(volumePtr, out vinfo);
+ if (vinfo.StorageType == 0)
+ throw new Exception("No memory card inserted");
+ //ignore the HDD
+ if (vinfo.szVolumeLabel != "HDD")
+ {
+ //get all child entries on this volume
+ list.AddRange(GetChildren(volumePtr, loadThumbs));
+ }
+ Edsdk.EdsRelease(volumePtr);
+ }
+ return new AsyncObservableCollection(list);
+ }
+
+ private List GetChildren(IntPtr ptr, bool loadThumbs)
+ {
+ int ChildCount;
+ //get children of first pointer
+ List list = new List();
+ Edsdk.EdsGetChildCount(ptr, out ChildCount);
+ if (ChildCount > 0)
+ {
+ //if it has children, create an array of entries
+ for (int i = 0; i < ChildCount; i++)
+ {
+ IntPtr ChildPtr;
+ //get children of children
+ Edsdk.EdsGetChildAtIndex(ptr, i, out ChildPtr);
+ //get the information about this children
+ Edsdk.EdsDirectoryItemInfo ChildInfo;
+ Edsdk.EdsGetDirectoryItemInfo(ChildPtr, out ChildInfo);
+
+ if (ChildInfo.isFolder == 0)
+ {
+ //if it's not a folder, create thumbnail and safe it to the entry
+ if (loadThumbs)
+ {
+ IntPtr stream;
+ Edsdk.EdsCreateMemoryStream(0, out stream);
+ Edsdk.EdsDownloadThumbnail(ChildPtr, stream);
+ list.Add(new DeviceObject()
+ {
+ FileName = ChildInfo.szFileName,
+ ThumbData = GetImage(stream, Edsdk.EdsImageSource.Thumbnail),
+ Handle = ChildInfo.szFileName
+ });
+ if (stream != IntPtr.Zero)
+ Edsdk.EdsRelease(stream);
+ }
+ else
+ {
+ list.Add(new DeviceObject()
+ {
+ FileName = ChildInfo.szFileName,
+ Handle = ChildPtr
+ });
+ }
+ }
+ else
+ {
+ //if it's a folder, check for children with recursion
+ list.AddRange(GetChildren(ChildPtr, loadThumbs));
+ Edsdk.EdsRelease(ChildPtr);
+ }
+ //release current children
+
+ }
+ }
+ return list;
+ }
+
+ public void GetFile(string fileName,string outFileName)
+ {
+ int count = 0;
+ Edsdk.EdsGetChildCount(Camera.Handle, out count);
+ for (int i = 0; i < count; i++)
+ {
+ IntPtr volumePtr;
+ Edsdk.EdsGetChildAtIndex(Camera.Handle, i, out volumePtr);
+ Edsdk.EdsVolumeInfo vinfo;
+ Edsdk.EdsGetVolumeInfo(volumePtr, out vinfo);
+ //ignore the HDD
+ if (vinfo.szVolumeLabel != "HDD")
+ {
+ GetFile(volumePtr, fileName, outFileName);
+ }
+ Edsdk.EdsRelease(volumePtr);
+ }
+ }
+
+ private void GetFile(IntPtr ptr,string fileName, string outfileName)
+ {
+ int ChildCount;
+ //get children of first pointer
+ List list = new List();
+ Edsdk.EdsGetChildCount(ptr, out ChildCount);
+ if (ChildCount > 0)
+ {
+ //if it has children, create an array of entries
+ for (int i = 0; i < ChildCount; i++)
+ {
+ IntPtr ChildPtr;
+ //get children of children
+ Edsdk.EdsGetChildAtIndex(ptr, i, out ChildPtr);
+ //get the information about this children
+ Edsdk.EdsDirectoryItemInfo ChildInfo;
+ Edsdk.EdsGetDirectoryItemInfo(ChildPtr, out ChildInfo);
+
+ if (ChildInfo.isFolder == 0)
+ {
+ if(ChildInfo.szFileName==fileName)
+ {
+ Camera._transporter.TransportAsFileName(ChildPtr, outfileName, Camera.Handle);
+ }
+ }
+ else
+ {
+ //if it's a folder, check for children with recursion
+ GetFile(ChildPtr, fileName, outfileName);
+ }
+ //release current children
+ Edsdk.EdsRelease(ChildPtr);
+ }
+ }
+ }
+
+ private byte[] GetImage(IntPtr img_stream, Edsdk.EdsImageSource imageSource)
+ {
+ IntPtr stream = IntPtr.Zero;
+ IntPtr img_ref = IntPtr.Zero;
+ IntPtr streamPointer = IntPtr.Zero;
+ Edsdk.EdsImageInfo imageInfo;
+ Edsdk.EdsSize outputSize = new Edsdk.EdsSize();
+ Byte[] buffer;
+ Byte temp;
+
+ //create reference to image
+ Edsdk.EdsCreateImageRef(img_stream, out img_ref);
+ //get information about image
+ Edsdk.EdsGetImageInfo(img_ref, imageSource, out imageInfo);
+
+ //calculate size, stride and buffersize
+ outputSize.width = imageInfo.EffectiveRect.width;
+ outputSize.height = imageInfo.EffectiveRect.height;
+ int Stride = ((outputSize.width*3) + 3) & ~3;
+ uint bufferSize = (uint) (outputSize.height*Stride);
+
+ //Init buffer
+ buffer = new Byte[bufferSize];
+ //Create memory stream to buffer
+ Edsdk.EdsCreateMemoryStreamFromPointer(buffer, bufferSize, out stream);
+ //copy image into buffer
+ Edsdk.EdsGetImage(img_ref, imageSource, Edsdk.EdsTargetImageType.RGB, imageInfo.EffectiveRect, outputSize,
+ stream);
+
+ //makes RGB out of BGR
+ if (outputSize.width%4 == 0)
+ {
+ for (int t = 0; t < bufferSize; t += 3)
+ {
+ temp = buffer[t];
+ buffer[t] = buffer[t + 2];
+ buffer[t + 2] = temp;
+ }
+ }
+ else
+ {
+ int Padding = Stride - (outputSize.width*3);
+ for (int y = outputSize.height - 1; y > -1; y--)
+ {
+ int RowStart = (outputSize.width*3)*y;
+ int TargetStart = Stride*y;
+
+ Array.Copy(buffer, RowStart, buffer, TargetStart, outputSize.width*3);
+
+ for (int t = TargetStart; t < TargetStart + (outputSize.width*3); t += 3)
+ {
+ temp = buffer[t];
+ buffer[t] = buffer[t + 2];
+ buffer[t + 2] = temp;
+ }
+ }
+ }
+
+ //create pointer to image data
+ Edsdk.EdsGetPointer(stream, out streamPointer);
+ //Release all ressources
+ Edsdk.EdsRelease(img_stream);
+ Edsdk.EdsRelease(img_ref);
+ Edsdk.EdsRelease(stream);
+ try
+ {
+ var bitmap = new Bitmap(outputSize.width, outputSize.height, Stride, PixelFormat.Format24bppRgb,
+ streamPointer);
+ using (MemoryStream memostream = new MemoryStream())
+ {
+ bitmap.Save(memostream, ImageFormat.Bmp);
+ memostream.Close();
+
+ return memostream.ToArray();
+ }
+ }
+ catch (Exception exception)
+ {
+ Log.Error("Error loading image ", exception);
+ }
+ return new byte[0];
+ }
+
+ public override void FormatStorage(object storageId)
+ {
+ try
+ {
+ lock (Locker)
+ {
+ Camera.Lock();
+ int count = 0;
+ Log.Debug("EdsGetChildCount");
+ if (Edsdk.EdsGetChildCount(Camera.Handle, out count) != Edsdk.EDS_ERR_OK)
+ throw new DeviceException("Error EdsGetChildCount");
+ for (int i = 0; i < count; i++)
+ {
+ IntPtr volumePtr;
+ Log.Debug("EdsGetChildAtIndex");
+ if (Edsdk.EdsGetChildAtIndex(Camera.Handle, i, out volumePtr) != Edsdk.EDS_ERR_OK)
+ throw new DeviceException("Error EdsGetChildAtIndex");
+ Edsdk.EdsVolumeInfo vinfo;
+ Log.Debug("EdsGetVolumeInfo");
+ if (Edsdk.EdsGetVolumeInfo(volumePtr, out vinfo) != Edsdk.EDS_ERR_OK)
+ throw new DeviceException("Error EdsGetVolumeInfo");
+ //ignore the HDD
+ if (vinfo.szVolumeLabel != "HDD")
+ {
+ Log.Debug("EdsFormatVolume");
+ if (Edsdk.EdsFormatVolume(volumePtr) != Edsdk.EDS_ERR_OK)
+ throw new DeviceException("Error EdsFormatVolume");
+ }
+ Log.Debug("EdsRelease");
+ if (Edsdk.EdsRelease(volumePtr) != Edsdk.EDS_ERR_OK)
+ throw new DeviceException("Error EdsRelease");
+ }
+ }
+ }
+ finally
+ {
+ Camera.Unlock();
+ }
+ }
+
+ public override string ToStringCameraData()
+ {
+ /* Canon SDK adds a EosCamera object
+ BatteryLevel (long) and BatteryQuality (string)
+ Copyright (string)
+ FirmwareVersion (string)
+ ImageQuality
+ PrimaryCompressLevel
+ PrimateImageFormat
+ PrimateImageSize
+ IsInLiveViewMode (bool)
+ */
+
+ StringBuilder c = new StringBuilder(base.ToStringCameraData() + "\n\tType..................Canon (SDK)");
+
+ if (Camera != null)
+ {
+ c.AppendFormat("\n\tFirmware version......{0}", Camera.FirmwareVersion);
+ c.AppendFormat("\n\tDate/Time.............{0}", DateTime.ToString());
+ c.AppendFormat("\n\tBattery...............{0,3}%, quality {1}, (note base class value is this + 20)", Camera.BatteryLevel, Camera.BatteryQuality);
+ c.AppendFormat("\n\tIs in LiveView Mode...{0}", Camera.IsInLiveViewMode ? "Yes" : "No");
+ c.Append("\n\tImage Quality - Primary");
+ c.AppendFormat("\n\t Format..............{0}", Camera.ImageQuality.PrimaryImageFormat);
+ c.AppendFormat("\n\t Size................{0}", Camera.ImageQuality.PrimaryImageSize);
+ c.AppendFormat("\n\t Compression.........{0}", Camera.ImageQuality.PrimaryCompressLevel);
+ if (!Camera.ImageQuality.SecondaryImageFormat.Equals(EosImageFormat.Unknown))
+ {
+ c.Append("\n\tImage Quality - Secondary");
+ c.AppendFormat("\n\t Format..............{0}", Camera.ImageQuality.SecondaryImageFormat);
+ c.AppendFormat("\n\t Size................{0}", Camera.ImageQuality.SecondaryImageSize);
+ c.AppendFormat("\n\t Compression.........{0}", Camera.ImageQuality.SecondaryCompressLevel);
+ }
+ c.AppendFormat("\n\tArtist................{0}", Camera.Artist);
+ c.AppendFormat("\n\tCopyright (c).........{0}", Camera.Copyright);
+ c.AppendFormat("\n\tDepth Preview.........{0}", Camera.DepthOfFieldPreview ? "Yes" : "No");
+ c.AppendFormat("\n\tWhite Balance.........{0}", Camera.WhiteBalance);
+ }
+ return c.ToString();
+ }
+ }
+}
\ No newline at end of file
diff --git a/DigiCamControl/CameraControl.Devices/Classes/AsyncObservableCollection.cs b/DigiCamControl/CameraControl.Devices/Classes/AsyncObservableCollection.cs
new file mode 100644
index 0000000..87649cb
--- /dev/null
+++ b/DigiCamControl/CameraControl.Devices/Classes/AsyncObservableCollection.cs
@@ -0,0 +1,143 @@
+#region Licence
+
+// Distributed under MIT License
+// ===========================================================
+//
+// digiCamControl - DSLR camera remote control open source software
+// Copyright (C) 2014 Duka Istvan
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY,FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH
+// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#endregion
+
+#region
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Collections.Specialized;
+using System.Windows.Data;
+using System.ComponentModel;
+using System.Linq;
+using System.Threading;
+using System.Windows.Threading;
+
+#endregion
+
+namespace CameraControl.Devices.Classes
+{
+ public class AsyncObservableCollection : ObservableCollection
+ {
+ private SynchronizationContext _synchronizationContext = SynchronizationContext.Current;
+
+ public AsyncObservableCollection()
+ {
+ enableCollectionSynchronization(this, _syncLock);
+ }
+
+ public AsyncObservableCollection(IEnumerable list)
+ : base(list)
+ {
+ enableCollectionSynchronization(this, _syncLock);
+ }
+
+
+
+ private void RaiseCollectionChanged(object param)
+ {
+ // We are in the creator thread, call the base implementation directly
+ try
+ {
+ base.OnCollectionChanged((NotifyCollectionChangedEventArgs) param);
+ }
+ catch (Exception)
+ {
+ }
+ }
+
+ protected override void OnPropertyChanged(PropertyChangedEventArgs e)
+ {
+ if (SynchronizationContext.Current == _synchronizationContext)
+ {
+ // Execute the PropertyChanged event on the current thread
+ RaisePropertyChanged(e);
+ }
+ else
+ {
+ // Post the PropertyChanged event on the creator thread
+ if (_synchronizationContext != null)
+ _synchronizationContext.Post(RaisePropertyChanged, e);
+ }
+ }
+
+ private void RaisePropertyChanged(object param)
+ {
+ // We are in the creator thread, call the base implementation directly
+ base.OnPropertyChanged((PropertyChangedEventArgs) param);
+ }
+
+ public override event NotifyCollectionChangedEventHandler CollectionChanged;
+ private static object _syncLock = new object();
+
+
+ protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
+ {
+ using (BlockReentrancy())
+ {
+ try
+ {
+ var eh = CollectionChanged;
+ if (eh == null) return;
+
+ var dispatcher = (from NotifyCollectionChangedEventHandler nh in eh.GetInvocationList()
+ let dpo = nh.Target as DispatcherObject
+ where dpo != null
+ select dpo.Dispatcher).FirstOrDefault();
+
+ if (dispatcher != null && dispatcher.CheckAccess() == false)
+ {
+ dispatcher.Invoke(DispatcherPriority.DataBind, (Action)(() => OnCollectionChanged(e)));
+ }
+ else
+ {
+ foreach (NotifyCollectionChangedEventHandler nh in eh.GetInvocationList())
+ nh.Invoke(this, e);
+ }
+
+ }
+ catch (Exception)
+ {
+
+ }
+ }
+ }
+
+ private static void enableCollectionSynchronization(IEnumerable collection, object lockObject)
+ {
+ var method = typeof(BindingOperations).GetMethod("EnableCollectionSynchronization",
+ new Type[] { typeof(IEnumerable), typeof(object) });
+ if (method != null)
+ {
+ // It's .NET 4.5
+ method.Invoke(null, new object[] { collection, lockObject });
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/DigiCamControl/CameraControl.Devices/Classes/BaseFieldClass.cs b/DigiCamControl/CameraControl.Devices/Classes/BaseFieldClass.cs
new file mode 100644
index 0000000..4d10b5f
--- /dev/null
+++ b/DigiCamControl/CameraControl.Devices/Classes/BaseFieldClass.cs
@@ -0,0 +1,113 @@
+#region Licence
+
+// Distributed under MIT License
+// ===========================================================
+//
+// digiCamControl - DSLR camera remote control open source software
+// Copyright (C) 2014 Duka Istvan
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY,FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH
+// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#endregion
+
+#region
+
+using System;
+using System.Collections;
+using System.ComponentModel;
+using System.Reflection;
+
+#endregion
+
+namespace CameraControl.Devices.Classes
+{
+ public class BaseFieldClass : INotifyPropertyChanged
+ {
+ #region Implementation of IEditableObject
+
+ private Hashtable props = null;
+
+ public virtual void BeginEdit()
+ {
+ PropertyInfo[] properties = (GetType()).GetProperties
+ (BindingFlags.Public | BindingFlags.Instance);
+
+ props = new Hashtable(properties.Length - 1);
+
+ for (int i = 0; i < properties.Length; i++)
+ {
+ //check if there is set accessor
+
+ if (null != properties[i].GetSetMethod())
+ {
+ object value = properties[i].GetValue(this, null);
+ props.Add(properties[i].Name, value);
+ }
+ }
+ }
+
+ public virtual void EndEdit()
+ {
+ props = null;
+ }
+
+ public virtual void CancelEdit()
+ {
+ //check for inappropriate call sequence
+
+ if (null == props) return;
+
+ //restore old values
+
+ PropertyInfo[] properties = (GetType()).GetProperties
+ (BindingFlags.Public | BindingFlags.Instance);
+ for (int i = 0; i < properties.Length; i++)
+ {
+ //check if there is set accessor
+
+ if (null != properties[i].GetSetMethod())
+ {
+ object value = props[properties[i].Name];
+ properties[i].SetValue(this, value, null);
+ NotifyPropertyChanged(properties[i].Name);
+ }
+ }
+
+ //delete current values
+
+ props = null;
+ }
+
+ #endregion
+
+ #region Implementation of INotifyPropertyChanged
+
+ public virtual event PropertyChangedEventHandler PropertyChanged;
+
+ public virtual void NotifyPropertyChanged(String info)
+ {
+ if (PropertyChanged != null)
+ {
+ PropertyChanged(this, new PropertyChangedEventArgs(info));
+ }
+ }
+
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/DigiCamControl/CameraControl.Devices/Classes/CameraFieldType.cs b/DigiCamControl/CameraControl.Devices/Classes/CameraFieldType.cs
new file mode 100644
index 0000000..8fd7d78
--- /dev/null
+++ b/DigiCamControl/CameraControl.Devices/Classes/CameraFieldType.cs
@@ -0,0 +1,37 @@
+#region Licence
+
+// Distributed under MIT License
+// ===========================================================
+//
+// digiCamControl - DSLR camera remote control open source software
+// Copyright (C) 2014 Duka Istvan
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY,FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH
+// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#endregion
+
+namespace CameraControl.Devices.Classes
+{
+ public enum CameraFieldType
+ {
+ Comment,
+ Artist,
+ Copyright
+ }
+}
\ No newline at end of file
diff --git a/DigiCamControl/CameraControl.Devices/Classes/Capability.cs b/DigiCamControl/CameraControl.Devices/Classes/Capability.cs
new file mode 100644
index 0000000..7fbd970
--- /dev/null
+++ b/DigiCamControl/CameraControl.Devices/Classes/Capability.cs
@@ -0,0 +1,21 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace CameraControl.Devices.Classes
+{
+ public class Capability
+ {
+ ///
+ /// Current value of the specified parameter.
+ ///
+ public virtual T Current { set; get; }
+
+ ///
+ /// Candidate values of the specified parameter.
+ ///
+ public virtual List Candidates { set; get; }
+ }
+}
diff --git a/DigiCamControl/CameraControl.Devices/Classes/CapabilityEnum.cs b/DigiCamControl/CameraControl.Devices/Classes/CapabilityEnum.cs
new file mode 100644
index 0000000..0dc61ed
--- /dev/null
+++ b/DigiCamControl/CameraControl.Devices/Classes/CapabilityEnum.cs
@@ -0,0 +1,44 @@
+#region Licence
+
+// Distributed under MIT License
+// ===========================================================
+//
+// digiCamControl - DSLR camera remote control open source software
+// Copyright (C) 2014 Duka Istvan
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY,FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH
+// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#endregion
+
+namespace CameraControl.Devices.Classes
+{
+ public enum CapabilityEnum
+ {
+ LiveView,
+ LiveViewStream,
+ Bulb,
+ RecordMovie,
+ CanLockFocus,
+ CaptureInRam,
+ CaptureNoAf,
+ SimpleManualFocus,
+ Zoom
+ }
+
+}
\ No newline at end of file
diff --git a/DigiCamControl/CameraControl.Devices/Classes/Conts.cs b/DigiCamControl/CameraControl.Devices/Classes/Conts.cs
new file mode 100644
index 0000000..4e41722
--- /dev/null
+++ b/DigiCamControl/CameraControl.Devices/Classes/Conts.cs
@@ -0,0 +1,65 @@
+#region Licence
+
+// Distributed under MIT License
+// ===========================================================
+//
+// digiCamControl - DSLR camera remote control open source software
+// Copyright (C) 2014 Duka Istvan
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY,FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH
+// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#endregion
+
+#region
+
+using System.Runtime.InteropServices;
+
+#endregion
+
+namespace CameraControl.Devices.Classes
+{
+ public class Conts
+ {
+ [MarshalAs(UnmanagedType.LPStr)] public const string wiaEventDeviceConnected =
+ "{A28BBADE-64B6-11D2-A231-00C04FA31809}";
+
+ [MarshalAs(UnmanagedType.LPStr)] public const string wiaEventDeviceDisconnected =
+ "{143E4E83-6497-11D2-A231-00C04FA31809}";
+
+ [MarshalAs(UnmanagedType.LPStr)] public const string wiaEventItemCreated =
+ "{4C8F4EF5-E14F-11D2-B326-00C04F68CE61}";
+
+ [MarshalAs(UnmanagedType.LPStr)] public const string wiaEventItemDeleted =
+ "{1D22A559-E14F-11D2-B326-00C04F68CE61}";
+
+ [MarshalAs(UnmanagedType.LPStr)] public const string wiaCommandTakePicture =
+ "{AF933CAC-ACAD-11D2-A093-00C04F72DC3C}";
+
+ public const string CONST_PROP_F_Number = "F Number";
+ public const string CONST_PROP_ISO_Number = "Exposure Index";
+ public const string CONST_PROP_Exposure_Time = "Exposure Time";
+ public const string CONST_PROP_WhiteBalance = "White Balance";
+ public const string CONST_PROP_ExposureMode = "Exposure Mode";
+ public const string CONST_PROP_ExposureCompensation = "Exposure Compensation";
+ public const string CONST_PROP_BatteryStatus = "Battery Status";
+ public const string CONST_PROP_CompressionSetting = "Compression Setting";
+ public const string CONST_PROP_ExposureMeteringMode = "Exposure Metering Mode";
+ public const string CONST_PROP_FocusMode = "Focus Mode";
+ }
+}
\ No newline at end of file
diff --git a/DigiCamControl/CameraControl.Devices/Classes/DelayedDelegate.cs b/DigiCamControl/CameraControl.Devices/Classes/DelayedDelegate.cs
new file mode 100644
index 0000000..0b9452f
--- /dev/null
+++ b/DigiCamControl/CameraControl.Devices/Classes/DelayedDelegate.cs
@@ -0,0 +1,79 @@
+#region Licence
+
+// Distributed under MIT License
+// ===========================================================
+//
+// digiCamControl - DSLR camera remote control open source software
+// Copyright (C) 2014 Duka Istvan
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY,FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH
+// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#endregion
+
+#region
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Timers;
+
+#endregion
+
+namespace CameraControl.Devices.Classes
+{
+ public class DelayedDelegate
+ {
+ private static Timer runDelegates;
+ private static Dictionary delayedDelegates = new Dictionary();
+
+ static DelayedDelegate()
+ {
+ runDelegates = new Timer();
+ runDelegates.Interval = 250;
+ runDelegates.Elapsed += RunDelegates;
+ runDelegates.Enabled = true;
+ runDelegates.Start();
+ }
+
+ public static void Add(Action method, int delay)
+ {
+ delayedDelegates.Add(method, DateTime.Now + TimeSpan.FromMilliseconds(delay));
+ }
+
+ private static void RunDelegates(object sender, EventArgs e)
+ {
+ List removeDelegates = new List();
+
+ foreach (Action method in delayedDelegates.Keys)
+ {
+ if (DateTime.Now >= delayedDelegates[method])
+ {
+ method();
+ removeDelegates.Add(method);
+ }
+ }
+
+ foreach (Action method in removeDelegates)
+ {
+ delayedDelegates.Remove(method);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/DigiCamControl/CameraControl.Devices/Classes/DeviceDescriptor.cs b/DigiCamControl/CameraControl.Devices/Classes/DeviceDescriptor.cs
new file mode 100644
index 0000000..e9e82bb
--- /dev/null
+++ b/DigiCamControl/CameraControl.Devices/Classes/DeviceDescriptor.cs
@@ -0,0 +1,51 @@
+#region Licence
+
+// Distributed under MIT License
+// ===========================================================
+//
+// digiCamControl - DSLR camera remote control open source software
+// Copyright (C) 2014 Duka Istvan
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY,FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH
+// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#endregion
+
+#region
+
+using CameraControl.Devices.TransferProtocol;
+using Canon.Eos.Framework;
+using PortableDeviceLib;
+using WIA;
+
+#endregion
+
+namespace CameraControl.Devices.Classes
+{
+ public class DeviceDescriptor
+ {
+ public string SerialNumber { get; set; }
+ public string WpdId { get; set; }
+ public ICameraDevice CameraDevice { get; set; }
+ public string WiaId { get; set; }
+ public IDeviceInfo WiaDeviceInfo { get; set; }
+ public Device WiaDevice { get; set; }
+ public EosCamera EosCamera { get; set; }
+ public ITransferProtocol StillImageDevice { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/DigiCamControl/CameraControl.Devices/Classes/DeviceDescriptorEnumerator.cs b/DigiCamControl/CameraControl.Devices/Classes/DeviceDescriptorEnumerator.cs
new file mode 100644
index 0000000..3a13216
--- /dev/null
+++ b/DigiCamControl/CameraControl.Devices/Classes/DeviceDescriptorEnumerator.cs
@@ -0,0 +1,88 @@
+#region Licence
+
+// Distributed under MIT License
+// ===========================================================
+//
+// digiCamControl - DSLR camera remote control open source software
+// Copyright (C) 2014 Duka Istvan
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY,FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH
+// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#endregion
+
+#region
+
+using System.Collections.Generic;
+using System.Linq;
+using Canon.Eos.Framework;
+
+#endregion
+
+namespace CameraControl.Devices.Classes
+{
+ public class DeviceDescriptorEnumerator
+ {
+ public List Devices { get; set; }
+
+ public DeviceDescriptorEnumerator()
+ {
+ Devices = new List();
+ }
+
+ public DeviceDescriptor GetBySerialNumber(string serial)
+ {
+ return Devices.FirstOrDefault(deviceDescriptor => deviceDescriptor.SerialNumber == serial);
+ }
+
+ public DeviceDescriptor GetByWiaId(string id)
+ {
+ return Devices.FirstOrDefault(deviceDescriptor => deviceDescriptor.WiaId == id);
+ }
+
+ public DeviceDescriptor GetByWpdId(string id)
+ {
+ return Devices.FirstOrDefault(deviceDescriptor => deviceDescriptor.WpdId == id);
+ }
+
+ public DeviceDescriptor GetByEosCamera(EosCamera id)
+ {
+ return Devices.FirstOrDefault(deviceDescriptor => deviceDescriptor.EosCamera == id);
+ }
+
+ public void RemoveDisconnected()
+ {
+ List removedDevices =
+ Devices.Where(deviceDescriptor => !deviceDescriptor.CameraDevice.IsConnected).ToList();
+ foreach (DeviceDescriptor deviceDescriptor in removedDevices)
+ {
+ Devices.Remove(deviceDescriptor);
+ }
+ }
+
+ public void Add(DeviceDescriptor descriptor)
+ {
+ Devices.Add(descriptor);
+ }
+
+ public void Remove(DeviceDescriptor descriptor)
+ {
+ Devices.Remove(descriptor);
+ }
+ }
+}
\ No newline at end of file
diff --git a/DigiCamControl/CameraControl.Devices/Classes/DeviceException.cs b/DigiCamControl/CameraControl.Devices/Classes/DeviceException.cs
new file mode 100644
index 0000000..fe8814f
--- /dev/null
+++ b/DigiCamControl/CameraControl.Devices/Classes/DeviceException.cs
@@ -0,0 +1,92 @@
+#region Licence
+
+// Distributed under MIT License
+// ===========================================================
+//
+// digiCamControl - DSLR camera remote control open source software
+// Copyright (C) 2014 Duka Istvan
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY,FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH
+// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#endregion
+
+#region
+
+using System;
+using System.Runtime.Serialization;
+
+#endregion
+
+namespace CameraControl.Devices.Classes
+{
+ [Serializable]
+ public class DeviceException : Exception
+ {
+ public uint ErrorCode { get; set; }
+
+ public DeviceException(string message)
+ : base(message)
+ {
+ }
+
+ public DeviceException(string message, uint errorcode)
+ : base(message)
+ {
+ ErrorCode = errorcode;
+ }
+
+ public DeviceException(string message, int errorcode)
+ : base(message)
+ {
+ ErrorCode = (uint) errorcode;
+ }
+
+ public DeviceException(string format, params object[] args)
+ : base(string.Format(format, args))
+ {
+ }
+
+ public DeviceException(string message, Exception innerException)
+ : base(message, innerException)
+ {
+ }
+
+ public DeviceException(string message, Exception innerException, uint code)
+ : base(message, innerException)
+ {
+ ErrorCode = code;
+ }
+
+
+ public DeviceException(string format, Exception innerException, params object[] args)
+ : base(string.Format(format, args), innerException)
+ {
+ }
+
+ protected DeviceException(SerializationInfo info, StreamingContext context)
+ : base(info, context)
+ {
+ }
+
+ public DeviceException()
+ : base()
+ {
+ }
+ }
+}
\ No newline at end of file
diff --git a/DigiCamControl/CameraControl.Devices/Classes/DeviceObject.cs b/DigiCamControl/CameraControl.Devices/Classes/DeviceObject.cs
new file mode 100644
index 0000000..b00f611
--- /dev/null
+++ b/DigiCamControl/CameraControl.Devices/Classes/DeviceObject.cs
@@ -0,0 +1,44 @@
+#region Licence
+
+// Distributed under MIT License
+// ===========================================================
+//
+// digiCamControl - DSLR camera remote control open source software
+// Copyright (C) 2014 Duka Istvan
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY,FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH
+// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#endregion
+
+#region
+
+using System;
+
+#endregion
+
+namespace CameraControl.Devices.Classes
+{
+ public class DeviceObject
+ {
+ public object Handle { get; set; }
+ public string FileName { get; set; }
+ public byte[] ThumbData { get; set; }
+ public DateTime FileDate { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/DigiCamControl/CameraControl.Devices/Classes/DisconnectCameraEventArgs.cs b/DigiCamControl/CameraControl.Devices/Classes/DisconnectCameraEventArgs.cs
new file mode 100644
index 0000000..6fabb67
--- /dev/null
+++ b/DigiCamControl/CameraControl.Devices/Classes/DisconnectCameraEventArgs.cs
@@ -0,0 +1,48 @@
+#region Licence
+
+// Distributed under MIT License
+// ===========================================================
+//
+// digiCamControl - DSLR camera remote control open source software
+// Copyright (C) 2014 Duka Istvan
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY,FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH
+// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#endregion
+
+#region
+
+using System;
+using CameraControl.Devices.TransferProtocol;
+using Canon.Eos.Framework;
+using PortableDeviceLib;
+
+#endregion
+
+namespace CameraControl.Devices.Classes
+{
+ public delegate void CameraDisconnectedEventHandler(object sender, DisconnectCameraEventArgs eventArgs);
+
+ public class DisconnectCameraEventArgs : EventArgs
+ {
+ public string WiaId { get; set; }
+ public ITransferProtocol StillImageDevice { get; set; }
+ public EosCamera EosCamera { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/DigiCamControl/CameraControl.Devices/Classes/ErrorCodes.cs b/DigiCamControl/CameraControl.Devices/Classes/ErrorCodes.cs
new file mode 100644
index 0000000..2102f85
--- /dev/null
+++ b/DigiCamControl/CameraControl.Devices/Classes/ErrorCodes.cs
@@ -0,0 +1,174 @@
+#region Licence
+
+// Distributed under MIT License
+// ===========================================================
+//
+// digiCamControl - DSLR camera remote control open source software
+// Copyright (C) 2014 Duka Istvan
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY,FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH
+// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#endregion
+
+#region
+
+using System.Runtime.InteropServices;
+using Canon.Eos.Framework.Internal.SDK;
+
+#endregion
+
+namespace CameraControl.Devices.Classes
+{
+ public class ErrorCodes
+ {
+ public const uint WIA_ERROR_GENERAL_ERROR = 0x80210001;
+ public const uint WIA_ERROR_OFFLINE = 0x80210005;
+ public const uint WIA_ERROR_BUSY = 0x80210006;
+ public const uint WIA_ERROR_DEVICE_COMMUNICATION = 0x8021000A;
+ public const uint WIA_ERROR_INVALID_COMMAND = 0x8021000B;
+ public const uint WIA_ERROR_INCORRECT_HARDWARE_SETTING = 0x8021000C;
+ public const uint WIA_ERROR_DEVICE_LOCKED = 0x8021000D;
+ public const uint WIA_ERROR_EXCEPTION_IN_DRIVER = 0x8021000E;
+ public const uint WIA_ERROR_INVALID_DRIVER_RESPONSE = 0x8021000F;
+ public const uint WIA_S_NO_DEVICE_AVAILABLE = 0x80210015;
+ public const uint WIA_ERROR_UNABLE_TO_FOCUS = 0x80004005;
+
+ public const uint MTP_OK = 0x2001;
+ public const uint MTP_General_Error = 0x2002;
+ public const uint MTP_Device_Busy = 0x2019;
+ public const uint MTP_Set_Property_Not_Support = 0xA005;
+ public const uint MTP_Store_Not_Available = 0x2013;
+ public const uint MTP_Out_of_Focus = 0xA002;
+ public const uint MTP_Shutter_Speed_Bulb = 0xA008;
+ public const uint MTP_Store_Full = 0x200C;
+ public const uint MTP_Store_Read_Only = 0x200E;
+ public const uint MTP_Parameter_Not_Supported = 0x2006;
+ public const uint MTP_Not_LiveView = 0xA00B;
+ public const uint MTP_Invalid_Parameter = 0x201D;
+ public const uint MTP_Invalid_Status = 0xA004;
+ public const uint MTP_Operation_Not_Supported = 0x2005;
+ public const uint MTP_Access_Denied = 0x200F;
+
+
+ public const uint E_WPD_DEVICE_IS_HUNG = 0x802A0006;
+ public const uint ERROR_BUSY = 0x800700AA;
+
+ public static void GetException(int code)
+ {
+ GetException((uint) code);
+ }
+
+ public static void GetCanonException(uint code)
+ {
+ if (code != 0 && code != Edsdk.EDS_ERR_OK)
+ {
+ switch (code)
+ {
+ default:
+ throw new DeviceException("Canon error code: " + code.ToString("X"), code);
+ }
+ }
+ }
+
+ public static void GetException(uint code)
+ {
+ if (code != 0 && code != MTP_OK)
+ {
+ switch (code)
+ {
+ case MTP_Device_Busy:
+ throw new DeviceException("Device MTP error: Device is busy", code);
+ case MTP_General_Error:
+ throw new DeviceException("General error. No focus ?", code);
+ case MTP_Store_Not_Available:
+ throw new DeviceException("The card cannot be accessed", code);
+ case MTP_Shutter_Speed_Bulb:
+ throw new DeviceException("Bulb mode isn't supported", code);
+ case MTP_Out_of_Focus:
+ throw new DeviceException("Unable to focus.", code);
+ case MTP_Store_Full:
+ throw new DeviceException("Storage is full.", code);
+ case MTP_Store_Read_Only:
+ throw new DeviceException("Storage is read only.", code);
+ case MTP_Not_LiveView:
+ throw new DeviceException("Not in live view.", code);
+ case MTP_Invalid_Parameter:
+ throw new DeviceException("Invalid parameter. Coding error !", code);
+ case MTP_Parameter_Not_Supported:
+ throw new DeviceException("Parameter Not Supported. Coding error !", code);
+ case MTP_Invalid_Status:
+ throw new DeviceException("Invalid status.", code);
+ case MTP_Access_Denied:
+ throw new DeviceException("Access denied.", code);
+ case MTP_Set_Property_Not_Support:
+ throw new DeviceException("Set Property Not Support.", code);
+ case E_WPD_DEVICE_IS_HUNG:
+ throw new DeviceException("E_WPD_DEVICE_IS_HUNG", code);
+ case ERROR_BUSY:
+ throw new DeviceException("MTP device busy", code);
+ case MTP_Operation_Not_Supported:
+ throw new DeviceException("Operation Not Supported", code);
+ default:
+ throw new DeviceException("Device MTP error code: " + code.ToString("X"), code);
+ }
+ }
+ }
+
+ public static void GetException(COMException exception)
+ {
+ switch ((uint) exception.ErrorCode)
+ {
+ case WIA_ERROR_BUSY:
+ throw new DeviceException("Device is busy. Error code :WIA_ERROR_BUSY", exception,
+ (uint) exception.ErrorCode);
+ case WIA_ERROR_DEVICE_COMMUNICATION:
+ throw new DeviceException("Device communication error. Error code :WIA_ERROR_DEVICE_COMMUNICATION",
+ exception, (uint) exception.ErrorCode);
+ case WIA_ERROR_DEVICE_LOCKED:
+ throw new DeviceException("Device is locked. Error code :WIA_ERROR_DEVICE_LOCKED", exception,
+ (uint) exception.ErrorCode);
+ case WIA_ERROR_EXCEPTION_IN_DRIVER:
+ throw new DeviceException("Exception in driver. Error code :WIA_ERROR_EXCEPTION_IN_DRIVER",
+ exception, (uint) exception.ErrorCode);
+ case WIA_ERROR_GENERAL_ERROR:
+ throw new DeviceException("General error. Error code :WIA_ERROR_GENERAL_ERROR", exception,
+ (uint) exception.ErrorCode);
+ case WIA_ERROR_INCORRECT_HARDWARE_SETTING:
+ throw new DeviceException(
+ "Incorrect hardware error. Error code :WIA_ERROR_INCORRECT_HARDWARE_SETTING", exception,
+ (uint) exception.ErrorCode);
+ case WIA_ERROR_INVALID_COMMAND:
+ throw new DeviceException("Invalid command. Error code :WIA_ERROR_INVALID_COMMAND", exception,
+ (uint) exception.ErrorCode);
+ case WIA_ERROR_INVALID_DRIVER_RESPONSE:
+ throw new DeviceException("Invalid driver response. Error code :WIA_ERROR_INVALID_DRIVER_RESPONSE",
+ exception, (uint) exception.ErrorCode);
+ case WIA_ERROR_OFFLINE:
+ throw new DeviceException("Device is offline. Error code :WIA_ERROR_OFFLINE", exception,
+ WIA_ERROR_OFFLINE, (uint) exception.ErrorCode);
+ case WIA_ERROR_UNABLE_TO_FOCUS:
+ throw new DeviceException("Unable to focus. Error code :WIA_ERROR_UNABLE_TO_FOCUS", exception,
+ WIA_ERROR_UNABLE_TO_FOCUS, (uint) exception.ErrorCode);
+ default:
+ throw new DeviceException("Unknown error. Error code:" + (uint) exception.ErrorCode, exception,
+ (uint) exception.ErrorCode);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/DigiCamControl/CameraControl.Devices/Classes/FocusAmount.cs b/DigiCamControl/CameraControl.Devices/Classes/FocusAmount.cs
new file mode 100644
index 0000000..9140859
--- /dev/null
+++ b/DigiCamControl/CameraControl.Devices/Classes/FocusAmount.cs
@@ -0,0 +1,9 @@
+namespace CameraControl.Devices.Classes
+{
+ public enum FocusAmount
+ {
+ Small,
+ Medium,
+ Large
+ }
+}
\ No newline at end of file
diff --git a/DigiCamControl/CameraControl.Devices/Classes/FocusDirection.cs b/DigiCamControl/CameraControl.Devices/Classes/FocusDirection.cs
new file mode 100644
index 0000000..7899f24
--- /dev/null
+++ b/DigiCamControl/CameraControl.Devices/Classes/FocusDirection.cs
@@ -0,0 +1,8 @@
+namespace CameraControl.Devices.Classes
+{
+ public enum FocusDirection
+ {
+ Near,
+ Far
+ }
+}
\ No newline at end of file
diff --git a/DigiCamControl/CameraControl.Devices/Classes/HttpHelper.cs b/DigiCamControl/CameraControl.Devices/Classes/HttpHelper.cs
new file mode 100644
index 0000000..66948d2
--- /dev/null
+++ b/DigiCamControl/CameraControl.Devices/Classes/HttpHelper.cs
@@ -0,0 +1,60 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Net;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace CameraControl.Devices.Classes
+{
+ public static class HttpHelper
+ {
+ public static void DownLoadFileByWebRequest(string urlAddress, string filePath, ICameraDevice device,long size=0)
+ {
+ try
+ {
+ HttpWebRequest request = null;
+ HttpWebResponse response = null;
+ request = (HttpWebRequest)WebRequest.Create(urlAddress);
+ request.Timeout = 30000; //8000 Not work
+ response = (HttpWebResponse)request.GetResponse();
+ Stream s = response.GetResponseStream();
+ if (File.Exists(filePath))
+ {
+ File.Delete(filePath);
+ }
+
+ FileStream os = new FileStream(filePath, FileMode.OpenOrCreate, FileAccess.Write);
+ byte[] buff = new byte[102400];
+ int c = 0;
+ int totalsize = 0;
+ while ((c = s.Read(buff, 0, 102400)) > 0)
+ {
+ os.Write(buff, 0, c);
+ os.Flush();
+ totalsize += c;
+ if (size > 0)
+ {
+ device.TransferProgress = (uint)(totalsize/(double)size*100.0);
+ }
+ else
+ {
+ device.TransferProgress += 1;
+ }
+
+ }
+ os.Close();
+ s.Close();
+ device.TransferProgress = 100;
+ }
+ catch(Exception ex)
+ {
+ Log.Error("Error download file", ex);
+ }
+ finally
+ {
+ }
+ }
+ }
+}
diff --git a/DigiCamControl/CameraControl.Devices/Classes/LiveViewData.cs b/DigiCamControl/CameraControl.Devices/Classes/LiveViewData.cs
new file mode 100644
index 0000000..fa5a604
--- /dev/null
+++ b/DigiCamControl/CameraControl.Devices/Classes/LiveViewData.cs
@@ -0,0 +1,132 @@
+#region Licence
+
+// Distributed under MIT License
+// ===========================================================
+//
+// digiCamControl - DSLR camera remote control open source software
+// Copyright (C) 2014 Duka Istvan
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY,FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH
+// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#endregion
+
+namespace CameraControl.Devices.Classes
+{
+ public class LiveViewData
+ {
+ public int LiveViewImageWidth { get; set; }
+ public int LiveViewImageHeight { get; set; }
+
+ ///
+ /// Gets or sets the width of the captured image.
+ ///
+ ///
+ /// The width of the image.
+ ///
+ public int ImageWidth { get; set; }
+ ///
+ /// Gets or sets the height of the captured image.
+ ///
+ ///
+ /// The height of the image.
+ ///
+ public int ImageHeight { get; set; }
+
+ ///
+ /// Gets or sets the focus point x axis .
+ ///
+ ///
+ /// The focus x.
+ ///
+ public int FocusX { get; set; }
+ ///
+ /// Gets or sets the focus point y axis.
+ ///
+ ///
+ /// The focus y.
+ ///
+ public int FocusY { get; set; }
+
+ public int FocusFrameXSize { get; set; }
+ public int FocusFrameYSize { get; set; }
+
+
+ ///
+ /// Gets or sets a value indicating whether focussing info included.
+ ///
+ ///
+ /// true if [have focus data]; otherwise, false.
+ ///
+ public bool HaveFocusData { get; set; }
+
+ ///
+ /// Gets or sets the live view image data.
+ /// May contain additional information, use ImageDataPosition to get live view image
+ ///
+ ///
+ /// The image data.
+ ///
+ public byte[] ImageData { get; set; }
+
+ public bool Focused { get; set; }
+
+ ///
+ /// Gets or sets the image data starting position in ImageData.
+ ///
+ ///
+ /// The image data position.
+ ///
+ public int ImageDataPosition { get; set; }
+
+ public int Rotation { get; set; }
+
+ public bool MovieIsRecording { get; set; }
+
+ public bool IsLiveViewRunning { get; set; }
+
+ public bool HaveLevelAngleData { get; set; }
+
+ public decimal LevelAngleRolling { get; set; }
+
+ public decimal LevelAnglePitching { get; set; }
+
+ public decimal LevelAngleYawing { get; set; }
+
+ public decimal MovieTimeRemain { get; set; }
+
+ public int SoundL { get; set; }
+
+ public int SoundR { get; set; }
+
+ public int PeakSoundL { get; set; }
+
+ public int PeakSoundR { get; set; }
+
+ public bool HaveSoundData { get; set; }
+
+ public LiveViewData()
+ {
+ IsLiveViewRunning = true;
+ HaveLevelAngleData = false;
+ SoundL = 0;
+ SoundR = 0;
+ HaveSoundData = false;
+ }
+ }
+}
\ No newline at end of file
diff --git a/DigiCamControl/CameraControl.Devices/Classes/LogEventArgs.cs b/DigiCamControl/CameraControl.Devices/Classes/LogEventArgs.cs
new file mode 100644
index 0000000..3ab0d96
--- /dev/null
+++ b/DigiCamControl/CameraControl.Devices/Classes/LogEventArgs.cs
@@ -0,0 +1,42 @@
+#region Licence
+
+// Distributed under MIT License
+// ===========================================================
+//
+// digiCamControl - DSLR camera remote control open source software
+// Copyright (C) 2014 Duka Istvan
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY,FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH
+// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#endregion
+
+#region
+
+using System;
+
+#endregion
+
+namespace CameraControl.Devices.Classes
+{
+ public class LogEventArgs : EventArgs
+ {
+ public object Message { get; set; }
+ public Exception Exception { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/DigiCamControl/CameraControl.Devices/Classes/OperationEnum.cs b/DigiCamControl/CameraControl.Devices/Classes/OperationEnum.cs
new file mode 100644
index 0000000..46b9a62
--- /dev/null
+++ b/DigiCamControl/CameraControl.Devices/Classes/OperationEnum.cs
@@ -0,0 +1,39 @@
+#region Licence
+
+// Distributed under MIT License
+// ===========================================================
+//
+// digiCamControl - DSLR camera remote control open source software
+// Copyright (C) 2014 Duka Istvan
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY,FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH
+// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#endregion
+
+namespace CameraControl.Devices.Classes
+{
+ public enum OperationEnum
+ {
+ Capture,
+ RecordMovie,
+ AutoFocus,
+ ManualFocus,
+ LiveView
+ }
+}
\ No newline at end of file
diff --git a/DigiCamControl/CameraControl.Devices/Classes/PhotoCapturedEventArgs.cs b/DigiCamControl/CameraControl.Devices/Classes/PhotoCapturedEventArgs.cs
new file mode 100644
index 0000000..6fc6bdc
--- /dev/null
+++ b/DigiCamControl/CameraControl.Devices/Classes/PhotoCapturedEventArgs.cs
@@ -0,0 +1,70 @@
+#region Licence
+
+// Distributed under MIT License
+// ===========================================================
+//
+// digiCamControl - DSLR camera remote control open source software
+// Copyright (C) 2014 Duka Istvan
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY,FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH
+// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#endregion
+
+#region
+
+using System;
+using WIA;
+
+#endregion
+
+namespace CameraControl.Devices.Classes
+{
+ public delegate void PhotoCapturedEventHandler(object sender, PhotoCapturedEventArgs eventArgs);
+
+ public class PhotoCapturedEventArgs
+ {
+ private Item _wiaImageItem;
+
+ public Item WiaImageItem
+ {
+ get { return _wiaImageItem; }
+ set
+ {
+ _wiaImageItem = value;
+ //ImageFile = (ImageFile)WiaImageItem.Transfer("{B96B3CAE-0728-11D3-9D7B-0000F81EF32E}");
+ }
+ }
+
+ public ImageFile ImageFile { get; set; }
+
+ public bool Transfer(string fileName)
+ {
+ //imageFile.SaveFile(fileName);
+ return true;
+ }
+
+ public object EventArgs { get; set; }
+
+ public ICameraDevice CameraDevice { get; set; }
+ public string FileName { get; set; }
+ public object Handle { get; set; }
+
+
+ }
+}
\ No newline at end of file
diff --git a/DigiCamControl/CameraControl.Devices/Classes/PictureControl.cs b/DigiCamControl/CameraControl.Devices/Classes/PictureControl.cs
new file mode 100644
index 0000000..facb7bf
--- /dev/null
+++ b/DigiCamControl/CameraControl.Devices/Classes/PictureControl.cs
@@ -0,0 +1,61 @@
+#region Licence
+
+// Distributed under MIT License
+// ===========================================================
+//
+// digiCamControl - DSLR camera remote control open source software
+// Copyright (C) 2014 Duka Istvan
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY,FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH
+// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#endregion
+
+#region
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+#endregion
+
+namespace CameraControl.Devices.Classes
+{
+ public class PictureControl
+ {
+ public byte ItemNumber { get; set; }
+ public bool IsLoaded { get; set; }
+ public bool Monocrome { get; set; }
+ public byte CustomFlag { get; set; }
+ public string RegistrationName { get; set; }
+ public byte QuickAdjustFlag { get; set; }
+ public sbyte QuickAdjust { get; set; }
+ public sbyte Saturation { get; set; }
+ public sbyte Hue { get; set; }
+ public sbyte Sharpening { get; set; }
+ public sbyte Contrast { get; set; }
+ public sbyte Brightness { get; set; }
+ public byte CustomCurveFlag { get; set; }
+ public byte[] CustomCurveData { get; set; }
+ //color
+ public byte FilterEffects { get; set; }
+ public byte Toning { get; set; }
+ public byte ToningDensity { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/DigiCamControl/CameraControl.Devices/Classes/PropertyValue.cs b/DigiCamControl/CameraControl.Devices/Classes/PropertyValue.cs
new file mode 100644
index 0000000..ff6e5af
--- /dev/null
+++ b/DigiCamControl/CameraControl.Devices/Classes/PropertyValue.cs
@@ -0,0 +1,506 @@
+#region Licence
+
+// Distributed under MIT License
+// ===========================================================
+//
+// digiCamControl - DSLR camera remote control open source software
+// Copyright (C) 2014 Duka Istvan
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY,FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH
+// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#endregion
+
+#region
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading;
+using PortableDeviceLib;
+
+#endregion
+
+namespace CameraControl.Devices.Classes
+{
+ public class PropertyValue : BaseFieldClass
+ {
+ public delegate void ValueChangedEventHandler(object sender, string key, T val);
+
+ public event ValueChangedEventHandler ValueChanged;
+
+ private Dictionary _valuesDictionary;
+ private Dictionary _replaceValues;
+ private AsyncObservableCollection _numericValues = new AsyncObservableCollection();
+ private AsyncObservableCollection _values = new AsyncObservableCollection();
+ private bool _notifyValuChange = true;
+ private readonly object _syncRoot = new object();
+ public string Tag { get; set; }
+
+
+ private uint _code;
+
+ public uint Code
+ {
+ get { return _code; }
+ set
+ {
+ _code = value;
+ NotifyPropertyChanged("Code");
+ }
+ }
+ ///
+ /// Indicate if the property is available and can be used
+ ///
+ public bool Available
+ {
+ get { return _available; }
+ set
+ {
+ _available = value;
+ NotifyPropertyChanged("Available");
+ }
+ }
+
+ ///
+ /// Gets or sets a value indicating the propertie
+ /// settings wasn't errorless.
+ ///
+ ///
+ /// true if [have error]; otherwise, false.
+ ///
+ public bool HaveError
+ {
+ get { return _haveError; }
+ set
+ {
+ _haveError = value;
+ NotifyPropertyChanged("HaveError");
+ NotifyPropertyChanged("ErrorColor");
+ }
+ }
+
+ public string ErrorColor
+ {
+ get { return HaveError ? "Red" : "Transparent"; }
+ }
+
+ public Type SubType { get; set; }
+ public bool DisableIfWrongValue { get; set; }
+
+ private string _name;
+
+ public string Name
+ {
+ get { return _name; }
+ set
+ {
+ _name = value;
+ NotifyPropertyChanged("Name");
+ }
+ }
+
+ private string _value;
+
+ public string Value
+ {
+ get
+ {
+ if (_value != null && _replaceValues != null && _replaceValues.Count > 0)
+ {
+ foreach (var replaceValue in _replaceValues.Where(replaceValue => replaceValue.Value == _value))
+ {
+ return replaceValue.Key;
+ }
+ }
+ return _value;
+ }
+ set
+ {
+ _value = value;
+ if (_value != null)
+ {
+ if (_replaceValues != null && _replaceValues.Count > 0 && _replaceValues.ContainsKey(_value))
+ {
+ _value = _replaceValues[_value];
+ }
+
+ HaveError = false;
+ if (ValueChanged != null && _notifyValuChange)
+ {
+ if (_valuesDictionary.ContainsKey(_value))
+ {
+ OnValueChanged(this, _value, _valuesDictionary[_value]);
+ }
+ }
+ }
+ else
+ {
+
+ }
+ NotifyPropertyChanged("Value");
+ }
+ }
+
+ private T _numericValue;
+
+ public T NumericValue
+ {
+ get { return _numericValue; }
+ set
+ {
+ _numericValue = value;
+ NotifyPropertyChanged("NumericValue");
+ }
+ }
+
+ public void NextValue()
+ {
+ lock (_syncRoot)
+ {
+ if (Values == null || Values.Count == 0 || !IsEnabled)
+ return;
+ int ind = Values.IndexOf(Value);
+ if (ind < 0)
+ return;
+ ind++;
+ if (ind < Values.Count)
+ Value = Values[ind];
+ }
+ }
+
+ public void PrevValue()
+ {
+ lock (_syncRoot)
+ {
+ if (Values == null || Values.Count == 0 || !IsEnabled)
+ return;
+ int ind = Values.IndexOf(Value);
+ ind--;
+ if (ind < 0)
+ return;
+
+ if (ind < Values.Count)
+ Value = Values[ind];
+ }
+ }
+
+
+ public void OnValueChanged(object sender, string key, T val)
+ {
+ Thread thread = new Thread(OnValueChangedThread);
+ thread.Name = "SetProperty thread " + Name;
+ thread.Start(new object[] { sender, key, val });
+ thread.Join(200);
+ }
+
+ public void OnValueChangedThread(object obj)
+ {
+ lock (_syncRoot)
+ {
+ object[] objparams = obj as object[];
+ bool retry;
+ int retrynum = 5;
+ do
+ {
+ retry = false;
+ try
+ {
+ object sender = objparams[0];
+ string key = objparams[1] as string;
+ T val = (T)objparams[2];
+ ValueChanged(sender, key, val);
+ }
+ catch (DeviceException exception)
+ {
+ if ((exception.ErrorCode == ErrorCodes.ERROR_BUSY ||
+ exception.ErrorCode == ErrorCodes.MTP_Device_Busy) && retrynum > 0)
+ {
+ retrynum--;
+ retry = true;
+ Thread.Sleep(100);
+ }
+ }
+ } while (retry);
+ }
+ }
+
+ private bool _isEnabled;
+ private bool _haveError;
+ private bool _available;
+
+ public bool IsEnabled
+ {
+ get
+ {
+ //if (Values == null || Values.Count==0)
+ // return false;
+ //if (DisableIfWrongValue)
+ //{
+ // return _isEnabled && !string.IsNullOrEmpty(Value);
+ //}
+ //else
+ //{
+ // return _isEnabled;
+ //}
+ return _isEnabled;
+ }
+ set
+ {
+ _isEnabled = value;
+ NotifyPropertyChanged("IsEnabled");
+ }
+ }
+
+ public AsyncObservableCollection Values
+ {
+ get
+ {
+ //if (_valuesDictionary.Count > 0 && _values.Count == 0)
+ // ReloadValues();
+ return _values;
+ }
+ }
+
+ public AsyncObservableCollection NumericValues
+ {
+ get { return _numericValues; }
+ }
+
+ public PropertyValue()
+ {
+ _valuesDictionary = new Dictionary();
+ _replaceValues = new Dictionary();
+ DisableIfWrongValue = false;
+ IsEnabled = true;
+ Available = true;
+ }
+
+ public void SetValue(T o, bool notifyValuChange)
+ {
+ _notifyValuChange = notifyValuChange;
+ SetValue(o);
+ _notifyValuChange = true;
+ }
+
+ public void SetValue(T o)
+ {
+ lock (_syncRoot)
+ {
+ NumericValue = o;
+ foreach (KeyValuePair keyValuePair in _valuesDictionary)
+ {
+ if (EqualityComparer.Default.Equals(keyValuePair.Value, o))
+ //(keyValuePair.Value== o)
+ {
+ Value = keyValuePair.Key;
+ return;
+ }
+ }
+ }
+ }
+
+ public void Filter(List values)
+ {
+ var old = new Dictionary(_valuesDictionary);
+ _valuesDictionary.Clear();
+ foreach (var val in old)
+ {
+ if (values.Contains(val.Value))
+ _valuesDictionary.Add(val.Key, val.Value);
+ }
+ _values = new AsyncObservableCollection(_valuesDictionary.Keys);
+ _numericValues = new AsyncObservableCollection(_valuesDictionary.Values);
+ NotifyPropertyChanged("Values");
+ }
+
+ public void SetValue()
+ {
+ Value = Value;
+ }
+
+
+ public void SetValue(string o, bool notifyValuChange = true)
+ {
+ lock (_syncRoot)
+ {
+ foreach (KeyValuePair keyValuePair in _valuesDictionary)
+ {
+ if (keyValuePair.Key == o)
+ {
+ _notifyValuChange = notifyValuChange;
+ Value = keyValuePair.Key;
+ _notifyValuChange = true;
+ return;
+ }
+ }
+ }
+ }
+
+ public void SetValue(byte[] ba, bool notifyValuChange)
+ {
+ _notifyValuChange = notifyValuChange;
+ SetValue(ba);
+ _notifyValuChange = true;
+ }
+
+ public void SetValue(MTPDataResponse data, bool notifyValuChange)
+ {
+ _notifyValuChange = notifyValuChange;
+ SetValue(data.Data);
+ _notifyValuChange = true;
+ }
+
+ public void SetValue(byte[] ba)
+ {
+ if (ba == null || ba.Length < 1)
+ return;
+ if (typeof(T) == typeof(int))
+ {
+ int val = ba.Length == 1 ? ba[0] : BitConverter.ToInt16(ba, 0);
+ SetValue((T)((object)val));
+ }
+ if (typeof(T) == typeof(uint))
+ {
+ uint val = BitConverter.ToUInt16(ba, 0);
+ SetValue((T)((object)val));
+ }
+ if (typeof(T) == typeof(long) && SubType == typeof(sbyte))
+ {
+ long val = Convert.ToSByte(ba[0]);
+ SetValue((T)((object)val));
+ return;
+ }
+ if (typeof(T) == typeof(long) && ba.Length == 1)
+ {
+ long val = ba[0];
+ SetValue((T)((object)val));
+ return;
+ }
+ if (typeof(T) == typeof(long) && ba.Length == 2 && SubType == typeof(UInt16))
+ {
+ long val = BitConverter.ToUInt16(ba, 0);
+ SetValue((T)((object)val));
+ return;
+ }
+ if (typeof(T) == typeof(long) && ba.Length == 2)
+ {
+ long val = BitConverter.ToInt16(ba, 0);
+ SetValue((T)((object)val));
+ return;
+ }
+ if (typeof(T) == typeof(long) && ba.Length == 4)
+ {
+ long val = BitConverter.ToUInt32(ba, 0);
+ SetValue((T)((object)val));
+ return;
+ }
+ if (typeof(T) == typeof(long))
+ {
+ long val = BitConverter.ToInt64(ba, 0);
+ SetValue((T)((object)val));
+ }
+ if (typeof(T) == typeof(uint))
+ {
+ uint val = BitConverter.ToUInt16(ba, 0);
+ SetValue((T)((object)val));
+ }
+ }
+
+ ///
+ /// After value add finished, ReloadValues should be called
+ ///
+ ///
+ ///
+ public void AddValues(string key, T value)
+ {
+
+ if (!_valuesDictionary.ContainsKey(key))
+ _valuesDictionary.Add(key, value);
+ }
+
+ ///
+ /// Reload display values
+ /// Should be called always after AddValues
+ ///
+ public void ReloadValues()
+ {
+ _values = new AsyncObservableCollection(_valuesDictionary.Keys);
+ _numericValues = new AsyncObservableCollection(_valuesDictionary.Values);
+ NotifyPropertyChanged("Values");
+ }
+
+ ///
+ /// Refresh display values based on replace values
+ ///
+ public void GetValues()
+ {
+ lock (_syncRoot)
+ {
+ string newVal = Value;
+ _values.Clear();
+ NotifyPropertyChanged("Values");
+ _values = new AsyncObservableCollection(_valuesDictionary.Keys);
+ if (_replaceValues != null && _replaceValues.Count > 0)
+ {
+ for (int i = 0; i < _values.Count; i++)
+ {
+ if (_replaceValues.ContainsValue(_values[i]))
+ {
+ foreach (var value in _replaceValues)
+ {
+ if (value.Value == _values[i])
+ _values[i] = value.Key;
+ }
+ }
+ }
+ }
+ _numericValues = new AsyncObservableCollection(_valuesDictionary.Values);
+ NotifyPropertyChanged("Values");
+ Value = newVal;
+ }
+ }
+
+ ///
+ /// Replace a displayed value
+ /// GetValues() call is required
+ ///
+ ///
+ ///
+ public void ReplaceValue(string oldVal, string newVal)
+ {
+ lock (_syncRoot)
+ {
+ if (!_replaceValues.ContainsKey(newVal))
+ {
+ _replaceValues.Add(newVal, oldVal);
+ }
+ }
+ }
+
+
+ public void Clear(bool notify = true)
+ {
+ _valuesDictionary.Clear();
+ _values.Clear();
+ _numericValues.Clear();
+ if (notify)
+ NotifyPropertyChanged("Values");
+ }
+ }
+}
\ No newline at end of file
diff --git a/DigiCamControl/CameraControl.Devices/Classes/ZoomDirection.cs b/DigiCamControl/CameraControl.Devices/Classes/ZoomDirection.cs
new file mode 100644
index 0000000..63cb993
--- /dev/null
+++ b/DigiCamControl/CameraControl.Devices/Classes/ZoomDirection.cs
@@ -0,0 +1,8 @@
+namespace CameraControl.Devices.Classes
+{
+ public enum ZoomDirection
+ {
+ In,
+ Out
+ }
+}
\ No newline at end of file
diff --git a/DigiCamControl/CameraControl.Devices/Custom/CustomDevice.cs b/DigiCamControl/CameraControl.Devices/Custom/CustomDevice.cs
new file mode 100644
index 0000000..e3ae087
--- /dev/null
+++ b/DigiCamControl/CameraControl.Devices/Custom/CustomDevice.cs
@@ -0,0 +1,111 @@
+using System;
+using System.CodeDom;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Runtime.InteropServices;
+using System.Text;
+using System.Threading;
+using CameraControl.Devices.Classes;
+using PortableDeviceLib;
+using PortableDeviceLib.Model;
+
+namespace CameraControl.Devices.Custom
+{
+ public class CustomDevice:BaseMTPCamera
+ {
+ public CustomDevice()
+ {
+
+ }
+
+ public bool Init(DeviceDescriptor deviceDescriptor,DeviceDescription description)
+ {
+ base.Init(deviceDescriptor);
+ StillImageDevice imageDevice = StillImageDevice as StillImageDevice;
+ if (imageDevice != null)
+ imageDevice.DeviceEvent += StillImageDevice_DeviceEvent;
+ foreach (var property in description.Properties)
+ {
+ if (!string.IsNullOrEmpty(property.Name))
+ {
+ try
+ {
+ MTPDataResponse result = StillImageDevice.ExecuteReadData(CONST_CMD_GetDevicePropDesc, property.Code);
+
+ ErrorCodes.GetException(result.ErrorCode);
+ uint dataType = BitConverter.ToUInt16(result.Data, 2);
+ int dataLength = StaticHelper.GetDataLength(dataType);
+
+ var value = new PropertyValue { Code = property.Code, Name = property.Name };
+ foreach (var propertyValue in property.Values)
+ {
+ value.AddValues(propertyValue.Name, propertyValue.Value);
+ }
+ value.ValueChanged += value_ValueChanged;
+
+ AdvancedProperties.Add(value);
+ }
+ catch (Exception ex)
+ {
+ Log.Error("Error ger property ", ex);
+ }
+ }
+ }
+ return true;
+ }
+
+ void value_ValueChanged(object sender, string key, long val)
+ {
+ PropertyValue res = sender as PropertyValue;
+ if (res != null)
+ SetProperty(CONST_CMD_SetDevicePropValue, BitConverter.GetBytes(val),
+ res.Code);
+ }
+
+ private void StillImageDevice_DeviceEvent(object sender, PortableDeviceEventArgs e)
+ {
+ if (e.EventType.EventGuid == PortableDeviceGuids.WPD_EVENT_OBJECT_ADDED)
+ {
+ var id = e.EventType.DeviceObject.ID;
+ PhotoCapturedEventArgs args = new PhotoCapturedEventArgs
+ {
+ WiaImageItem = null,
+ CameraDevice = this,
+ FileName = e.EventType.DeviceObject.Name,
+ Handle = e.EventType.DeviceObject.ID
+ };
+ OnPhotoCapture(this, args);
+ }
+ }
+
+ public override void TransferFile(object o, Stream stream)
+ {
+ ((StillImageDevice) StillImageDevice).SaveFile((string) o, stream);
+ }
+
+ public override void CapturePhoto()
+ {
+ Monitor.Enter(Locker);
+ try
+ {
+ IsBusy = true;
+ ErrorCodes.GetException( ExecuteWithNoData(CONST_CMD_InitiateCapture));
+ }
+ catch (COMException comException)
+ {
+ IsBusy = false;
+ ErrorCodes.GetException(comException);
+ }
+ catch
+ {
+ IsBusy = false;
+ throw;
+ }
+ finally
+ {
+ Monitor.Exit(Locker);
+ }
+ }
+ }
+}
diff --git a/DigiCamControl/CameraControl.Devices/Custom/DeviceDescription.cs b/DigiCamControl/CameraControl.Devices/Custom/DeviceDescription.cs
new file mode 100644
index 0000000..8f981bb
--- /dev/null
+++ b/DigiCamControl/CameraControl.Devices/Custom/DeviceDescription.cs
@@ -0,0 +1,58 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Xml.Serialization;
+
+namespace CameraControl.Devices.Custom
+{
+ public class DeviceDescription
+ {
+ [XmlAttribute]
+ public string Model { get; set; }
+ [XmlAttribute]
+ public string BaseDevice { get; set; }
+ [XmlAttribute]
+ public string Manufacturer { get; set; }
+
+ public string Description { get; set; }
+
+ public List Properties { get; set; }
+
+ public DeviceDescription()
+ {
+ Properties = new List();
+ }
+
+ public void Save(string file)
+ {
+ XmlSerializer serializer = new XmlSerializer(typeof(DeviceDescription));
+ Stream writer = new FileStream(file, FileMode.Create);
+ serializer.Serialize(writer, this);
+ writer.Close();
+ }
+
+ public static DeviceDescription Load(string file)
+ {
+ try
+ {
+ DeviceDescription settings = new DeviceDescription();
+ XmlSerializer mySerializer = new XmlSerializer(typeof(DeviceDescription));
+ FileStream myFileStream = new FileStream(file, FileMode.Open);
+ settings = (DeviceDescription)mySerializer.Deserialize(myFileStream);
+ myFileStream.Close();
+
+ return settings;
+ }
+ catch (Exception ex)
+ {
+ Log.Error("Error load device description "+file,ex);
+ return null;
+
+ }
+ }
+
+ }
+
+}
diff --git a/DigiCamControl/CameraControl.Devices/Custom/DeviceProperty.cs b/DigiCamControl/CameraControl.Devices/Custom/DeviceProperty.cs
new file mode 100644
index 0000000..8291bab
--- /dev/null
+++ b/DigiCamControl/CameraControl.Devices/Custom/DeviceProperty.cs
@@ -0,0 +1,28 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Xml.Serialization;
+using CameraControl.Devices.Classes;
+
+namespace CameraControl.Devices.Custom
+{
+ public class DeviceProperty
+ {
+ [XmlAttribute]
+ public string Name { get; set; }
+ [XmlAttribute]
+ public uint Code { get; set; }
+ [XmlAttribute]
+ public bool ReadOnly { get; set; }
+ [XmlAttribute]
+ public string MapTo { get; set; }
+
+ public List Values { get; set; }
+
+ public DeviceProperty()
+ {
+ Values = new List();
+ }
+ }
+}
diff --git a/DigiCamControl/CameraControl.Devices/Custom/DevicePropertyValue.cs b/DigiCamControl/CameraControl.Devices/Custom/DevicePropertyValue.cs
new file mode 100644
index 0000000..5723a46
--- /dev/null
+++ b/DigiCamControl/CameraControl.Devices/Custom/DevicePropertyValue.cs
@@ -0,0 +1,17 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Xml.Serialization;
+
+namespace CameraControl.Devices.Custom
+{
+ public class DevicePropertyValue
+ {
+ [XmlAttribute]
+ public long Value { get; set; }
+ [XmlAttribute]
+ public string Name { get; set; }
+
+ }
+}
diff --git a/DigiCamControl/CameraControl.Devices/ICameraDevice.cs b/DigiCamControl/CameraControl.Devices/ICameraDevice.cs
new file mode 100644
index 0000000..ffa657e
--- /dev/null
+++ b/DigiCamControl/CameraControl.Devices/ICameraDevice.cs
@@ -0,0 +1,211 @@
+#region Licence
+
+// Distributed under MIT License
+// ===========================================================
+//
+// digiCamControl - DSLR camera remote control open source software
+// Copyright (C) 2014 Duka Istvan
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY,FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH
+// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#endregion
+
+#region
+
+using System;
+using CameraControl.Devices.Classes;
+
+#endregion
+
+namespace CameraControl.Devices
+{
+ public interface ICameraDevice
+ {
+ ///
+ /// If false the camera is ready to take next capture
+ /// Should be handled by the user code
+ ///
+ bool IsBusy { get; set; }
+
+ ///
+ /// This property will be removed, replaced by GetCapability
+ ///
+ bool HaveLiveView { get; set; }
+
+ ///
+ /// Gets or sets a value indicating whether photos captured are captured in SDRam.
+ ///
+ ///
+ /// true if true photos are captured in SDRam; otherwise, false photos will be recorded in card.
+ ///
+ bool CaptureInSdRam { get; set; }
+
+ PropertyValue FNumber { get; set; }
+ PropertyValue IsoNumber { get; set; }
+ PropertyValue ShutterSpeed { get; set; }
+ PropertyValue WhiteBalance { get; set; }
+ PropertyValue Mode { get; set; }
+ PropertyValue ExposureCompensation { get; set; }
+ PropertyValue CompressionSetting { get; set; }
+ PropertyValue ExposureMeteringMode { get; set; }
+ PropertyValue FocusMode { get; set; }
+ DateTime DateTime { get; set; }
+ ///
+ /// Gets or sets a unique indentifier for device based on connection mode.
+ ///
+ ///
+ /// The name of the port.
+ ///
+ string PortName { get; set; }
+
+ ///
+ /// Gets or sets a value indicating whether the camera is connected.
+ ///
+ ///
+ /// true if this instance is connected; otherwise, false.
+ ///
+ bool IsConnected { get; set; }
+
+ bool IsChecked { get; set; }
+
+ ///
+ /// Gets or sets the attached abject to the camera .
+ ///
+ ///
+ /// The attached photo session.
+ ///
+ object AttachedPhotoSession { get; set; }
+
+ string DeviceName { get; set; }
+ string Manufacturer { get; set; }
+ string SerialNumber { get; set; }
+ string DisplayName { get; set; }
+ int ExposureStatus { get; set; }
+ bool PreventShutDown { get; set; }
+
+ ///
+ /// Check is a capability is supported
+ ///
+ /// The capability enum.
+ /// true if capability supported
+ bool GetCapability(CapabilityEnum capabilityEnum);
+
+ ///
+ /// The current file transfer progress (0-100 %)
+ ///
+ ///
+ /// The transfer progress.
+ ///
+ uint TransferProgress { get; set; }
+
+ int Battery { get; set; }
+ PropertyValue LiveViewImageZoomRatio { get; set; }
+
+ bool Init(DeviceDescriptor deviceDescriptor);
+ void StartLiveView();
+ void StopLiveView();
+ string GetLiveViewStream();
+
+ LiveViewData GetLiveViewImage();
+ void AutoFocus();
+ int Focus(int step);
+ void Focus(int x, int y);
+ void Focus(FocusDirection direction, FocusAmount amount);
+ void CapturePhotoNoAf();
+ void CapturePhoto();
+ void StartRecordMovie();
+ void StopRecordMovie();
+ ///
+ /// Gets the prohibition condition for the specified operation.
+ /// If a operation can be executed empty string will returned,
+ /// Else the error code or error description
+ ///
+ /// The operation enum.
+ ///
+ string GetProhibitionCondition(OperationEnum operationEnum);
+ bool GetStatus(OperationEnum operationEnum);
+ ///
+ /// Support only if capability Bulb is specified
+ ///
+ void EndBulbMode();
+
+ ///
+ /// Support only if capability Bulb is specified
+ ///
+ void StartBulbMode();
+
+ void LockCamera();
+ void UnLockCamera();
+ void Close();
+
+ void StartZoom(ZoomDirection direction);
+ void StopZoom(ZoomDirection direction);
+
+ ///
+ /// Should be called after file tranferred
+ ///
+ /// The o.
+ void ReleaseResurce(object o);
+
+ void TransferFileThumb(object o, string filename);
+ void TransferFile(object o, string filename);
+ void TransferFile(object o, System.IO.Stream stream);
+
+ ///
+ /// Occurs when photo captured.
+ ///
+ event PhotoCapturedEventHandler PhotoCaptured;
+
+ ///
+ /// Occurs when all capture images done.
+ ///
+ event EventHandler CaptureCompleted;
+
+ ///
+ /// Occurs when [camera disconnected].
+ ///
+ event CameraDisconnectedEventHandler CameraDisconnected;
+
+ event CameraDeviceManager.CameraConnectedEventHandler CameraInitDone;
+
+ ///
+ /// Gets or sets the arbitrary number of advanced properties.
+ ///
+ ///
+ /// The advanced properties.
+ ///
+ AsyncObservableCollection> AdvancedProperties { get; set; }
+
+ AsyncObservableCollection> Properties { get; set; }
+ ///
+ /// Gets files stored in card.
+ ///
+ /// The storage id.
+ /// Load thumbnail atached to object
+ ///
+ AsyncObservableCollection GetObjects(object storageId, bool loadThumbs);
+
+ void FormatStorage(object storageId);
+ bool DeleteObject(DeviceObject deviceObject);
+
+ void SetCameraField(CameraFieldType cameraFieldType, string comment);
+
+ void WaitForReady();
+ }
+}
\ No newline at end of file
diff --git a/DigiCamControl/CameraControl.Devices/IWifiDeviceProvider.cs b/DigiCamControl/CameraControl.Devices/IWifiDeviceProvider.cs
new file mode 100644
index 0000000..065526b
--- /dev/null
+++ b/DigiCamControl/CameraControl.Devices/IWifiDeviceProvider.cs
@@ -0,0 +1,11 @@
+using CameraControl.Devices.Classes;
+
+namespace CameraControl.Devices
+{
+ public interface IWifiDeviceProvider
+ {
+ string Name { get; set; }
+ string DefaultIp { get; set; }
+ DeviceDescriptor Connect(string address);
+ }
+}
diff --git a/DigiCamControl/CameraControl.Devices/Log.cs b/DigiCamControl/CameraControl.Devices/Log.cs
new file mode 100644
index 0000000..0306c21
--- /dev/null
+++ b/DigiCamControl/CameraControl.Devices/Log.cs
@@ -0,0 +1,135 @@
+#region Licence
+
+// Distributed under MIT License
+// ===========================================================
+//
+// digiCamControl - DSLR camera remote control open source software
+// Copyright (C) 2014 Duka Istvan
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY,FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH
+// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#endregion
+
+#region
+
+using System;
+using CameraControl.Devices.Classes;
+
+#endregion
+
+namespace CameraControl.Devices
+{
+ public delegate void LogEventHandler(LogEventArgs e);
+
+ public static class Log
+ {
+ public static event LogEventHandler LogDebug;
+ public static event LogEventHandler LogError;
+ public static event LogEventHandler LogInfo;
+
+ public static bool IsVerbose { get; set; } = false;
+
+ /* The xxxWithWritexxx methods are for convenience instead of doing
+ * Console.WriteLine(String.Format("...format...", objects));
+ * Log.Verbose(String.Format("...format...", objects));
+ * with all the overhead twice... */
+
+ public static void Debug(object message, Exception exception)
+ {
+ if (LogDebug != null)
+ LogDebug(new LogEventArgs() {Exception = exception, Message = message});
+ }
+
+ public static void Debug(object message)
+ {
+ Debug(message, null);
+ }
+
+ public static void Error(object message, Exception exception)
+ {
+ if (LogError != null)
+ LogError(new LogEventArgs() {Exception = exception, Message = message});
+ }
+
+ public static void Error(object message)
+ {
+ Error(message, null);
+ }
+
+ public static void Info(object message, Exception exception)
+ {
+ if (LogInfo != null)
+ LogInfo(new LogEventArgs() {Exception = exception, Message = message});
+ }
+
+ public static void Info(object message)
+ {
+ LogInfo?.Invoke(new LogEventArgs() { Exception = null, Message = message });
+ }
+
+ public static void InfoWithWriteLine(object message)
+ {
+ Console.WriteLine(message);
+ LogInfo?.Invoke(new LogEventArgs() { Exception = null, Message = message });
+ }
+
+ public static void Verbose(object message)
+ {
+ if (IsVerbose)
+ LogInfo?.Invoke(new LogEventArgs() { Exception = null, Message = message });
+ }
+
+ public static void VerboseWithWriteLine(object message)
+ {
+ if (IsVerbose)
+ {
+ Console.WriteLine(message);
+ LogInfo?.Invoke(new LogEventArgs() { Exception = null, Message = message });
+ }
+ }
+
+ public static void VerboseWithWriteLineAlways(object message)
+ {
+ Console.WriteLine(message);
+ if (IsVerbose)
+ {
+ LogInfo?.Invoke(new LogEventArgs() { Exception = null, Message = message });
+ }
+ }
+
+ public static void VerboseWithWrite(object message)
+ {
+ if (IsVerbose)
+ {
+ Console.Write(message);
+ LogInfo?.Invoke(new LogEventArgs() { Exception = null, Message = message });
+ }
+ }
+
+ public static void VerboseWithWriteAlways(object message)
+ {
+ Console.Write(message);
+ if (IsVerbose)
+ {
+ LogInfo?.Invoke(new LogEventArgs() { Exception = null, Message = message });
+ }
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/DigiCamControl/CameraControl.Devices/Nikon/NikonBase.cs b/DigiCamControl/CameraControl.Devices/Nikon/NikonBase.cs
new file mode 100644
index 0000000..759a4ba
--- /dev/null
+++ b/DigiCamControl/CameraControl.Devices/Nikon/NikonBase.cs
@@ -0,0 +1,2623 @@
+#region Licence
+
+// Distributed under MIT License
+// ===========================================================
+//
+// digiCamControl - DSLR camera remote control open source software
+// Copyright (C) 2014 Duka Istvan
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY,FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH
+// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#endregion
+
+#region
+
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Runtime.InteropServices;
+using System.Text;
+using System.Threading;
+using System.Timers;
+using CameraControl.Devices.Classes;
+using CameraControl.Devices.Xml;
+using PortableDeviceLib;
+using PortableDeviceLib.Model;
+using Timer = System.Timers.Timer;
+
+#endregion
+
+namespace CameraControl.Devices.Nikon
+{
+ ///
+ /// Base Nikon driver
+ ///
+ public class NikonBase : BaseMTPCamera
+ {
+ public const uint CONST_CMD_AfDrive = 0x90C1;
+ public const uint CONST_CMD_StartLiveView = 0x9201;
+ public const uint CONST_CMD_EndLiveView = 0x9202;
+ public const uint CONST_CMD_GetLiveViewImage = 0x9203;
+ public const uint CONST_CMD_InitiateCaptureRecInMedia = 0x9207;
+ public const uint CONST_CMD_AfAndCaptureRecInSdram = 0x90CB;
+ public const uint CONST_CMD_InitiateCaptureRecInSdram = 0x90C0;
+ public const uint CONST_CMD_ChangeAfArea = 0x9205;
+ public const uint CONST_CMD_MfDrive = 0x9204;
+ public const uint CONST_CMD_GetLargeThumb = 0x90C4;
+
+ public const uint CONST_CMD_GetEvent = 0x90C7;
+
+ public const uint CONST_CMD_DeviceReady = 0x90C8;
+ public const uint CONST_CMD_ChangeCameraMode = 0x90C2;
+ public const uint CONST_CMD_StartMovieRecInCard = 0x920A;
+ public const uint CONST_CMD_EndMovieRec = 0x920B;
+
+ public const uint CONST_PROP_ImageSize = 0x5003;
+ public const uint CONST_PROP_Fnumber = 0x5007;
+ public const uint CONST_PROP_MovieFnumber = 0xD1A9;
+ public const uint CONST_PROP_ExposureIndex = 0x500F;
+ public const uint CONST_PROP_ExposureIndexEx = 0xD0B4;
+ public const uint CONST_PROP_MovieExposureIndex = 0xD1AA;
+ public const uint CONST_PROP_ExposureTime = 0x500D;
+ public const uint CONST_PROP_ShutterSpeed = 0xD100;
+ public const uint CONST_PROP_MovieShutterSpeed = 0xD1A8;
+ public const uint CONST_PROP_WhiteBalance = 0x5005;
+ public const uint CONST_PROP_ExposureProgramMode = 0x500E;
+ public const uint CONST_PROP_ExposureBiasCompensation = 0x5010;
+ public const uint CONST_PROP_MovieExposureBiasCompensation = 0xD1AB;
+ public const uint CONST_PROP_DateTime = 0x5011;
+ public const uint CONST_PROP_LiveViewImageZoomRatio = 0xD1A3;
+ public const uint CONST_PROP_AFModeSelect = 0xD161;
+ public const uint CONST_PROP_AfModeAtLiveView = 0xD061;
+ public const uint CONST_PROP_CompressionSetting = 0x5004;
+ public const uint CONST_PROP_ExposureMeteringMode = 0x500B;
+ public const uint CONST_PROP_FocusMode = 0x500A;
+ public const uint CONST_PROP_LiveViewStatus = 0xD1A2;
+ public const uint CONST_PROP_LiveViewSelector = 0xD1A6;
+ public const uint CONST_PROP_ExposureIndicateStatus = 0xD1B1;
+ public const uint CONST_PROP_RecordingMedia = 0xD10B;
+ public const uint CONST_PROP_NoiseReduction = 0xD06B;
+ public const uint CONST_PROP_ApplicationMode = 0xD1F0;
+ public const uint CONST_PROP_RawCompressionType = 0xD016;
+ public const uint CONST_PROP_RawCompressionBitMode = 0xD149;
+ public const uint CONST_PROP_ActivePicCtrlItem = 0xD200;
+ public const uint CONST_PROP_ColorSpace = 0xD032;
+ public const uint CONST_PROP_WbTuneFluorescentType = 0xD14F;
+ public const uint CONST_PROP_WbColorTemp = 0xD01E;
+ public const uint CONST_PROP_ISOAutoHighLimit = 0xD183;
+ public const uint CONST_PROP_FlashCompensation = 0xD124;
+
+ public const uint CONST_Event_DevicePropChanged = 0x4006;
+ public const uint CONST_Event_StoreFull = 0x400A;
+ public const uint CONST_Event_CaptureComplete = 0x400D;
+ public const uint CONST_Event_CaptureCompleteRecInSdram = 0xC102;
+ public const uint CONST_Event_ObsoleteEvent = 0xC104;
+
+
+ protected Dictionary _isoTable = new Dictionary()
+ {
+ {0x0064, "100"},
+ {0x007D, "125"},
+ {0x00A0, "160"},
+ {0x00C8, "200"},
+ {0x00FA, "250"},
+ {0x0140, "320"},
+ {0x0190, "400"},
+ {0x01F4, "500"},
+ {0x0280, "640"},
+ {0x0320, "800"},
+ {0x03E8, "1000"},
+ {0x04E2, "1250"},
+ {0x0640, "1600"},
+ {0x07D0, "2000"},
+ {0x09C4, "2500"},
+ {0x0C80, "3200"},
+ {0x0FA0, "4000"},
+ {0x1388, "5000"},
+ {0x1900, "6400"},
+ {0x1F40, "Hi 0.3"},
+ {0x2710, "Hi 0.7"},
+ {0x3200, "Hi 1"},
+ {0x6400, "Hi 2"},
+ };
+
+ protected Dictionary _autoIsoTable = new Dictionary()
+ {
+ {0, "200"},
+ {1, "400"},
+ {2, "800"},
+ {3, "1600"},
+ {4, "3200"},
+ {5, "6400"},
+ {6, "Hi 1.7"},
+ {7, "Hi 2"},
+ };
+
+ protected Dictionary _shutterTable = new Dictionary
+ {
+ {1, "1/6400"},
+ {2, "1/4000"},
+ {3, "1/3200"},
+ {4, "1/2500"},
+ {5, "1/2000"},
+ {6, "1/1600"},
+ {8, "1/1250"},
+ {10, "1/1000"},
+ {12, "1/800"},
+ {13, "1/750"},
+ {15, "1/640"},
+ {20, "1/500"},
+ {25, "1/400"},
+ {28, "1/350"},
+ {31, "1/320"},
+ {40, "1/250"},
+ {50, "1/200"},
+ {55, "1/180"},
+ {62, "1/160"},
+ {80, "1/125"},
+ {100, "1/100"},
+ {111, "1/90"},
+ {125, "1/80"},
+ {166, "1/60"},
+ {200, "1/50"},
+ {222, "1/45"},
+ {250, "1/40"},
+ {333, "1/30"},
+ {400, "1/25"},
+ {500, "1/20"},
+ {666, "1/15"},
+ {769, "1/13"},
+ {1000, "1/10"},
+ {1250, "1/8"},
+ {1666, "1/6"},
+ {2000, "1/5"},
+ {2500, "1/4"},
+ {3333, "1/3"},
+ {4000, "1/2.5"},
+ {5000, "1/2"},
+ {6250, "1/1.6"},
+ {6666, "1/1.5"},
+ {7692, "1/1.3"},
+ {10000, "1s"},
+ {13000, "1.3s"},
+ {15000, "1.5s"},
+ {16000, "1.6s"},
+ {20000, "2s"},
+ {25000, "2.5s"},
+ {30000, "3s"},
+ {40000, "4s"},
+ {50000, "5s"},
+ {60000, "6s"},
+ {80000, "8s"},
+ {100000, "10s"},
+ {130000, "13s"},
+ {150000, "15s"},
+ {200000, "20s"},
+ {250000, "25s"},
+ {300000, "30s"},
+ {0xFFFFFFFF, "Bulb"},
+ };
+
+ private Dictionary _exposureModeTable = new Dictionary()
+ {
+ {1, "M"},
+ {2, "P"},
+ {3, "A"},
+ {4, "S"},
+ {0x8010, "[Scene mode] AUTO"},
+ {0x8011, "[Scene mode] Portrait"},
+ {0x8012, "[Scene mode] Landscape"},
+ {0x8013, "[Scene mode] Close up"},
+ {0x8014, "[Scene mode] Sports"},
+ {0x8016, "[Scene mode] Flash prohibition AUTO"},
+ {0x8017, "[Scene mode] Child"},
+ {0x8018, "[Scene mode] SCENE"},
+ {0x8019, "[EffectMode] EFFECTS"},
+ };
+
+ private Dictionary _wbTable = new Dictionary()
+ {
+ {2, "Auto"},
+ {4, "Daylight"},
+ {5, "Fluorescent"},
+ {6, "Incandescent"},
+ {7, "Flash"},
+ {0x8010, "Cloudy"},
+ {0x8011, "Shade"},
+ {0x8012, "Kelvin"},
+ {0x8013, "Custom"},
+ {0x8016, "Natural Light Auto"}
+ };
+
+ protected Dictionary _csTable = new Dictionary()
+ {
+ {0, "JPEG (BASIC)"},
+ {1, "JPEG (NORMAL)"},
+ {2, "JPEG (FINE)"},
+ {3, "TIFF (RGB)"},
+ {4, "RAW"},
+ {5, "RAW + JPEG (BASIC)"},
+ {6, "RAW + JPEG (NORMAL)"},
+ {7, "RAW + JPEG (FINE)"}
+ };
+
+ private Dictionary _emmTable = new Dictionary
+ {
+ {2, "Center-weighted metering"},
+ {3, "Multi-pattern metering"},
+ {4, "Spot metering"},
+ {0x8010, "Highlight-weighted"}
+ };
+
+ private Dictionary _fmTable = new Dictionary()
+ {
+ {1, "[M] Manual focus"},
+ {0x8010, "[S] Single AF servo"},
+ {0x8011, "[C] Continuous AF servo"},
+ {0x8012, "[A] AF servo mode automatic switching"},
+ {0x8013, "[F] Constant AF servo"},
+ };
+
+ public bool LiveViewOn
+ {
+ get { return _liveViewOn; }
+ set
+ {
+ _liveViewOn = value;
+ FocusMode = LiveViewOn ? LiveViewFocusMode : NormalFocusMode;
+ SetMovieMode();
+ }
+ }
+
+ ///
+ /// Gets or sets a value indicating whether the camera swich is in movie mode.
+ ///
+ ///
+ /// true if [live view is in movie mode]; otherwise, false.
+ ///
+ public bool LiveViewMovieOn
+ {
+ get { return _liveViewMovieOn; }
+ set
+ {
+ _liveViewMovieOn = value;
+ SetMovieMode();
+ }
+ }
+
+ public PropertyValue LiveViewFocusMode { get; set; }
+ public PropertyValue NormalFocusMode { get; set; }
+
+ public PropertyValue NormalFNumber { get; set; }
+ public PropertyValue MovieFNumber { get; set; }
+
+ public PropertyValue NormalIsoNumber { get; set; }
+ public PropertyValue MovieIsoNumber { get; set; }
+
+ public PropertyValue NormalShutterSpeed { get; set; }
+ public PropertyValue MovieShutterSpeed { get; set; }
+
+ public PropertyValue NormalExposureCompensation { get; set; }
+ public PropertyValue MovieExposureCompensation { get; set; }
+
+ public NikonBase()
+ {
+ _timer.AutoReset = true;
+ _timer.Elapsed += _timer_Elapsed;
+ SlowDownEventTimer();
+ }
+
+ private void SetMovieMode()
+ {
+ if (LiveViewOn && LiveViewMovieOn)
+ {
+ FNumber = MovieFNumber ;
+ IsoNumber = MovieIsoNumber;
+ ShutterSpeed = MovieShutterSpeed;
+ ExposureCompensation = MovieExposureCompensation;
+ }
+ else
+ {
+ FNumber = NormalFNumber;
+ IsoNumber = NormalIsoNumber;
+ ShutterSpeed = NormalShutterSpeed;
+ ExposureCompensation = NormalExposureCompensation;
+ }
+ }
+
+ private void SlowDownEventTimer()
+ {
+ _timer.Interval = 1000/10;
+ }
+
+ private void SpeedUpEventTimer()
+ {
+ _timer.Interval = 1000/10;
+ }
+
+ private void _timer_Elapsed(object sender, ElapsedEventArgs e)
+ {
+ try
+ {
+ _timer.Stop();
+ lock (Locker)
+ {
+ ThreadPool.QueueUserWorkItem(GetEvent);
+ }
+ }
+ catch (Exception)
+ {
+ }
+ //_timer.Start();
+ }
+
+ public PictureControl GetPictureControl(byte slotnum)
+ {
+ PictureControl control = new PictureControl();
+ MTPDataResponse result = ExecuteReadDataEx(0x90CC, slotnum, 0);
+ if (result.Data != null && result.Data.Length > 30)
+ {
+ control.IsLoaded = true;
+ control.ItemNumber = slotnum;
+ control.Monocrome = result.Data[1] == 1;
+ control.CustomFlag = result.Data[2];
+ string name = Encoding.ASCII.GetString(result.Data, 3, 20);
+ control.RegistrationName = name.Contains("\0") ? name.Split('\0')[0] : name;
+ if (!control.Monocrome)
+ {
+ control.QuickAdjustFlag = result.Data[23];
+ control.QuickAdjust = (sbyte) result.Data[24];
+ control.Saturation = (sbyte) result.Data[25];
+ control.Hue = (sbyte) result.Data[26];
+ }
+ else
+ {
+ control.FilterEffects = result.Data[23];
+ control.Toning = result.Data[24];
+ control.ToningDensity = result.Data[25];
+ //control.Hue = result.Data[27];
+ }
+ control.Sharpening = (sbyte) result.Data[27];
+ control.Contrast = (sbyte) result.Data[28];
+ control.Brightness = (sbyte) result.Data[29];
+ control.CustomCurveFlag = result.Data[30];
+ if (control.CustomCurveFlag == 1)
+ result.Data.CopyTo(control.CustomCurveData, 31);
+ }
+ else
+ {
+ return null;
+ }
+ return control;
+ }
+
+ public void SetPictureControl(PictureControl control)
+ {
+ }
+
+ protected virtual PropertyValue InitHostMode()
+ {
+ var res = new PropertyValue() { Name = "Lock", IsEnabled = true };
+ res.AddValues("OFF", 0);
+ res.AddValues("ON", 1);
+ res.ReloadValues();
+ res.Value = "OFF";
+ res.ValueChanged += delegate (object sender, string key, long val)
+ {
+ ExecuteWithNoData(CONST_CMD_ChangeCameraMode, (uint) (key == "OFF" ? 0 : 1));
+ Mode.IsEnabled = key == "ON";
+ GetEvent(null);
+ ReadDeviceProperties(CONST_PROP_ExposureProgramMode);
+ };
+ return res;
+ }
+
+ public override bool Init(DeviceDescriptor deviceDescriptor)
+ {
+ try
+ {
+ IsBusy = true;
+ Capabilities.Add(CapabilityEnum.CaptureInRam);
+ Capabilities.Add(CapabilityEnum.CaptureNoAf);
+ StillImageDevice = deviceDescriptor.StillImageDevice;
+ // check if is mtp device
+ StillImageDevice imageDevice = StillImageDevice as StillImageDevice;
+ if (imageDevice != null)
+ imageDevice.DeviceEvent += _stillImageDevice_DeviceEvent;
+ HaveLiveView = true;
+ DeviceReady();
+ DeviceName = StillImageDevice.Model;
+ Manufacturer = StillImageDevice.Manufacturer;
+ IsConnected = true;
+ CaptureInSdRam = true;
+ PropertyChanged += NikonBase_PropertyChanged;
+ var ser = StillImageDevice.SerialNumber;
+ Log.Debug("Serial number" + ser ?? "");
+ if (ser != null && ser.Length >= 7)
+ {
+ SerialNumber = ser.Substring(0, 7);
+ // there in some cases the leading zero order differs
+ if (SerialNumber == "0000000")
+ {
+ SerialNumber = ser.Substring(ser.Length-7,7);
+ }
+ }
+ // load advanced properties in a separated thread to speed up camera connection
+ //var thread = new Thread(LoadProperties) {Priority = ThreadPriority.Lowest};
+ //thread.Start();
+ LoadProperties();
+ //FearL0rd test
+ Thread thread = new Thread(() =>
+ {
+ Thread.Sleep(200);
+ OnCameraInitDone();
+ });
+ }
+ catch (Exception exception)
+ {
+ Log.Error("Error initialize device", exception);
+ }
+ return true;
+ }
+
+ public void LoadProperties()
+ {
+ try
+ {
+ InitIso();
+ InitShutterSpeed();
+ InitFNumber();
+ ReadDeviceProperties(CONST_PROP_LiveViewSelector);
+ InitMode();
+ InitWhiteBalance();
+ InitExposureCompensation();
+ InitCompressionSetting();
+ InitExposureMeteringMode();
+ InitFocusMode();
+ InitOther();
+ ReadDeviceProperties(CONST_PROP_BatteryLevel);
+ ReadDeviceProperties(CONST_PROP_ExposureIndicateStatus);
+ AddAditionalProps();
+ ReInitShutterSpeed();
+ ReadDeviceProperties(CONST_PROP_LiveViewStatus);
+ _timer.Start();
+ OnCameraInitDone();
+
+ }
+ catch (Exception exception)
+ {
+ Log.Error("Error load device properties", exception);
+ }
+ IsBusy = false;
+ }
+
+ public virtual void AddAditionalProps()
+ {
+ AdvancedProperties.Add(InitImageSize());
+ AdvancedProperties.Add(InitRawQuality());
+ AdvancedProperties.Add(InitBurstNumber());
+ AdvancedProperties.Add(InitStillCaptureMode());
+ AdvancedProperties.Add(InitOnOffProperty("Auto Iso", 0xD054));
+ AdvancedProperties.Add(InitFlash());
+ AdvancedProperties.Add(InitOnOffProperty("Long exp NR", CONST_PROP_NoiseReduction));
+ AdvancedProperties.Add(InitNRHiIso());
+ AdvancedProperties.Add(InitExposureDelay());
+ AdvancedProperties.Add(InitLock());
+ AdvancedProperties.Add(InitPictControl());
+ AdvancedProperties.Add(InitRawBit());
+ AdvancedProperties.Add(InitColorSpace()); //12
+ AdvancedProperties.Add(InitWbTuneFluorescentType());
+ AdvancedProperties.Add(InitWbColorTemp());
+ AdvancedProperties.Add(InitOnOffProperty("Application mode", CONST_PROP_ApplicationMode));
+ AdvancedProperties.Add(InitAutoIsoHight());
+ AdvancedProperties.Add(CenterWeightedExRange());
+ AdvancedProperties.Add(FlashCompensation());
+ AdvancedProperties.Add(FlashSyncSpeed());
+ AdvancedProperties.Add(CaptureAreaCrop());
+ AdvancedProperties.Add(ActiveDLighting());
+ AdvancedProperties.Add(HDRMode());
+ AdvancedProperties.Add(HDREv());
+ AdvancedProperties.Add(HDRSmoothing());
+ AdvancedProperties.Add(ActiveSlot());
+ AdvancedProperties.Add(LensSort());
+ AdvancedProperties.Add(InitHostMode());
+ try
+ {
+ var deviceinfo = LoadDeviceData(ExecuteReadDataEx(0x1001));
+ foreach (PropertyValue value in AdvancedProperties)
+ {
+ if (!deviceinfo.PropertyExist(value.Code))
+ value.Available = false;
+ }
+ }
+ catch (Exception ex)
+ {
+ Log.Error("Unable to check advanced proprties", ex);
+ }
+ foreach (PropertyValue value in AdvancedProperties)
+ {
+ ReadDeviceProperties(value.Code);
+ }
+ }
+
+ protected virtual PropertyValue LensSort()
+ {
+ PropertyValue res = new PropertyValue()
+ {
+ Name = "Lens Sort",
+ IsEnabled = false,
+ Code = 0xD0E1,
+ SubType = typeof(sbyte)
+ };
+ res.AddValues("Not mounted", 0);
+ res.AddValues("CPU lens mounted", 1);
+ res.ReloadValues();
+ res.ValueChanged +=
+ (sender, key, val) => SetProperty(CONST_CMD_SetDevicePropValue, BitConverter.GetBytes(val), res.Code);
+ return res;
+ }
+
+ protected virtual PropertyValue ActiveSlot()
+ {
+ PropertyValue res = new PropertyValue()
+ {
+ Name = "Active Slot",
+ IsEnabled = false,
+ Code = 0xD1F2,
+ SubType = typeof(sbyte)
+ };
+ res.AddValues("Card not inserted", 0);
+ res.AddValues("CF slot", 1);
+ res.AddValues("SD slot", 2);
+ res.AddValues("CF slot & SD slot", 3);
+ res.ReloadValues();
+ res.ValueChanged +=
+ (sender, key, val) => SetProperty(CONST_CMD_SetDevicePropValue, BitConverter.GetBytes(val), res.Code);
+ return res;
+ }
+
+ protected virtual PropertyValue FlashSyncSpeed()
+ {
+ PropertyValue res = new PropertyValue()
+ {
+ Name = "Flash sync speed",
+ IsEnabled = true,
+ Code = 0xD074,
+ SubType = typeof(sbyte)
+ };
+ res.AddValues("1/320 sec. (auto FP)", 0);
+ res.AddValues("1/250 sec. (auto FP)", 1);
+ res.AddValues("1/250 sec.", 2);
+ res.AddValues("1/200 sec.", 3);
+ res.AddValues("1/160 sec.", 4);
+ res.AddValues("1/125 sec.", 5);
+ res.AddValues("1/100 sec.", 6);
+ res.AddValues("1/80 sec.", 7);
+ res.AddValues("1/60 sec.", 8);
+ res.ReloadValues();
+ res.ValueChanged +=
+ (sender, key, val) => SetProperty(CONST_CMD_SetDevicePropValue, BitConverter.GetBytes(val), res.Code);
+ return res;
+ }
+
+ protected virtual PropertyValue HDRSmoothing()
+ {
+ PropertyValue res = new PropertyValue()
+ {
+ Name = "HDR intensity",
+ IsEnabled = true,
+ Code = 0xD132,
+ SubType = typeof(sbyte)
+ };
+ res.AddValues("High", 0);
+ res.AddValues("Normal", 1);
+ res.AddValues("Low", 2);
+ res.AddValues("Auto", 3);
+ res.AddValues("Extra high", 4);
+ res.ReloadValues();
+ res.ValueChanged +=
+ (sender, key, val) => SetProperty(CONST_CMD_SetDevicePropValue, BitConverter.GetBytes(val), res.Code);
+ return res;
+ }
+
+ protected virtual PropertyValue HDREv()
+ {
+ PropertyValue res = new PropertyValue()
+ {
+ Name = "HDR Exposure deviation",
+ IsEnabled = true,
+ Code = 0xD131,
+ SubType = typeof(sbyte)
+ };
+ res.AddValues("Auto", 0);
+ res.AddValues("1 EV", 1);
+ res.AddValues("2 EV", 2);
+ res.AddValues("3 EV", 3);
+ res.ReloadValues();
+ res.ValueChanged +=
+ (sender, key, val) => SetProperty(CONST_CMD_SetDevicePropValue, BitConverter.GetBytes(val), res.Code);
+ return res;
+ }
+
+ protected virtual PropertyValue HDRMode()
+ {
+ PropertyValue res = new PropertyValue()
+ {
+ Name = "HDRMode",
+ IsEnabled = true,
+ Code = 0xD130,
+ SubType = typeof(sbyte)
+ };
+ res.AddValues("OFF", 0);
+ res.AddValues("ON (single)", 1);
+ res.AddValues("ON (sequence)", 2);
+ res.ReloadValues();
+ res.ValueChanged +=
+ (sender, key, val) => SetProperty(CONST_CMD_SetDevicePropValue, BitConverter.GetBytes(val), res.Code);
+ return res;
+ }
+
+
+ protected virtual PropertyValue ActiveDLighting()
+ {
+ PropertyValue res = new PropertyValue()
+ {
+ Name = "Active D-Lighting",
+ IsEnabled = true,
+ Code = 0xD14E,
+ SubType = typeof(sbyte)
+ };
+ res.AddValues("Extra high", 0);
+ res.AddValues("High", 1);
+ res.AddValues("Normal", 2);
+ res.AddValues("Low", 3);
+ res.AddValues("Not performed", 4);
+ res.AddValues("Auto", 5);
+ res.ReloadValues();
+ res.ValueChanged +=
+ (sender, key, val) => SetProperty(CONST_CMD_SetDevicePropValue, BitConverter.GetBytes(val), res.Code);
+ return res;
+ }
+
+ protected virtual PropertyValue CaptureAreaCrop()
+ {
+ PropertyValue res = new PropertyValue()
+ {
+ Name = "Capture area crop",
+ IsEnabled = true,
+ Code = 0xD030,
+ SubType = typeof(sbyte)
+ };
+ res.AddValues("FX format (36x24)", 0);
+ res.AddValues("DX format (24x16)", 1);
+ res.AddValues("5:4 (30x24)", 2);
+ res.AddValues("1.2x (30x20)", 3);
+ res.ReloadValues();
+ res.ValueChanged +=
+ (sender, key, val) => SetProperty(CONST_CMD_SetDevicePropValue, BitConverter.GetBytes(val), res.Code);
+ return res;
+ }
+
+ protected virtual PropertyValue FlashCompensation ()
+ {
+ PropertyValue res = new PropertyValue()
+ {
+ Name = "Ext. flash compensation",
+ IsEnabled = true,
+ Code = CONST_PROP_FlashCompensation,
+ SubType = typeof (sbyte)
+ };
+ for (decimal i = -18; i <= 18; i++)
+ {
+ if (i > 0)
+ res.AddValues("+"+Decimal.Round(i/6, 1).ToString("0.0", CultureInfo.CreateSpecificCulture("en-US")), (long) i);
+ else
+ res.AddValues(Decimal.Round(i / 6, 1).ToString("0.0", CultureInfo.CreateSpecificCulture("en-US")), (long)i);
+ }
+ res.ReloadValues();
+ res.ValueChanged +=
+ (sender, key, val) => SetProperty(CONST_CMD_SetDevicePropValue, BitConverter.GetBytes((sbyte)val), res.Code);
+ return res;
+ }
+
+ protected virtual PropertyValue CenterWeightedExRange()
+ {
+ PropertyValue res = new PropertyValue()
+ {
+ Name = "Center-weighted area",
+ IsEnabled = true,
+ Code = 0xD059,
+ SubType = typeof(byte)
+ };
+ res.AddValues("6 mm", 0);
+ res.AddValues("8 mm", 1);
+ res.AddValues("10 mm", 2);
+ res.AddValues("10 mm", 3);
+ res.AddValues("Average on the entire screen", 4);
+ res.ReloadValues();
+ res.ValueChanged +=
+ (sender, key, val) => SetProperty(CONST_CMD_SetDevicePropValue, BitConverter.GetBytes(val), res.Code);
+ return res;
+ }
+
+ public virtual PropertyValue InitAutoIsoHight()
+ {
+ var res = new PropertyValue();
+ try
+ {
+ DeviceReady();
+ byte datasize = 1;
+ res.Name = "ISO Auto High Limit";
+ res.SubType = typeof (byte);
+ res.Code = CONST_PROP_ISOAutoHighLimit;
+ res.ValueChanged +=
+ (sender, key, val) =>
+ SetProperty(CONST_CMD_SetDevicePropValue, new[] { (byte)val }, res.Code);
+
+ var result = StillImageDevice.ExecuteReadData(CONST_CMD_GetDevicePropDesc,
+ CONST_PROP_ISOAutoHighLimit);
+ int type = BitConverter.ToInt16(result.Data, 2);
+ byte formFlag = result.Data[(2*datasize) + 5];
+ byte defval = result.Data[datasize + 5];
+
+ foreach (KeyValuePair pair in _autoIsoTable)
+ {
+ res.AddValues(pair.Value, pair.Key);
+ }
+ res.ReloadValues();
+ res.SetValue(defval, false);
+ }
+ catch (Exception)
+ {
+ }
+ return res;
+ }
+
+
+
+ protected virtual PropertyValue InitColorSpace()
+ {
+ PropertyValue res = new PropertyValue()
+ {
+ Name = "Color space",
+ IsEnabled = true,
+ Code = CONST_PROP_ColorSpace,
+ SubType = typeof (byte)
+ };
+ res.AddValues("sRGB", 0);
+ res.AddValues("Adobe RGB", 1);
+ res.ReloadValues();
+ res.ValueChanged +=
+ (sender, key, val) => SetProperty(CONST_CMD_SetDevicePropValue, BitConverter.GetBytes(val), res.Code);
+ return res;
+ }
+
+ protected virtual PropertyValue InitWbTuneFluorescentType()
+ {
+ PropertyValue res = new PropertyValue()
+ {
+ Name = "Fluorescent light type",
+ IsEnabled = WhiteBalance.NumericValue == 5,
+ Code = CONST_PROP_WbTuneFluorescentType,
+ SubType = typeof (byte),
+ DisableIfWrongValue = false
+ };
+ res.AddValues("Sodium lamp mixed light", 0);
+ res.AddValues("Cool white fluorescent lamp", 1);
+ res.AddValues("Warm white fluorescent lamp", 2);
+ res.AddValues("White fluorescent lamp", 3);
+ res.AddValues("Day white fluorescent lamp", 4);
+ res.AddValues("Daylight fluorescent lamp", 5);
+ res.AddValues("High color-temperature mercury lamp", 6);
+ res.ReloadValues();
+ res.ValueChanged +=
+ (sender, key, val) => SetProperty(CONST_CMD_SetDevicePropValue, BitConverter.GetBytes(val),
+ res.Code);
+ return res;
+ }
+
+ protected virtual PropertyValue InitWbColorTemp()
+ {
+ PropertyValue res = new PropertyValue