Batch load files in AutoCAD - c#

I'm running into problems writing an application to batch load and export files in AutoCAD using a C#. I've received numerous errors listed below whenever I point to a folder full of .dxf files. I've been able to narrow the problem down to the point where I know it's only breaking on load. Sometimes it loads fine, others it will only load 3-4 files, and the rest of the time it will simply throw an error. The errors I'm seeing include but are not limited to FaultExecutionEngineError, NullExceptionError, IndexOutOfRange error, and the wonderful FATAL EXCEPTION error, which causes Autocad to crash as well.
Here is my code:
public class MyCommands
{
string folderPath = #"C:\Users\kdhyne\Desktop\New folder\";
// Modal Command with localized name
[CommandMethod("FileCycle", CommandFlags.Session)]
public void MyCommand() // This method can have any name
{
var acDocManager = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager;
string[] filesInDirectory;
Document acDoc = null;
filesInDirectory = Directory.GetFiles(folderPath, "*.dxf", SearchOption.TopDirectoryOnly);
foreach (string someFile in filesInDirectory)
{
acDoc = acDocManager.Open(someFile);
}
}
}
I've stripped this down as far as I can think. Hopefully someone can help. Thank you for reading.

Do a release build before opening it in AutoCAD and it seems to work fine! Apparently it wasn't compiling all the libraries into the debug build.

Related

Illegal character in path in released version but not in debug mode

TL;DR Why is it when running debug mode my application works but in release it does not?
I am using MVVM to load a file path to process some data. When I am using the debugger version it loads, validates and converts fine, but when I am using the published/released version it fails so I am unable to track where it occurs. One note is that we tried to accompanied long file paths so we included #"\\?\"
Attached is our converter.
public static string CheckFilePath(string filePath)
{
//Network Location
if (filePath.StartsWith(#"\\"))
{
filePath = filePath.TrimStart(#"\\".ToCharArray());
return #"\\?\unc\" + filePath;
}
//Local location
if (!filePath.StartsWith(#"\\?\") && (!filePath.StartsWith(#"\\") || !filePath.StartsWith(#"\\?\UNC\")))
{
return #"\\?\" + filePath;
}
return filePath;
}
Also we're using 4.6.2 and using this to try and accomodate long file paths. Please note this is just my converter to check to see if it has a #"\\?\" or a #"\\" and replaces it with the following required for a long path. This converter may not be the problem... Any help would be great!
Alright everyone thanks for the help, but I found a workaround. Turns out there is something wrong with my published version versus my release version kind of like what jdweng said. If I just run the executable from the release it works, but when I try to install it via publish, it does not.

Why is StreamReader.ReadLine() and File.ReadAllText() returning null or empty

I did find a few similar questions, but they weren't able to point me in the right direction... This may be something entirely stupid, but if anyone could tell me why I can't get a string populated I'd appreciate it. Here's my method that's failing:
private static string passwordTrace { get; set; }
// ... lots of other code
private static void RefreshPassword()
{
try
{
string filePath = "\\\\[server ip]\\share\\folder\\file.abcd";
string npDecrypted;
DateTime lastRefreshDate = Properties.Settings.Default.lastRefresh;
if (DateTime.Now >= lastRefreshDate.AddDays(30))
{
using (StreamReader sr = new StreamReader(filePath))
{
string npEncrypted = sr.ReadLine();
if (npEncrypted.Length != 24)
{
string fr = File.ReadAllText(filePath);
npEncrypted = fr.Substring(0, 24);
}
npDecrypted = Decryptor(npEncrypted);
passwordTrace = npDecrypted; // added for debugging only! remove when done.
secureString npSecure = new SecureString();
foreach (char c in npDecrypted)
{
npSecure.AppendChar(c)
}
Properties.Settings.Default.adminpw = npSecure;
Properties.Settings.Default.Save();
}
}
}
catch (FileNotFoundException fnfe)
{
// code for handling this type of exception
}
catch (NullReferenceException nre)
{
// code for handling this type of exception
}
catch (Exception e)
{
// code to catch ANY other type of exception
}
}
Now, there are no errors or warnings when the VS debugger compiles everything, and it works correctly when debugging. But, if I copy the compiled exe (from C:\project\bin\Debug directory) and run it the issue arises.
The point that says passwordTrace = ... is called at another point by a message box. This works correctly when running via debugger and there aren't any exceptions thrown anywhere (I do have try/catches all over the place), but for whatever reason the PasswordTrace and the Properties.Settings.Default.adminpw don't seem to be holding their value throughout the applications execution.
Also, the file that is being read is an encrypted text file which will always have only 1 line of characters and that line is always 24 characters long. An example would be:
09sdjf09ausd08uf9!%38==
As a final statement, I also copied the app.exe.config and app.pdb to the server directory where I copied the compiled .exe file to see if that had anything to do with it and it didn't fix anything. I also tried running the .exe directly from the Debug directory (the same file that I'm copying elsewhere) and it works correctly. As soon as I move it off of the Local Disk it doesn't work.
So, my suspicions are that it has something to do with the environments working directory, or something to do with how the app is executing. I read something somewhere that noted the default users is not set, but I think that was specifically regarding ASP.NET. If that was the case and the user double-clicking on the .exe didn't have a proper network authentication then what would I do? And if it has something to do with the working directory, how can I circumvent this?
I'm gonna keep fiddling and if I figure it out I'll update this, but I'm so lost at the moment! lol! And for the last time - everything it/was working correctly until copying it to the server location.
Thanks in advance! :)

IMAPI: COMException Internal file system error occurred [-1062555360 ]

I am writing CD/DVD using IMAPI with C#.NET windows application.
The data I write on CD contains one executable file (test.exe) which is also developed with C#.NET and virtualized (sandobx) using Turbo Virtualization Studio.
All data to be written on CD is placed in one folder (source path) on C drive.
Following is small code snippet: -
IStream stream = null;
try
{
System.Diagnostics.Debug.Print("Adding - " + thisFileItem.SourcePath);
if (thisFileItem.SourcePath != null)
Win32.SHCreateStreamOnFile(thisFileItem.SourcePath, Win32.STGM_READ | Win32.STGM_SHARE_DENY_WRITE, ref stream);
if (stream != null)
{
fileSystemImage.Root.AddFile(thisFileItem.DestPath + thisFileItem.DisplayName, stream);
}
}
finally
{
if (stream != null)
{
Marshal.FinalReleaseComObject(stream);
}
}
Call to "fileSystemImage.Root.AddFile" method while adding test.exe throws COMException -1062555360 "Internal file system error occurred." All other files add and write properly.
Exception Details: -
COMException -1062555360
Internal file system error occurred.
at ImapiInterop.IFsiDirectoryItem.AddFile(String path, IStream fileData)
at ImapiImplementation.CDWriter.objBackgroundWorker_DoWork(Object sender, DoWorkEventArgs e) in C:\.........\CDWriter.cs:line 405
If I put my source folder on some other location (Desktop or D drive), all writing process (including test.exe) happens fine without error.
I suspect the issue is due to virutalization but not sure.
Please help.
The error message returned by IMAPI is incorrect and that is why all confusion.
Refer following link.
social.msdn.microsoft.com
Following is the text copied from answer (from Dmitri) on above site: -
IMAPI supports the ISupportErrorInfo interface, and we are aware of
the issue of mismatching error messages in your scenario.
Internally, IMAPI creates rollback objects to undo add/remove file
actions. We've had an issue where the rollback action was created
prematurely, so after the return code for IFsiDirectoryItem::AddFile
was already set, the rollback action was to remove the file from the
image. Since the file hasn't been added, IMAPI_E_FSI_INTERNAL_ERROR
exception was thrown, which changed the IErrorInfo message to the one
you're seeing.
We are aware of this issue, and it will be fixed in the next release
of IMAPI. Unfortunately, it is not serious enough to be addressed in a
hotfix.

Why can't I programatically replace perfc009.dat in windows 7?

We have an application that uses the Windows 7 performance counters to track the total CPU usage. Every so often the registry at HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Perflib\009 will become corrupted and just be empty.
Manually following the steps found here http://support.microsoft.com/kb/300956 works perfectly. But when I make a C# program to programatically replace the 2 files mentioned no errors, exceptions, etc. But the files are not saved to the proper directory.
Here's what I've been using to test:
static void Main(string[] args)
{
string fileToReadPath1 = #"perfc009.dat";
string fileToReadPath2 = #"perfh009.dat";
FileInfo fileToRead1 = new FileInfo(fileToReadPath1);
FileInfo fileToRead2 = new FileInfo(fileToReadPath2);
FileInfo fileToReplaceInfo1 = new FileInfo(#"C:\Windows\System32\perfc009.dat");
FileInfo fileToReplaceInfo2 = new FileInfo(#"C:\Windows\System32\perfh009.dat");
File.Copy(fileToRead1.FullName, fileToReplaceInfo1.FullName, true);
File.Copy(fileToRead2.FullName, fileToReplaceInfo2.FullName, true);
}
I do make sure to run it with Administrative privileges.
Anyone know why the program would seem to run fine, but not copy the files to that directory? Is there some Windows security thing stopping this?
Thanks to Mike Z and the link shared in the comments above. Turns out because I was running in a 32-bit process, the OS did not allow it to edit those files. Compiling to 64-bit did work.
Reposting the link:
http://msdn.microsoft.com/en-us/library/windows/desktop/aa384187(v=vs.85).aspx

Is there anyway to get all files names without exceptions in C#?

Update: I be glad to drop the C# requirement, and just see any program that can list all the files running as Admin or System, my question is has anyone seen such a thing?
There are numerous methods of enumerating files in a directory, but all suffer the same problems:
"The specified path, file name, or both are too long. The fully qualified file name must be less than 260 characters, and the directory name must be less than 248 characters."
"Access to the path 'C:\Users\All Users\Application Data' is denied"
etc.
Even running under admin, single user machine, it seems impossible to list all the files without encountering exceptions\errors.
Is it really an impossible task just to get list of all the files under windows? Has anyone ever been able to obtain the complete list of all files on their machine using C# or any other method?
This link from MS with the title "Enumerate Directories and Files" , does not show how to Enumerate Directories and Files, it only show a subset of what that will not throw : DirectoryNotFoundException, UnauthorizedAccessException, PathTooLongException,
Update : Here is sample code to run over C and attempt to enumerate all the files and errors. Even when running this as admin there are folders that not only can be access, but I even can't change their ownership to Admin! for example : "C:\Windows\CSC"
just have look at "Errors {0}.csv" log file to see how many places are inaccessible to admin.
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
class Program
{
static System.IO.StreamWriter logfile;
static System.IO.StreamWriter errorfile;
static void Main(string[] args)
{
string directory = #"C:\";
logfile = new System.IO.StreamWriter(string.Format(#"E:\Files {0}.csv", DateTime.Now.ToString("yyyyMMddHHmm")));
errorfile = new System.IO.StreamWriter(string.Format(#"E:\Errors {0}.csv", DateTime.Now.ToString("yyyyMMddHHmm")));
TraverseTree(directory, OnGotFileInfo, OnGotException);
logfile.Close();
errorfile.Close();
}
public static void OnGotFileInfo(System.IO.FileInfo fileInfo)
{
logfile.WriteLine("{0},{1},", fileInfo.FullName, fileInfo.Length.ToString("N0"));
}
public static void OnGotException(Exception ex, string info)
{
errorfile.WriteLine("{0},{1}", ex.Message, info);
}
public static void TraverseTree(string root, Action<System.IO.FileInfo> fileAction, Action<Exception, string> errorAction)
{
// Data structure to hold names of subfolders to be
// examined for files.
Stack<string> dirs = new Stack<string>(20);
if (!System.IO.Directory.Exists(root))
{
throw new ArgumentException();
}
dirs.Push(root);
while (dirs.Count > 0)
{
string currentDir = dirs.Pop();
string[] subDirs;
try
{
subDirs = System.IO.Directory.GetDirectories(currentDir);
}
// An UnauthorizedAccessException exception will be thrown if we do not have
// discovery permission on a folder or file. It may or may not be acceptable
// to ignore the exception and continue enumerating the remaining files and
// folders. It is also possible (but unlikely) that a DirectoryNotFound exception
// will be raised. This will happen if currentDir has been deleted by
// another application or thread after our call to Directory.Exists. The
// choice of which exceptions to catch depends entirely on the specific task
// you are intending to perform and also on how much you know with certainty
// about the systems on which this code will run.
catch (System.Exception e)
{
errorAction(e, currentDir);
continue;
}
string[] files = null;
try
{
files = System.IO.Directory.GetFiles(currentDir);
}
catch (System.Exception e)
{
errorAction(e, currentDir);
continue;
}
// Perform the required action on each file here.
// Modify this block to perform your required task.
foreach (string file in files)
{
try
{
// Perform whatever action is required in your scenario.
System.IO.FileInfo fi = new System.IO.FileInfo(file);
fileAction(fi);
}
catch (System.Exception e)
{
// If file was deleted by a separate application
// or thread since the call to TraverseTree()
// then just continue.
errorAction(e ,file);
continue;
}
}
// Push the subdirectories onto the stack for traversal.
// This could also be done before handing the files.
foreach (string str in subDirs)
dirs.Push(str);
}
}
}
Yes, it is at very least hard to enumerate all files without exceptions.
Several set of issues here:
some path (long ones- PathTooLongException) are not supported by CLR
security restrictions on folders/files
junctions/hard links that introduce duplicates (and in theory cycles to case StackOverflow in recursive iteration).
basic sharing violation restrictions (if you try to read files).
For PathTooLongException: I think you'll need to deal with PInvoke of corresponding Win32 functions. All path related methods in CLR are restricted to 256 characters long.
Security restrictions - you may be able to enumerate everything if you run under system (not sure) or with backup permissions, but any other account is guaranteed to not being able to access all files on system configured by default.
Instead of getting exceptions you can PInvoke native versions and handle error codes instead. You may be able to decrease number of exceptions on going into directories by checking ACL on the directly first.

Categories

Resources