├── .gitattributes ├── .gitignore ├── License.txt ├── README.md ├── RevitRemoteControl ├── Properties │ └── AssemblyInfo.cs ├── RemoteControl.cs ├── RequestHandler.cs ├── RevitHttpListener.cs ├── RevitRemoteControl.addin └── RevitRemoteControl.csproj ├── RevitTask.sln ├── RevitTask ├── Properties │ └── AssemblyInfo.cs ├── README.md ├── RevitTask.cs ├── RevitTask.csproj └── _Refs │ ├── 2016 │ └── RevitAPIUI.dll │ ├── 2017 │ └── RevitAPIUI.dll │ ├── 2018 │ └── RevitAPIUI.dll │ ├── 2019 │ └── RevitAPIUI.dll │ └── 2020 │ └── RevitAPIUI.dll └── RevitTaskExample ├── Commands └── StartCommand.cs ├── Properties └── AssemblyInfo.cs ├── RevitTaskExample.addin ├── RevitTaskExample.csproj ├── UiCommand.cs ├── ViewModels └── MainViewModel.cs ├── Views ├── MainWindow.xaml └── MainWindow.xaml.cs └── _Refs ├── 2016 ├── RevitAPI.dll └── RevitAPIUI.dll ├── 2017 ├── RevitAPI.dll └── RevitAPIUI.dll ├── 2018 ├── RevitAPI.dll └── RevitAPIUI.dll ├── 2019 ├── RevitAPI.dll └── RevitAPIUI.dll └── 2020 ├── RevitAPI.dll └── RevitAPIUI.dll /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.userosscache 8 | *.sln.docstates 9 | 10 | # User-specific files (MonoDevelop/Xamarin Studio) 11 | *.userprefs 12 | 13 | # Build results 14 | [Dd]ebug/ 15 | [Dd]ebugPublic/ 16 | [Rr]elease/ 17 | [Rr]eleases/ 18 | x64/ 19 | x86/ 20 | bld/ 21 | [Bb]in/ 22 | [Oo]bj/ 23 | [Ll]og/ 24 | 25 | # Visual Studio 2015 cache/options directory 26 | .vs/ 27 | # Uncomment if you have tasks that create the project's static files in wwwroot 28 | #wwwroot/ 29 | 30 | # MSTest test Results 31 | [Tt]est[Rr]esult*/ 32 | [Bb]uild[Ll]og.* 33 | 34 | # NUNIT 35 | *.VisualState.xml 36 | TestResult.xml 37 | 38 | # Build Results of an ATL Project 39 | [Dd]ebugPS/ 40 | [Rr]eleasePS/ 41 | dlldata.c 42 | 43 | # DNX 44 | project.lock.json 45 | project.fragment.lock.json 46 | artifacts/ 47 | 48 | *_i.c 49 | *_p.c 50 | *_i.h 51 | *.ilk 52 | *.meta 53 | *.obj 54 | *.pch 55 | *.pdb 56 | *.pgc 57 | *.pgd 58 | *.rsp 59 | *.sbr 60 | *.tlb 61 | *.tli 62 | *.tlh 63 | *.tmp 64 | *.tmp_proj 65 | *.log 66 | *.vspscc 67 | *.vssscc 68 | .builds 69 | *.pidb 70 | *.svclog 71 | *.scc 72 | 73 | # Chutzpah Test files 74 | _Chutzpah* 75 | 76 | # Visual C++ cache files 77 | ipch/ 78 | *.aps 79 | *.ncb 80 | *.opendb 81 | *.opensdf 82 | *.sdf 83 | *.cachefile 84 | *.VC.db 85 | *.VC.VC.opendb 86 | 87 | # Visual Studio profiler 88 | *.psess 89 | *.vsp 90 | *.vspx 91 | *.sap 92 | 93 | # TFS 2012 Local Workspace 94 | $tf/ 95 | 96 | # Guidance Automation Toolkit 97 | *.gpState 98 | 99 | # ReSharper is a .NET coding add-in 100 | _ReSharper*/ 101 | *.[Rr]e[Ss]harper 102 | *.DotSettings.user 103 | 104 | # JustCode is a .NET coding add-in 105 | .JustCode 106 | 107 | # TeamCity is a build add-in 108 | _TeamCity* 109 | 110 | # DotCover is a Code Coverage Tool 111 | *.dotCover 112 | 113 | # NCrunch 114 | _NCrunch_* 115 | .*crunch*.local.xml 116 | nCrunchTemp_* 117 | 118 | # MightyMoose 119 | *.mm.* 120 | AutoTest.Net/ 121 | 122 | # Web workbench (sass) 123 | .sass-cache/ 124 | 125 | # Installshield output folder 126 | [Ee]xpress/ 127 | 128 | # DocProject is a documentation generator add-in 129 | DocProject/buildhelp/ 130 | DocProject/Help/*.HxT 131 | DocProject/Help/*.HxC 132 | DocProject/Help/*.hhc 133 | DocProject/Help/*.hhk 134 | DocProject/Help/*.hhp 135 | DocProject/Help/Html2 136 | DocProject/Help/html 137 | 138 | # Click-Once directory 139 | publish/ 140 | 141 | # Publish Web Output 142 | *.[Pp]ublish.xml 143 | *.azurePubxml 144 | # TODO: Comment the next line if you want to checkin your web deploy settings 145 | # but database connection strings (with potential passwords) will be unencrypted 146 | #*.pubxml 147 | *.publishproj 148 | 149 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 150 | # checkin your Azure Web App publish settings, but sensitive information contained 151 | # in these scripts will be unencrypted 152 | PublishScripts/ 153 | 154 | # NuGet Packages 155 | *.nupkg 156 | # The packages folder can be ignored because of Package Restore 157 | **/packages/* 158 | # except build/, which is used as an MSBuild target. 159 | !**/packages/build/ 160 | # Uncomment if necessary however generally it will be regenerated when needed 161 | #!**/packages/repositories.config 162 | # NuGet v3's project.json files produces more ignoreable files 163 | *.nuget.props 164 | *.nuget.targets 165 | 166 | # Microsoft Azure Build Output 167 | csx/ 168 | *.build.csdef 169 | 170 | # Microsoft Azure Emulator 171 | ecf/ 172 | rcf/ 173 | 174 | # Windows Store app package directories and files 175 | AppPackages/ 176 | BundleArtifacts/ 177 | Package.StoreAssociation.xml 178 | _pkginfo.txt 179 | 180 | # Visual Studio cache files 181 | # files ending in .cache can be ignored 182 | *.[Cc]ache 183 | # but keep track of directories ending in .cache 184 | !*.[Cc]ache/ 185 | 186 | # Others 187 | ClientBin/ 188 | ~$* 189 | *~ 190 | *.dbmdl 191 | *.dbproj.schemaview 192 | *.jfm 193 | *.pfx 194 | *.publishsettings 195 | node_modules/ 196 | orleans.codegen.cs 197 | 198 | # Since there are multiple workflows, uncomment next line to ignore bower_components 199 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 200 | #bower_components/ 201 | 202 | # RIA/Silverlight projects 203 | Generated_Code/ 204 | 205 | # Backup & report files from converting an old project file 206 | # to a newer Visual Studio version. Backup files are not needed, 207 | # because we have git ;-) 208 | _UpgradeReport_Files/ 209 | Backup*/ 210 | UpgradeLog*.XML 211 | UpgradeLog*.htm 212 | 213 | # SQL Server files 214 | *.mdf 215 | *.ldf 216 | 217 | # Business Intelligence projects 218 | *.rdl.data 219 | *.bim.layout 220 | *.bim_*.settings 221 | 222 | # Microsoft Fakes 223 | FakesAssemblies/ 224 | 225 | # GhostDoc plugin setting file 226 | *.GhostDoc.xml 227 | 228 | # Node.js Tools for Visual Studio 229 | .ntvs_analysis.dat 230 | 231 | # Visual Studio 6 build log 232 | *.plg 233 | 234 | # Visual Studio 6 workspace options file 235 | *.opt 236 | 237 | # Visual Studio LightSwitch build output 238 | **/*.HTMLClient/GeneratedArtifacts 239 | **/*.DesktopClient/GeneratedArtifacts 240 | **/*.DesktopClient/ModelManifest.xml 241 | **/*.Server/GeneratedArtifacts 242 | **/*.Server/ModelManifest.xml 243 | _Pvt_Extensions 244 | 245 | # Paket dependency manager 246 | .paket/paket.exe 247 | paket-files/ 248 | 249 | # FAKE - F# Make 250 | .fake/ 251 | 252 | # JetBrains Rider 253 | .idea/ 254 | *.sln.iml 255 | 256 | # CodeRush 257 | .cr/ 258 | 259 | # Python Tools for Visual Studio (PTVS) 260 | __pycache__/ 261 | *.pyc -------------------------------------------------------------------------------- /License.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2020, Igor Serdyukov. All rights reserved. 2 | 3 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 4 | 5 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 6 | 7 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 8 | 9 | 3. Neither the author's name nor the names of the contributors may be used to endorse or promote products derived from this software without specific prior written permission. 10 | 11 | THIS SOFTWARE IS PROVIDED BY Igor Serdyukov "AS IS" AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Igor Serdyukov BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # RevitTask 2 | 3 | RevitTask is available as a [Nuget package](https://www.nuget.org/packages/RevitTask). 4 | 5 | To be able to use this library in your Revit add-in, your project should also reference RevitAPIUI.dll. 6 | 7 | The main purpose of the RevitTask class is to simplify work with `IExternalEventHandler` implementations, 8 | taking advantage of `async`/`await` style. 9 | 10 | General use case is obtaining result of an arbitrary function that depends (or even not) on `UIApplication`. 11 | 12 | ## CAUTION 13 | 14 | RevitTask class is not intended to be used from an `IExternalCommand` context, though it may work well. 15 | 16 | RevitTask class instances should not be created on non-Revit context threads, UI for example, because by default 17 | it continues on captured context. Meaning that you have to follow MVVM-pattern or the like and allocate tasks 18 | inside your ViewModel or Model layer. 19 | 20 | Keep in mind that this library doesn't add any degree of parallelism to Revit, only asynchrony and 21 | a convenient way of returning results of ExternalEvent handlers and dealing with exceptions. 22 | 23 | ## Example 24 | 25 | ``` 26 | var task = new RevitTask(); 27 | 28 | string mess = string.Empty; 29 | try 30 | { 31 | var i = await task.Run(app => app.ActiveUIDocument 32 | .Selection 33 | .PickObjects(Autodesk.Revit.UI.Selection.ObjectType.Element) 34 | .Count); 35 | 36 | mess = i.ToString(); 37 | } 38 | catch (Exception ex) 39 | { 40 | mess = ex.Message; 41 | } 42 | 43 | Autodesk.Revit.UI.TaskDialog.Show("Deb", mess); 44 | ``` 45 | 46 | For any feedback, please [e-mail sis000@mail.ru](mailto:sis000@mail.ru). 47 | 48 | -------------------------------------------------------------------------------- /RevitRemoteControl/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("RevitRemoteControl")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("RevitRemoteControl")] 13 | [assembly: AssemblyCopyright("Copyright © 2020")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("4231bdef-7537-4532-9654-77a68b1cc9b5")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /RevitRemoteControl/RemoteControl.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using Autodesk.Revit.Attributes; 3 | using Autodesk.Revit.DB; 4 | using Autodesk.Revit.UI; 5 | using Autodesk.Revit.UI.Events; 6 | 7 | namespace RevitRemoteControl 8 | { 9 | ////[Transaction(TransactionMode.Manual)] 10 | ////[Regeneration(RegenerationOption.Manual)] 11 | public class RemoteControl : IExternalApplication 12 | { 13 | private bool _started; 14 | 15 | public Result Execute( 16 | ExternalCommandData commandData, 17 | ref string message, 18 | ElementSet elements) 19 | { 20 | Run(); 21 | 22 | return Result.Succeeded; 23 | } 24 | 25 | public Result OnShutdown(UIControlledApplication application) 26 | { 27 | return Result.Succeeded; 28 | } 29 | 30 | public Result OnStartup(UIControlledApplication application) 31 | { 32 | application.Idling += ApplicationOnIdling; 33 | 34 | return Result.Succeeded; 35 | } 36 | 37 | private void ApplicationOnIdling(object sender, IdlingEventArgs e) 38 | { 39 | if (!_started) 40 | { 41 | Run(); 42 | } 43 | 44 | _started = true; 45 | } 46 | 47 | public void Run() 48 | { 49 | var handler = new RequestHandler(); 50 | 51 | var listener = new RevitHttpListener(handler); 52 | 53 | Task.Run(() => listener.Start()); 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /RevitRemoteControl/RequestHandler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Threading.Tasks; 4 | using Autodesk.Revit.DB; 5 | using Autodesk.Revit.UI; 6 | 7 | namespace RevitRemoteControl 8 | { 9 | public class RequestHandler 10 | { 11 | private readonly RevitTask _revitTask = new RevitTask(); 12 | 13 | public async Task HandleAsync(string request) 14 | { 15 | string[] result; 16 | 17 | Task task; 18 | 19 | if (request == "FILEDIALOG") 20 | { 21 | task = _revitTask 22 | .Run((app) => 23 | { 24 | //// var document = app.Document; 25 | 26 | var dialog = new FileOpenDialog("Revit Files (*.rvt)|*.rvt"); 27 | 28 | var dialogResult = dialog.Show(); 29 | 30 | var modelPath = dialog.GetSelectedModelPath(); 31 | 32 | var path = ModelPathUtils 33 | .ConvertModelPathToUserVisiblePath(modelPath); 34 | 35 | return new[] { path }; 36 | }); 37 | } 38 | else if (request == "VIEWLIST") 39 | { 40 | task = _revitTask 41 | .Run((uiapp) => 42 | { 43 | if (uiapp.ActiveUIDocument?.Document == null) 44 | { 45 | return new[] {"No opened documents"}; 46 | } 47 | 48 | var document = uiapp.ActiveUIDocument.Document; 49 | 50 | var plans = new FilteredElementCollector(document) 51 | .WhereElementIsNotElementType() 52 | .OfClass(typeof(View)) 53 | .Select(x => x.Name) 54 | .ToArray(); 55 | 56 | return plans; 57 | }); 58 | } 59 | else 60 | { 61 | task = _revitTask 62 | .Run(uiapp => 63 | { 64 | //// TaskDialog.Show("Deb", $"Requested: {request}"); 65 | 66 | var command = (PostableCommand)Enum.Parse( 67 | typeof(PostableCommand), 68 | request, 69 | true); 70 | 71 | var id = RevitCommandId 72 | .LookupPostableCommandId(command); 73 | 74 | uiapp.PostCommand(id); 75 | 76 | return new[] { $"Successfully posted command {command}" }; 77 | }); 78 | } 79 | 80 | 81 | try 82 | { 83 | result = await task; 84 | } 85 | catch (Exception e) 86 | { 87 | result = new[] { $"{e.Message} in {e.StackTrace}" }; 88 | } 89 | 90 | return result; 91 | } 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /RevitRemoteControl/RevitHttpListener.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Net; 4 | using System.Text; 5 | using Autodesk.Revit.UI; 6 | 7 | namespace RevitRemoteControl 8 | { 9 | public class RevitHttpListener 10 | { 11 | private readonly HttpListener _listener; 12 | private readonly RequestHandler _requestHandler; 13 | 14 | public RevitHttpListener( 15 | RequestHandler requestHandler) 16 | { 17 | if (!HttpListener.IsSupported) 18 | { 19 | throw new InvalidOperationException( 20 | "Unsupported operating system!"); 21 | } 22 | 23 | var url = "http://127.0.0.1"; 24 | string port = "8080"; 25 | string prefix = $"{url}:{port}/"; 26 | _listener = new HttpListener(); 27 | _listener.Prefixes.Add(prefix); 28 | _requestHandler = requestHandler; 29 | } 30 | 31 | public async void Start() 32 | { 33 | if (_listener.IsListening) 34 | { 35 | return; 36 | } 37 | 38 | try 39 | { 40 | _listener.Start(); 41 | } 42 | catch (Exception e) 43 | { 44 | TaskDialog.Show("Error", e.Message); 45 | return; 46 | } 47 | 48 | while (true) 49 | { 50 | try 51 | { 52 | var context = await _listener 53 | .GetContextAsync(); 54 | 55 | var request = context 56 | .Request 57 | .RawUrl 58 | .Replace("/", string.Empty) 59 | .ToUpper(); 60 | 61 | var response = context.Response; 62 | 63 | if (request == "STOP") 64 | { 65 | Stop(); 66 | break; 67 | } 68 | 69 | if (request.Contains("FAVICON.ICO")) 70 | { 71 | response.StatusCode = (int)HttpStatusCode.BadRequest; 72 | 73 | response.OutputStream.Close(); 74 | 75 | continue; 76 | } 77 | 78 | var result = await _requestHandler 79 | .HandleAsync(request); 80 | 81 | var list = string.Join("", result 82 | .Select((x, i) => "

" + (i + 1) + ". " + x + "

")); 83 | 84 | var responseString = 85 | $"" + 86 | list + 87 | $""; 88 | 89 | var buffer = Encoding.UTF8 90 | .GetBytes(responseString); 91 | 92 | response.ContentLength64 = buffer.Length; 93 | 94 | response.OutputStream.Write(buffer, 0, buffer.Length); 95 | 96 | response.OutputStream.Close(); 97 | } 98 | catch (HttpListenerException) 99 | { } 100 | } 101 | } 102 | 103 | public void Stop() 104 | { 105 | _listener.Stop(); 106 | _listener.Close(); 107 | } 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /RevitRemoteControl/RevitRemoteControl.addin: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | RevitRemoteControl.dll 5 | A83DF02D-E9AA-4373-99F8-BFBD526C2A54 6 | RevitRemoteControl.RemoteControl 7 | Revit Remote Control 8 | AlwaysVisible 9 | WHSH 10 | OCEAN 11 | 12 | -------------------------------------------------------------------------------- /RevitRemoteControl/RevitRemoteControl.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | AnyCPU 6 | {4231BDEF-7537-4532-9654-77A68B1CC9B5} 7 | Library 8 | RevitRemoteControl 9 | RevitRemoteControl 10 | bin\$(Configuration)\ 11 | 512 12 | true 13 | 14 | 15 | 16 | v4.5 17 | 18 | 19 | v4.6 20 | 21 | 22 | full 23 | true 24 | 25 | 26 | v4.6 27 | 28 | 29 | v4.7 30 | 31 | 32 | v4.7 33 | 34 | 35 | 36 | 37 | 38 | False 39 | ..\packages\Revit_All_Main_Versions_API_x64.$(Configuration).0.1\lib\net45\RevitAPI.dll 40 | False 41 | 42 | 43 | False 44 | ..\packages\Revit_All_Main_Versions_API_x64.$(Configuration).0.1\lib\net45\RevitAPIUI.dll 45 | False 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | False 54 | ..\packages\Revit_All_Main_Versions_API_x64.$(Configuration).0.1\lib\net46\RevitAPI.dll 55 | False 56 | 57 | 58 | False 59 | ..\packages\Revit_All_Main_Versions_API_x64.$(Configuration).0.1\lib\net46\RevitAPIUI.dll 60 | False 61 | 62 | 63 | 64 | 65 | 66 | 67 | False 68 | ..\packages\Revit_All_Main_Versions_API_x64.$(Configuration).0.1\lib\net47\RevitAPI.dll 69 | False 70 | 71 | 72 | False 73 | ..\packages\Revit_All_Main_Versions_API_x64.$(Configuration).0.1\lib\net47\RevitAPIUI.dll 74 | False 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | $(Configuration).0.1 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | {4c58a8df-3c83-46d8-b340-3459daac6744} 97 | RevitTask 98 | False 99 | 100 | 101 | 102 | 103 | 104 | 105 | -------------------------------------------------------------------------------- /RevitTask.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.29503.13 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RevitTask", "RevitTask\RevitTask.csproj", "{4C58A8DF-3C83-46D8-B340-3459DAAC6744}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RevitTaskExample", "RevitTaskExample\RevitTaskExample.csproj", "{FB731CF5-D924-49F4-9899-E9A2BF7EB08F}" 9 | EndProject 10 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RevitRemoteControl", "RevitRemoteControl\RevitRemoteControl.csproj", "{4231BDEF-7537-4532-9654-77A68B1CC9B5}" 11 | EndProject 12 | Global 13 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 14 | 2016|Any CPU = 2016|Any CPU 15 | 2017|Any CPU = 2017|Any CPU 16 | 2018|Any CPU = 2018|Any CPU 17 | 2019|Any CPU = 2019|Any CPU 18 | 2020|Any CPU = 2020|Any CPU 19 | EndGlobalSection 20 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 21 | {4C58A8DF-3C83-46D8-B340-3459DAAC6744}.2016|Any CPU.ActiveCfg = 2016|Any CPU 22 | {4C58A8DF-3C83-46D8-B340-3459DAAC6744}.2016|Any CPU.Build.0 = 2016|Any CPU 23 | {4C58A8DF-3C83-46D8-B340-3459DAAC6744}.2017|Any CPU.ActiveCfg = 2017|Any CPU 24 | {4C58A8DF-3C83-46D8-B340-3459DAAC6744}.2017|Any CPU.Build.0 = 2017|Any CPU 25 | {4C58A8DF-3C83-46D8-B340-3459DAAC6744}.2018|Any CPU.ActiveCfg = 2018|Any CPU 26 | {4C58A8DF-3C83-46D8-B340-3459DAAC6744}.2018|Any CPU.Build.0 = 2018|Any CPU 27 | {4C58A8DF-3C83-46D8-B340-3459DAAC6744}.2019|Any CPU.ActiveCfg = 2019|Any CPU 28 | {4C58A8DF-3C83-46D8-B340-3459DAAC6744}.2019|Any CPU.Build.0 = 2019|Any CPU 29 | {4C58A8DF-3C83-46D8-B340-3459DAAC6744}.2020|Any CPU.ActiveCfg = 2020|Any CPU 30 | {4C58A8DF-3C83-46D8-B340-3459DAAC6744}.2020|Any CPU.Build.0 = 2020|Any CPU 31 | {FB731CF5-D924-49F4-9899-E9A2BF7EB08F}.2016|Any CPU.ActiveCfg = 2016|Any CPU 32 | {FB731CF5-D924-49F4-9899-E9A2BF7EB08F}.2016|Any CPU.Build.0 = 2016|Any CPU 33 | {FB731CF5-D924-49F4-9899-E9A2BF7EB08F}.2017|Any CPU.ActiveCfg = 2017|Any CPU 34 | {FB731CF5-D924-49F4-9899-E9A2BF7EB08F}.2017|Any CPU.Build.0 = 2017|Any CPU 35 | {FB731CF5-D924-49F4-9899-E9A2BF7EB08F}.2018|Any CPU.ActiveCfg = 2018|Any CPU 36 | {FB731CF5-D924-49F4-9899-E9A2BF7EB08F}.2018|Any CPU.Build.0 = 2018|Any CPU 37 | {FB731CF5-D924-49F4-9899-E9A2BF7EB08F}.2019|Any CPU.ActiveCfg = 2019|Any CPU 38 | {FB731CF5-D924-49F4-9899-E9A2BF7EB08F}.2019|Any CPU.Build.0 = 2019|Any CPU 39 | {FB731CF5-D924-49F4-9899-E9A2BF7EB08F}.2020|Any CPU.ActiveCfg = 2020|Any CPU 40 | {FB731CF5-D924-49F4-9899-E9A2BF7EB08F}.2020|Any CPU.Build.0 = 2020|Any CPU 41 | {4231BDEF-7537-4532-9654-77A68B1CC9B5}.2016|Any CPU.ActiveCfg = 2016|Any CPU 42 | {4231BDEF-7537-4532-9654-77A68B1CC9B5}.2016|Any CPU.Build.0 = 2016|Any CPU 43 | {4231BDEF-7537-4532-9654-77A68B1CC9B5}.2017|Any CPU.ActiveCfg = 2017|Any CPU 44 | {4231BDEF-7537-4532-9654-77A68B1CC9B5}.2017|Any CPU.Build.0 = 2017|Any CPU 45 | {4231BDEF-7537-4532-9654-77A68B1CC9B5}.2018|Any CPU.ActiveCfg = 2018|Any CPU 46 | {4231BDEF-7537-4532-9654-77A68B1CC9B5}.2018|Any CPU.Build.0 = 2018|Any CPU 47 | {4231BDEF-7537-4532-9654-77A68B1CC9B5}.2019|Any CPU.ActiveCfg = 2019|Any CPU 48 | {4231BDEF-7537-4532-9654-77A68B1CC9B5}.2019|Any CPU.Build.0 = 2019|Any CPU 49 | {4231BDEF-7537-4532-9654-77A68B1CC9B5}.2020|Any CPU.ActiveCfg = 2020|Any CPU 50 | {4231BDEF-7537-4532-9654-77A68B1CC9B5}.2020|Any CPU.Build.0 = 2020|Any CPU 51 | EndGlobalSection 52 | GlobalSection(SolutionProperties) = preSolution 53 | HideSolutionNode = FALSE 54 | EndGlobalSection 55 | GlobalSection(ExtensibilityGlobals) = postSolution 56 | SolutionGuid = {A0505EED-04E0-450B-B0D4-5DB0ACF2C6C6} 57 | EndGlobalSection 58 | EndGlobal 59 | -------------------------------------------------------------------------------- /RevitTask/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | 4 | // General Information about an assembly is controlled through the following 5 | // set of attributes. Change these attribute values to modify the information 6 | // associated with an assembly. 7 | [assembly: AssemblyTitle("RevitTask")] 8 | [assembly: AssemblyDescription("Provides Task-based work in Revit")] 9 | [assembly: AssemblyProduct("Provides Task-based work in Revit")] 10 | [assembly: AssemblyCopyright("Copyright © 2020, Igor Serdyukov")] 11 | 12 | // Setting ComVisible to false makes the types in this assembly not visible 13 | // to COM components. If you need to access a type in this assembly from 14 | // COM, set the ComVisible attribute to true on that type. 15 | [assembly: ComVisible(false)] 16 | 17 | // The following GUID is for the ID of the typelib if this project is exposed to COM 18 | [assembly: Guid("4c58a8df-3c83-46d8-b340-3459daac6744")] 19 | 20 | // Version information for an assembly consists of the following four values: 21 | // 22 | // Major Version 23 | // Minor Version 24 | // Build Number 25 | // Revision 26 | // 27 | // You can specify all the values or you can default the Build and Revision Numbers 28 | // by using the '*' as shown below: 29 | // [assembly: AssemblyVersion("1.0.*")] 30 | [assembly: AssemblyVersion("3.0.0.0")] 31 | -------------------------------------------------------------------------------- /RevitTask/README.md: -------------------------------------------------------------------------------- 1 | To be able to use this library in your Revit addin project, it should have a reference to `RevitAPIUI.dll`. 2 | 3 | The main purpose of RevitTask class is to simplify work with `IExternalEventHandler` implementations 4 | taking advantage of `async`/`await` style. 5 | 6 | General use case is obtaning result of an arbitrary function that depends (or even not) on `UIApplication`. 7 | 8 | CAUTION: RevitTask class is not intended to be used from `IExternalCommand` context, though it may work well. 9 | 10 | The `RevitTask` class instance should not be created on non-Revit context threads, UI for example, because 11 | by default it continues on captured context. Meaning that you have to follow MVVM-pattern and allocate tasks 12 | inside your ViewModel or Model layer. 13 | 14 | Keep in mind that this library doesn't add any degree of parallelism to Revit, only asynchrony. 15 | 16 | Example: 17 | 18 | var task = new RevitTask(); 19 | 20 | string mess = string.Empty; 21 | try 22 | { 23 | var i = await task.Run(app => 24 | { 25 | return app.ActiveUIDocument 26 | .Selection 27 | .PickObjects(Autodesk.Revit.UI.Selection.ObjectType.Element) 28 | .Count; 29 | }); 30 | 31 | mess = i.ToString(); 32 | } 33 | catch (Exception ex) 34 | { 35 | mess = ex.Message; 36 | } 37 | 38 | Autodesk.Revit.UI.TaskDialog.Show("Deb", mess); 39 | 40 | For any feedback, please e-mail me at [sis000@mail.ru](mailto:sis000@mail.ru). 41 | -------------------------------------------------------------------------------- /RevitTask/RevitTask.cs: -------------------------------------------------------------------------------- 1 | using Autodesk.Revit.UI; 2 | using System; 3 | using System.Threading.Tasks; 4 | 5 | /// 6 | /// wrapper 7 | /// for 8 | /// 9 | /// 10 | public class RevitTask 11 | { 12 | private EventHandler _handler; 13 | private TaskCompletionSource _tcs; 14 | private ExternalEvent _externalEvent; 15 | 16 | /// 17 | /// .ctor 18 | /// 19 | public RevitTask() 20 | { 21 | _handler = new EventHandler(); 22 | 23 | _handler.EventCompleted += OnEventCompleted; 24 | 25 | _externalEvent = ExternalEvent.Create(_handler); 26 | } 27 | 28 | /// 29 | /// Sets required as a body 30 | /// of 31 | /// method and raises related 32 | /// 33 | /// Any function that depends on 34 | /// 35 | /// and results in object of type. 36 | public Task Run(Func func) 37 | { 38 | _tcs = new TaskCompletionSource(); 39 | 40 | var task = Task.Run(async () => (TResult)await _tcs.Task); 41 | 42 | _handler.Func = (app) => func(app); 43 | 44 | _externalEvent.Raise(); 45 | 46 | //// var task = Task.FromResult((TResult)_tcs.Task.Result); 47 | 48 | return task; 49 | } 50 | 51 | /// 52 | /// Sets required as a body 53 | /// of 54 | /// method and raises related 55 | /// 56 | /// Any action that depends on 57 | /// 58 | /// and results in object of type. 59 | public Task Run(Action act) 60 | { 61 | _tcs = new TaskCompletionSource(); 62 | 63 | _handler.Func = (app) => { act(app); return new object(); }; 64 | 65 | _externalEvent.Raise(); 66 | 67 | return _tcs.Task; 68 | } 69 | 70 | /// 71 | /// Sets Task result to object of TResult type or Exception 72 | /// after 73 | /// completes. 74 | /// 75 | /// 76 | /// 77 | private void OnEventCompleted(object sender, object result) 78 | { 79 | if (_handler.Exception == null) 80 | { 81 | _tcs.TrySetResult(result); 82 | } 83 | else 84 | { 85 | _tcs.TrySetException(_handler.Exception); 86 | } 87 | } 88 | 89 | private class EventHandler : 90 | IExternalEventHandler 91 | { 92 | private Func _func; 93 | 94 | public event EventHandler EventCompleted; 95 | 96 | public Exception Exception { get; private set; } 97 | 98 | public Func Func 99 | { 100 | get => _func; 101 | set => _func = value ?? 102 | throw new ArgumentNullException(); 103 | } 104 | 105 | public void Execute(UIApplication app) 106 | { 107 | object result = null; 108 | 109 | Exception = null; 110 | 111 | try 112 | { 113 | result = Func(app); 114 | } 115 | catch (Exception ex) 116 | { 117 | Exception = ex; 118 | } 119 | 120 | EventCompleted?.Invoke(this, result); 121 | } 122 | 123 | public string GetName() 124 | { 125 | return "RevitTask"; 126 | } 127 | } 128 | } -------------------------------------------------------------------------------- /RevitTask/RevitTask.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | AnyCPU 6 | {4C58A8DF-3C83-46D8-B340-3459DAAC6744} 7 | Library 8 | Properties 9 | RevitTask 10 | RevitTask 11 | bin\$(Configuration)\ 12 | 512 13 | true 14 | 15 | 16 | true 17 | full 18 | false 19 | DEBUG;TRACE 20 | prompt 21 | 4 22 | bin\Debug\RevitTask.xml 23 | 24 | 25 | v4.5 26 | 27 | 28 | v4.5.2 29 | 30 | 31 | v4.5.2 32 | 33 | 34 | v4.7 35 | 36 | 37 | v4.7 38 | 39 | 40 | 41 | 42 | 43 | False 44 | .\_Refs\$(Configuration)\RevitAPIUI.dll 45 | False 46 | 47 | 48 | 49 | 50 | 51 | 52 | False 53 | .\_Refs\$(Configuration)\RevitAPIUI.dll 54 | False 55 | 56 | 57 | 58 | 59 | 60 | 61 | False 62 | .\_Refs\$(Configuration)\RevitAPIUI.dll 63 | False 64 | 65 | 66 | 67 | 68 | 69 | 70 | False 71 | .\_Refs\$(Configuration)\RevitAPIUI.dll 72 | False 73 | 74 | 75 | 76 | 77 | 78 | 79 | False 80 | .\_Refs\$(Configuration)\RevitAPIUI.dll 81 | False 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | -------------------------------------------------------------------------------- /RevitTask/_Refs/2016/RevitAPIUI.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WhiteSharq/RevitTask/4f8e2892c2b4fcb82d517fd1be9c612b61bb6a21/RevitTask/_Refs/2016/RevitAPIUI.dll -------------------------------------------------------------------------------- /RevitTask/_Refs/2017/RevitAPIUI.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WhiteSharq/RevitTask/4f8e2892c2b4fcb82d517fd1be9c612b61bb6a21/RevitTask/_Refs/2017/RevitAPIUI.dll -------------------------------------------------------------------------------- /RevitTask/_Refs/2018/RevitAPIUI.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WhiteSharq/RevitTask/4f8e2892c2b4fcb82d517fd1be9c612b61bb6a21/RevitTask/_Refs/2018/RevitAPIUI.dll -------------------------------------------------------------------------------- /RevitTask/_Refs/2019/RevitAPIUI.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WhiteSharq/RevitTask/4f8e2892c2b4fcb82d517fd1be9c612b61bb6a21/RevitTask/_Refs/2019/RevitAPIUI.dll -------------------------------------------------------------------------------- /RevitTask/_Refs/2020/RevitAPIUI.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WhiteSharq/RevitTask/4f8e2892c2b4fcb82d517fd1be9c612b61bb6a21/RevitTask/_Refs/2020/RevitAPIUI.dll -------------------------------------------------------------------------------- /RevitTaskExample/Commands/StartCommand.cs: -------------------------------------------------------------------------------- 1 | using Autodesk.Revit.Attributes; 2 | using Autodesk.Revit.DB; 3 | using Autodesk.Revit.UI; 4 | using System.Threading; 5 | 6 | namespace RevitTaskExample 7 | { 8 | [Transaction(TransactionMode.Manual)] 9 | [Regeneration(RegenerationOption.Manual)] 10 | public class StartCommand : 11 | IExternalCommand 12 | { 13 | public Result Execute( 14 | ExternalCommandData commandData, 15 | ref string message, 16 | ElementSet elements) 17 | { 18 | var id = Thread.CurrentThread.ManagedThreadId; 19 | 20 | var viewModel = new MainViewModel(); 21 | 22 | var mainWindow = new MainWindow(viewModel); 23 | 24 | mainWindow.Show(); 25 | 26 | return Result.Succeeded; 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /RevitTaskExample/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Resources; 3 | using System.Runtime.CompilerServices; 4 | using System.Runtime.InteropServices; 5 | using System.Windows; 6 | 7 | // General Information about an assembly is controlled through the following 8 | // set of attributes. Change these attribute values to modify the information 9 | // associated with an assembly. 10 | [assembly: AssemblyTitle("RevitTaskExample")] 11 | [assembly: AssemblyDescription("")] 12 | [assembly: AssemblyConfiguration("")] 13 | [assembly: AssemblyCompany("")] 14 | [assembly: AssemblyProduct("RevitTaskExample")] 15 | [assembly: AssemblyCopyright("Copyright © 2020")] 16 | [assembly: AssemblyTrademark("")] 17 | [assembly: AssemblyCulture("")] 18 | 19 | // Setting ComVisible to false makes the types in this assembly not visible 20 | // to COM components. If you need to access a type in this assembly from 21 | // COM, set the ComVisible attribute to true on that type. 22 | [assembly: ComVisible(false)] 23 | 24 | //In order to begin building localizable applications, set 25 | //CultureYouAreCodingWith in your .csproj file 26 | //inside a . For example, if you are using US english 27 | //in your source files, set the to en-US. Then uncomment 28 | //the NeutralResourceLanguage attribute below. Update the "en-US" in 29 | //the line below to match the UICulture setting in the project file. 30 | 31 | //[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)] 32 | 33 | 34 | [assembly: ThemeInfo( 35 | ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located 36 | //(used if a resource is not found in the page, 37 | // or application resource dictionaries) 38 | ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located 39 | //(used if a resource is not found in the page, 40 | // app, or any theme specific resource dictionaries) 41 | )] 42 | 43 | 44 | // Version information for an assembly consists of the following four values: 45 | // 46 | // Major Version 47 | // Minor Version 48 | // Build Number 49 | // Revision 50 | // 51 | // You can specify all the values or you can default the Build and Revision Numbers 52 | // by using the '*' as shown below: 53 | // [assembly: AssemblyVersion("1.0.*")] 54 | [assembly: AssemblyVersion("1.0.0.0")] 55 | [assembly: AssemblyFileVersion("1.0.0.0")] 56 | -------------------------------------------------------------------------------- /RevitTaskExample/RevitTaskExample.addin: -------------------------------------------------------------------------------- 1 |  2 | 3 | RevitTaskExample.dll 4 | 85621631-CDA8-46EE-AD82-E0FC91D40BAA 5 | RevitTaskExample.StartCommand 6 | RevitTask Example 7 | AlwaysVisible 8 | Unknown 9 | WHSH 10 | 11 | -------------------------------------------------------------------------------- /RevitTaskExample/RevitTaskExample.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | AnyCPU 6 | {FB731CF5-D924-49F4-9899-E9A2BF7EB08F} 7 | Library 8 | RevitTaskExample 9 | RevitTaskExample 10 | bin\$(Configuration)\ 11 | 512 12 | {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 13 | 4 14 | true 15 | 16 | 17 | AnyCPU 18 | true 19 | full 20 | false 21 | bin\Debug\ 22 | DEBUG;TRACE 23 | prompt 24 | 4 25 | 26 | 27 | v4.5 28 | 29 | 30 | v4.6 31 | 32 | 33 | v4.6 34 | 35 | 36 | v4.7 37 | 38 | 39 | v4.7 40 | 41 | 42 | 43 | 44 | 45 | False 46 | ..\packages\Revit_All_Main_Versions_API_x64.$(Configuration).0.1\lib\net45\RevitAPI.dll 47 | False 48 | 49 | 50 | False 51 | ..\packages\Revit_All_Main_Versions_API_x64.$(Configuration).0.1\lib\net45\RevitAPIUI.dll 52 | False 53 | 54 | 55 | 56 | 57 | 58 | 59 | False 60 | ..\packages\Revit_All_Main_Versions_API_x64.$(Configuration).0.1\lib\net46\RevitAPI.dll 61 | False 62 | 63 | 64 | False 65 | ..\packages\Revit_All_Main_Versions_API_x64.$(Configuration).0.1\lib\net46\RevitAPIUI.dll 66 | False 67 | 68 | 69 | 70 | 71 | 72 | 73 | False 74 | ..\packages\Revit_All_Main_Versions_API_x64.$(Configuration).0.1\lib\net46\RevitAPI.dll 75 | False 76 | 77 | 78 | False 79 | ..\packages\Revit_All_Main_Versions_API_x64.$(Configuration).0.1\lib\net46\RevitAPIUI.dll 80 | False 81 | 82 | 83 | 84 | 85 | 86 | 87 | False 88 | ..\packages\Revit_All_Main_Versions_API_x64.$(Configuration).0.1\lib\net47\RevitAPI.dll 89 | False 90 | 91 | 92 | False 93 | ..\packages\Revit_All_Main_Versions_API_x64.$(Configuration).0.1\lib\net47\RevitAPIUI.dll 94 | False 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | MSBuild:Compile 104 | Designer 105 | 106 | 107 | 108 | 109 | MainWindow.xaml 110 | Code 111 | 112 | 113 | 114 | 115 | Code 116 | 117 | 118 | 119 | 120 | {4c58a8df-3c83-46d8-b340-3459daac6744} 121 | RevitTask 122 | False 123 | 124 | 125 | 126 | 127 | $(Configuration).0.1 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | -------------------------------------------------------------------------------- /RevitTaskExample/UiCommand.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows.Input; 3 | 4 | namespace RevitTaskExample 5 | { 6 | public class UiCommand : ICommand 7 | { 8 | private readonly Action _act; 9 | 10 | public UiCommand(Action act) 11 | { 12 | _act = act; 13 | } 14 | 15 | public event EventHandler CanExecuteChanged; 16 | 17 | public bool CanExecute(object parameter) 18 | { 19 | return true; 20 | } 21 | 22 | public void Execute(object parameter) 23 | { 24 | _act(); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /RevitTaskExample/ViewModels/MainViewModel.cs: -------------------------------------------------------------------------------- 1 | using Autodesk.Revit.DB; 2 | using Autodesk.Revit.UI; 3 | using System; 4 | using System.Windows.Input; 5 | 6 | namespace RevitTaskExample 7 | { 8 | public class MainViewModel 9 | { 10 | private RevitTask _revitTask = new RevitTask(); 11 | 12 | public MainViewModel() 13 | { 14 | RunLongRevit = new UiCommand(PlaceInstances); 15 | } 16 | 17 | public ICommand RunLongRevit { get; set; } 18 | 19 | private FamilyInstance CreateFamilyInstance( 20 | Document document, 21 | FamilySymbol fs) 22 | { 23 | using (var t = new Transaction(document)) 24 | { 25 | t.Start(nameof(CreateFamilyInstance)); 26 | 27 | var instance = document.Create.NewFamilyInstance( 28 | new XYZ(), 29 | fs, 30 | document.ActiveView); 31 | 32 | t.Commit(); 33 | 34 | return instance; 35 | } 36 | } 37 | 38 | private async void PlaceInstances() 39 | { 40 | try 41 | { 42 | for (int i = 0; i < 10; i++) 43 | { 44 | var instance = (FamilyInstance)await _revitTask.Run((uiApp) => 45 | CreateFamilyInstance( 46 | uiApp.ActiveUIDocument.Document, 47 | null)); 48 | } 49 | } 50 | catch(Exception e) 51 | { 52 | TaskDialog.Show("Debug", e.Message); 53 | } 54 | } 55 | } 56 | } -------------------------------------------------------------------------------- /RevitTaskExample/Views/MainWindow.xaml: -------------------------------------------------------------------------------- 1 |  9 | 10 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /RevitTaskExample/Views/MainWindow.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Threading; 2 | using System.Windows; 3 | 4 | namespace RevitTaskExample 5 | { 6 | /// 7 | /// Interaction logic for MainWindow.xaml 8 | /// 9 | public partial class MainWindow : Window 10 | { 11 | public MainWindow() 12 | { 13 | var id = Thread.CurrentThread.ManagedThreadId; 14 | InitializeComponent(); 15 | } 16 | 17 | public MainWindow(MainViewModel viewModel) : this() 18 | { 19 | var id = Thread.CurrentThread.ManagedThreadId; 20 | DataContext = viewModel; 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /RevitTaskExample/_Refs/2016/RevitAPI.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WhiteSharq/RevitTask/4f8e2892c2b4fcb82d517fd1be9c612b61bb6a21/RevitTaskExample/_Refs/2016/RevitAPI.dll -------------------------------------------------------------------------------- /RevitTaskExample/_Refs/2016/RevitAPIUI.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WhiteSharq/RevitTask/4f8e2892c2b4fcb82d517fd1be9c612b61bb6a21/RevitTaskExample/_Refs/2016/RevitAPIUI.dll -------------------------------------------------------------------------------- /RevitTaskExample/_Refs/2017/RevitAPI.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WhiteSharq/RevitTask/4f8e2892c2b4fcb82d517fd1be9c612b61bb6a21/RevitTaskExample/_Refs/2017/RevitAPI.dll -------------------------------------------------------------------------------- /RevitTaskExample/_Refs/2017/RevitAPIUI.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WhiteSharq/RevitTask/4f8e2892c2b4fcb82d517fd1be9c612b61bb6a21/RevitTaskExample/_Refs/2017/RevitAPIUI.dll -------------------------------------------------------------------------------- /RevitTaskExample/_Refs/2018/RevitAPI.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WhiteSharq/RevitTask/4f8e2892c2b4fcb82d517fd1be9c612b61bb6a21/RevitTaskExample/_Refs/2018/RevitAPI.dll -------------------------------------------------------------------------------- /RevitTaskExample/_Refs/2018/RevitAPIUI.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WhiteSharq/RevitTask/4f8e2892c2b4fcb82d517fd1be9c612b61bb6a21/RevitTaskExample/_Refs/2018/RevitAPIUI.dll -------------------------------------------------------------------------------- /RevitTaskExample/_Refs/2019/RevitAPI.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WhiteSharq/RevitTask/4f8e2892c2b4fcb82d517fd1be9c612b61bb6a21/RevitTaskExample/_Refs/2019/RevitAPI.dll -------------------------------------------------------------------------------- /RevitTaskExample/_Refs/2019/RevitAPIUI.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WhiteSharq/RevitTask/4f8e2892c2b4fcb82d517fd1be9c612b61bb6a21/RevitTaskExample/_Refs/2019/RevitAPIUI.dll -------------------------------------------------------------------------------- /RevitTaskExample/_Refs/2020/RevitAPI.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WhiteSharq/RevitTask/4f8e2892c2b4fcb82d517fd1be9c612b61bb6a21/RevitTaskExample/_Refs/2020/RevitAPI.dll -------------------------------------------------------------------------------- /RevitTaskExample/_Refs/2020/RevitAPIUI.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WhiteSharq/RevitTask/4f8e2892c2b4fcb82d517fd1be9c612b61bb6a21/RevitTaskExample/_Refs/2020/RevitAPIUI.dll --------------------------------------------------------------------------------