无法使用Google Calendar API加载System.Threading.Tasks程序集

解决了 !

非常感谢Sam Leach

以下是我工作的app.config文件的示例:

 ...                  

我也发现了这个来源


编辑:原始问题在线下。

我正在使用.NET 4.0 Framework,从我的研究中我知道不再需要System.Threading.Tasks程序集(因为它是自动包含的)。 我错了吗?

如果我是对的,我现在非常确定会引发错误,因为google-api-dotnet-client开发人员使用的System.Threading.Tasks版本与Visual Studio 2010使用的版本不同。

当我删除一些行时,我注意到在检查应用程序的行为时。

这些线出来了:

 gcal = new CalendarService(new BaseClientService.Initializer() { Authenticator = auth, ApplicationName = APP_NAME, }); 

所以,我的新问题是:

有没有办法强制在VS2010中使用一个特定版本的参考组件?

感谢您帮助我,我相信它会对很多人有所帮助,因为google-calendar-api-v3的记录很糟糕。

亲切的问候,布鲁诺。


我的问题是我无法通过VisualStudio访问Google API作为服务。

我收到此错误:

 L'exception System.IO.FileLoadException n'a pas été gérée Message=Impossible de charger le fichier ou l'assembly 'System.Threading.Tasks, Version=1.5.11.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' ou une de ses dépendances. La définition trouvée du manifeste de l'assembly ne correspond pas à la référence de l'assembly. (Exception de HRESULT : 0x80131040) Source=MVMA FileName=System.Threading.Tasks, Version=1.5.11.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a FusionLog==== Informations d'état de liaison préalable === JRN : utilisateur = MODAL\brbo JRN : DisplayName = System.Threading.Tasks, Version=1.5.11.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a (Fully-specified) JRN : Appbase = file:///C:/Users/brbo/Documents/Visual Studio 2010/Projects/MVMA-V5.0 (With Gantt)/MVMA/bin/Debug/ JRN : PrivatePath initial = NULL Assembly appelant : Google.Apis, Version=1.4.0.28227, Culture=neutral, PublicKeyToken=null. === JRN : cette liaison démarre dans le contexte de chargement de default. JRN : utilisation du fichier de configuration de l'application : C:\Users\brbo\Documents\Visual Studio 2010\Projects\MVMA-V5.0 (With Gantt)\MVMA\bin\Debug\MVMA.vshost.exe.Config JRN : utilisation du fichier de configuration d'hôte : JRN : utilisation du fichier de configuration de l'ordinateur à partir de C:\Windows\Microsoft.NET\Framework64\v4.0.30319\config\machine.config. JRN : référence post-stratégie : System.Threading.Tasks, Version=1.5.11.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a JRN : tentative de téléchargement de la nouvelle URL file:///C:/Users/brbo/Documents/Visual Studio 2010/Projects/MVMA-V5.0 (With Gantt)/MVMA/bin/Debug/System.Threading.Tasks.DLL. AVT : la comparaison du nom de l'assembly a entraîné l'incompatibilité : Version principale ERR : impossible de terminer l'installation de l'assembly (hr = 0x80131040). Détection terminée. StackTrace: à MVMA.Classes.GoogleCalendar.BuildCalendarService() à System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx) à System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) à System.Threading.ThreadHelper.ThreadStart() 

这是我的类(相同的命名空间),它尝试使用Json Web Tokens连接到Google Calendar API v3:

 public class GoogleCalendar { // Chaînes d'accès aux services Google public const string APP_NAME = "HIDDEN"; public const string CLIENT_ID = "HIDDEN"; public const string CLIENT_SECRET = "HIDDEN"; public const string SERVICE_CLIENT_ID = "HIDDEN"; public const string EMAIL_ADDRESS = "HIDDEN"; public const string PUB_KEY = "HIDDEN"; public const string PRIV_KEY_PATH = @"C:\MVMA\HIDDEN-privatekey.p12"; public const string PRIV_KEY_SECRET = "notasecret"; public const string SIMPLE_API_KEY = "HIDDEN"; public const string SCOPE_CALENDAR = "https://www.googleapis.com/auth/calendar"; public const string SCOPE_CALENDAR_READONLY = "https://www.googleapis.com/auth/calendar.readonly"; private static CalendarService gcal; public static void ImportFromMVMA() { Thread yat = new Thread(new ThreadStart(BuildCalendarService)); yat.Start(); } // Permet de récupérer le service calendrier // Define the method that receives a callback when the results are available. private static void BuildCalendarService() { var certificate = new X509Certificate2(PRIV_KEY_PATH, PRIV_KEY_SECRET, X509KeyStorageFlags.Exportable); var privateKey = certificate.Export(X509ContentType.Cert); var provider = new AssertionFlowClient(GoogleAuthenticationServer.Description, certificate) { ServiceAccountId = EMAIL_ADDRESS, Scope = SCOPE_CALENDAR }; var auth = new OAuth2Authenticator(provider, AssertionFlowClient.GetState); gcal = new CalendarService(new BaseClientService.Initializer() { Authenticator = auth, ApplicationName = APP_NAME, }); } } public enum JwtHashAlgorithm { RS256, HS384, HS512 } public class JsonWebToken { private static Dictionary<JwtHashAlgorithm, Func> HashAlgorithms; static JsonWebToken() { HashAlgorithms = new Dictionary<JwtHashAlgorithm, Func> { { JwtHashAlgorithm.RS256, (key, value) => { using (var sha = new HMACSHA256(key)) { return sha.ComputeHash(value); } } }, { JwtHashAlgorithm.HS384, (key, value) => { using (var sha = new HMACSHA384(key)) { return sha.ComputeHash(value); } } }, { JwtHashAlgorithm.HS512, (key, value) => { using (var sha = new HMACSHA512(key)) { return sha.ComputeHash(value); } } } }; } public static string Encode(object payload, string key, JwtHashAlgorithm algorithm) { return Encode(payload, Encoding.UTF8.GetBytes(key), algorithm); } public static string Encode(object payload, byte[] keyBytes, JwtHashAlgorithm algorithm) { var segments = new List(); var header = new { alg = algorithm.ToString(), typ = "JWT" }; byte[] headerBytes = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(header, Formatting.None)); byte[] payloadBytes = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(payload, Formatting.None)); segments.Add(Base64UrlEncode(headerBytes)); segments.Add(Base64UrlEncode(payloadBytes)); var stringToSign = string.Join(".", segments.ToArray()); var bytesToSign = Encoding.UTF8.GetBytes(stringToSign); byte[] signature = HashAlgorithms[algorithm](keyBytes, bytesToSign); segments.Add(Base64UrlEncode(signature)); return string.Join(".", segments.ToArray()); } public static string Decode(string token, string key) { return Decode(token, key, true); } public static string Decode(string token, string key, bool verify) { var parts = token.Split('.'); var header = parts[0]; var payload = parts[1]; byte[] crypto = Base64UrlDecode(parts[2]); var headerJson = Encoding.UTF8.GetString(Base64UrlDecode(header)); var headerData = JObject.Parse(headerJson); var payloadJson = Encoding.UTF8.GetString(Base64UrlDecode(payload)); var payloadData = JObject.Parse(payloadJson); if (verify) { var bytesToSign = Encoding.UTF8.GetBytes(string.Concat(header, ".", payload)); var keyBytes = Encoding.UTF8.GetBytes(key); var algorithm = (string)headerData["alg"]; var signature = HashAlgorithms[GetHashAlgorithm(algorithm)](keyBytes, bytesToSign); var decodedCrypto = Convert.ToBase64String(crypto); var decodedSignature = Convert.ToBase64String(signature); if (decodedCrypto != decodedSignature) { throw new ApplicationException(string.Format("Invalid signature. Expected {0} got {1}", decodedCrypto, decodedSignature)); } } return payloadData.ToString(); } private static JwtHashAlgorithm GetHashAlgorithm(string algorithm) { switch (algorithm) { case "RS256": return JwtHashAlgorithm.RS256; case "HS384": return JwtHashAlgorithm.HS384; case "HS512": return JwtHashAlgorithm.HS512; default: throw new InvalidOperationException("Algorithm not supported."); } } // from JWT spec private static string Base64UrlEncode(byte[] input) { var output = Convert.ToBase64String(input); output = output.Split('=')[0]; // Remove any trailing '='s output = output.Replace('+', '-'); // 62nd char of encoding output = output.Replace('/', '_'); // 63rd char of encoding return output; } // from JWT spec private static byte[] Base64UrlDecode(string input) { var output = input; output = output.Replace('-', '+'); // 62nd char of encoding output = output.Replace('_', '/'); // 63rd char of encoding switch (output.Length % 4) // Pad with trailing '='s { case 0: break; // No pad chars in this case case 2: output += "=="; break; // Two pad chars case 3: output += "="; break; // One pad char default: throw new System.Exception("Illegal base64url string!"); } var converted = Convert.FromBase64String(output); // Standard base64 decoder return converted; } } public class GoogleJsonWebToken { public static string GetAccessToken(string email, string certificateFilePath, string serviceScope) { var utc0 = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc); var issueTime = DateTime.Now; var iat = (int)issueTime.Subtract(utc0).TotalSeconds; var exp = (int)issueTime.AddMinutes(55).Subtract(utc0).TotalSeconds; // Expiration time is up to 1 hour, but lets play on safe side var payload = new { iss = email, scope = serviceScope, aud = "https://accounts.google.com/o/oauth2/token", exp = exp, iat = iat }; var certificate = new X509Certificate2(certificateFilePath, GoogleCalendar.PRIV_KEY_SECRET); var privateKey = certificate.Export(X509ContentType.Cert); return JsonWebToken.Encode(payload, privateKey, JwtHashAlgorithm.RS256); } } 

我不明白为什么我在System.Threading.Tasks程序集上有一个FileLoadException。 我尝试向已经使用任务而没有问题的应用程序添加新function。 此应用程序使用在不同线程中运行的TabPage对象。

删除对System.Threading.Tasks所有引用,然后从您使用的任何.NET版本(.NET 4.0)中添加一个。

Google Calendar API可能使用不同版本的.NET

手动重定向程序集

您可以指定要在app.config中使用的程序集版本