2

I am able to get Firestore access through winforms by itself and it works. however, if I try to access Firestore through an external command, I get an error:

System.IO.FileNotFoundException: 'Could not load file or assembly 'Google.Apis.Auth, Version=1.44.1.0, Culture=neutral, PublicKeyToken=XXXXXXXXXX' or one of its dependencies. The system cannot find the file specified.'

The weird part is that I have Google.Apis.Auth, Version=1.46.0.0 as a reference.

If I change my reference version to 1.44.1.0, then it asks me to change the reference version to 1.21.0.0

How can I make this work?

Here is my code:

App.cs

#region Namespaces
using System;
using System.Collections.Generic;
using Autodesk.Revit.ApplicationServices;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using System.Reflection;
using System.Windows.Media.Imaging;
using Google.Cloud.Firestore;
using System.Windows.Forms;
#endregion

namespace testformsFirestore
{
    class App : IExternalApplication
    {
        public Result OnStartup(UIControlledApplication a)
        {

            RibbonPanel panel = ribbonPanel(a);
            string thisAssemblyPath = Assembly.GetExecutingAssembly().Location;
            PushButton button = panel.AddItem(new PushButtonData("testformsFirestore" ,
                "testformsFirestore Button", thisAssemblyPath, "testformsFirestore.Command")) as PushButton; 

            button.ToolTip = "this is a simple tooltip";
            var globePath = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), "Corvette.PNG");
            
            Uri uriImage = new Uri(globePath);
            BitmapImage largeImage = new BitmapImage(uriImage);
            button.LargeImage = largeImage;

            

            a.ApplicationClosing += a_ApplicationClosing;

            // Set application idling
            a.Idling += a_Idling;


            return Result.Succeeded;
        }

        void a_Idling(object sender, Autodesk.Revit.UI.Events.IdlingEventArgs e)
        {

        }

        void a_ApplicationClosing(object sender, Autodesk.Revit.UI.Events.ApplicationClosingEventArgs e)
        {
            throw new NotImplementedException();
        }


        public RibbonPanel ribbonPanel(UIControlledApplication a)
        {
            string tab = "My test tab";
            RibbonPanel ribbonPanel = null;
            try
            {
                a.CreateRibbonTab(tab);
            }
            catch { }
            try
            {
                RibbonPanel panel = a.CreateRibbonPanel(tab, "test");
            }
            catch { }

            List<RibbonPanel> panels = a.GetRibbonPanels(tab);
            foreach (RibbonPanel p in panels)
            {
                if (p.Name == "test")
                {
                    ribbonPanel = p;
                }
            }
            return ribbonPanel;
        }


        public Result OnShutdown(UIControlledApplication a)
        {
            return Result.Succeeded;
        }
    }
}

Command.cs

#region Namespaces
using System;
using System.Collections.Generic;
using System.Diagnostics;
using Autodesk.Revit.ApplicationServices;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Selection;
#endregion

namespace testformsFirestore
{
    [Transaction(TransactionMode.Manual)]
    public class Command : IExternalCommand
    {
        public Result Execute(
          ExternalCommandData commandData,
          ref string message,
          ElementSet elements)
        {
            UIApplication uiapp = commandData.Application;
            UIDocument uidoc = uiapp.ActiveUIDocument;
            Application app = uiapp.Application;
            Document doc = uidoc.Document;

            Form1 form1 = new Form1();


            using (Transaction tx = new Transaction(doc, "Transaction Name"))
            {
                try
                {
                    tx.Start();

                    // Code goes here.
                    form1.Show();


                    tx.Commit();
                }
                catch (Exception e)
                {
                    Debug.Print(e.Message);
                    tx.RollBack();
                }
            }

            return Result.Succeeded;
        }
    }
}

Form1.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Google.Cloud.Firestore;

namespace testformsFirestore
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {

            string path = "\\\\Mac\\Home\\Desktop\\testformsFirestore\\testFormsFirestore\\bin\\Debug\\myProjectJsonPath.json";
            Environment.SetEnvironmentVariable("GOOGLE_APPLICATION_CREDENTIALS", path);
            
            FirestoreDb db = FirestoreDb.Create("myProjectId");

            CollectionReference collection = db.Collection("Users");

            getSnapshot();
            async void getSnapshot()
            {
                // A CollectionReference is a Query, so we can just fetch everything
                QuerySnapshot allUsers = await collection.GetSnapshotAsync();
                foreach (DocumentSnapshot document in allUsers.Documents)
                {

                    MessageBox.Show(document.GetValue<string>("username").ToString()); ;
                    
                }

            }
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }
    }
}

app.config

        <assemblyIdentity name="Google.Apis.Auth" publicKeyToken="XXXXXXXXXX" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-1.46.0.0" newVersion="1.46.0.0" />
      </dependentAssembly>

StackTrace

System.IO.FileNotFoundException
  HResult=0x80070002
  Message=Could not load file or assembly 'Google.Apis.Auth, Version=1.21.0.0, Culture=neutral, PublicKeyToken=XXXXXXXXXX' or one of its dependencies. The system cannot find the file specified.
  Source=Google.Api.Gax.Grpc
  StackTrace:
   at Google.Api.Gax.Grpc.ChannelPool.<CreateChannelCredentialsUncached>d__5.MoveNext()
   at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.Start[TStateMachine](TStateMachine& stateMachine)
   at Google.Api.Gax.Grpc.ChannelPool.CreateChannelCredentialsUncached()
   at System.Threading.Tasks.Task`1.InnerInvoke()
   at System.Threading.Tasks.Task.Execute()
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at Google.Api.Gax.TaskExtensions.WaitWithUnwrappedExceptions(Task task)
   at Google.Api.Gax.Grpc.ChannelPool.GetChannel(GrpcAdapter grpcAdapter, String endpoint, GrpcChannelOptions channelOptions)
   at Google.Api.Gax.Grpc.ClientBuilderBase`1.CreateCallInvoker()
   at Google.Cloud.Firestore.V1.FirestoreClientBuilder.BuildImpl()
   at Google.Cloud.Firestore.FirestoreDbBuilder.Build()
   at DockableDialog.RegisterDockableWindow.Execute(ExternalCommandData commandData, String& message, ElementSet elements) in \\Mac\Home\Desktop\Revit-API---C-\DockableWPFPane2021\DockablePane2021\Ribbon.cs:line 137
   at apiManagedExecuteCommand(AString* assemblyName, AString* className, AString* vendorDescription, MFCApp* pMFCApp, DBView* pDBView, AString* message, Set<ElementId\,std::less<ElementId>\,tnallc<ElementId> >* ids, Map<AString\,AString\,std::less<AString>\,tnallc<std::pair<AString const \,AString> > >* data, AString* exceptionName, AString* exceptionMessage)

Log

'Revit.exe' (CLR v4.0.30319: DefaultDomain): Loaded 'C:\Users\myName\AppData\Roaming\Autodesk\Revit\Addins\2021\testForms.dll'. 
System.Windows.Media.Animation Warning: 6 : Unable to perform action because the specified Storyboard was never applied to this object for interactive control.; Action='Stop'; Storyboard='System.Windows.Media.Animation.Storyboard'; Storyboard.HashCode='6995273'; Storyboard.Type='System.Windows.Media.Animation.Storyboard'; TargetElement='Autodesk.Internal.Windows.ToolTip'; TargetElement.HashCode='54242802'; TargetElement.Type='Autodesk.Internal.Windows.ToolTip'
'Revit.exe' (CLR v4.0.30319: DefaultDomain): Loaded 'C:\Users\myName\AppData\Roaming\Autodesk\Revit\Addins\2021\Google.Cloud.Firestore.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'Revit.exe' (CLR v4.0.30319: DefaultDomain): Loaded 'C:\Users\myName\AppData\Roaming\Autodesk\Revit\Addins\2021\Google.Cloud.Firestore.V1.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'Revit.exe' (CLR v4.0.30319: DefaultDomain): Loaded 'C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.ValueTuple\v4.0_4.0.0.0__cc7b13ffcd2ddd51\System.ValueTuple.dll'. Module was built without symbols.
'Revit.exe' (CLR v4.0.30319: DefaultDomain): Loaded 'C:\Users\myName\AppData\Roaming\Autodesk\Revit\Addins\2021\Google.Api.Gax.Grpc.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'Revit.exe' (CLR v4.0.30319: DefaultDomain): Loaded 'C:\Users\myName\AppData\Roaming\Autodesk\Revit\Addins\2021\Google.Api.Gax.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'Revit.exe' (CLR v4.0.30319: DefaultDomain): Loaded 'C:\Users\myName\AppData\Roaming\Autodesk\Revit\Addins\2021\Grpc.Core.Api.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'Revit.exe' (CLR v4.0.30319: DefaultDomain): Loaded 'C:\Users\myName\AppData\Roaming\Autodesk\Revit\Addins\2021\Google.Api.Gax.Grpc.GrpcCore.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'Revit.exe' (CLR v4.0.30319: DefaultDomain): Loaded 'C:\Users\myName\AppData\Roaming\Autodesk\Revit\Addins\2021\Google.Apis.Auth.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'Revit.exe' (CLR v4.0.30319: DefaultDomain): Loaded 'C:\Users\myName\AppData\Roaming\Autodesk\Revit\Addins\2021\Google.Apis.Core.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'Revit.exe' (CLR v4.0.30319: DefaultDomain): Loaded 'C:\Users\myName\AppData\Roaming\Autodesk\Revit\Addins\2021\Grpc.Auth.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
An unhandled exception of type 'System.IO.FileNotFoundException' occurred in mscorlib.dll
Could not load file or assembly 'Google.Apis.Auth, Version=1.21.0.0, Culture=neutral, PublicKeyToken=XXXXXXXXXX' or one of its dependencies. The system cannot find the file specified.
Cflux
  • 1,423
  • 3
  • 19
  • 39

1 Answers1

1

Notice that you set the environment variable for authentication and create the Firestore client (FirestoreDb db = FirestoreDb.Create("myProjectId");) within the method when the button is clicked.

        private void button1_Click(object sender, EventArgs e)
        {

            string path = "\\\\Mac\\Home\\Desktop\\testformsFirestore\\testFormsFirestore\\bin\\Debug\\myProjectJsonPath.json";
            Environment.SetEnvironmentVariable("GOOGLE_APPLICATION_CREDENTIALS", path);
            
            FirestoreDb db = FirestoreDb.Create("myProjectId");

            CollectionReference collection = db.Collection("Users");

Set the environment variable:

string path = "\\\\Mac\\Home\\Desktop\\testformsFirestore\\testFormsFirestore\\bin\\Debug\\myProjectJsonPath.json";
Environment.SetEnvironmentVariable("GOOGLE_APPLICATION_CREDENTIALS", path)

and make the initialization of the client:

FirestoreDb db = FirestoreDb.Create("myProjectId");
CollectionReference collection = db.Collection("Users");

in a previous step within your application.

Daniel Ocando
  • 3,554
  • 2
  • 11
  • 19
  • so I tried placing it in the Command.cs file which calls Form1.cs, and then I also tried placing it in App.cs which calls Command.cs which is the earliest step I can place it in but I still get the same result. I will post my code for App.cs. – Cflux Jun 29 '20 at 17:43
  • If that's the case I think their could be a specific problem with how the packages and it's dependencies are installed on your computer. Have you tried taking any of the measures mentioned [here](https://stackoverflow.com/questions/10878602/system-io-filenotfoundexception-could-not-load-file-or-assembly-x-or-one-of-i). Maybe the [following video](https://www.youtube.com/watch?v=0ddSgiAX9RE) could also be helpful. – Daniel Ocando Jun 30 '20 at 08:07
  • So I just tried following the video which had me delete the existing reference and repath it to a copy in my project's debug file. It is still asking for the different versions `1.44.1.0` and `1.21.0.0`. I'll try the dependency walker mentioned in your other link. – Cflux Jun 30 '20 at 18:29
  • so i tried the other route. no luck. i've updated my question to include the stack trace. I have also found, what i believe to be the source of the issue. One of `Grpc.Auth`'s dependencies is `>= Google.Apis.Auth version 1.21.0.0`.thats just a guess. I have also gone down the route of looking at Binding Redirects but im not having any luck with that either. – Cflux Jul 01 '20 at 04:29
  • I added to log to the question for reference. I've noticed that either `Google.Apis.Auth` is trying to load a second time as version `1.21.0.0` or its trying to load one of its dependencies oddly. – Cflux Jul 01 '20 at 20:40
  • I would take a look at the `An unhandled exception of type 'System.IO.FileNotFoundException' occurred in mscorlib.dll` error that is showing up. Maybe one of the troubleshooting steps mentioned [here](https://stackoverflow.com/questions/42469185/an-unhandled-exception-of-type-system-io-filenotfoundexception-occurred-in-msc) can be of use. – Daniel Ocando Jul 02 '20 at 12:59
  • 1
    Also, I think it would be a good idea for you to delete the PublicKeyToken from the post. As it is in general not a good idea to share keys, tokens, passwords, etc. through any public forums. – Daniel Ocando Jul 02 '20 at 13:44