We receive Revit model from other companies, so those models are not central models or local models, or have access to their central model location. I created, what I thought, was a simple routine to open the received model, detached, so I can save it as a new central model on our network.
ModelPath path = ModelPathUtils.ConvertUserVisiblePathToModelPath(#"C:\Temp\received model.rvt");
OpenOptions opts = new OpenOptions();
opts.Audit = true;
opts.AllowOpeningLocalByWrongUser = true;
opts.DetachFromCentralOption = DetachFromCentralOption.DetachAndPreserveWorksets;
opts.SetOpenWorksetsConfiguration(new WorksetConfiguration(WorksetConfigurationOption.OpenAllWorksets));
UIDocument uidoc = this.OpenAndActivateDocument(path, opts, false);
The code works as expected in all but ONE case: when the received file has it's a Workset Configuration of "Specify...". No matter what WorksetConfiguration I use to try and open the Document, I get the exception.
When I look at the journal file, where the open fails I have this message:
Observable::getWorksetConfigForLoading 'Specify' = askUser
I've tried using, WorksetConfigurationOption.OpenAllWorksets, WorksetConfigurationOption.CloseAllWorksets and WorksetConfigurationOption.OpenLastViewed. I'm in Revit 2016, 2018 and 2020.
You could try the three levels of Detecting and Handling Dialogues and Failures. Maybe the Failure API will help, or the JtClicker Windows API hook approach.
Related
Good afternoon,
I am trying to use Eyeshot in a .NET Framework Web Application to create a Bitmap image. The steps of the process in my code are the following: I generate all the necessary Entities and then I add them to a Model control that is not visible in the Web Application; once all Entities are added, I use the ZoomFit() method to zoom to the desired Entities and then I use the RenderToBitmap() method to create the Bitmap image.
The issue regards the ZoomFit() method: when executed, it gives the following error message:
"Control's handle must be created first".
The portion of code regarding the creation of the Model control is the following:
Model model1 = new Model();
model1.InitializeViewports();
model1.Size = new Size(500, 300);
model1.CreateControl();
model1.Layers.Add("Grid");
model1.Layers["Grid"].LineWeight = 0.3f;
model1.Layers["Grid"].Color = Color.LightGray;
model1.Layers.Add("Gauges");
model1.Layers["Gauges"].LineWeight = 1.5f;
// List of entities for correct zooming
IList<Entity> Grid = new List<Entity>();
IList<Entity> Gauges = new List<Entity>();
// List of strings containing the paths to the dxf files on the server
List<string> drawingsFilePaths = (List<string>)Session["drawingsFilePaths"];
// List of images
List<Bitmap> drawings = new List<Bitmap>();
foreach (string path in drawingsFilePaths)
{
// Clearing the entities every time I change the file
model1.Entities.Clear();
// Creating the viewport starting from the dxf files
ReadAutodesk read = new ReadAutodesk(path);
read.DoWork();
foreach (Entity en in read.Entities)
{
if (en.LayerName == "Grid")
{
Grid.Add(en);
}
else if (en.LayerName == "Gauges")
{
Gauges.Add(en);
}
model1.Entities.Add(en);
}
model1.ActiveViewport.OriginSymbol.Visible = false;
model1.ActiveViewport.ViewCubeIcon.Visible = false;
model1.ActiveViewport.ToolBar.Visible = false;
model1.ActiveViewport.SetView(viewType.Right);
model1.ZoomFit(Gauges, false);
Bitmap tmp = model1.RenderToBitmap(1);
drawings.Add(tmp);
However, this issue is faced ONLY when publishing the Web Application on a remote Server (Windows Server 2012); in fact, when I publish it using my own personal computer (Windows 10) as a server, everything works perfectly.
I already checked the presence of all the Eyeshot DLLs in the pubblished Web Application, and the settings of IIS on my PC and on the Server are the same. Could it be an issue related to some missing references that are implicitly called by Eyeshot DLLs and are not present on Windows Server? What do you think is the problem?
Kind regards,
Giacomo Balestrieri
This is a licensing issue. Eyeshot Trial version cannot be copied on other machines. The same problem would occur if you copy your app to a different Win10 machine.
So we have created an updated version of a WSP for SharePoint 2010 due to our migration/update from 2007 to 2010.
The WSP is a event handler/reciever for ItemAdded() and we have it working as intended. Issue is that the operation seems to only work for one computer/machine and no others.
When the Item is Added to a list the WSP creates a Folder in Shared Documents library, creates a wiki page, then updates the new List Item with links to the Shared Doc and Wiki.
When triggered by Machine #1 and User #1 all operations work, when Machine #2(M2) and user #2(U2) or M3 and U3 non of the tasks take place when a new Item is created.
User #2 can log in on M1 and create a new item and all operations work. But if U1 uses M2 or M3 to create an item the events don't trigger. Machine #1 is able to trigger the event as many times as they want but no other computer is able to.
If you were able to follow is it something with the code or some sort of cache setting on the local machine or the SP server, or something else? Any help is appreciated.
Update: All machines are on the same network. Non of the machines are the server but various personal laptops. Development was done on a separate machine. All are accessing via the same URL. All users have same access. This is on our test site currently which would be switched to being production once migration/upgrade takes place.
Before current .WSP deployment we noticed the same issue but it was reverse, Machine #2 did all the updates but Machine #1 and #3 couldn't. Only thing we can think of was that those machines were the first to trigger the event after deployment.
I'm Not doing the .WSP install but our IT guy is(won't let us have access :/ but I understand) but below is the install commands he is running.
Add-SPSolution -LiteralPath "OurPath/ourFile.wsp"
Install-SPSolution -Identity ourIdentity -WebApplication http://myhost.com/ -GACDeployment
Below is the main part of the code
public class CreateWikiAndFolder : Microsoft.SharePoint.SPItemEventReceiver
{
public override void ItemAdded(SPItemEventProperties properties)
{
try
{
//this.DisableEventFiring();
base.EventFiringEnabled = false;
string sUrlOfWikiPage = string.Empty;
string sUrlOfNewFolder = string.Empty;
string sSubsiteRUL = string.Empty;
string sCurrentItemTitle = properties.ListItem["Title"].ToString();
string sWikiListName = "TR Wikis";
string sDocLibName = "Shared Documents";
string sTRListID = "TR Status";
if (sTRListID.ToUpper().Equals(properties.ListTitle.ToString().ToUpper()))
{
//Create the Folder
sUrlOfNewFolder = CreateFolder(properties.ListItem.Web, sDocLibName, sCurrentItemTitle);
//Create the Wiki
string ItemDispFormUrl = String.Concat(properties.ListItem.Web.Url, "/", properties.ListItem.ParentList.Forms[PAGETYPE.PAGE_DISPLAYFORM].Url, "?ID=", properties.ListItem.ID.ToString());
sUrlOfWikiPage = CreateWiki(properties.ListItem.Web, sWikiListName, sCurrentItemTitle, ItemDispFormUrl, sUrlOfNewFolder);
//Update the current TR Item
SPWeb myWeb = properties.ListItem.Web;
myWeb.AllowUnsafeUpdates = true;
SPListItem myListItem = properties.ListItem;
SPFieldUrlValue shareFolderURLValue = new SPFieldUrlValue();
shareFolderURLValue.Description = "Shared Folder";
shareFolderURLValue.Url = sUrlOfNewFolder ;
myListItem["SharedFolder"] = shareFolderURLValue;
myListItem.Update();
myWeb.AllowUnsafeUpdates = false;
}
base.EventFiringEnabled = true;
}
catch (Exception e)
{
//Currently throwing nothing
}
}
}
It could be a hardcoded path/url, however there is not enough information to identify the problem, I would be glad to update my answer with a more detailed theory if you provide more details or if you share some of your code.
Figured out the issue. I didn't include them with the above file code. But we were StreamWriting to a text file on the server to help us with debugging. Issue was with that, When user 1 was logged on their machine and the log files didn't exist, they would get generated. Now no other users then had read/write access to those files and so it errored out at our debug files for anyone else. But that Windows user could run it as much as they wanted as they were the owner of the file :/
I am having some problems in communicating between actors in Cluster.
My test project has this structure below.
TestJob [C# Console Project]
TestJobService.cs
TestJobActor
MainProject [C# Console Project] //Note: I configured this service as a seed node. I didn't use lighthouse.
MainService
JobManagerActor
Note: I don't want to put actors in Shared project or Main project. The actors that are supposed to do a test job should be under "TestJob" project.
I already followed this article http://getakka.net/docs/clustering/cluster-overview and video. I did enable Akka.Cluster based on the article. I am able to run both console projects but when I tried to "tell" from JobManagerActor to TestJobActor, it doesn't work. No error but doesn't work.
I have this config in MainProject.
actor {
provider = "Akka.Cluster.ClusterActorRefProvider, Akka.Cluster"
deployment {
/TestJobAActor {
router = consistent-hashing-group
routees.paths = ["/user/TestJobAActor"]
virtual-nodes-factor = 8
cluster {
enabled = on
max-nr-of-instances-per-node = 2
allow-local-routees = off
use-role = backend
}
}
}
}
Here is the code that I use for sending the message.
var backendRouter = Context.ActorOf(Props.Empty.WithRouter(new ClusterRouterGroup(new ConsistentHashingGroup("/user/TestJobAActor"),new ClusterRouterGroupSettings(10, false, "backend", ImmutableHashSet.Create("/user/TestJobAActor")))));
backendRouter.Tell("Yo yo!");
What am I missing? Thanks in advance.
Note: My test project with similar structure can be found here https://github.com/michaelsync/APMDemo . (VS2015 project)
One more question: Can we still use the actor selection when using cluster?
var actorSelection = Context.ActorSelection("akka.tcp://MyBackendProcessingSystem#127.0.0.1:2553/user/BackEndJobAActor"); //This can come from Model
actorSelection.Tell("Yo yo!");
No worries!
I managed to fix it myself. You can see the fixes in my temp repo https://github.com/michaelsync/APMDemo/tree/allinoneproject.
The problem was that I didn't know I need to use IConsistentHashable for sending message in consistent-route. I keep on sending the string and didn't work.
local route was off.
I want to create and delete a branch on git using libgit2sharp. I came up with this code but it throws an error at repo.Network.Push(localBranch, pushOptions);
using (var repo = new Repository(GIT_PATH))
{
var branch = repo.CreateBranch(branchName);
var localBranch = repo.Branches[branchName];
//repo.Index.Stage(GIT_PATH);
repo.Checkout(localBranch);
repo.Commit("Commiting at " + DateTime.Now);
var pushOptions = new PushOptions() { Credentials = credentials };
repo.Network.Push(localBranch, pushOptions); // error
branch = repo.Branches["origin/master"];
repo.Network.Push(branch, pushOptions);
}
The error message is The branch 'buggy-3' ("refs/heads/buggy-3") that you are trying to push does not track an upstream branch.
I tried searching this error on the internet but no solution that I found could fix the problem. Is it possible to do this using libgit2sharp?
You have to associate your local branch with a remote against which you'd like to push.
For instance, given an already existing "origin" remote:
Remote remote = repo.Network.Remotes["origin"];
// The local branch "buggy-3" will track a branch also named "buggy-3"
// in the repository pointed at by "origin"
repo.Branches.Update(localBranch,
b => b.Remote = remote.Name,
b => b.UpstreamBranch = localBranch.CanonicalName);
// Thus Push will know where to push this branch (eg. the remote)
// and which branch it should target in the target repository
repo.Network.Push(localBranch, pushOptions);
// Do some stuff
....
// One can call Push() again without having to configure the branch
// as everything has already been persisted in the repository config file
repo.Network.Push(localBranch, pushOptions);
Note:: Push() exposes other overloads that allow you to dynamically provide such information without storing it in the config.
I am working on an application which reads eventlogs(Application) from remote machines. I am making use of EventLog class in .net and then iterating on the Log entries but this is very slow. In some cases, some machines have 40000+ log entries and it takes hours to iterate through the entries.
what is the best way to accomplish this task? Are there any other classes in .net which are faster or in any other technology?
Man, I feel your pain. We had the exact same issue in our app.
Your solution has a branch depending on what server version you're running on and what server version your "target" machine is running on.
If you're both on Vista or Windows Server 2008, you're in luck. You should look at System.Diagnostics.Eventing.Reader.EventLogQuery and System.Diagnostics.Eventing.Reader.EventLogReader. These are new in .net 3.5.
Basically, you can build a query in XML and ship it over to run on the remote computer. Maybe you're just searching for events of a specific type, or maybe just new events from a specific point in time. The search runs on the remote machine, and then you just get back the matching events. The new classes are much faster than the old .net 2.0 way, but again, they are only supported on Vista or Windows Server 2008.
For our app when the target is NOT on Vista/Win2008, we downloaded the raw .evt file from the remote system, and then parsed the file using its binary format. There are several sources of data about the event log format for .evt files (pre-Vista), including link text and an article I recall on codeproject.com that had some c# code.
Vista and Windows Server 2008 machines use a new .evtx format that is a new format, so you can't use the same binary parsing approach across all versions. But the new EventLogQuery and EventLogReader classes are so fast that you won't have to. It's now perfectly speedy to just use the built-in classes.
Event Log Reader is horribly slow... too slow. WTF Microsoft?
Use LogParser 2.2 - Search for C# and LogParser on the Internet (or you can use the log parser commands from the command line). I don't want to duplicate the work already contributed by others.
I pull the log from the remote system by having the log exported as an EVTX file. I then copy the file from the remote system. This process is really quick - even with a network that spans the planet (I had issues with having the log exported to a network resource). Once you have it local, you can do your searches and processing.
There are multiple reasons for having the EVTX - I won't get into the reasons why we do this.
The following is a working example of the code to save a copy of the log as an EVTX:
(Notes: "device" is the network host name or IP. "LogName" is the name of the log desired: "System", "Security", or "Application". outputPathOnRemoteSystem is the path on the remote computer, such as "c:\temp\%hostname%.%LogName%.%YYYYMMDD_HH.MM%.evtx".)
static public bool DumpLog(string device, string LogName, string outputPathOnRemoteSystem, out string errMessage)
{
bool wasExported = false;
string errorMessage = "";
try
{
System.Diagnostics.Eventing.Reader.EventLogSession els = new System.Diagnostics.Eventing.Reader.EventLogSession(device);
els.ExportLogAndMessages(LogName, PathType.LogName, "*", outputPathOnRemoteSystem);
wasExported = true;
}
catch (UnauthorizedAccessException e)
{
errorMessage = "Unauthorized - Access Denied: " + e.Message;
}
catch (EventLogNotFoundException e)
{
errorMessage = "Event Log Not Found: " + e.Message;
}
catch (EventLogException e)
{
errorMessage = "Export Failed: " + e.Message + ", Log: " + LogName + ", Device: " + device;
}
errMessage = errorMessage;
return wasExported;
}
A good Explanation/Example can be found on MSDN.
EventLogSession session = new EventLogSession(Environment.MachineName);
// [System/Level=2] filters out the errors
// Where "Log" is the log you want to get data from.
EventLogQuery query = new EventLogQuery("Log", PathType.LogName, "*[System/Level=2]");
EventLogReader reader = new EventLogReader(query);
for (EventRecord eventInstance = reader.ReadEvent();
null != eventInstance;
eventInstance = reader.ReadEvent())
{
// Output or save your event data here.
}
When waiting 5-20 minutes with the old code this one does it in less than 10 seconds.
Maybe WMI can help you:
WMI with C#
Have you tried using the remoting features in powershell 2.0? They allow you to execute cmdlets (like ones to read event logs) on remote machines and return the results (as objects, of course) to the calling session.
You could place a Program at those machines that save the log to file and sends it to your webapplication i think that would be alot faster as you can do the looping local but im not sure how to do it so i cant ive you any code :(
I recently did such thing via WCF callback interface however my clients interacted with the server through WCF and adding a WCF Callback was easy in my project, full code with examples is available here
Just had the same issue and want to share my solution. It makes a search through application, system and security eventlogs from 260 seconds (using EventLog) about a 100 times faster (using EventLogQuery).
And this in a way where it is possible to check if the event message contains a pattern or any other check without the requirement of FormatDescription().
My trick is to use the same mechanism as PowerShells Get-WinEvent does and then pass it through the result check.
Here is my code to find all events within last 4 days where the event message contains a filter pattern.
string[] eventLogSources = {"Application", "System", "Security"};
var messagePattern = "*Your Message Search Pattern*";
var timeStamp = DateTime.Now.AddDays(-4);
var matchingEvents = new List<EventRecord>();
foreach (var eventLogSource in eventLogSources)
{
var i = 0;
var query = string.Format("*[System[TimeCreated[#SystemTime >= '{0}']]]",
timeStamp.ToUniversalTime().ToString("o"));
var elq = new EventLogQuery(eventLogSource, PathType.LogName, query);
var elr = new EventLogReader(elq);
EventRecord entryEventRecord;
while ((entryEventRecord = elr.ReadEvent()) != null)
{
if ((entryEventRecord.Properties)
.FirstOrDefault(x => (x.Value.ToString()).Contains(messagePattern)) != null)
{
matchingEvents.Add(entryEventRecord);
i++;
}
}
}
Maybe that the remote computers could do a little bit of computing. So this way your server would only deal with relevant information. It would be a kind of cluster using the remote computer to do some light filtering and the server would the the analysis part.