EditorUtility.OpenFilePanel is executed twice - c#

I want to open an OBJ file in Unity using C# during runtime when I press L. However, the file dialog always opens twice. After I selected the first file, I get a new dialog. Whatever file I select the first and second time, both files are opened and displayed.
I have:
void Update ()
{
if (Input.GetKeyDown(KeyCode.L)) {
LoadObj();
//StartCoroutine(ExecuteAfterTime(5));
}
}
IEnumerator ExecuteAfterTime(float time)
{
yield return new WaitForSeconds(time);
}
void LoadObj()
{
string path = EditorUtility.OpenFilePanel("Load scan file", "", "obj");
\\Open the file and display it
}
I tried:
Add a time (see commented code above) -- did not work
Add a boolean that allows to execute LoadObj() only when the previous file is opened -- did not work
Added EditorUtility.OpenFilePanel() before or after yield return new WaitForSeconds(time) -- in the latter case, there is the delay of 5 seconds, but it still opens twice in both cases.
I searched for other solutions, but did not find anything else.
I work on a Windows machine and use Unity 2018. The aim is to open a single file at a time, but it must be possible to open another file, say, after a few minutes.
Any idea how to prevent the dialog from opening twice?

As #Eshan Mohammadi suggested, I checked if I only had a single instance of the code. I deleted the entire file, created a new one and added it to my GameObject. However, only then I noticed that this particular GameObject is copied, including the code, of course.
So, I chaned the way the GameObject was copied and problem solved.

Related

Error while executing script for a TableObject located at the PageFooter section

We have a report that displays at the PageFooter which payment way the customer used to pay an order, in that area we have three other TableObjects that are working correctly, but there's one that executes a script to build manually the TableObject, the problem we located is when it executes that script it fails showing the message StackOverflowException in System.Drawing.dll
The message on top means the report generation is executing.
The script that I located it fails is this one, if this script is not executing the report displays correctly but without the information we want to display in that TableObject
private void TableModalidadPago_ManualBuild(object sender, EventArgs e)
{
// get the data source by its name
DataSourceBase rowData = Report.GetDataSource("DOCUMENTO_MODALIDAD_PAGO");
// init the data source
rowData.Init();
if (rowData.RowCount == 0)
{
TableModalidadPago.Visible = false;
return;
}
// print the first table row - it is a header
TableModalidadPago.PrintRow(0);
TableModalidadPago.PrintColumns();
TableModalidadPago.PrintRow(1);
TableModalidadPago.PrintColumns();
// now enumerate the data source and print the table body
while (rowData.HasMoreRows)
{
// print the table body
TableModalidadPago.PrintRow(2);
TableModalidadPago.PrintColumns();
// go next data source row
rowData.Next();
}
TableModalidadPago.CanBreak = false;
TableModalidadPago.CanGrow = true;
}
It fails at line
TableModalidadPago.PrintRow(0);
And if I put the TableObject in other section that is not the PageFooter it works perfectly.
Anyone knows if there's any restriction to execute code at PageFooter or if there's any error at the provided script?
I already posted this information in FastReports forum but still no answer(Link)
Edit: I also created a ticket in FastReports Support centre and still no answer...
Edit2: 24/06/2016 today I saw they published a new version of the FastReports.Net (2016.3 previous was 2016.2) and I downloaded and install it, after cleaning up my project and tried again, the error still ocurring, with this new version the program just unexplectly closes and doesn't display any error message, I updated my ticket with support center
Thanks.
The stack overflow error suggests that the while loop may be infinite. Could it actually be failing at the line
TableModalidadPago.PrintRow(2);
Perhaps you need to remove rows from rowData object once you've printed them?

Write into a log file with C#

I am using the JitBit Macro Recorder to create "bots" that save me a lot of time at work. This program can use the mouse and the keyboard and perform tasks by checking different if-options like "if image found on screen".
My newest "bot" is about 900 lines of commands long and I would like to make a log-file to find an error somewhere in there. Sadly, this program doesn't offer such an option, but it let's me use c# as a task. I have NO experience with c# but I thought, that this is easy to do for someone who has some experience.
If I click execute c# code, I get the following input field:
Important: This code MUST contain a class named "Program" with a static method "Main"!
public class Program
{
public static void Main()
{
System.Windows.Forms.MessageBox.Show("test");
}
}
Now I need two code templates:
1. Write a message to a "bot_log.txt" located on my desktop.
[19.05.2016 - 12:21:09] "Checking if item with number 3 exists..."
The number "3" changes with every run and is an exact paste of the clipboard.
2. Add an empty line to the same file
(Everything should be added to a new line at the end of this file.)
If you have no idea how to program in C#, then you should learn it,
if you want to use code provided from answers.
And if you want to generate timestamps and stuff then it's not done within minutes and I don't think someone writes the whole code just for your fitting. Normally questions should have at least a bit of general interest.
Anyway:
This works, if you have a RichTextTbox in your program.
Just do a new event (like clicking a button) and do this inside it.
(This was posted somewhere here too or on another site, with sligh changes)
public static void SaveMyFile(RichTextBox rtb)
{
// Create a SaveFileDialog to request a path and file name to save to.
SaveFileDialog saveLog = new SaveFileDialog();
// Initialize the SaveFileDialog to specify the RTF extention for the file.
saveLog.DefaultExt = "*.rtf";
saveLog.Filter = "RTF Files|*.rtf"; //You can do other extensions here.
// Determine whether the user selected a file name from the saveFileDialog.
if (saveLog.ShowDialog() == System.Windows.Forms.DialogResult.OK &&
saveLog.FileName.Length > 0)
{
// Save the contents of the RichTextBox into the file.
try
{
rtb.SaveFile(saveLog.FileName);
}
catch
{
MessageBox.Show("Error creating the file.\n Is the name correct and is enough free space on your disk\n ?");
}
MessageBox.Show("Logfile was saved successful.");
}
}

File.Delete() not deleting file before program completes

I am trying to programmatically delete a broken symbolic link and replace it with one that is has a valid target by the same name. However, by the time CreateSymbolicLink() executes, File.Delete() still has not actually deleted the file (I have verified the file still exists after File.Delete() executes, with no errors or warnings).
When the program finishes executing, only then does the file actually get deleted. What the heck? This is blocking the symbolic link from being created. Any ideas what to do?
private static string replaceSymbolicLink(string linkPath, string newTargetPath)
{
Boolean linkIsFile = File.Exists(linkPath);
Boolean linkIsDir = Directory.Exists(linkPath);
// Create a replacement of the same name and link type with the new target
string newTargetPathDOS = getAbsPathFromPath(newTargetPath);
Boolean targetIsFile = File.Exists(newTargetPathDOS);
Boolean targetIsDir = Directory.Exists(newTargetPathDOS);
if (targetIsFile || targetIsDir)
{
if (linkIsFile)
{
File.Delete(linkPath);
Console.WriteLine(File.Exists(linkPath));
}
else
{
Directory.Delete(linkPath);
}
SymbolicLink type;
if (targetIsFile)
{
type = SymbolicLink.File;
}
else
{
type = SymbolicLink.Directory;
}
CreateSymbolicLink(linkPath, newTargetPath, type);
return getGuidFromPath(linkPath);
}
return null;
}
On Windows deletions are not immediate. Files are being marked as deleted and actually disappear when the last handle is being closed. Normally, this mechanism is not visible since most files are opened with sharing rights that prevent deletion. This causes deletes to either fail or go through immediately.
FileShare.Delete allows to keep a file (a FileStream) open while it is being deleted. This can be surprising behavior if you have never heard of this before.
So you probably have the file still open or some other process has.

How to open a .DWG file in Autocad 2014 through C#

Hi I have a requirement in which I have to open a drawing file stored in C:\Temp Folder.
I tried the following code
public void launchacad(string pth) //pth is the path to the .DWG file
{
const string progID = "AutoCAD.Application.19.1";
const string exePath = #"C:\Program Files\Autodesk\AutoCAD 2014\acad.exe";
AcadApplication acApp = null;
try
{
acApp =
(AcadApplication)Marshal.GetActiveObject(progID);
}
catch { }
if (acApp != null)
{
MessageBox.Show("An instance of AutoCAD is already running.");
}
else
{
try
{
ProcessStartInfo psi =new ProcessStartInfo(exePath);
psi.WorkingDirectory = #"C:\Temp";
psi.Arguments = pth;
Process pr = Process.Start(psi);
pr.WaitForInputIdle();
while (acApp == null)
{
try
{
acApp =(AcadApplication)Marshal.GetActiveObject(progID);
}
catch
{
Application.DoEvents();
}
}
}
catch (Exception ex)
{
MessageBox.Show(
"Cannot create or attach to AutoCAD object: "
+ ex.Message
);
}
}
if (acApp != null)
{
acApp.Visible = true;
acApp.ActiveDocument.SendCommand("_MYCOMMAND ");
}
}
But as soon as Autocad starts it popups an error message saying Cannot find the specified drawing. When I use CMD.exe and type
"C:\Program Files\Autodesk\AutoCAD 2014\acad.exe" "C:\Temp\41 Stabd.dwg" It opens Autocad with the file(41 Stand.dwg) open.
I can't understand where I am making an error. Can someone help me out.
If still the drawing persists with problems, continue on to the next set of steps.
These can be done in any order, but have been listed in the order that Autodesk recommends makes the most sense. The file can be checked after each step. If things appear back to normal, there is no need to continue on to the rest of the steps.
​Open a blank DWG and type RECOVER at the command line. Browse to the problematic file to - allow AutoCAD a chance to restore the file.
Type OVERKILL at the command line, and select all objects. Check or uncheck properties to include or ignore, then click OK.
Type DELCON at the command line, and select all objects.
Type BREP and select all objects (if there are solids or surfaces in the file)
Type -SCALELISTEDIT, then "R" for reset, then "Y" for yes.
Type FILTERS, then click on the 'delete filters' button.
The DGNPURGE tool can be run if the file size is unexpectedly very large: http://knowledge.autodesk.com/article/AutoCAD-DWG-files-unexpectedly-increase-in-file-size
Try using a different version of AutoCAD to open the drawing, such as AutoCAD 2013 vs. AutoCAD 2015 or plain AutoCAD vs. AutoCAD Architecture, etc. Try different computers if available.
Open a blank DWG, and try to attach the problematic file as an XREF. If it allows you to attach the file, try next to BIND it to the current file. If that works, run the repair steps listed above.
Use the SAVEAS command to save the DWG in an older file format. Attempt to open the newly created file.
Export the file to DXF format using the DXFOUT command. Next, open a blan DWG and use the DXFIN command to import the file just created.
< Restore the Layout tabs:
Right-Click one of the default layout tabs
Select 'From Template...'
Open the original file
Choose the layout tabs to restore. (It is recommended to do this one tab at a time, in case one or more layout tabs are corrupted)
Move drawing objects between model and paper space. You may find that only one drawing space is usable in your file, although your main concern is model space:
​​1. Create a new layout and if need be, create a viewport.
Use CHSPACE to move all the geometry to paper space.
Create a new drawing and use the Design Center (ADC) to move the layout from the damaged file into it.
Use CHSPACE again to move the geometry back to model space.
Restore the original layouts from the bad file using the Design Center.
Dissect the drawing. In a copy of the file, conduct a process of elimination using QSELECT to select different object types and then delete them to see if that fixes what is wrong in the file. Do PURGE All after each deletion. Eventually you should remove the problem elements and then you can choose to leave them out, copy them in again from another file, recreate them, or further troubleshoot individual items to pinpoint exactly which one is problematic. A quick start to this whole process is to delete everything in the drawing and then test it. This will quickly tell you if the issue is with a drawing object or if it is a part of the drawing database.​

Why is PictureBox.Load locking image on some systems?

(Please see the edit on the bottom of the question, if you do not want to read the whole story.)
Hi,
I am new to stackoverflow. Don’t get me wrong, I use it quite often. But up until now I never actually posted something. This is because I did not have something new/useful to say and my English is not that good. The first thing (might have) changed, the latter did not.
I ran into a problem at a customer's Windows 7 system quite recently. I was shipping a C# .Net 4.0 Windows Forms application via ClickOnce. Basically, it is an application that creates a bitmap file and shows it to the user. If the bitmap exists prior to the creation, the existing file gets deleted first. After that the new file is created and loaded by a PictureBox.
The following thing occurred at the customer’s system: After starting the application the first creation succeeds – the second and all following ones do not. The file cannot be deleted, because some process is blocking it. This process is the application itself.
System.IO.IOException: The process cannot access the file “filename” because it is being used by another process.
Well, of course that is nothing unusual. The thing is I tested the application on several systems. None showed this exception. And until now I am unable to see an code error.
So I looked a little bit closer on the customer’s system: The only difference I could find is, that they changed the users folder so that they are not located on the windows partition, but on a different one (C:\Users --> D:\Users). I searched for an instruction on the internet and did the same thing on one of my test systems. To my surprise I got the same exception when I ran my application on it.
With that I could change my code so that the exception does not occur anymore. But I do not understand why that is. So maybe there is something wrong with my code and the error just reveals itself under that special circumstances. Or maybe the code is okay and the reason lies somewhere else. I just hoped that you might be able to help me.
So here is some code I put together, that shows the same behavior. I used 3 buttons, an OpenFileDialog and a PictureBox on a Form. First thing to do is to choose an image file. By pressing one of the two remaining buttons it gets copied into the main folder of the application. After being copied it is shown by the PictureBox. By the way, it does not seem to matter if it is a ClickOnce-application or a “normal” one.
String m_FileName;
private void btnChooseFile_Click(object sender, EventArgs e) {
if(openFileDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK) { // If file was chosen, set file name for later use and activate buttons.
m_FileName = "Test" + Path.GetExtension(openFileDialog1.FileName);
}
}
private void button1_Click(object sender, EventArgs e) {
// This is not working.
if(this.pictureBox1.Image != null) {
//Image img = this.pictureBox1.Image; // I was not sure, if maybe the pictureBox somehow prevents the disposing of the image, as long as it's assigned to it.
//this.pictureBox1.ImageLocation = null; // So I set them null, both the image and the image location.
//this.pictureBox1.Image = null;
//img.Dispose(); // Then I disposed the image.
this.pictureBox1.Image.Dispose(); // The short version. It is not working either way.
this.pictureBox1.Image = null;
}
(new FileInfo(openFileDialog1.FileName)).CopyTo(m_FileName, true); // But still this is where the Exception occurs.
this.pictureBox1.Load(m_FileName);
}
private void button2_Click(object sender, EventArgs e) {
//This is working.
if(this.pictureBox1.Image != null) {
//Image img = this.pictureBox1.Image;
//this.pictureBox1.Image = null;
//img.Dispose();
this.pictureBox1.Image.Dispose();
this.pictureBox1.Image = null;
}
(new FileInfo(openFileDialog1.FileName)).CopyTo(m_FileName, true);
pictureBox1.Image = Image.FromFile(m_FileName);
}
What happens now is the following: If I start the application and click button1 twice, I will get the exception (on the second click). If I start it and click button2 twice, I will not. If I start the application and click buttons1 first and after that button2, I will get the exception. So, the Picture.Load-Function somehow blocks the file, even if I dispose it.
When I searched on the internet, I found an article from microsoft: http://support.microsoft.com/kb/309482/en-us. But it does not hit the bull's eye.
Take into account, that both versions are working on all my test machines. I just get the exception when I change the users folder to a non-windows-partition.
Why is that? And where is the difference in the presented versions?
Edit
Okay, because of the first and only reaction so far, it seems to me, that it is still not clear, what really happens: If I take the above code, put it in a Windows Forms application, compile it and run it on different computers (at work, at home, does not matter) it works - both button1 and button2 (with the Click-functions linked to them) can be used as often as I like - no exception thrown. If I run the application on a computer, where I changed the users folder, and click button1 the second time - bam - IOException, file locked by process. Button2 works as long as I do not press button1.
The first answer implies, that I should get the locking on every system. But I DO NOT (as long as I do not change the users folder)! I tested it on every single computer I could get my hands on - no IOException. I set up a new system, just to rule out some special changes to the systems in my company - both buttonx_Click functions worked - no exception either. I even compiled the program on another computer - same behavior. The only three systems to throw that exception were the ones with the changed users folder.
So far I have no clue, why this difference in behavior occurs. Can somebody help me?
Anybody?
Yes, this is normal. Happens on any operating system, doesn't have anything to do with the Users folder location. The PictureBox.Load() method was intented to be used to load images from locations other than the file system. Like a web site. Which is slow, it avoids freezing the UI while the download is taking place.
It internally uses a FileStream when it discovers that the url you pass is actually a file and not a website name. This FileStream does not get disposed until the PictureBox itself is disposed or you call the Load() method again. A requirement because Image.FromStream() requires the stream to remain readable until the image is no longer used. It is this FileStream that keeps a lock on the file. Disposing the PictureBox.Image is not enough to also dispose the FileStream, the Image object doesn't know that it is being displayed inside a picture box.
There are several ways to solve this problem:
Use the Image property instead of Load(), assign it from Image.FromFile(). Disposing the Image now also releases the lock on the file. As you found out
Keep a dummy image around, one that perhaps displays a "Loading..." bitmap. Load() it first to release the lock on the file
Dispose the PictureBox and recreate it.
This works and unlocks the file
Image img= Image.FromFile(mypath);
Graphics g = pictureBox1.CreateGraphics();
g.DrawImage(img,0,0);
img.Dispose();

Categories